mirror of
https://github.com/irmen/prog8.git
synced 2024-11-19 11:32:17 +00:00
662 lines
10 KiB
Lua
662 lines
10 KiB
Lua
; Prog8 internal library routines - always included by the compiler
|
|
;
|
|
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
|
;
|
|
; indent format: TABS, size=8
|
|
|
|
|
|
~ prog8_lib {
|
|
; @TODO move all this assembly to a real .asm file instead and include that...
|
|
|
|
|
|
; note: the following ZP scratch registers must be the same as in c64lib
|
|
memory ubyte SCRATCH_ZPB1 = $02 ; scratch byte 1 in ZP
|
|
memory ubyte SCRATCH_ZPREG = $03 ; scratch register in ZP
|
|
memory uword SCRATCH_ZPWORD1 = $fb ; scratch word in ZP ($fb/$fc)
|
|
memory uword SCRATCH_ZPWORD2 = $fd ; scratch word in ZP ($fd/$fe)
|
|
const uword ESTACK_LO = $ce00
|
|
const uword ESTACK_HI = $cf00
|
|
|
|
|
|
%asm {{
|
|
|
|
; 16-bit rotate right (as opposed to the 6502's usual 17-bit rotate with carry)
|
|
; the word is placed in SCRATCH_ZPWORD1
|
|
ror2_word .proc
|
|
lsr SCRATCH_ZPWORD1+1
|
|
ror SCRATCH_ZPWORD1
|
|
bcc +
|
|
lda SCRATCH_ZPWORD1+1
|
|
ora #$80
|
|
sta SCRATCH_ZPWORD1+1
|
|
+ rts
|
|
.pend
|
|
|
|
|
|
|
|
; @todo: implement stubs!
|
|
; @todo: move float operations to their own library (only included when floats are enabled)
|
|
|
|
ub2float .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
b2float .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
uw2float .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
w2float .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
push_float .proc
|
|
; ---- push mflpt5 in A/Y onto stack
|
|
; (taking 3 stack positions = 6 bytes of which 1 is padding)
|
|
sta SCRATCH_ZPWORD1
|
|
sty SCRATCH_ZPWORD1+1
|
|
ldy #0
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta ESTACK_LO,x
|
|
iny
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta ESTACK_HI,x
|
|
dex
|
|
iny
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta ESTACK_LO,x
|
|
iny
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta ESTACK_HI,x
|
|
dex
|
|
iny
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta ESTACK_LO,x
|
|
dex
|
|
rts
|
|
.pend
|
|
|
|
|
|
push_float_from_indexed_var .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
pop_float .proc
|
|
; ---- pops mflpt5 from stack to memory A/Y
|
|
; (frees 3 stack positions = 6 bytes of which 1 is padding)
|
|
sta SCRATCH_ZPWORD1
|
|
sty SCRATCH_ZPWORD1+1
|
|
ldy #4
|
|
inx
|
|
lda ESTACK_LO,x
|
|
sta (SCRATCH_ZPWORD1),y
|
|
dey
|
|
inx
|
|
lda ESTACK_HI,x
|
|
sta (SCRATCH_ZPWORD1),y
|
|
dey
|
|
lda ESTACK_LO,x
|
|
sta (SCRATCH_ZPWORD1),y
|
|
dey
|
|
inx
|
|
lda ESTACK_HI,x
|
|
sta (SCRATCH_ZPWORD1),y
|
|
dey
|
|
lda ESTACK_LO,x
|
|
sta (SCRATCH_ZPWORD1),y
|
|
rts
|
|
.pend
|
|
|
|
pop_float_to_indexed_var .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
pop_mem_float .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
copy_float .proc
|
|
; -- copies the 5 bytes of the mflt value pointed to by SCRATCH_ZPWORD1,
|
|
; into the 5 bytes pointed to by A/Y. Clobbers Y.
|
|
sta SCRATCH_ZPWORD2
|
|
sty SCRATCH_ZPWORD2+1
|
|
ldy #0
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta (SCRATCH_ZPWORD2),y
|
|
iny
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta (SCRATCH_ZPWORD2),y
|
|
iny
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta (SCRATCH_ZPWORD2),y
|
|
iny
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta (SCRATCH_ZPWORD2),y
|
|
iny
|
|
lda (SCRATCH_ZPWORD1),y
|
|
sta (SCRATCH_ZPWORD2),y
|
|
rts
|
|
.pend
|
|
|
|
inc_var_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
dec_var_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
div_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
add_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
sub_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
mul_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
neg_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
|
|
add_w .proc
|
|
rts ; @todo inline?
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
add_uw .proc
|
|
rts ; @todo inline?
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
sub_w .proc
|
|
rts ; @todo inline?
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
sub_uw .proc
|
|
rts ; @todo inline?
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
mul_b .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
mul_ub .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
mul_w .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
mul_uw .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
div_b .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
div_ub .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
div_w .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
div_uw .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
remainder_b .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
remainder_ub .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
remainder_w .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
remainder_uw .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
remainder_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
|
|
equal_b .proc
|
|
; -- are the two bytes on the stack identical?
|
|
lda ESTACK_LO+2,x
|
|
cmp ESTACK_LO+1,x
|
|
bne _equal_b_false
|
|
_equal_b_true lda #1
|
|
_equal_b_store inx
|
|
sta ESTACK_LO+1,x
|
|
rts
|
|
_equal_b_false lda #0
|
|
beq _equal_b_store
|
|
.pend
|
|
|
|
|
|
equal_w .proc
|
|
; -- are the two words on the stack identical?
|
|
; @todo optimize according to http://www.6502.org/tutorials/compare_beyond.html
|
|
lda ESTACK_LO+1,x
|
|
cmp ESTACK_LO+2,x
|
|
bne equal_b._equal_b_false
|
|
lda ESTACK_HI+1,x
|
|
cmp ESTACK_HI+2,x
|
|
bne equal_b._equal_b_false
|
|
beq equal_b._equal_b_true
|
|
.pend
|
|
|
|
notequal_b .proc
|
|
; -- are the two bytes on the stack different?
|
|
inx
|
|
lda ESTACK_LO,x
|
|
eor ESTACK_LO+1,x
|
|
sta ESTACK_LO+1,x
|
|
rts
|
|
.pend
|
|
|
|
notequal_w .proc
|
|
; -- are the two words on the stack different?
|
|
inx
|
|
lda ESTACK_LO,x
|
|
eor ESTACK_LO+1,x
|
|
beq +
|
|
sta ESTACK_LO+1,x
|
|
rts
|
|
+ lda ESTACK_HI,x
|
|
eor ESTACK_HI+1,x
|
|
sta ESTACK_LO+1,x
|
|
rts
|
|
.pend
|
|
|
|
less_ub .proc
|
|
lda ESTACK_LO+2,x
|
|
cmp ESTACK_LO+1,x
|
|
bcc equal_b._equal_b_true
|
|
bcs equal_b._equal_b_false
|
|
.pend
|
|
|
|
less_b .proc
|
|
; see http://www.6502.org/tutorials/compare_beyond.html
|
|
lda ESTACK_LO+2,x
|
|
sec
|
|
sbc ESTACK_LO+1,x
|
|
bvc +
|
|
eor #$80
|
|
+ bmi equal_b._equal_b_true
|
|
bpl equal_b._equal_b_false
|
|
.pend
|
|
|
|
less_uw .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
less_w .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
lesseq_ub .proc
|
|
lda ESTACK_LO+2,x
|
|
cmp ESTACK_LO+1,x
|
|
bcc equal_b._equal_b_true
|
|
beq equal_b._equal_b_true
|
|
bcs equal_b._equal_b_false
|
|
.pend
|
|
|
|
lesseq_b .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
lesseq_uw .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
lesseq_w .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
greater_ub .proc
|
|
lda ESTACK_LO+2,x
|
|
cmp ESTACK_LO+1,x
|
|
beq equal_b._equal_b_false
|
|
bcs equal_b._equal_b_true
|
|
bcc equal_b._equal_b_false
|
|
.pend
|
|
|
|
greater_b .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
greater_uw .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
greater_w .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
greatereq_ub .proc
|
|
lda ESTACK_LO+2,x
|
|
cmp ESTACK_LO+1,x
|
|
bcs equal_b._equal_b_true
|
|
bcc equal_b._equal_b_false
|
|
.pend
|
|
|
|
greatereq_b .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
greatereq_uw .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
greatereq_w .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
equal_f .proc
|
|
; -- are the two mflpt5 numbers on the stack identical?
|
|
; @todo optimize according to http://www.6502.org/tutorials/compare_beyond.html
|
|
inx
|
|
inx
|
|
inx
|
|
inx
|
|
lda ESTACK_LO-3,x
|
|
cmp ESTACK_LO,x
|
|
bne equal_b._equal_b_false
|
|
lda ESTACK_LO-2,x
|
|
cmp ESTACK_LO+1,x
|
|
bne equal_b._equal_b_false
|
|
lda ESTACK_LO-1,x
|
|
cmp ESTACK_LO+2,x
|
|
bne equal_b._equal_b_false
|
|
lda ESTACK_HI-2,x
|
|
cmp ESTACK_HI+1,x
|
|
bne equal_b._equal_b_false
|
|
lda ESTACK_HI-1,x
|
|
cmp ESTACK_HI+2,x
|
|
bne equal_b._equal_b_false
|
|
beq equal_b._equal_b_true
|
|
.pend
|
|
|
|
notequal_f .proc
|
|
; -- are the two mflpt5 numbers on the stack different?
|
|
jsr equal_f
|
|
eor #1 ; invert the result
|
|
sta ESTACK_LO+1,x
|
|
rts
|
|
.pend
|
|
|
|
less_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
lesseq_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
greater_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
greatereq_f .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
|
|
|
|
func_sin .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_cos .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_abs .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_acos .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_asin .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_tan .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_atan .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_ln .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_log2 .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_log10 .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_sqrt .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_rad .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_deg .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_round .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_floor .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_ceil .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_max .proc
|
|
rts
|
|
.warn "not implemented--what does it max over???"
|
|
.pend
|
|
|
|
func_min .proc
|
|
rts
|
|
.warn "not implemented--what does it min over???"
|
|
.pend
|
|
|
|
func_avg .proc
|
|
rts
|
|
.warn "not implemented--what does it avg over???"
|
|
.pend
|
|
|
|
func_sum .proc
|
|
rts
|
|
.warn "not implemented--what does it sum over???"
|
|
.pend
|
|
|
|
func_len .proc
|
|
rts
|
|
.warn "not implemented--of what does it take len?"
|
|
.pend
|
|
|
|
func_any .proc
|
|
rts
|
|
.warn "not implemented--of what does it do any?"
|
|
.pend
|
|
|
|
func_all .proc
|
|
rts
|
|
.warn "not implemented--of what does it do all?"
|
|
.pend
|
|
|
|
|
|
func_rnd .proc
|
|
; -- put a random ubyte on the estack
|
|
jsr math.randbyte
|
|
sta ESTACK_LO,x
|
|
dex
|
|
rts
|
|
.pend
|
|
|
|
func_rndw .proc
|
|
; -- put a random uword on the estack
|
|
jsr math.randword
|
|
sta ESTACK_LO,x
|
|
tya
|
|
sta ESTACK_HI,x
|
|
dex
|
|
rts
|
|
.pend
|
|
|
|
func_rndf .proc
|
|
; -- put a random floating point value on the stack
|
|
stx SCRATCH_ZPREG
|
|
lda #1
|
|
jsr c64.FREADSA
|
|
jsr c64.RND ; rng into fac1
|
|
ldx #<_rndf_rnum5
|
|
ldy #>_rndf_rnum5
|
|
jsr c64.FTOMEMXY ; fac1 to mem X/Y
|
|
ldx SCRATCH_ZPREG
|
|
lda #<_rndf_rnum5
|
|
ldy #>_rndf_rnum5
|
|
jmp push_float
|
|
_rndf_rnum5 .fill 5
|
|
.pend
|
|
|
|
|
|
func_wrd .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_uwrd .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_str2byte .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_str2ubyte .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_str2word .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_str2uword .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
func_str2float .proc
|
|
rts
|
|
.warn "not implemented"
|
|
.pend
|
|
|
|
|
|
}}
|
|
}
|