Skyhigh 11 ch18 Coders Corner

From C64 Diskmag Wiki
Jump to: navigation, search
             coders corner.

 this is the second time i'm writing the
beginning of the code-chapter. why ?.
well, my text-disc got lost somewhere in
my room or maybe it has flown away.

 i was planning to do some sort of a
'mnemonic-appendix' which descripes ALL
the MC-commands, the different way of
adressing them, the way they effect the
flags in the status-register and of-
course some hints & tips. (eg. remember
to use at SEC before SBC if you subtract
without knowing what the CARRY-FLAG
holds). i've allready written ca 450
lines. hopefully i'll find my disc soon
and you'll see my 'MC-appendix' in the
next issue of skyhigh.


 as written in the previous code-chapter
i assume you're using an assembler with
this MC-curse. the assembler translates
the mnemonics to the real machine-code
(opcodes, opcode vectors & datas. eg.
LDA $c000,x = $bd $00 $c0 ). i'll now
introduce you to the turbo-ass.
 this is a general introduction and it
should work with allmost all variants.


the turbo-assembler uses the following
locations for the assember itself & for
source-code and datas.

$9000-$d000 : turbo-assembler program.

$d000-$ffff : labels & other datas.

$????-$8fff : source-code.

 $???? is the end-address of the source-
code. please note that the source-code
is taking up memory-space backwards.
 the counter starts at $8fff and de-
creases as more lines are added. the
current address can be read in the
status-line in the buttom of the screen.
 use the memory-location below this
address for you own program. (if you
are a skilled programmer, you'll find
out ways to use the rest of the memory.
eg. by using a cross assembler).

 for our test programs we'll use the
address $4000.

             the '*' symbol:

 the turbo assembler uses the symbol
'*' as a 'program counter'. the '*'
always hold the current address. when
the source-code is assembled the '*'
will hold the start-value (eg $4000) and
during the assembling process it'll
indicate where to in the memory the
code is being assembled.


     * = $4000  ; set start-address

     lda #$00   ;'*' holds the value
                ;$4000 when this command
                ;is about to be assemb-

     sta $d020  ;'*' now holds the add.

     rts        ;$4005

example 2:

     * = $4000 ;start

     lda #$00  ; all this is assembled
     sta $d020 ; into the area $4000-
     rts       ; $4005 (inclusive).

     * = $2000 ;new start in the same

     .byte $00,$01,$02,$03,$04

               ;these datas are ass.
               ;into $2000-$2004.

           THE USE OF NUMBERS.

 the turbo-assembler 'understands'
three different set of numbers. decimal,
hex and binary.

 a '$' sign infront of the number indi-
cates hex.

 '%' means binary.

 if you use binary numbers, the turbo-
assembler will only accept you entries
if it made of 8 digits. if the number
is too big (eg. %1111110011) you'll
get a error message. if the number is
too small the assembler will inset the
'missing' zeros (eg %10001 = %00010001)
 the turbo-assembler always work eigher
byte-wise (1 byte = 8 bits = 8 BInary
digiTS) or WORD-wise (2 bytes). binary
numbers are bytes only. HEX can be both.
(eg: you write $1, the turbo-assembler
insets a zero = $01. example 2: $211 is
equal to $0211). is quite a clever act
to inset the missing zeros. by doing
this the turbo-assembler you source-
code easier to understand:

example:  (this is chaos:)

       lda #$1
       sta $400
       sta $0401
       lda #%101
       sta $0400
       sta $401
       lda #%0101
       sta $d020
       lda #%1010
       sta $800

 if you enter this mess in turbo-ass,
you'll get this listing:

       lda #$01
       sta $0400
       sta $0401
       lda #%00000101
       sta $0400
       sta $0401
       lda #%00000101
       sta $d020
       lda #%00001010
       sta $0800

 NOTICE: DECIMAL numbers are shown
as they are written = no zeros infront.
 i normally stick up hex-numbers, and
only use the decimal version when i'm
too lazy to find out the hex-value or
if i'm changing the number very often.
(eg. in my firework routine in 'camel
park' (soon to be released) i used a
label which hold the number of plots.
(maxplots = 54) i had to change this
as i optimized the routine. lazyness ?)

            JUMPS AND LABELS.

 last time i expained the general func-
tion of 'LDA', 'STA' and RTS.
 the next command i'll introduce is the

 as told last issue the 6502/6510 has
got Program Counter (PC) which is a 2-
byte (1 word) register which points to
the location of the command currently
being executed. the function of the
'JMP' (JuMP) is the change the pointer.
 is quite simple: by using a JMP you
can perform a jump to somewhere else
in you code.


$4000   lda #$00    ;'A'=0
$4002   sta $d020   ;'A' into $d020
$4005   sta $d021   ;'A' into $d021
$4008   jmp $4020   ;jump .....
$4009                         .
 .                            .
 .                            .
 .                            .
