Skyhigh 11 ch18 Coders Corner
From C64 Diskmag Wiki
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. USING THE TURBO-ASSEMBLER. 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. MEMORY. 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. exampels: * = $4000 ; set start-address lda #$00 ;'*' holds the value ;$4000 when this command ;is about to be assemb- ;led. sta $d020 ;'*' now holds the add. ;$4002. rts ;$4005 ;$4006 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 ;source-code. .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 'JMP'. 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. example: $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.) example: SOURCE CODE: ASSEMBLED CODE: * = $4000 jmp white 4000 jmp $400e black lda #$00 4003 lda #$00 sta $d020 4005 sta $d020 sta $d021 4008 sta $d021 jmp exit 400b jmp $4016 white lda #$01 400e lda #$01 sta $d020 4010 sta $d020 sta $d021 4013 sta $d021 exit 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. example: 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 ;yellow. 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 accumulator: 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 inx sta $d020,x ;store in $d021 example 2: lda #$0f ldy #$21 sta $d000,y ;store in $d021 dey sta $d000,y ;store in $d020 LOOPS: 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 loop sta $0400,y;store $01 into screen dey ;decrease y by 1 bne loop ;jump if not zero sta $0400,y;when y=0 rts 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. NEXT ISSUE MY BIG MC-COMMAND APPENDIX WILL BE HERE. see you in the next coders corner. -raz