mirror of
https://github.com/irmen/prog8.git
synced 2024-11-30 08:52:30 +00:00
497 lines
9.7 KiB
NASM
497 lines
9.7 KiB
NASM
; Internal library routines - always included by the compiler
|
|
; Generic machine independent 6502 code.
|
|
|
|
|
|
orig_stackpointer .byte 0 ; stores the Stack pointer register at program start
|
|
|
|
|
|
read_byte_from_address_in_AY .proc
|
|
sta P8ZP_SCRATCH_W2
|
|
sty P8ZP_SCRATCH_W2+1
|
|
ldy #0
|
|
lda (P8ZP_SCRATCH_W2),y
|
|
rts
|
|
.pend
|
|
|
|
|
|
write_byte_X_to_address_in_AY .proc
|
|
sta P8ZP_SCRATCH_W2
|
|
sty P8ZP_SCRATCH_W2+1
|
|
ldy #0
|
|
txa
|
|
sta (P8ZP_SCRATCH_W2),y
|
|
rts
|
|
.pend
|
|
|
|
|
|
reg_less_uw .proc
|
|
; AY < P8ZP_SCRATCH_W2?
|
|
cpy P8ZP_SCRATCH_W2+1
|
|
bcc _true
|
|
bne _false
|
|
cmp P8ZP_SCRATCH_W2
|
|
bcc _true
|
|
_false lda #0
|
|
rts
|
|
_true lda #1
|
|
rts
|
|
.pend
|
|
|
|
reg_less_w .proc
|
|
; -- AY < P8ZP_SCRATCH_W2?
|
|
cmp P8ZP_SCRATCH_W2
|
|
tya
|
|
sbc P8ZP_SCRATCH_W2+1
|
|
bvc +
|
|
eor #$80
|
|
+ bmi _true
|
|
lda #0
|
|
rts
|
|
_true lda #1
|
|
rts
|
|
.pend
|
|
|
|
reg_lesseq_uw .proc
|
|
; AY <= P8ZP_SCRATCH_W2?
|
|
cpy P8ZP_SCRATCH_W2+1
|
|
beq +
|
|
bcc _true
|
|
lda #0
|
|
rts
|
|
+ cmp P8ZP_SCRATCH_W2
|
|
bcc _true
|
|
beq _true
|
|
lda #0
|
|
rts
|
|
_true lda #1
|
|
rts
|
|
.pend
|
|
|
|
reg_lesseq_w .proc
|
|
; -- P8ZP_SCRATCH_W2 <= AY ? (note: order different from other routines)
|
|
cmp P8ZP_SCRATCH_W2
|
|
tya
|
|
sbc P8ZP_SCRATCH_W2+1
|
|
bvc +
|
|
eor #$80
|
|
+ bpl +
|
|
lda #0
|
|
rts
|
|
+ lda #1
|
|
rts
|
|
.pend
|
|
|
|
|
|
memcopy16_up .proc
|
|
; -- copy memory UP from (P8ZP_SCRATCH_W1) to (P8ZP_SCRATCH_W2) of length X/Y (16-bit, X=lo, Y=hi)
|
|
; clobbers register A,X,Y
|
|
source = P8ZP_SCRATCH_W1
|
|
dest = P8ZP_SCRATCH_W2
|
|
length = P8ZP_SCRATCH_B1 ; (and SCRATCH_ZPREG)
|
|
|
|
stx length
|
|
sty length+1
|
|
|
|
ldx length ; move low byte of length into X
|
|
bne + ; jump to start if X > 0
|
|
dec length ; subtract 1 from length
|
|
+ ldy #0 ; set Y to 0
|
|
- lda (source),y ; set A to whatever (source) points to offset by Y
|
|
sta (dest),y ; move A to location pointed to by (dest) offset by Y
|
|
iny ; increment Y
|
|
bne + ; if Y<>0 then (rolled over) then still moving bytes
|
|
inc source+1 ; increment hi byte of source
|
|
inc dest+1 ; increment hi byte of dest
|
|
+ dex ; decrement X (lo byte counter)
|
|
bne - ; if X<>0 then move another byte
|
|
dec length ; we've moved 255 bytes, dec length
|
|
bpl - ; if length is still positive go back and move more
|
|
rts ; done
|
|
.pend
|
|
|
|
|
|
memset .proc
|
|
; -- fill memory from (P8ZP_SCRATCH_W1), length XY, with value in A.
|
|
; clobbers X, Y
|
|
stx P8ZP_SCRATCH_B1
|
|
sty _save_reg
|
|
ldy #0
|
|
ldx _save_reg
|
|
beq _lastpage
|
|
|
|
_fullpage sta (P8ZP_SCRATCH_W1),y
|
|
iny
|
|
bne _fullpage
|
|
inc P8ZP_SCRATCH_W1+1 ; next page
|
|
dex
|
|
bne _fullpage
|
|
|
|
_lastpage ldy P8ZP_SCRATCH_B1
|
|
beq +
|
|
- dey
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
bne -
|
|
|
|
+ rts
|
|
_save_reg .byte 0
|
|
.pend
|
|
|
|
|
|
memsetw .proc
|
|
; -- fill memory from (P8ZP_SCRATCH_W1) number of words in P8ZP_SCRATCH_W2, with word value in AY.
|
|
; clobbers A, X, Y
|
|
sta _mod1+1 ; self-modify
|
|
sty _mod1b+1 ; self-modify
|
|
sta _mod2+1 ; self-modify
|
|
sty _mod2b+1 ; self-modify
|
|
ldx P8ZP_SCRATCH_W1
|
|
stx P8ZP_SCRATCH_B1
|
|
ldx P8ZP_SCRATCH_W1+1
|
|
inx
|
|
stx P8ZP_SCRATCH_REG ; second page
|
|
|
|
ldy #0
|
|
ldx P8ZP_SCRATCH_W2+1
|
|
beq _lastpage
|
|
|
|
_fullpage
|
|
_mod1 lda #0 ; self-modified
|
|
sta (P8ZP_SCRATCH_W1),y ; first page
|
|
sta (P8ZP_SCRATCH_B1),y ; second page
|
|
iny
|
|
_mod1b lda #0 ; self-modified
|
|
sta (P8ZP_SCRATCH_W1),y ; first page
|
|
sta (P8ZP_SCRATCH_B1),y ; second page
|
|
iny
|
|
bne _fullpage
|
|
inc P8ZP_SCRATCH_W1+1 ; next page pair
|
|
inc P8ZP_SCRATCH_W1+1 ; next page pair
|
|
inc P8ZP_SCRATCH_B1+1 ; next page pair
|
|
inc P8ZP_SCRATCH_B1+1 ; next page pair
|
|
dex
|
|
bne _fullpage
|
|
|
|
_lastpage ldx P8ZP_SCRATCH_W2
|
|
beq _done
|
|
|
|
ldy #0
|
|
-
|
|
_mod2 lda #0 ; self-modified
|
|
sta (P8ZP_SCRATCH_W1), y
|
|
inc P8ZP_SCRATCH_W1
|
|
bne _mod2b
|
|
inc P8ZP_SCRATCH_W1+1
|
|
_mod2b lda #0 ; self-modified
|
|
sta (P8ZP_SCRATCH_W1), y
|
|
inc P8ZP_SCRATCH_W1
|
|
bne +
|
|
inc P8ZP_SCRATCH_W1+1
|
|
+ dex
|
|
bne -
|
|
_done rts
|
|
.pend
|
|
|
|
|
|
|
|
ror2_mem_ub .proc
|
|
; -- in-place 8-bit ror of byte at memory location in AY
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy #0
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
lsr a
|
|
bcc +
|
|
ora #$80
|
|
+ sta (P8ZP_SCRATCH_W1),y
|
|
rts
|
|
.pend
|
|
|
|
rol2_mem_ub .proc
|
|
; -- in-place 8-bit rol of byte at memory location in AY
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy #0
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
cmp #$80
|
|
rol a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
rts
|
|
.pend
|
|
|
|
rol_array_ub .proc
|
|
; -- rol a ubyte in an array
|
|
lda _arg_target
|
|
ldy _arg_target+1
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy _arg_index
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
rol a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
rts
|
|
_arg_target .word 0
|
|
_arg_index .byte 0
|
|
.pend
|
|
|
|
|
|
ror_array_ub .proc
|
|
; -- ror a ubyte in an array
|
|
lda _arg_target
|
|
ldy _arg_target+1
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy _arg_index
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
ror a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
rts
|
|
_arg_target .word 0
|
|
_arg_index .byte 0
|
|
.pend
|
|
|
|
ror2_array_ub .proc
|
|
; -- ror2 (8-bit ror) a ubyte in an array
|
|
lda _arg_target
|
|
ldy _arg_target+1
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy _arg_index
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
lsr a
|
|
bcc +
|
|
ora #$80
|
|
+ sta (P8ZP_SCRATCH_W1),y
|
|
rts
|
|
_arg_target .word 0
|
|
_arg_index .byte 0
|
|
.pend
|
|
|
|
rol2_array_ub .proc
|
|
; -- rol2 (8-bit rol) a ubyte in an array
|
|
lda _arg_target
|
|
ldy _arg_target+1
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy _arg_index
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
cmp #$80
|
|
rol a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
rts
|
|
_arg_target .word 0
|
|
_arg_index .byte 0
|
|
.pend
|
|
|
|
ror_array_uw .proc
|
|
; -- ror a uword in an array
|
|
php
|
|
lda _arg_target
|
|
ldy _arg_target+1
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
lda _arg_index
|
|
asl a
|
|
tay
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
plp
|
|
ror a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
dey
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
ror a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
rts
|
|
_arg_target .word 0
|
|
_arg_index .byte 0
|
|
.pend
|
|
|
|
rol_array_uw .proc
|
|
; -- rol a uword in an array
|
|
php
|
|
lda _arg_target
|
|
ldy _arg_target+1
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
lda _arg_index
|
|
asl a
|
|
tay
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
plp
|
|
rol a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
rol a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
rts
|
|
_arg_target .word 0
|
|
_arg_index .byte 0
|
|
.pend
|
|
|
|
rol2_array_uw .proc
|
|
; -- rol2 (16-bit rol) a uword in an array
|
|
lda _arg_target
|
|
ldy _arg_target+1
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
lda _arg_index
|
|
asl a
|
|
tay
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
asl a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
rol a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
bcc +
|
|
dey
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
adc #0
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
+ rts
|
|
_arg_target .word 0
|
|
_arg_index .byte 0
|
|
.pend
|
|
|
|
ror2_array_uw .proc
|
|
; -- ror2 (16-bit ror) a uword in an array
|
|
lda _arg_target
|
|
ldy _arg_target+1
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
lda _arg_index
|
|
asl a
|
|
tay
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
lsr a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
dey
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
ror a
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
bcc +
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
ora #$80
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
+ rts
|
|
_arg_target .word 0
|
|
_arg_index .byte 0
|
|
.pend
|
|
|
|
|
|
strcpy .proc
|
|
; copy a string (must be 0-terminated) from A/Y to (P8ZP_SCRATCH_W1)
|
|
; it is assumed the target string is large enough.
|
|
; returns the length of the string that was copied in Y.
|
|
sta P8ZP_SCRATCH_W2
|
|
sty P8ZP_SCRATCH_W2+1
|
|
ldy #$ff
|
|
- iny
|
|
lda (P8ZP_SCRATCH_W2),y
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
bne -
|
|
rts
|
|
.pend
|
|
|
|
strcmp_expression .proc
|
|
; -- compare strings, result in A
|
|
lda _arg_s2
|
|
ldy _arg_s2+1
|
|
sta P8ZP_SCRATCH_W2
|
|
sty P8ZP_SCRATCH_W2+1
|
|
lda _arg_s1
|
|
ldy _arg_s1+1
|
|
jmp strcmp_mem
|
|
_arg_s1 .word 0
|
|
_arg_s2 .word 0
|
|
.pend
|
|
|
|
strcmp_mem .proc
|
|
; -- compares strings in s1 (AY) and s2 (P8ZP_SCRATCH_W2).
|
|
; Returns -1,0,1 in A, depeding on the ordering. Clobbers Y.
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy #0
|
|
_loop lda (P8ZP_SCRATCH_W1),y
|
|
bne +
|
|
lda (P8ZP_SCRATCH_W2),y
|
|
bne _return_minusone
|
|
beq _return
|
|
+ cmp (P8ZP_SCRATCH_W2),y
|
|
bcc _return_minusone
|
|
bne _return_one
|
|
inc P8ZP_SCRATCH_W1
|
|
bne +
|
|
inc P8ZP_SCRATCH_W1+1
|
|
+ inc P8ZP_SCRATCH_W2
|
|
bne _loop
|
|
inc P8ZP_SCRATCH_W2+1
|
|
bne _loop
|
|
_return_one
|
|
lda #1
|
|
_return rts
|
|
_return_minusone
|
|
lda #-1
|
|
rts
|
|
.pend
|
|
|
|
|
|
strlen .proc
|
|
; -- returns the number of bytes in the string in AY, in Y.
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy #0
|
|
- lda (P8ZP_SCRATCH_W1),y
|
|
beq +
|
|
iny
|
|
bne -
|
|
+ rts
|
|
.pend
|
|
|
|
|
|
containment_bytearray .proc
|
|
; -- check if a value exists in a byte array.
|
|
; parameters: P8ZP_SCRATCH_W1: address of the byte array, A = byte to check, Y = length of array (>=1).
|
|
; returns boolean 0/1 in A.
|
|
dey
|
|
- cmp (P8ZP_SCRATCH_W1),y
|
|
beq +
|
|
dey
|
|
cpy #255
|
|
bne -
|
|
lda #0
|
|
rts
|
|
+ lda #1
|
|
rts
|
|
.pend
|
|
|
|
containment_wordarray .proc
|
|
; -- check if a value exists in a word array.
|
|
; parameters: P8ZP_SCRATCH_W1: value to check, P8ZP_SCRATCH_W2: address of the word array, Y = length of array (>=1).
|
|
; returns boolean 0/1 in A.
|
|
dey
|
|
tya
|
|
asl a
|
|
tay
|
|
- lda P8ZP_SCRATCH_W1
|
|
cmp (P8ZP_SCRATCH_W2),y
|
|
bne +
|
|
lda P8ZP_SCRATCH_W1+1
|
|
iny
|
|
cmp (P8ZP_SCRATCH_W2),y
|
|
beq _found
|
|
dey
|
|
+ dey
|
|
dey
|
|
cpy #254
|
|
bne -
|
|
lda #0
|
|
rts
|
|
_found lda #1
|
|
rts
|
|
.pend
|