#if VERBOSE = 1 LASTINIT SET . #endif ; Subroutines ; ---------------------------------------------------------------------- ; Clear screen -- easy clearScreen SUBROUTINE ldx #$ff .loop: lda #$80 sta $400,x sta $500,x sta $600,x sta $700,x lda #$05 sta $d800,x sta $d900,x sta $da00,x sta $db00,x dex cpx #$ff bne .loop ; Do some math to calculate tile address in video memory ; using x,y coordinates ; Formula: addr = $400 + y * SCREEN_W + x calcTileMem SUBROUTINE ; Save registers pha txa pha tya pha ; Set tileMem to $400 lda #$00 sta tileMem lda #$04 sta tileMem + 1 ldy calcTileY ; Get head Y coordinate calcTileMult: tya beq calcTileEnd ; if Y is equal to zero, nothing to do, just skip moltiplication, else... dey ; decrement Y clc lda #SCREEN_W ; A = screen width = 40 adc tileMem ; A = screen width + tileMem (low) sta tileMem ; update tileMem (low) lda #0 ; do the same with higher byte: A = 0 adc tileMem + 1 ; add (eventual) carry sta tileMem + 1 ; update tileMem (high) jmp calcTileMult ; do again until Y == 0 calcTileEnd: ; now multiplication is ended, so add X lda calcTileX adc tileMem sta tileMem lda #0 adc tileMem + 1 sta tileMem + 1 ; Restore old registers pla tay pla tax pla rts ; Print a byte in hexadecimal ; A input register for byte to print ; Y input register for printing colum (on first line) printByte SUBROUTINE ; Copy parameter also in X tax lsr ; Take most significant nibble lsr lsr lsr ora #$c0 ; add 192 (see font) sta $400,y ; print msb char txa ; Take least significant nibble (use previous copy) and #$0f ora #$c0 ; add 192 (see font) sta $401,y ; print lsb char rts printString SUBROUTINE ; Print string ; Input parameters: ; srcStringPointer pointer to string to be printed (source) ; dstScreenPointer pointer to text video memory on screen where to print (dest) ; Output results: ; Y leaves string length in reg Y ldy #0 .loop: lda (srcStringPointer),y ; get char from string beq .end ; if zero, then end (string must be null-terminated) cmp #$20 ; is space? bne .checkP1 lda #$80 jmp .print .checkP1: cmp #$28 ; is char '(' ? bne .checkP2 lda #$9b jmp .print .checkP2: cmp #$29 ; is char ')' ? bne .checkP3 lda #$9c jmp .print .checkP3 cmp #$2e ; is char '.' ? bne .checkNumber lda #$9d jmp .print .checkNumber: ; is char a number? cmp #$2f bcc .nextCheck cmp #$3a bcs .nextCheck sec sbc #$30 clc adc #$c0 jmp .print .nextCheck: .isLetter: ; defaults to an uppercase letter of ASCII set clc adc #$40 .print: sta (dstScreenPointer),y ; put screen code to screen iny ; next char in string jmp .loop .end: rts ; Increment a pointer in the zeropage ; Input parameters: ; nextPointerPointer pointer to the pointer in zeropage ; regX value to increment nextPointer: lda #0 sta nextPointerPointer + 1 txa clc ldy #0 adc (nextPointerPointer),y sta (nextPointerPointer),y ldy #1 lda (nextPointerPointer),y adc #0 sta (nextPointerPointer),y rts #if VERBOSE = 1 ECHO "subroutines.asm @ ",LASTINIT,"len:",(. - LASTINIT) #endif