mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-08-09 04:25:12 +00:00
727 lines
10 KiB
NASM
727 lines
10 KiB
NASM
.pc = $801 "Basic"
|
|
:BasicUpstart(main)
|
|
.pc = $80d "Program"
|
|
.label zp1 = $61
|
|
// #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported --
|
|
.label zp2 = $62
|
|
.label TIMEHI = $a1
|
|
.label TIMELO = $a2
|
|
.label VICBANK = $d018
|
|
main: {
|
|
.label _2 = 6
|
|
.label _3 = 6
|
|
.label _4 = 8
|
|
.label _11 = 6
|
|
.label _12 = 6
|
|
.label _13 = 8
|
|
.label v = 4
|
|
.label u = 2
|
|
lda #$17
|
|
sta VICBANK
|
|
lda #0
|
|
sta zp1
|
|
lda #<$6e85
|
|
sta u
|
|
lda #>$6e85
|
|
sta u+1
|
|
b1:
|
|
lda #0
|
|
sta TIMEHI
|
|
sta TIMELO
|
|
sta zp2
|
|
b2:
|
|
jsr div16u
|
|
inc zp2
|
|
lda zp2
|
|
cmp #$c8
|
|
bcc b2
|
|
lda TIMEHI
|
|
sta _2
|
|
lda #0
|
|
sta _2+1
|
|
ldy #8
|
|
cpy #0
|
|
beq !e+
|
|
!:
|
|
asl _3
|
|
rol _3+1
|
|
dey
|
|
bne !-
|
|
!e:
|
|
lda TIMELO
|
|
sta _4
|
|
lda #0
|
|
sta _4+1
|
|
lda myprintf.w3
|
|
clc
|
|
adc _4
|
|
sta myprintf.w3
|
|
lda myprintf.w3+1
|
|
adc _4+1
|
|
sta myprintf.w3+1
|
|
lda #<str
|
|
sta myprintf.str
|
|
lda #>str
|
|
sta myprintf.str+1
|
|
jsr myprintf
|
|
jsr Print
|
|
lda u
|
|
sec
|
|
sbc #<$4d2
|
|
sta u
|
|
lda u+1
|
|
sbc #>$4d2
|
|
sta u+1
|
|
inc zp1
|
|
lda zp1
|
|
cmp #$a
|
|
bcc b1
|
|
lda #0
|
|
sta zp1
|
|
lda #<$6e85
|
|
sta u
|
|
lda #>$6e85
|
|
sta u+1
|
|
b5:
|
|
lda #0
|
|
sta TIMEHI
|
|
sta TIMELO
|
|
sta zp2
|
|
b6:
|
|
jsr div10
|
|
inc zp2
|
|
lda zp2
|
|
cmp #$c8
|
|
bcc b6
|
|
lda TIMEHI
|
|
sta _11
|
|
lda #0
|
|
sta _11+1
|
|
ldy #8
|
|
cpy #0
|
|
beq !e+
|
|
!:
|
|
asl _12
|
|
rol _12+1
|
|
dey
|
|
bne !-
|
|
!e:
|
|
lda TIMELO
|
|
sta _13
|
|
lda #0
|
|
sta _13+1
|
|
lda myprintf.w3
|
|
clc
|
|
adc _13
|
|
sta myprintf.w3
|
|
lda myprintf.w3+1
|
|
adc _13+1
|
|
sta myprintf.w3+1
|
|
lda #<str1
|
|
sta myprintf.str
|
|
lda #>str1
|
|
sta myprintf.str+1
|
|
jsr myprintf
|
|
jsr Print
|
|
lda u
|
|
sec
|
|
sbc #<$4d2
|
|
sta u
|
|
lda u+1
|
|
sbc #>$4d2
|
|
sta u+1
|
|
inc zp1
|
|
lda zp1
|
|
cmp #$a
|
|
bcc b5
|
|
rts
|
|
str: .text "200 DIV16U: %5d,%4d IN %04d FRAMESm@"
|
|
str1: .text "200 DIV10 : %5d,%4d IN %04d FRAMESm@"
|
|
}
|
|
Print: {
|
|
// can this assembly be placed in a separate file and call it from the C code here?
|
|
ldy #0
|
|
loop:
|
|
lda strTemp,y
|
|
beq done
|
|
jsr $ffd2
|
|
iny
|
|
jmp loop
|
|
done:
|
|
rts
|
|
}
|
|
// myprintf(byte* zeropage(8) str, word zeropage(2) w1, word zeropage(4) w2, word zeropage(6) w3)
|
|
myprintf: {
|
|
.label _17 = $12
|
|
.label str = 8
|
|
.label bDigits = $11
|
|
.label bLen = $10
|
|
.label digit = $a
|
|
.label bArg = $b
|
|
.label return = $10
|
|
.label w1 = 2
|
|
.label w2 = 4
|
|
.label w3 = 6
|
|
.label bFormat = $a
|
|
.label w = $c
|
|
.label bTrailing = $e
|
|
.label bLeadZero = $f
|
|
lda #0
|
|
sta bLeadZero
|
|
sta bDigits
|
|
sta bTrailing
|
|
sta w
|
|
sta w+1
|
|
sta bLen
|
|
sta bArg
|
|
sta bFormat
|
|
b1:
|
|
ldy #0
|
|
lda (str),y
|
|
tax
|
|
lda bFormat
|
|
cmp #0
|
|
bne !b2+
|
|
jmp b2
|
|
!b2:
|
|
cpx #'0'
|
|
bne b3
|
|
lda #1
|
|
sta bLeadZero
|
|
b27:
|
|
inc str
|
|
bne !+
|
|
inc str+1
|
|
!:
|
|
ldy #0
|
|
lda (str),y
|
|
cmp #0
|
|
bne b1
|
|
tya
|
|
ldy return
|
|
sta strTemp,y
|
|
rts
|
|
b3:
|
|
cpx #'1'
|
|
bcc !b37+
|
|
jmp b37
|
|
!b37:
|
|
b4:
|
|
cpx #'-'
|
|
bne b5
|
|
lda #1
|
|
sta bTrailing
|
|
jmp b27
|
|
b5:
|
|
cpx #'c'
|
|
bne !b6+
|
|
jmp b6
|
|
!b6:
|
|
cpx #'d'
|
|
beq b7
|
|
cpx #'x'
|
|
beq b26
|
|
cpx #'X'
|
|
beq b26
|
|
b22:
|
|
lda #0
|
|
sta bFormat
|
|
jmp b27
|
|
b26:
|
|
lda w+1
|
|
sta _17+1
|
|
lda w
|
|
sta _17
|
|
ldy #4
|
|
!:
|
|
lsr _17+1
|
|
ror _17
|
|
dey
|
|
bne !-
|
|
lda _17
|
|
and #$f
|
|
tax
|
|
cpx #$a
|
|
bcc b8
|
|
lda #$57
|
|
jmp b9
|
|
b8:
|
|
lda #'0'
|
|
b9:
|
|
stx $ff
|
|
clc
|
|
adc $ff
|
|
ldy bLen
|
|
sta strTemp,y
|
|
iny
|
|
lda w
|
|
and #$f
|
|
tax
|
|
cpx #$a
|
|
bcc b10
|
|
lda #$57
|
|
jmp b11
|
|
b10:
|
|
lda #'0'
|
|
b11:
|
|
stx $ff
|
|
clc
|
|
adc $ff
|
|
sta strTemp,y
|
|
iny
|
|
sty bLen
|
|
jmp b22
|
|
b7:
|
|
lda w
|
|
sta utoa.value
|
|
lda w+1
|
|
sta utoa.value+1
|
|
jsr utoa
|
|
ldx #1
|
|
b12:
|
|
lda buf6,x
|
|
cmp #0
|
|
bne b13
|
|
lda bTrailing
|
|
cmp #0
|
|
beq b39
|
|
b15:
|
|
lda #0
|
|
sta digit
|
|
b19:
|
|
ldy digit
|
|
lda buf6,y
|
|
ldy bLen
|
|
sta strTemp,y
|
|
inc bLen
|
|
inc digit
|
|
txa
|
|
cmp digit
|
|
beq !+
|
|
bcs b19
|
|
!:
|
|
lda bTrailing
|
|
cmp #0
|
|
bne b40
|
|
jmp b22
|
|
b40:
|
|
cpx bDigits
|
|
bcc b21
|
|
jmp b22
|
|
b21:
|
|
lda #' '
|
|
ldy bLen
|
|
sta strTemp,y
|
|
inc bLen
|
|
dec bDigits
|
|
cpx bDigits
|
|
bcc b21
|
|
jmp b22
|
|
b39:
|
|
cpx bDigits
|
|
bcc b16
|
|
jmp b15
|
|
b16:
|
|
lda bLeadZero
|
|
cmp #0
|
|
beq b14
|
|
lda #'0'
|
|
jmp b18
|
|
b14:
|
|
lda #' '
|
|
b18:
|
|
ldy bLen
|
|
sta strTemp,y
|
|
inc bLen
|
|
dec bDigits
|
|
cpx bDigits
|
|
bcc b16
|
|
jmp b15
|
|
b13:
|
|
inx
|
|
jmp b12
|
|
b6:
|
|
lda w
|
|
// "switch" is the normal way -- not supported
|
|
ldy bLen
|
|
sta strTemp,y
|
|
inc bLen
|
|
jmp b22
|
|
b37:
|
|
cpx #'9'
|
|
bcc b23
|
|
beq b23
|
|
jmp b4
|
|
b23:
|
|
txa
|
|
axs #'0'
|
|
stx bDigits
|
|
jmp b27
|
|
b2:
|
|
cpx #'%'
|
|
bne b28
|
|
// default format
|
|
//w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks"
|
|
lda bArg
|
|
cmp #0
|
|
beq b42
|
|
lda #1
|
|
cmp bArg
|
|
beq b43
|
|
lda w3
|
|
sta w
|
|
lda w3+1
|
|
sta w+1
|
|
b29:
|
|
inc bArg
|
|
lda #0
|
|
sta bLeadZero
|
|
lda #1
|
|
sta bDigits
|
|
lda #0
|
|
sta bTrailing
|
|
lda #1
|
|
sta bFormat
|
|
jmp b27
|
|
b43:
|
|
lda w2
|
|
sta w
|
|
lda w2+1
|
|
sta w+1
|
|
jmp b29
|
|
b42:
|
|
lda w1
|
|
sta w
|
|
lda w1+1
|
|
sta w+1
|
|
jmp b29
|
|
b28:
|
|
cpx #$41
|
|
bcs b41
|
|
b30:
|
|
// swap 0x41 / 0x61 when in lower case mode
|
|
ldy bLen
|
|
txa
|
|
sta strTemp,y
|
|
inc bLen
|
|
jmp b27
|
|
b41:
|
|
cpx #$5a+1
|
|
bcc b35
|
|
jmp b30
|
|
b35:
|
|
txa
|
|
axs #-[$20]
|
|
jmp b30
|
|
buf6: .fill 6, 0
|
|
}
|
|
// utoa(word zeropage($12) value, byte* zeropage($14) dst)
|
|
utoa: {
|
|
.label value = $12
|
|
.label dst = $14
|
|
lda value+1
|
|
cmp #>$2710
|
|
bcc !+
|
|
beq !b5+
|
|
jmp b5
|
|
!b5:
|
|
lda value
|
|
cmp #<$2710
|
|
bcc !b5+
|
|
jmp b5
|
|
!b5:
|
|
!:
|
|
lda #<myprintf.buf6
|
|
sta dst
|
|
lda #>myprintf.buf6
|
|
sta dst+1
|
|
ldx #0
|
|
b1:
|
|
cpx #1
|
|
beq b6
|
|
lda value+1
|
|
cmp #>$3e8
|
|
bcc !+
|
|
bne b6
|
|
lda value
|
|
cmp #<$3e8
|
|
bcs b6
|
|
!:
|
|
b2:
|
|
cpx #1
|
|
beq b7
|
|
lda value+1
|
|
cmp #>$64
|
|
bcc !+
|
|
bne b7
|
|
lda value
|
|
cmp #<$64
|
|
bcs b7
|
|
!:
|
|
b3:
|
|
cpx #1
|
|
beq b8
|
|
lda value+1
|
|
cmp #>$a
|
|
bcc !+
|
|
bne b8
|
|
lda value
|
|
cmp #<$a
|
|
bcs b8
|
|
!:
|
|
b4:
|
|
lda value
|
|
clc
|
|
adc #'0'
|
|
ldy #0
|
|
sta (dst),y
|
|
inc dst
|
|
bne !+
|
|
inc dst+1
|
|
!:
|
|
lda #0
|
|
tay
|
|
sta (dst),y
|
|
rts
|
|
b8:
|
|
lda #$a
|
|
sta append.sub
|
|
lda #0
|
|
sta append.sub+1
|
|
jsr append
|
|
inc dst
|
|
bne !+
|
|
inc dst+1
|
|
!:
|
|
jmp b4
|
|
b7:
|
|
lda #$64
|
|
sta append.sub
|
|
lda #0
|
|
sta append.sub+1
|
|
jsr append
|
|
inc dst
|
|
bne !+
|
|
inc dst+1
|
|
!:
|
|
ldx #1
|
|
jmp b3
|
|
b6:
|
|
lda #<$3e8
|
|
sta append.sub
|
|
lda #>$3e8
|
|
sta append.sub+1
|
|
jsr append
|
|
inc dst
|
|
bne !+
|
|
inc dst+1
|
|
!:
|
|
ldx #1
|
|
jmp b2
|
|
b5:
|
|
lda #<$2710
|
|
sta append.sub
|
|
lda #>$2710
|
|
sta append.sub+1
|
|
lda #<myprintf.buf6
|
|
sta append.dst
|
|
lda #>myprintf.buf6
|
|
sta append.dst+1
|
|
jsr append
|
|
lda #<myprintf.buf6+1
|
|
sta dst
|
|
lda #>myprintf.buf6+1
|
|
sta dst+1
|
|
ldx #1
|
|
jmp b1
|
|
}
|
|
// simple 'utoa' without using multiply or divide
|
|
// append(byte* zeropage($14) dst, word zeropage($12) value, word zeropage($16) sub)
|
|
append: {
|
|
.label value = $12
|
|
.label return = $12
|
|
.label dst = $14
|
|
.label sub = $16
|
|
lda #'0'
|
|
ldy #0
|
|
sta (dst),y
|
|
b1:
|
|
lda sub+1
|
|
cmp value+1
|
|
bne !+
|
|
lda sub
|
|
cmp value
|
|
!:
|
|
bcc b2
|
|
beq b2
|
|
rts
|
|
b2:
|
|
ldy #0
|
|
lda (dst),y
|
|
clc
|
|
adc #1
|
|
sta (dst),y
|
|
lda value
|
|
sec
|
|
sbc sub
|
|
sta value
|
|
lda value+1
|
|
sbc sub+1
|
|
sta value+1
|
|
jmp b1
|
|
}
|
|
// div10(word zeropage(4) val)
|
|
div10: {
|
|
.label _0 = 4
|
|
.label _2 = 6
|
|
.label _3 = 4
|
|
.label _4 = 6
|
|
.label _5 = 6
|
|
.label val = 4
|
|
.label val_1 = 6
|
|
.label return = 4
|
|
.label val_4 = 2
|
|
lda val_4+1
|
|
lsr
|
|
sta _0+1
|
|
lda val_4
|
|
ror
|
|
sta _0
|
|
inc val
|
|
bne !+
|
|
inc val+1
|
|
!:
|
|
lda val
|
|
asl
|
|
sta _2
|
|
lda val+1
|
|
rol
|
|
sta _2+1
|
|
lda val_1
|
|
clc
|
|
adc val
|
|
sta val_1
|
|
lda val_1+1
|
|
adc val+1
|
|
sta val_1+1
|
|
sta _3+1
|
|
lda val_1
|
|
sta _3
|
|
ldy #4
|
|
!:
|
|
lsr _3+1
|
|
ror _3
|
|
dey
|
|
bne !-
|
|
lda val
|
|
clc
|
|
adc val_1
|
|
sta val
|
|
lda val+1
|
|
adc val_1+1
|
|
sta val+1
|
|
sta _4+1
|
|
lda val
|
|
sta _4
|
|
ldy #4
|
|
!:
|
|
lsr _4+1
|
|
ror _4
|
|
dey
|
|
bne !-
|
|
ldy #4
|
|
!:
|
|
lsr _5+1
|
|
ror _5
|
|
dey
|
|
bne !-
|
|
lda val
|
|
clc
|
|
adc _5
|
|
sta val
|
|
lda val+1
|
|
adc _5+1
|
|
sta val+1
|
|
ldy #4
|
|
!:
|
|
lsr return+1
|
|
ror return
|
|
dey
|
|
bne !-
|
|
rts
|
|
}
|
|
// Performs division on two 16 bit unsigned words
|
|
// Returns the quotient dividend/divisor.
|
|
// The remainder will be set into the global variable rem16u
|
|
// Implemented using simple binary division
|
|
// div16u(word zeropage(2) dividend)
|
|
div16u: {
|
|
.label divisor = $a
|
|
.label return = 4
|
|
.label dividend = 2
|
|
lda dividend
|
|
sta divr16u.dividend
|
|
lda dividend+1
|
|
sta divr16u.dividend+1
|
|
jsr divr16u
|
|
rts
|
|
}
|
|
// Performs division on two 16 bit unsigned words and an initial remainder
|
|
// Returns the quotient dividend/divisor.
|
|
// The final remainder will be set into the global variable rem16u
|
|
// Implemented using simple binary division
|
|
// divr16u(word zeropage(8) dividend, word zeropage(6) rem)
|
|
divr16u: {
|
|
.label rem = 6
|
|
.label dividend = 8
|
|
.label quotient = 4
|
|
.label return = 4
|
|
ldx #0
|
|
txa
|
|
sta quotient
|
|
sta quotient+1
|
|
sta rem
|
|
sta rem+1
|
|
b1:
|
|
asl rem
|
|
rol rem+1
|
|
lda dividend+1
|
|
and #$80
|
|
cmp #0
|
|
beq b2
|
|
lda #1
|
|
ora rem
|
|
sta rem
|
|
b2:
|
|
asl dividend
|
|
rol dividend+1
|
|
asl quotient
|
|
rol quotient+1
|
|
lda rem+1
|
|
cmp #>div16u.divisor
|
|
bcc b3
|
|
bne !+
|
|
lda rem
|
|
cmp #<div16u.divisor
|
|
bcc b3
|
|
!:
|
|
inc quotient
|
|
bne !+
|
|
inc quotient+1
|
|
!:
|
|
lda rem
|
|
sec
|
|
sbc #<div16u.divisor
|
|
sta rem
|
|
lda rem+1
|
|
sbc #>div16u.divisor
|
|
sta rem+1
|
|
b3:
|
|
inx
|
|
cpx #$10
|
|
bne b1
|
|
rts
|
|
}
|
|
// "char buf16[16]" is the normal way -- not supported
|
|
strTemp: .fill $64, 0
|