some cleanups in library asm code

This commit is contained in:
Irmen de Jong 2019-03-21 22:36:46 +01:00
parent f6bc69139d
commit 7114d3193c
10 changed files with 91 additions and 95 deletions

View File

@ -235,7 +235,7 @@ asmsub GETIN () -> clobbers(X,Y) -> (ubyte @ A) = $FFE4 ; (via 810 ($32A))
asmsub CLALL () -> clobbers(A,X) -> () = $FFE7 ; (via 812 ($32C)) close all files asmsub CLALL () -> clobbers(A,X) -> () = $FFE7 ; (via 812 ($32C)) close all files
asmsub UDTIM () -> clobbers(A,X) -> () = $FFEA ; update the software clock asmsub UDTIM () -> clobbers(A,X) -> () = $FFEA ; update the software clock
asmsub SCREEN () -> clobbers() -> (ubyte @ X, ubyte @ Y) = $FFED ; read number of screen rows and columns asmsub SCREEN () -> clobbers() -> (ubyte @ X, ubyte @ Y) = $FFED ; read number of screen rows and columns
asmsub PLOT (ubyte dir @ Pc, ubyte col @ Y, ubyte row @ X) -> clobbers() -> (ubyte @ X, ubyte @ Y) = $FFF0 ; read/set position of cursor on screen. See c64scr.PLOT for a 'safe' wrapper that preserves X. asmsub PLOT (ubyte dir @ Pc, ubyte col @ Y, ubyte row @ X) -> clobbers() -> (ubyte @ X, ubyte @ Y) = $FFF0 ; read/set position of cursor on screen. Use c64scr.plot for a 'safe' wrapper that preserves X.
asmsub IOBASE () -> clobbers() -> (uword @ XY) = $FFF3 ; read base address of I/O devices asmsub IOBASE () -> clobbers() -> (uword @ XY) = $FFF3 ; read base address of I/O devices
; ---- end of C64 kernal routines ---- ; ---- end of C64 kernal routines ----

View File

