A2osX/ProDOS.FX/ProDOS.S.LDR.B.txt
2019-10-31 07:54:28 +01:00

375 lines
9.4 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
*--------------------------------------
* relocation subroutine. on entry, regs yx = address of parameter table
* with the following parameters:
*
* (1) command: 0 = zero destination range
* 1 = move data from src to dst
* 2 = hi addr ref tbl, relocate and move
* 3 = lo/hi addr ref tbl, relocate and move
* 4 = program, relocate and move
* >4 = end of sequence of commands
* (2) destination
* (2) length
* (2) source
* (1) # of address ranges (n) to be relocated
* (n+1) list of low page addresses to be relocated
* (n+1) list of high page addresses to be relocated
* (n+1) list of offset amounts to be added to be added
* if low and high limits have not been met
*
* on exit, carry set if error and yx = addr of error
* with acc = $00 for table error or $FF if illegal opcode
reloc stx idxl save address of control table
sty idxl+1
rloop lda (idxl) get relocation command.
cmp #$05
bcs rlend taken if >= 5 then done.
tax move destination to page 0
ldy #$01 for indirect access.
lda (idxl),y
sta dst
iny
lda (idxl),y
sta dst+1
iny
lda (idxl),y also the length (byte count)
sta cnt of the destination area.
iny
lda (idxl),y
sta cnt+1
bmi rlerr branch if >= 32k.
txa is it a request to zero destination?
beq zero if yes.
iny
lda (idxl),y get source address.
sta src used for move.
sta cde used for relocation
iny
clc
adc cnt add length to get final address
sta ecde
lda (idxl),y
sta src+1
sta cde+1
adc cnt+1
sta ecde+1
dex test for 'move' command
beq H2AA3 branch if move only (no relocation)
stx wsize save element size (1,2,3)
iny
lda (idxl),y get # of ranges that are valid
sta sgcnt relocation target addresses.
tax separate serial range groups into tbls
H2A42 iny
lda (idxl),y transfer low limits to 'limlo' table
sta limlo,x
dex
bpl H2A42
ldx sgcnt # of ranges
H2A4E iny
lda (idxl),y transfer high limits to 'limhi' table
sta limhi,x
dex
bpl H2A4E
ldx sgcnt # of ranges
H2A5A iny
lda (idxl),y transfer offsets to 'ofset' table
sta ofset,x
dex
bpl H2A5A
jsr adjtbl adj index pointer to next entry.
ldx wsize test for machine code relocation
cpx #$03
beq rlcode branch if program relocation
jsr reladr otherwise, relocate addresses in
H2A70 jsr moveSrcDst tables then move to destination.
bra rloop do next table
rlend clc
rts
rlerr jmp tblerr
rlcode jsr rlprog relocate machine code refs
bra H2A70
* fill destination range with 0's
zero jsr adjtbl adj table pointer to next entry.
lda #$00
ldy cnt+1 is it at least 1 page?
beq H2A94 branch if not.
tay
H2A89 sta (dst),y
iny
bne H2A89
inc dst+1 next page
dec cnt+1
bne H2A89 if more pages to clear.
H2A94 ldy cnt any bytes left to 0?
beq H2AA0 if not.
tay
H2A99 sta (dst),y zero out remainder
iny
cpy cnt
bcc H2A99
H2AA0 jmp rloop
H2AA3 jsr adjtbl
bra H2A70
adjtbl tya add previous table length to
sec get next entry position in table
adc idxl
sta idxl
bcc H2AB2
inc idxl+1
H2AB2 rts
moveSrcDst lda src+1 is move up, down or not at all?
cmp dst+1
bcc movup
bne movdn
lda src
cmp dst
bcc movup
bne movdn
rts no move.
movup ldy cnt+1 calc highest page to move up
tya and adj src and dst.
clc
adc src+1
sta src+1
tya
clc
adc dst+1
sta dst+1
ldy cnt move partial page 1st.
beq H2ADE taken if no partial pages
H2AD6 dey
lda (src),y
sta (dst),y
tya end of page transfer?
bne H2AD6 no
H2ADE dec dst+1
dec src+1
dec cnt+1 done with all pages?
bpl H2AD6 no
rts
movdn ldy #$00
lda cnt+1 partial page move only?
beq H2AFC taken if < 1 page to move
H2AED lda (src),y
sta (dst),y
iny
bne H2AED
inc dst+1 next page
inc src+1
dec cnt+1 more pages?
bne H2AED if more.
H2AFC lda cnt move partial page.
beq H2B09 if no more to move
H2B00 lda (src),y
sta (dst),y
iny
cpy cnt
bne H2B00
H2B09 rts
* relocate addresses
reladr ldy wsize 1 or 2 byte reference
dey
lda (cde),y
jsr adjadr relocate reference.
lda wsize update and test code pointer.
jsr adjcde
bcc reladr if more to do
rts
rlprog ldy #$00 get next opcode
lda (cde),y
jsr oplen determine if a 3 byte instruction.
beq rperr branch if not an opcode
cmp #$03
bne H2B30
ldy #$02
jsr adjadr relocate address
lda #$03
H2B30 jsr adjcde update and test if done.
bcc rlprog if more to do
rts
rperr pla
pla
ldx cde bad code address in y,x
ldy cde+1
lda #$FF indicates bad opcode
sec
rts
tblerr ldx idxl bad table address in y,x
ldy idxl+1
lda #$00 indicates input table error
sec
rts
adjadr lda (cde),y get page address and
ldx sgcnt test against limits.
H2B4D cmp limlo,x is it >= low?
bcc H2B59 if not.
cmp limhi,x is it <= high?
bcc H2B5D branch if it is
beq H2B5D
H2B59 dex try next limit set
bpl H2B4D
rts return w/o adjustment.
H2B5D clc add offset to form relocated
adc ofset,x page address and replace
sta (cde),y old address with result.
rts
adjcde clc update code pointer
adc cde
ldy cde+1
bcc H2B6C branch if not page cross
iny otherwise, update page#.
H2B6C cpy ecde+1 has all code/data been processed?
bcc H2B72 if not.
cmp ecde
H2B72 sta cde save updated values.
sty cde+1
rts return result (carry set = done).
oplen pha form index to tbl & which 2-bit group.
and #$03 low 2 bits specify group
tay
pla
lsr upper 6 bits specify byte in table
lsr
tax
lda opcodln,x
nxgroup dey is opcode len in lowest 2 bits of acc?
bmi H2B89 branch if it is
lsr shift to next group.
lsr (if length = 0 then error)
bne nxgroup
H2B89 and #$03
rts if z-set then error
* relocation table contains length of each opcode in 2-bit groups
opcodln .HS 0928193C0A280D3C
.HS 0B2A193F0A280D3C
.HS 0928193F0A280D3C
.HS 0928193F0A280D3C
.HS 082A113F0A2A1D0C
.HS 2A2A193F0A2A1D3F
.HS 0A2A193F0A280D3C
.HS 0A2A193F0A280D3C
wsize .HS 00
sgcnt .HS 00
limlo .HS 0000000000000000
limhi .HS 0000000000000000
ofset .HS 0000000000000000
* patch to gsos vectors so error is returned for os calls - rev note #101
patch101 php
sei disable interrupts
clc
xce full native mode
>LONGMX
phb save DBR
pha
pha
pea $0000 length of patch
pea $0010 0000/0010 = 16 bytes
pea $3101 user id for prodos 8
pea $8018 attributes (locked/nospec/nocross)
pha
pha
>IIGS NewHandle
lda $01,s retrieve handle
tax
lda $03,s
tay
pea $0000 copy the code into the handle
pea L2C4D
phy
phx
pea $0000 length of patch = 0000/0010
pea $0010
>IIGS PtrToHand
plx low word of handle
plb set DBR to handle's bank
lda >1,x get upper 16 bits of 24 bit address
tay save in y
lda >0,x get low 8 bits of address
and ##$00FF clear high byte
xba put address in high byte
ora ##$005C include JML opcode
sta GSOS2 store in gsos vectors
clc
adc ##$000B
sta GSOS
tya store upper 16 bits too
sta GSOS2+2
adc ##$0000 adj for possible page crossing
sta GSOS+2
plb remove garbage byte from stack
plb restore DBR.
sec
xce back to emulation mode
plp
rts
* copy of the code that goes in the handle
L2C4D lda 1,s
sta 7,s
lda 2,s
sta 8,s
pla
pla
pla
lda ##$00FF #NoOS
sec
rtl
.BS $2C80-*
RAMDRV.Install ldy #$99 move $9A bytesfrom lcsrc to lcdest.
.1 lda RAM,y transfer main bank portion of driver
sta RAMDRV,y
dey
cpy #$FF
bne .1
ldx #RAMX set up to move aux portion of driver
stx A1L
dex
stx A2L
ldx /RAMX
stx A1L+1
inx
stx A2L+1
lda #RAMXDRV
sta A4L
lda /RAMXDRV RAMX to RAMXDRV
sta A4L+1
sec irection = to aux bank.
jsr auxmove move aux bank portion of driver.
lda #RAMDRV put driver address into
sta drivertbl2+6 slot 3, drive 2.
lda /RAMDRV
sta drivertbl2+7
inc numdevs count (-1) active devices
ldx numdevs
lda #$BF unit num of /RAM
sta devlist,x
rts
RAM_1_END .EQ * end of /RAM installer
.BS $2D00-* pad 0's to page boundary
MAN
SAVE USR/SRC/PRODOS.FX/PRODOS.S.LDR.B
LOAD USR/SRC/PRODOS.FX/PRODOS.S
ASM