snake6502/src/subroutines.asm

178 lines
3.9 KiB
NASM
Raw Normal View History

2021-11-07 17:14:59 +00:00
SEG zeropageSegment
; Where is the snake head in video memory? Do math to calculate address
; using pointer at tileMem
tileMem WORD
2020-04-08 07:15:25 +00:00
2021-11-07 17:14:59 +00:00
SEG programSegment
2020-04-08 07:15:25 +00:00
; Clear screen -- easy
clearScreen SUBROUTINE
ldx #$ff
.loop:
lda #$80
2020-04-08 07:15:25 +00:00
sta $400,x
sta $500,x
sta $600,x
sta $700,x
2021-04-14 07:50:46 +00:00
lda #$05
2020-04-08 07:15:25 +00:00
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
2020-04-06 20:00:15 +00:00
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)
2020-04-06 20:00:15 +00:00
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)
2020-04-06 16:44:54 +00:00
sta $401,y ; print lsb char
rts
2021-11-07 17:14:59 +00:00
SEG zeropageSegment
; Pointer to string
srcStringPointer WORD
; Pointer to screen position where to print intro string
dstScreenPointer DS 2
SEG programSegment
2020-04-08 09:03:03 +00:00
printString SUBROUTINE
; Print string
; Input parameters:
2020-04-08 09:03:03 +00:00
; srcStringPointer pointer to string to be printed (source)
; dstScreenPointer pointer to text video memory on screen where to print (dest)
2020-04-08 07:15:25 +00:00
; Output results:
; Y leaves string length in reg Y
ldy #0
2020-04-06 20:00:15 +00:00
.loop:
2020-04-08 09:03:03 +00:00
lda (srcStringPointer),y ; get char from string
2020-04-06 20:00:15 +00:00
beq .end ; if zero, then end (string must be null-terminated)
2020-04-06 16:44:54 +00:00
cmp #$20 ; is space?
2020-04-06 20:00:15 +00:00
bne .checkP1
lda #$80
2020-04-06 20:00:15 +00:00
jmp .print
.checkP1:
cmp #$28 ; is char '(' ?
bne .checkP2
lda #$9b
2020-04-06 20:00:15 +00:00
jmp .print
.checkP2:
cmp #$29 ; is char ')' ?
bne .checkP3
lda #$9c
2020-04-06 20:00:15 +00:00
jmp .print
.checkP3
cmp #$2e ; is char '.' ?
bne .checkNumber
lda #$9d
2020-04-06 20:00:15 +00:00
jmp .print
.checkNumber: ; is char a number?
cmp #$2f
bcc .nextCheck
cmp #$3a
bcs .nextCheck
sec
2020-04-06 20:00:15 +00:00
sbc #$30
clc
adc #$c0
2020-04-06 20:00:15 +00:00
jmp .print
.nextCheck:
2020-04-06 20:00:15 +00:00
.isLetter:
; defaults to an uppercase letter of ASCII set
clc
adc #$40
2020-04-06 20:00:15 +00:00
.print:
2020-04-08 09:03:03 +00:00
sta (dstScreenPointer),y ; put screen code to screen
iny ; next char in string
2020-04-06 20:00:15 +00:00
jmp .loop
.end:
rts
SEG zeropageSegment
; Pointer for Pointer in the NextPointer routine
nextPointerPointer DS 2
SEG programSegment
2020-04-02 15:09:57 +00:00
; 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