$401f                         .
$4020   lda #$01   ;...........
$4022   sta $0400  ;$01 into $0400
$4023   rts        ;return to basic.

 this is an example of a direct jump.

 if you move the code at $4020 to some-
where else in the memory you'll have
to change the jump.

 in an assembler you'll allways use
LABELS instead.

 LABELS are words which descripes diffe-
rent location in the code. 'inside' the
assembler the labels represent a value
(normally the position in the code
where they are written.)



      * = $4000

      jmp white    4000 jmp $400e
      lda #$00     4003 lda #$00
      sta $d020    4005 sta $d020
      sta $d021    4008 sta $d021
      jmp exit     400b jmp $4016
      lda #$01     400e lda #$01
      sta $d020    4010 sta $d020
      sta $d021    4013 sta $d021
      lda #$01     4016 lda #$01
      sta $0400    4018 sta $0400
      rts          401b rts

 if you'd written this small program
in a mc-monitor you'll get serious
trouble if you want to expand the
routine 'black'. you'd have to copy the
rest of the program 'white','exit' to
another location. (eg. if you want to
inplant a 'sta $d015' in 'black' you'll
have to push the rest of the program
3 bytes). you'll then have to modify
all the JMPs.
 if you use an assembler, it'll take
care of this for you.

              PRESET LABELS

 if the labels are written as descriped
(as marks in the sourcecode) they'll
represent the value of the memory-
location of the next order (and this is
handy of jumps etc). however it's
possible to assign any value to a label.


clrscr   = $e544 ;the lable 'clrscr' is
                 ;set to the value
                 ;$e544 (where the ROM
                 ;clearscreen routine
                 ;is placed.

       * = $4000 ;start of own program.

       lda #$0b  ;grey
       sta $d020
       lda #$00  ;black
       sta $d021
       lda #$07  ;yellow
       sta $0286 ;set basic-char-col to

       jmp clrscr;jump to ROM-clear-
                 ;screen routine.
                 ;(it clears the screen
                 ;and fills the col-ram
                 ;with the value
                 ;written in $0286.

 in some version of turbo-assember the
addressing will be messed up if you
place the setting of the labels in the
middle of the program. you can avoid
this by placing all the preset labels
above the start-address setting
(* $xxxx) or by witting a * = * after
the settings.

                 X and Y

 so far i've use the accumulator (A) in
my examples. the 6502/6510 has got two
more registers which can be used of
manipulating the memory. the X and Y
register can be used the same way as the
accumulator, but they make more sophis-
ticated adressing possible also.

 using X and Y the same way as the

               LDX & LDY:

        like LDA but for X and Y.

               STX & STY:

                like sta.

 loading one register (a,x or y) does
not change the contents of the others.

 it's possible to use the x and y
register for flexible addressing:

       LDA $XXXX,X and LDA $XXXX,Y

 loading the accumulator from an address
coma x, makes the processor load A from
the specified address PLUS the number
hold in x:

example 1:

       ldx #$02
       lda $4000,x ;load a from $4002

example 2:

       ldy #$fe
       lda $4157,y ;load a from $4255

example 3:

       ldy #$02
       ldx $4000,y ;load x from $4002

example 4:

       ldx #$28
       ldy $0400,x ;load y from $0428

 STA can be used much the same way:

example 1:

       lda #$00
       ldx #$01
       sta $d020,x ;set $d021 to $00

example 2:

       lda #$0f
       ldx #$20
       sta $d000,x ;set $d020 to $0f

NOTICE: stx,y and sty,x are NOT possible
        unless you store ZEROPAGE,x/y.

 (read MUCH more about all the diffe-
rent ways of addressing in the next iss.

          DEX, INX & DEY, INY.

      (DEcrease X/Y, INcrease X/Y)

 these four orders can be used for in-/
de-creasing x and y by 1 BYTE.

example 1:

       lda #$00
       ldx #$00
       sta $d020,x ;store in $d020
       sta $d020,x ;store in $d021

example 2:

       lda #$0f
       ldy #$21
       sta $d000,y ;store in $d021
       sta $d000,y ;store in $d020


 the last thing i'm going to teach you
now is how to make a loop. further
information on all different types to
'test-and-jumps' (branches) will be
printed in the next issue.

       * = $4000

       lda #$01 ;$01=char $01='a'
       ldy #$27
       sta $0400,y;store $01 into screen
       dey        ;decrease y by 1
       bne loop   ;jump if not zero

       sta $0400,y;when y=0

 the program fills the first line on the
screen with 'a's. the 'dey' decreases y
and the sta $0400,y will therefore store
to a decreasing location during the loop
($0427,$0426,$0425...$0402,$0401). when
y reaces zero a flag will be set in the
statuts-register. 'bne' test this flag.
as long as y (DEY is the only command
that influences on this flag during the
loop) is different from zero the
program will jump to 'loop'. the last
sta $0400,y is used to make a sta $0400.

              WILL BE HERE.

   see you in the next coders corner.

Personal tools