mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-08 17:54:40 +00:00
335 lines
5.4 KiB
NASM
335 lines
5.4 KiB
NASM
.pc = $801 "Basic"
|
|
:BasicUpstart(main)
|
|
.pc = $80d "Program"
|
|
.label RASTER = $d012
|
|
.label BORDERCOL = $d020
|
|
.label SCREEN = $400
|
|
.label print_char_cursor = 5
|
|
main: {
|
|
.label a = $4d2
|
|
.label b = $929
|
|
.label r = $e
|
|
jsr mulf_init
|
|
sei
|
|
lda #<$400
|
|
sta.z print_char_cursor
|
|
lda #>$400
|
|
sta.z print_char_cursor+1
|
|
b2:
|
|
lda #$ff
|
|
cmp RASTER
|
|
bne b2
|
|
inc BORDERCOL
|
|
jsr mulf16u
|
|
dec BORDERCOL
|
|
jsr print_dword
|
|
jsr print_set_screen
|
|
lda #<SCREEN
|
|
sta.z print_char_cursor
|
|
lda #>SCREEN
|
|
sta.z print_char_cursor+1
|
|
jmp b2
|
|
}
|
|
// Set the screen to print on. Also resets current line/char cursor.
|
|
print_set_screen: {
|
|
rts
|
|
}
|
|
// Print a dword as HEX
|
|
// print_dword(dword zeropage($e) dw)
|
|
print_dword: {
|
|
.label dw = $e
|
|
lda.z dw+2
|
|
sta.z print_word.w
|
|
lda.z dw+3
|
|
sta.z print_word.w+1
|
|
jsr print_word
|
|
lda.z dw
|
|
sta.z print_word.w
|
|
lda.z dw+1
|
|
sta.z print_word.w+1
|
|
jsr print_word
|
|
rts
|
|
}
|
|
// Print a word as HEX
|
|
// print_word(word zeropage(2) w)
|
|
print_word: {
|
|
.label w = 2
|
|
lda.z w+1
|
|
tax
|
|
jsr print_byte
|
|
lda.z w
|
|
tax
|
|
jsr print_byte
|
|
rts
|
|
}
|
|
// Print a byte as HEX
|
|
// print_byte(byte register(X) b)
|
|
print_byte: {
|
|
txa
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
tay
|
|
lda print_hextab,y
|
|
jsr print_char
|
|
lda #$f
|
|
axs #0
|
|
lda print_hextab,x
|
|
jsr print_char
|
|
rts
|
|
}
|
|
// Print a single char
|
|
// print_char(byte register(A) ch)
|
|
print_char: {
|
|
ldy #0
|
|
sta (print_char_cursor),y
|
|
inc.z print_char_cursor
|
|
bne !+
|
|
inc.z print_char_cursor+1
|
|
!:
|
|
rts
|
|
}
|
|
// Fast multiply two unsigned words to a double word result
|
|
// Done in assembler to utilize fast addition A+X
|
|
mulf16u: {
|
|
.label memA = $f8
|
|
.label memB = $fa
|
|
.label memR = $fc
|
|
.label return = $e
|
|
lda #<main.a
|
|
sta memA
|
|
lda #>main.a
|
|
sta memA+1
|
|
lda #<main.b
|
|
sta memB
|
|
lda #>main.b
|
|
sta memB+1
|
|
lda memA
|
|
sta sm1a+1
|
|
sta sm3a+1
|
|
sta sm5a+1
|
|
sta sm7a+1
|
|
eor #$ff
|
|
sta sm2a+1
|
|
sta sm4a+1
|
|
sta sm6a+1
|
|
sta sm8a+1
|
|
lda memA+1
|
|
sta sm1b+1
|
|
sta sm3b+1
|
|
sta sm5b+1
|
|
sta sm7b+1
|
|
eor #$ff
|
|
sta sm2b+1
|
|
sta sm4b+1
|
|
sta sm6b+1
|
|
sta sm8b+1
|
|
ldx memB
|
|
sec
|
|
sm1a:
|
|
lda mulf_sqr1_lo,x
|
|
sm2a:
|
|
sbc mulf_sqr2_lo,x
|
|
sta memR+0
|
|
sm3a:
|
|
lda mulf_sqr1_hi,x
|
|
sm4a:
|
|
sbc mulf_sqr2_hi,x
|
|
sta _AA+1
|
|
sec
|
|
sm1b:
|
|
lda mulf_sqr1_lo,x
|
|
sm2b:
|
|
sbc mulf_sqr2_lo,x
|
|
sta _cc+1
|
|
sm3b:
|
|
lda mulf_sqr1_hi,x
|
|
sm4b:
|
|
sbc mulf_sqr2_hi,x
|
|
sta _CC+1
|
|
ldx memB+1
|
|
sec
|
|
sm5a:
|
|
lda mulf_sqr1_lo,x
|
|
sm6a:
|
|
sbc mulf_sqr2_lo,x
|
|
sta _bb+1
|
|
sm7a:
|
|
lda mulf_sqr1_hi,x
|
|
sm8a:
|
|
sbc mulf_sqr2_hi,x
|
|
sta _BB+1
|
|
sec
|
|
sm5b:
|
|
lda mulf_sqr1_lo,x
|
|
sm6b:
|
|
sbc mulf_sqr2_lo,x
|
|
sta _dd+1
|
|
sm7b:
|
|
lda mulf_sqr1_hi,x
|
|
sm8b:
|
|
sbc mulf_sqr2_hi,x
|
|
sta memR+3
|
|
clc
|
|
_AA:
|
|
lda #0
|
|
_bb:
|
|
adc #0
|
|
sta memR+1
|
|
_BB:
|
|
lda #0
|
|
_CC:
|
|
adc #0
|
|
sta memR+2
|
|
bcc !+
|
|
inc memR+3
|
|
clc
|
|
!:
|
|
_cc:
|
|
lda #0
|
|
adc memR+1
|
|
sta memR+1
|
|
_dd:
|
|
lda #0
|
|
adc memR+2
|
|
sta memR+2
|
|
bcc !+
|
|
inc memR+3
|
|
!:
|
|
lda memR
|
|
sta.z return
|
|
lda memR+1
|
|
sta.z return+1
|
|
lda memR+2
|
|
sta.z return+2
|
|
lda memR+3
|
|
sta.z return+3
|
|
rts
|
|
}
|
|
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
|
|
mulf_init: {
|
|
.label c = 4
|
|
.label sqr1_hi = 5
|
|
.label sqr = $c
|
|
.label sqr1_lo = 2
|
|
.label sqr2_hi = 9
|
|
.label sqr2_lo = 7
|
|
.label dir = $b
|
|
ldx #0
|
|
lda #<mulf_sqr1_hi+1
|
|
sta.z sqr1_hi
|
|
lda #>mulf_sqr1_hi+1
|
|
sta.z sqr1_hi+1
|
|
txa
|
|
sta.z sqr
|
|
sta.z sqr+1
|
|
sta.z c
|
|
lda #<mulf_sqr1_lo+1
|
|
sta.z sqr1_lo
|
|
lda #>mulf_sqr1_lo+1
|
|
sta.z sqr1_lo+1
|
|
b1:
|
|
lda.z sqr1_lo+1
|
|
cmp #>mulf_sqr1_lo+$200
|
|
bne b2
|
|
lda.z sqr1_lo
|
|
cmp #<mulf_sqr1_lo+$200
|
|
bne b2
|
|
lda #$ff
|
|
sta.z dir
|
|
lda #<mulf_sqr2_hi
|
|
sta.z sqr2_hi
|
|
lda #>mulf_sqr2_hi
|
|
sta.z sqr2_hi+1
|
|
ldx #-1
|
|
lda #<mulf_sqr2_lo
|
|
sta.z sqr2_lo
|
|
lda #>mulf_sqr2_lo
|
|
sta.z sqr2_lo+1
|
|
b5:
|
|
lda.z sqr2_lo+1
|
|
cmp #>mulf_sqr2_lo+$1ff
|
|
bne b6
|
|
lda.z sqr2_lo
|
|
cmp #<mulf_sqr2_lo+$1ff
|
|
bne b6
|
|
// Set the very last value g(511) = f(256)
|
|
lda mulf_sqr1_lo+$100
|
|
sta mulf_sqr2_lo+$1ff
|
|
lda mulf_sqr1_hi+$100
|
|
sta mulf_sqr2_hi+$1ff
|
|
rts
|
|
b6:
|
|
lda mulf_sqr1_lo,x
|
|
ldy #0
|
|
sta (sqr2_lo),y
|
|
lda mulf_sqr1_hi,x
|
|
sta (sqr2_hi),y
|
|
inc.z sqr2_hi
|
|
bne !+
|
|
inc.z sqr2_hi+1
|
|
!:
|
|
txa
|
|
clc
|
|
adc.z dir
|
|
tax
|
|
cpx #0
|
|
bne b8
|
|
lda #1
|
|
sta.z dir
|
|
b8:
|
|
inc.z sqr2_lo
|
|
bne !+
|
|
inc.z sqr2_lo+1
|
|
!:
|
|
jmp b5
|
|
b2:
|
|
inc.z c
|
|
lda #1
|
|
and.z c
|
|
cmp #0
|
|
bne b3
|
|
inx
|
|
inc.z sqr
|
|
bne !+
|
|
inc.z sqr+1
|
|
!:
|
|
b3:
|
|
lda.z sqr
|
|
ldy #0
|
|
sta (sqr1_lo),y
|
|
lda.z sqr+1
|
|
sta (sqr1_hi),y
|
|
inc.z sqr1_hi
|
|
bne !+
|
|
inc.z sqr1_hi+1
|
|
!:
|
|
txa
|
|
clc
|
|
adc.z sqr
|
|
sta.z sqr
|
|
bcc !+
|
|
inc.z sqr+1
|
|
!:
|
|
inc.z sqr1_lo
|
|
bne !+
|
|
inc.z sqr1_lo+1
|
|
!:
|
|
jmp b1
|
|
}
|
|
print_hextab: .text "0123456789abcdef"
|
|
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
|
|
// <f(x) = <(( x * x )/4)
|
|
.align $100
|
|
mulf_sqr1_lo: .fill $200, 0
|
|
// >f(x) = >(( x * x )/4)
|
|
.align $100
|
|
mulf_sqr1_hi: .fill $200, 0
|
|
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
|
|
.align $100
|
|
mulf_sqr2_lo: .fill $200, 0
|
|
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
|
|
.align $100
|
|
mulf_sqr2_hi: .fill $200, 0
|