1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
; Altirra BASIC - Memory handling module
; Copyright (C) 2014-2016 Avery Lee, All Rights Reserved.
;
; Copying and distribution of this file, with or without modification,
; are permitted in any medium without royalty provided the copyright
; notice and this notice are preserved. This file is offered as-is,
; without any warranty.
;==========================================================================
; Input:
; Y:A Total bytes required
; X ZP offset of first pointer to offset
; A0 Insertion point
;
; Errors:
; Error 2 if out of memory (yes, this may invoke TRAP!)
;
.proc expandTable
;##TRACE "Expanding table: $%04x bytes required, table offset $%02x (%y:%y) [$%04x:$%04x], insert pt=$%04x" y*256+a x x-2 x dw(x-2) dw(x) dw(a0)
sta a2
sty a2+1
txa
pha
;compute number of bytes to copy
;##ASSERT dw(a0) <= dw(memtop2)
sec
sbw memtop2 a0 a3
;top of src = memtop2
;top of dst = memtop2 + N
clc
lda memtop2
sta a1
adc a2
tay
lda memtop2+1
sta a1+1
adc a2+1
;check if we're going to go above MEMTOP with the copy and throw
;error 2 if so; note that we are deliberately off by one here to
;match FRE(0)
jsr MemCheckAddrAY
jsr copyDescendingDstAY
pla
tax
.def :MemAdjustTablePtrs = *
ldy #a2
offset_loop:
jsr IntAdd
inx
inx
cpx #memtop2+2
bne offset_loop
.def :MemAdjustAPPMHI = * ;NOTE: Must not modify X or CLR/NEW will break.
;update OS APPMHI from our memory top
sta appmhi+1
lda memtop2
sta appmhi
nothing_to_do:
xit:
rts
.endp
;==========================================================================
.proc MemCheckAddrAY
bcs out_of_memory ;dst+N > $FFFF => obviously out of memory
;out of memory if (dst+N) > memtop
cmp memtop+1
bne test_byte
cpy memtop
beq expandTable.xit
test_byte:
bcc expandTable.xit
out_of_memory:
jmp errorNoMemory
.endp
;==========================================================================
; Input:
; A1 end of source range
; A0 end of destination range
; A3 bytes to copy
;
; Modified:
; A0, A1
;
; Preserved:
; A2
.proc copyDescendingDstAY
sty a0
sta a0+1
.def :copyDescending
;##TRACE "Copy descending src=$%04x-$%04x, dst=$%04x-$%04x (len=$%04x)" dw(a0)-dw(a3) dw(a0) dw(a1)-dw(a3) dw(a1) dw(a3)
;##ASSERT dw(a3) <= dw(a0) and dw(a3) <= dw(a1)
ldy #0
;check if we have any whole pages to copy
ldx a3+1
inx
bne loop_entry ;!! - unconditional
loop:
dey
lda (a1),y
sta (a0),y
tya
bne loop
loop_entry:
dec a0+1
dec a1+1
dex
bne loop
ldx a3
beq leftovers_done
leftover_loop:
dey
lda (a1),y
sta (a0),y
dex
bne leftover_loop
leftovers_done:
rts
.endp
;==========================================================================
.proc IntAddToFR0
ldx #fr0
.def :IntAdd = *
lda 0,x
add 0,y
sta 0,x
lda 1,x
adc 1,y
sta 1,x
rts
.endp
|