2021-01-07 00:56:31 +00:00
|
|
|
; Internal library routines - always included by the compiler
|
2020-08-25 17:44:08 +00:00
|
|
|
; Generic machine independent 6502 code.
|
2019-01-20 23:00:26 +00:00
|
|
|
|
2020-11-21 18:09:02 +00:00
|
|
|
|
2022-01-09 00:33:30 +00:00
|
|
|
orig_stackpointer .byte 0 ; stores the Stack pointer register at program start
|
|
|
|
|
2023-07-15 13:40:51 +00:00
|
|
|
|
2023-08-04 21:36:51 +00:00
|
|
|
read_byte_from_address_in_AY_into_A .proc
|
2023-07-15 13:40:51 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2021-03-15 23:33:15 +00:00
|
|
|
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
|
|
|
|
|
2020-11-21 22:46:18 +00:00
|
|
|
reg_less_w .proc
|
|
|
|
; -- AY < P8ZP_SCRATCH_W2?
|
2020-11-30 00:53:44 +00:00
|
|
|
cmp P8ZP_SCRATCH_W2
|
2020-11-21 22:46:18 +00:00
|
|
|
tya
|
|
|
|
sbc P8ZP_SCRATCH_W2+1
|
|
|
|
bvc +
|
|
|
|
eor #$80
|
|
|
|
+ bmi _true
|
2020-11-30 00:53:44 +00:00
|
|
|
lda #0
|
2020-11-21 22:46:18 +00:00
|
|
|
rts
|
2020-11-30 00:53:44 +00:00
|
|
|
_true lda #1
|
2020-11-21 22:46:18 +00:00
|
|
|
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
|
2020-12-01 01:09:48 +00:00
|
|
|
; -- P8ZP_SCRATCH_W2 <= AY ? (note: order different from other routines)
|
|
|
|
cmp P8ZP_SCRATCH_W2
|
|
|
|
tya
|
|
|
|
sbc P8ZP_SCRATCH_W2+1
|
2020-11-21 22:46:18 +00:00
|
|
|
bvc +
|
|
|
|
eor #$80
|
2020-12-01 01:09:48 +00:00
|
|
|
+ bpl +
|
2020-11-30 01:12:49 +00:00
|
|
|
lda #0
|
2020-11-21 22:46:18 +00:00
|
|
|
rts
|
2020-12-01 01:09:48 +00:00
|
|
|
+ lda #1
|
2020-11-21 22:46:18 +00:00
|
|
|
rts
|
|
|
|
.pend
|
|
|
|
|
2020-03-13 01:05:15 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
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)
|
2019-03-31 16:04:19 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
stx length
|
|
|
|
sty length+1
|
2019-03-31 16:04:19 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
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
|
2020-10-28 22:13:53 +00:00
|
|
|
.pend
|
|
|
|
|
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
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
|
2020-10-28 22:13:53 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
_fullpage sta (P8ZP_SCRATCH_W1),y
|
|
|
|
iny
|
|
|
|
bne _fullpage
|
|
|
|
inc P8ZP_SCRATCH_W1+1 ; next page
|
|
|
|
dex
|
|
|
|
bne _fullpage
|
2020-10-28 22:13:53 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
_lastpage ldy P8ZP_SCRATCH_B1
|
|
|
|
beq +
|
|
|
|
- dey
|
|
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
|
|
bne -
|
2020-10-28 22:13:53 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
+ rts
|
|
|
|
_save_reg .byte 0
|
2020-10-28 22:13:53 +00:00
|
|
|
.pend
|
|
|
|
|
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
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
|
2020-10-28 22:13:53 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
ldy #0
|
|
|
|
ldx P8ZP_SCRATCH_W2+1
|
|
|
|
beq _lastpage
|
2019-01-20 23:00:26 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
_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
|
2020-11-03 21:42:59 +00:00
|
|
|
dex
|
2020-11-05 21:27:50 +00:00
|
|
|
bne _fullpage
|
2019-01-20 23:00:26 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
_lastpage ldx P8ZP_SCRATCH_W2
|
|
|
|
beq _done
|
2019-01-20 23:00:26 +00:00
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
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
|
2019-01-20 23:00:26 +00:00
|
|
|
.pend
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
ror2_mem_ub .proc
|
2020-11-06 22:51:39 +00:00
|
|
|
; -- in-place 8-bit ror of byte at memory location in AY
|
2020-11-05 21:27:50 +00:00
|
|
|
sta P8ZP_SCRATCH_W1
|
2020-11-06 22:51:39 +00:00
|
|
|
sty P8ZP_SCRATCH_W1+1
|
2020-11-05 21:27:50 +00:00
|
|
|
ldy #0
|
|
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
|
|
lsr a
|
|
|
|
bcc +
|
|
|
|
ora #$80
|
|
|
|
+ sta (P8ZP_SCRATCH_W1),y
|
2019-01-20 23:00:26 +00:00
|
|
|
rts
|
|
|
|
.pend
|
|
|
|
|
2020-11-05 21:27:50 +00:00
|
|
|
rol2_mem_ub .proc
|
2020-11-06 22:51:39 +00:00
|
|
|
; -- in-place 8-bit rol of byte at memory location in AY
|
2020-11-05 21:27:50 +00:00
|
|
|
sta P8ZP_SCRATCH_W1
|
2020-11-06 22:51:39 +00:00
|
|
|
sty P8ZP_SCRATCH_W1+1
|
2020-11-05 21:27:50 +00:00
|
|
|
ldy #0
|
|
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
|
|
cmp #$80
|
|
|
|
rol a
|
|
|
|
sta (P8ZP_SCRATCH_W1),y
|
2019-01-20 23:00:26 +00:00
|
|
|
rts
|
|
|
|
.pend
|
|
|
|
|
2020-08-20 16:07:48 +00:00
|
|
|
|
2020-06-05 21:19:06 +00:00
|
|
|
strcpy .proc
|
2020-10-04 15:47:57 +00:00
|
|
|
; copy a string (must be 0-terminated) from A/Y to (P8ZP_SCRATCH_W1)
|
2020-06-05 21:19:06 +00:00
|
|
|
; it is assumed the target string is large enough.
|
2020-12-14 16:20:16 +00:00
|
|
|
; returns the length of the string that was copied in Y.
|
2020-08-25 17:44:08 +00:00
|
|
|
sta P8ZP_SCRATCH_W2
|
|
|
|
sty P8ZP_SCRATCH_W2+1
|
2020-06-05 21:19:06 +00:00
|
|
|
ldy #$ff
|
|
|
|
- iny
|
2020-08-25 17:44:08 +00:00
|
|
|
lda (P8ZP_SCRATCH_W2),y
|
|
|
|
sta (P8ZP_SCRATCH_W1),y
|
2020-06-05 21:19:06 +00:00
|
|
|
bne -
|
|
|
|
rts
|
|
|
|
.pend
|
2020-08-20 16:07:48 +00:00
|
|
|
|
2020-11-06 21:59:56 +00:00
|
|
|
strcmp_expression .proc
|
2020-11-10 20:48:28 +00:00
|
|
|
; -- compare strings, result in A
|
|
|
|
lda _arg_s2
|
|
|
|
ldy _arg_s2+1
|
2020-11-06 21:59:56 +00:00
|
|
|
sta P8ZP_SCRATCH_W2
|
|
|
|
sty P8ZP_SCRATCH_W2+1
|
2020-11-10 20:48:28 +00:00
|
|
|
lda _arg_s1
|
|
|
|
ldy _arg_s1+1
|
2020-11-06 21:59:56 +00:00
|
|
|
jmp strcmp_mem
|
2020-11-10 20:48:28 +00:00
|
|
|
_arg_s1 .word 0
|
|
|
|
_arg_s2 .word 0
|
2020-11-06 21:59:56 +00:00
|
|
|
.pend
|
|
|
|
|
2020-10-15 23:12:20 +00:00
|
|
|
strcmp_mem .proc
|
2020-10-16 23:30:49 +00:00
|
|
|
; -- compares strings in s1 (AY) and s2 (P8ZP_SCRATCH_W2).
|
2020-10-15 23:12:20 +00:00
|
|
|
; Returns -1,0,1 in A, depeding on the ordering. Clobbers Y.
|
2021-01-07 00:56:31 +00:00
|
|
|
sta P8ZP_SCRATCH_W1
|
|
|
|
sty P8ZP_SCRATCH_W1+1
|
2022-02-04 15:07:03 +00:00
|
|
|
ldy #0
|
|
|
|
_loop lda (P8ZP_SCRATCH_W1),y
|
2021-01-07 00:56:31 +00:00
|
|
|
bne +
|
|
|
|
lda (P8ZP_SCRATCH_W2),y
|
|
|
|
bne _return_minusone
|
|
|
|
beq _return
|
2022-02-04 15:07:03 +00:00
|
|
|
+ cmp (P8ZP_SCRATCH_W2),y
|
|
|
|
bcc _return_minusone
|
|
|
|
bne _return_one
|
2021-01-07 00:56:31 +00:00
|
|
|
inc P8ZP_SCRATCH_W1
|
|
|
|
bne +
|
|
|
|
inc P8ZP_SCRATCH_W1+1
|
|
|
|
+ inc P8ZP_SCRATCH_W2
|
|
|
|
bne _loop
|
|
|
|
inc P8ZP_SCRATCH_W2+1
|
|
|
|
bne _loop
|
2020-10-15 23:12:20 +00:00
|
|
|
_return_one
|
2021-01-07 00:56:31 +00:00
|
|
|
lda #1
|
|
|
|
_return rts
|
2020-10-15 23:12:20 +00:00
|
|
|
_return_minusone
|
2021-01-07 00:56:31 +00:00
|
|
|
lda #-1
|
|
|
|
rts
|
|
|
|
.pend
|
2020-11-24 21:26:11 +00:00
|
|
|
|
|
|
|
|
2021-03-20 01:39:53 +00:00
|
|
|
strlen .proc
|
2023-11-30 22:07:25 +00:00
|
|
|
; -- returns the number of bytes in the string in AY, in Y. Clobbers A.
|
2021-03-20 01:39:53 +00:00
|
|
|
sta P8ZP_SCRATCH_W1
|
|
|
|
sty P8ZP_SCRATCH_W1+1
|
|
|
|
ldy #0
|
|
|
|
- lda (P8ZP_SCRATCH_W1),y
|
|
|
|
beq +
|
|
|
|
iny
|
|
|
|
bne -
|
|
|
|
+ rts
|
|
|
|
.pend
|
2021-12-29 15:21:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
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
|
2022-11-12 22:19:01 +00:00
|
|
|
dey
|
2021-12-29 15:21:37 +00:00
|
|
|
+ dey
|
|
|
|
dey
|
|
|
|
cpy #254
|
|
|
|
bne -
|
|
|
|
lda #0
|
|
|
|
rts
|
|
|
|
_found lda #1
|
|
|
|
rts
|
|
|
|
.pend
|
2024-02-10 02:07:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
arraycopy_split_to_normal_words .proc
|
|
|
|
; P8ZP_SCRATCH_W1 = start of lsb array
|
|
|
|
; P8ZP_SCRATCH_W2 = start of msb array
|
|
|
|
; AY = start of normal word target array
|
|
|
|
; X = number of elements to copy
|
|
|
|
sta _modlsb+1
|
|
|
|
sty _modlsb+2
|
|
|
|
clc
|
|
|
|
adc #1
|
|
|
|
bne +
|
|
|
|
iny
|
|
|
|
+ sta _modmsb+1
|
|
|
|
sty _modmsb+2
|
|
|
|
ldy #0
|
|
|
|
- lda (P8ZP_SCRATCH_W1),y
|
|
|
|
_modlsb sta $ffff ; modified lsb store
|
|
|
|
lda _modlsb+1
|
|
|
|
clc
|
|
|
|
adc #2
|
|
|
|
sta _modlsb+1
|
|
|
|
bcc +
|
|
|
|
inc _modlsb+2
|
|
|
|
+ lda (P8ZP_SCRATCH_W2),y
|
|
|
|
_modmsb sta $ffff ; modified msb store
|
|
|
|
lda _modmsb+1
|
|
|
|
clc
|
|
|
|
adc #2
|
|
|
|
sta _modmsb+1
|
|
|
|
bcc +
|
|
|
|
inc _modmsb+2
|
|
|
|
+ iny
|
|
|
|
dex
|
|
|
|
bne -
|
|
|
|
rts
|
|
|
|
.pend
|
|
|
|
|
|
|
|
|
|
|
|
arraycopy_normal_to_split_words .proc
|
|
|
|
; P8ZP_SCRATCH_W1 = start of target lsb array
|
|
|
|
; P8ZP_SCRATCH_W2 = start of target msb array
|
|
|
|
; AY = start of normal word source array
|
|
|
|
; X = number of elements to copy
|
|
|
|
sta _modsrclsb+1
|
|
|
|
sty _modsrclsb+2
|
|
|
|
clc
|
|
|
|
adc #1
|
|
|
|
bne +
|
|
|
|
iny
|
|
|
|
+ sta _modsrcmsb+1
|
|
|
|
sty _modsrcmsb+2
|
|
|
|
ldy #0
|
|
|
|
_modsrclsb lda $ffff ; modified lsb read
|
|
|
|
sta (P8ZP_SCRATCH_W1),y
|
|
|
|
lda _modsrclsb+1
|
|
|
|
clc
|
|
|
|
adc #2
|
|
|
|
sta _modsrclsb+1
|
|
|
|
bcc +
|
|
|
|
inc _modsrclsb+2
|
|
|
|
+
|
|
|
|
_modsrcmsb lda $ffff ; modnfied msb read
|
|
|
|
sta (P8ZP_SCRATCH_W2),y
|
|
|
|
lda _modsrcmsb+1
|
|
|
|
clc
|
|
|
|
adc #2
|
|
|
|
sta _modsrcmsb+1
|
|
|
|
bcc +
|
|
|
|
inc _modsrcmsb+2
|
|
|
|
+ iny
|
|
|
|
dex
|
|
|
|
bne _modsrclsb
|
|
|
|
rts
|
|
|
|
.pend
|
2024-02-11 22:27:26 +00:00
|
|
|
|
|
|
|
memcopy_small .proc
|
|
|
|
; copy up to a single page (256 bytes) of memory.
|
|
|
|
; note: only works for NON-OVERLAPPING memory regions!
|
|
|
|
; P8ZP_SCRATCH_W1 = from address
|
|
|
|
; P8ZP_SCRATCH_W2 = destination address
|
|
|
|
; Y = number of bytes to copy (where 0 means 256)
|
|
|
|
cpy #0
|
|
|
|
beq _fullpage
|
|
|
|
dey
|
|
|
|
beq _lastbyte
|
|
|
|
_loop lda (P8ZP_SCRATCH_W1),y
|
|
|
|
sta (P8ZP_SCRATCH_W2),y
|
|
|
|
dey
|
|
|
|
bne _loop
|
|
|
|
_lastbyte lda (P8ZP_SCRATCH_W1),y
|
|
|
|
sta (P8ZP_SCRATCH_W2),y
|
|
|
|
rts
|
|
|
|
_fullpage lda (P8ZP_SCRATCH_W1),y
|
|
|
|
sta (P8ZP_SCRATCH_W2),y
|
|
|
|
dey
|
|
|
|
bne _fullpage
|
|
|
|
rts
|
|
|
|
.pend
|