@ -54,40 +54,39 @@ asmsub ubyte2hex (ubyte value @ A) -> clobbers() -> (ubyte @ A, ubyte @ Y) {
pha pha
and #$0f and #$0f
tax tax
ldy hex_digits,x ldy _hex_digits,x
pla pla
lsr a lsr a
lsr a lsr a
lsr a lsr a
lsr a lsr a
tax tax
lda hex_digits,x lda _hex_digits,x
ldx c64.SCRATCH_ZPREGX ldx c64.SCRATCH_ZPREGX
rts rts
hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as well _hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as well
}} }}
} }
str word2hex_output = "1234" ; 0-terminated, to make printing easier
asmsub uword2hex (uword value @ AY) -> clobbers(A,Y) -> () { asmsub uword2hex (uword value @ AY) -> clobbers(A,Y) -> () {
; ---- convert 16 bit uword in A/Y into 4-character hexadecimal string into memory 'word2hex_output' ; ---- convert 16 bit uword in A/Y into 4-character hexadecimal string 'uword2hex.output' (0-terminated)
%asm {{ %asm {{
sta c64.SCRATCH_ZPREG sta c64.SCRATCH_ZPREG
tya tya
jsr ubyte2hex jsr ubyte2hex
sta word2hex_output sta output
sty word2hex_output+1 sty output+1
lda c64.SCRATCH_ZPREG lda c64.SCRATCH_ZPREG
jsr ubyte2hex jsr ubyte2hex
sta word2hex_output+2 sta output+2
sty word2hex_output+3 sty output+3
rts rts
output .text "0000", $00 ; 0-terminated output buffer (to make printing easier)
}} }}
} }
ubyte[3] word2bcd_bcdbuff = [0, 0, 0]
asmsub uword2bcd (uword value @ AY) -> clobbers(A,Y) -> () { asmsub uword2bcd (uword value @ AY) -> clobbers(A,Y) -> () {
; Convert an 16 bit binary value to BCD ; Convert an 16 bit binary value to BCD
; ;
@ -106,22 +105,22 @@ asmsub uword2bcd (uword value @ AY) -> clobbers(A,Y) -> () {
sei ; disable interrupts because of bcd math sei ; disable interrupts because of bcd math
sed ; switch to decimal mode sed ; switch to decimal mode
lda #0 ; ensure the result is clear lda #0 ; ensure the result is clear
sta word2bcd_bcdbuff+0 sta bcdbuff+0
sta word2bcd_bcdbuff+1 sta bcdbuff+1
sta word2bcd_bcdbuff+2 sta bcdbuff+2
ldy #16 ; the number of source bits ldy #16 ; the number of source bits
- asl c64.SCRATCH_ZPB1 ; shift out one bit - asl c64.SCRATCH_ZPB1 ; shift out one bit
rol c64.SCRATCH_ZPREG rol c64.SCRATCH_ZPREG
lda word2bcd_bcdbuff+0 ; and add into result lda bcdbuff+0 ; and add into result
adc word2bcd_bcdbuff+0 adc bcdbuff+0
sta word2bcd_bcdbuff+0 sta bcdbuff+0
lda word2bcd_bcdbuff+1 ; propagating any carry lda bcdbuff+1 ; propagating any carry
adc word2bcd_bcdbuff+1 adc bcdbuff+1
sta word2bcd_bcdbuff+1 sta bcdbuff+1
lda word2bcd_bcdbuff+2 ; ... thru whole result lda bcdbuff+2 ; ... thru whole result
adc word2bcd_bcdbuff+2 adc bcdbuff+2
sta word2bcd_bcdbuff+2 sta bcdbuff+2
dey ; and repeat for next bit dey ; and repeat for next bit
bne - bne -
cld ; back to binary cld ; back to binary
@ -130,23 +129,24 @@ asmsub uword2bcd (uword value @ AY) -> clobbers(A,Y) -> () {
cli ; enable interrupts again (only if they were enabled before) cli ; enable interrupts again (only if they were enabled before)
+ rts + rts
_had_irqd .byte 0 _had_irqd .byte 0
bcdbuff .byte 0,0,0
}} }}
} }
ubyte[5] word2decimal_output = 0 asmsub uword2decimal (uword value @ AY) -> clobbers(A) -> (ubyte @ Y) {
asmsub uword2decimal (uword value @ AY) -> clobbers(A,Y) -> () { ; ---- convert 16 bit uword in A/Y into 0-terminated decimal string into memory 'uword2decimal.output'
; ---- convert 16 bit uword in A/Y into decimal string into memory 'word2decimal_output' ; returns length of resulting string in Y
%asm {{ %asm {{
jsr uword2bcd jsr uword2bcd
lda word2bcd_bcdbuff+2 lda uword2bcd.bcdbuff+2
clc clc
adc #'0' adc #'0'
sta word2decimal_output sta output
ldy #1 ldy #1
lda word2bcd_bcdbuff+1 lda uword2bcd.bcdbuff+1
jsr + jsr +
lda word2bcd_bcdbuff+0 lda uword2bcd.bcdbuff+0
+ pha + pha
lsr a lsr a
@ -155,14 +155,19 @@ asmsub uword2decimal (uword value @ AY) -> clobbers(A,Y) -> () {
lsr a lsr a
clc clc
adc #'0' adc #'0'
sta word2decimal_output,y sta output,y
iny iny
pla pla
and #$0f and #$0f
adc #'0' adc #'0'
sta word2decimal_output,y sta output,y
iny iny
lda #0
sta output,y
rts rts
output .text "00000", $00 ; 0 terminated
}} }}
} }
@ -337,9 +342,9 @@ _irq_handler_init
dex dex
dex dex
rts rts
_irq_handler_end _irq_handler_end
; restore all zp scratch registers and the X register ; restore all zp scratch registers and the X register
lda IRQ_SCRATCH_ZPB1 lda IRQ_SCRATCH_ZPB1
sta c64.SCRATCH_ZPB1 sta c64.SCRATCH_ZPB1
lda IRQ_SCRATCH_ZPREG lda IRQ_SCRATCH_ZPREG
@ -356,7 +361,7 @@ _irq_handler_end
sta c64.SCRATCH_ZPWORD2+1 sta c64.SCRATCH_ZPWORD2+1
ldx IRQ_X_REG ldx IRQ_X_REG
rts rts
IRQ_X_REG .byte 0 IRQ_X_REG .byte 0
IRQ_SCRATCH_ZPB1 .byte 0 IRQ_SCRATCH_ZPB1 .byte 0
IRQ_SCRATCH_ZPREG .byte 0 IRQ_SCRATCH_ZPREG .byte 0
@ -517,7 +522,7 @@ _loop sta c64.Colors,y
} }
asmsub scroll_left_full (ubyte alsocolors @ Pc) -> clobbers(A, Y) -> () { asmsub scroll_left_full (ubyte alsocolors @ Pc) -> clobbers(A, Y) -> () {
; ---- scroll the whole screen 1 character to the left ; ---- scroll the whole screen 1 character to the left
; contents of the rightmost column are unchanged, you should clear/refill this yourself ; contents of the rightmost column are unchanged, you should clear/refill this yourself
; Carry flag determines if screen color data must be scrolled too ; Carry flag determines if screen color data must be scrolled too
@ -578,7 +583,7 @@ _scroll_screen ; scroll the screen memory
} }
asmsub scroll_right_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () { asmsub scroll_right_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
; ---- scroll the whole screen 1 character to the right ; ---- scroll the whole screen 1 character to the right
; contents of the leftmost column are unchanged, you should clear/refill this yourself ; contents of the leftmost column are unchanged, you should clear/refill this yourself
; Carry flag determines if screen color data must be scrolled too ; Carry flag determines if screen color data must be scrolled too
@ -631,7 +636,7 @@ _scroll_screen ; scroll the screen memory
} }
asmsub scroll_up_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () { asmsub scroll_up_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
; ---- scroll the whole screen 1 character up ; ---- scroll the whole screen 1 character up
; contents of the bottom row are unchanged, you should refill/clear this yourself ; contents of the bottom row are unchanged, you should refill/clear this yourself
; Carry flag determines if screen color data must be scrolled too ; Carry flag determines if screen color data must be scrolled too
@ -684,7 +689,7 @@ _scroll_screen ; scroll the screen memory
} }
asmsub scroll_down_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () { asmsub scroll_down_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
; ---- scroll the whole screen 1 character down ; ---- scroll the whole screen 1 character down
; contents of the top row are unchanged, you should refill/clear this yourself ; contents of the top row are unchanged, you should refill/clear this yourself
; Carry flag determines if screen color data must be scrolled too ; Carry flag determines if screen color data must be scrolled too
@ -889,7 +894,7 @@ asmsub print_uw0 (uword value @ AY) -> clobbers(A,Y) -> () {
%asm {{ %asm {{
jsr c64utils.uword2decimal jsr c64utils.uword2decimal
ldy #0 ldy #0
- lda c64utils.word2decimal_output,y - lda c64utils.uword2decimal.output,y
jsr c64.CHROUT jsr c64.CHROUT
iny iny
cpy #5 cpy #5
@ -904,25 +909,25 @@ asmsub print_uw (uword value @ AY) -> clobbers(A,Y) -> () {
%asm {{ %asm {{
jsr c64utils.uword2decimal jsr c64utils.uword2decimal
ldy #0 ldy #0
lda c64utils.word2decimal_output lda c64utils.uword2decimal.output
cmp #'0' cmp #'0'
bne _pr_decimal bne _pr_decimal
iny iny
lda c64utils.word2decimal_output+1 lda c64utils.uword2decimal.output+1
cmp #'0' cmp #'0'
bne _pr_decimal bne _pr_decimal
iny iny
lda c64utils.word2decimal_output+2 lda c64utils.uword2decimal.output+2
cmp #'0' cmp #'0'
bne _pr_decimal bne _pr_decimal
iny iny
lda c64utils.word2decimal_output+3 lda c64utils.uword2decimal.output+3
cmp #'0' cmp #'0'
bne _pr_decimal bne _pr_decimal
iny iny
_pr_decimal _pr_decimal
lda c64utils.word2decimal_output,y lda c64utils.uword2decimal.output,y
jsr c64.CHROUT jsr c64.CHROUT
iny iny
cpy #5 cpy #5
@ -932,7 +937,7 @@ _pr_decimal
} }
asmsub print_w (word value @ AY) -> clobbers(A,Y) -> () { asmsub print_w (word value @ AY) -> clobbers(A,Y) -> () {
; ---- print the (signed) word in A/Y in decimal form, without left padding 0s ; ---- print the (signed) word in A/Y in decimal form, without left padding 0's
%asm {{ %asm {{
cpy #0 cpy #0
bpl + bpl +
@ -1081,7 +1086,7 @@ _colormod sta $ffff ; modified
}} }}
} }
asmsub PLOT (ubyte col @ Y, ubyte row @ A) -> clobbers(A) -> () { asmsub plot (ubyte col @ Y, ubyte row @ A) -> clobbers(A) -> () {
; ---- safe wrapper around PLOT kernel routine, to save the X register. ; ---- safe wrapper around PLOT kernel routine, to save the X register.
%asm {{ %asm {{
stx c64.SCRATCH_ZPREGX stx c64.SCRATCH_ZPREGX

View File

@ -44,10 +44,10 @@ sub start() {
sub print_notes(ubyte n1, ubyte n2) { sub print_notes(ubyte n1, ubyte n2) {
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.PLOT(n1/2, 24) c64scr.plot(n1/2, 24)
c64.COLOR=7 c64.COLOR=7
c64.CHROUT('Q') c64.CHROUT('Q')
c64scr.PLOT(n2/2, 24) c64scr.plot(n2/2, 24)
c64.COLOR=4 c64.COLOR=4
c64.CHROUT('Q') c64.CHROUT('Q')
} }

View File

@ -24,7 +24,7 @@
c64scr.clear_screenchars(32) c64scr.clear_screenchars(32)
draw_edges() draw_edges()
time+=0.2 time+=0.2
c64scr.PLOT(0,0) c64scr.plot(0,0)
c64scr.print("3d cube! (float) ") c64scr.print("3d cube! (float) ")
c64scr.print_ub(c64.TIME_LO) c64scr.print_ub(c64.TIME_LO)
c64scr.print(" jiffies/frame") c64scr.print(" jiffies/frame")

View File

@ -89,7 +89,7 @@
anglex-=500 anglex-=500
angley+=217 angley+=217
anglez+=452 anglez+=452
c64scr.PLOT(0,0) c64scr.plot(0,0)
c64scr.print("3d cube! (sprites) ") c64scr.print("3d cube! (sprites) ")
c64scr.print_ub(c64.TIME_LO) c64scr.print_ub(c64.TIME_LO)
c64scr.print(" jiffies/frame ") c64scr.print(" jiffies/frame ")

View File

@ -29,7 +29,7 @@
anglex+=1000 anglex+=1000
angley+=433 angley+=433
anglez+=907 anglez+=907
c64scr.PLOT(0,0) c64scr.plot(0,0)
c64scr.print("3d cube! (integer) ") c64scr.print("3d cube! (integer) ")
c64scr.print_ub(c64.TIME_LO) c64scr.print_ub(c64.TIME_LO)
c64scr.print(" jiffies/frame") c64scr.print(" jiffies/frame")

View File

@ -1,4 +1,6 @@
; @todo fix this (issue #11 on github): it generates invalid asm due to improper label names
~ main { ~ main {
sub start() { sub start() {

View File

@ -42,7 +42,7 @@
float duration = floor(((c64.TIME_LO as float) float duration = floor(((c64.TIME_LO as float)
+ 256.0*(c64.TIME_MID as float) + 256.0*(c64.TIME_MID as float)
+ 65536.0*(c64.TIME_HI as float))/60.0) + 65536.0*(c64.TIME_HI as float))/60.0)
c64scr.PLOT(0, 21) c64scr.plot(0, 21)
c64scr.print("finished in ") c64scr.print("finished in ")
c64flt.print_f(duration) c64flt.print_f(duration)
c64scr.print(" seconds!\n") c64scr.print(" seconds!\n")

View File

@ -214,24 +214,24 @@ waitkey:
sub gameOver() { sub gameOver() {
sound.gameover() sound.gameover()
c64scr.PLOT(7, 7) c64scr.plot(7, 7)
c64.CHROUT('U') c64.CHROUT('U')
c64scr.print("────────────────────────") c64scr.print("────────────────────────")
c64.CHROUT('I') c64.CHROUT('I')
c64scr.PLOT(7, 8) c64scr.plot(7, 8)
c64scr.print("│*** g a m e o v e r ***│") c64scr.print("│*** g a m e o v e r ***│")
c64scr.PLOT(7, 9) c64scr.plot(7, 9)
c64.CHROUT('J') c64.CHROUT('J')
c64scr.print("────────────────────────") c64scr.print("────────────────────────")
c64.CHROUT('K') c64.CHROUT('K')
c64scr.PLOT(7, 18) c64scr.plot(7, 18)
c64.CHROUT('U') c64.CHROUT('U')
c64scr.print("────────────────────────") c64scr.print("────────────────────────")
c64.CHROUT('I') c64.CHROUT('I')
c64scr.PLOT(7, 19) c64scr.plot(7, 19)
c64scr.print("│ f1 for new game │") c64scr.print("│ f1 for new game │")
c64scr.PLOT(7, 20) c64scr.plot(7, 20)
c64.CHROUT('J') c64.CHROUT('J')
c64scr.print("────────────────────────") c64scr.print("────────────────────────")
c64.CHROUT('K') c64.CHROUT('K')
@ -270,34 +270,34 @@ waitkey:
sub drawBoard() { sub drawBoard() {
c64.CLEARSCR() c64.CLEARSCR()
c64.COLOR = 7 c64.COLOR = 7
c64scr.PLOT(1,1) c64scr.plot(1,1)
c64scr.print("irmen's") c64scr.print("irmen's")
c64scr.PLOT(2,2) c64scr.plot(2,2)
c64scr.print("teh▁triz") c64scr.print("teh▁triz")
c64.COLOR = 5 c64.COLOR = 5
c64scr.PLOT(6,4) c64scr.plot(6,4)
c64scr.print("hold:") c64scr.print("hold:")
c64scr.PLOT(2,22) c64scr.plot(2,22)
c64scr.print("speed: ") c64scr.print("speed: ")
c64scr.PLOT(28,3) c64scr.plot(28,3)
c64scr.print("next:") c64scr.print("next:")
c64scr.PLOT(28,10) c64scr.plot(28,10)
c64scr.print("lines:") c64scr.print("lines:")
c64scr.PLOT(28,14) c64scr.plot(28,14)
c64scr.print("score:") c64scr.print("score:")
c64.COLOR = 12 c64.COLOR = 12
c64scr.PLOT(27,18) c64scr.plot(27,18)
c64scr.print("controls:") c64scr.print("controls:")
c64.COLOR = 11 c64.COLOR = 11
c64scr.PLOT(28,19) c64scr.plot(28,19)
c64scr.print(",/ move") c64scr.print(",/ move")
c64scr.PLOT(28,20) c64scr.plot(28,20)
c64scr.print("zx rotate") c64scr.print("zx rotate")
c64scr.PLOT(29,21) c64scr.plot(29,21)
c64scr.print(". descend") c64scr.print(". descend")
c64scr.PLOT(27,22) c64scr.plot(27,22)
c64scr.print("spc drop") c64scr.print("spc drop")
c64scr.PLOT(29,23) c64scr.plot(29,23)
c64scr.print("c hold") c64scr.print("c hold")
c64scr.setcc(boardOffsetX-1, boardOffsetY-2, 255, 0) ; invisible barrier c64scr.setcc(boardOffsetX-1, boardOffsetY-2, 255, 0) ; invisible barrier
@ -331,11 +331,11 @@ waitkey:
sub drawScore() { sub drawScore() {
c64.COLOR=1 c64.COLOR=1
c64scr.PLOT(30,11) c64scr.plot(30,11)
c64scr.print_uw(lines) c64scr.print_uw(lines)
c64scr.PLOT(30,15) c64scr.plot(30,15)
c64scr.print_uw(score) c64scr.print_uw(score)
c64scr.PLOT(9,22) c64scr.plot(9,22)
c64scr.print_ub(speedlevel) c64scr.print_ub(speedlevel)
} }

View File

@ -1,33 +1,22 @@
%import c64utils
%import c64lib
%zeropage basicsafe %zeropage basicsafe
; @todo see problem in looplabelproblem.p8 ; @todo fix this (issue #11 on github): it generates invalid asm due to improper label names
~ main { ~ main {
sub start() { sub start() {
c64utils.set_rasterirq(220) ; enable animation
uword offs=0 if A>10 {
while(true) { A=44
uword z=1 while true {
for ubyte x in 0 to 200 { ;derp
@(z*($0400+offs)) = lsb(offs+x)
offs += 1
if offs > 40*25
offs=0
} }
} else {
gameover:
goto gameover
} }
}
}
~ irq {
sub irq() {
c64.EXTCOL = X
} }
} }