4cade/src/glue.prorwts2.a

498 lines
12 KiB
Plaintext
Raw Normal View History

;license:MIT
;(c) 2018 by 4am & qkumba
;
; ProRWTS2 glue functions
;
; Public functions
; - LoadFile
; - LoadDHRFile
2018-11-10 15:08:14 +00:00
; - SaveSmallFile
;
2018-11-10 15:08:14 +00:00
; A general note about paths:
;
2018-11-10 15:08:14 +00:00
; LoadFile, LoadDHRFile, and SaveSmallFile support files in subdirectories.
; Paths are delimited by '/' like ProDOS. HOWEVER, you should never include a
; disk volume name. At program startup, we get the current directory and save
; it; that is the PROGRAM ROOT DIRECTORY. The first '/' always points to the
; PROGRAM ROOT DIRECTORY. All pathnames are relative to the PROGRAM ROOT
; DIRECTORY.
;
; The PROGRAM ROOT DIRECTORY is not guaranteed to be the root directory of the
; underlying ProDOS disk (although it can be). These functions provide no
2018-11-10 15:14:12 +00:00
; access to any directory above the PROGRAM ROOT DIRECTORY, i.e. you can't use
; '..' to access the parent directory.
2018-11-10 15:08:14 +00:00
;
; Examples:
; '/PREFS.CONF' points to a file named 'PREFS.CONF' in the PROGRAM ROOT
; DIRECTORY.
;
; '/FX/RIPPLE' points to a file named 'RIPPLE' in a directory named 'FX' in the
; PROGRAM ROOT DIRECTORY.
2018-10-28 15:44:26 +00:00
gRootDirectory
!word $FDFD
gPrefix
!word $FDFD
2018-10-28 15:44:26 +00:00
;------------------------------------------------------------------------------
; LoadFile
; load a file into memory all at once, using ProRWTS2
2018-11-10 15:08:14 +00:00
; supports paths, see note
; uses file's load address
;
; in: stack contains 2 bytes of parameters:
; +1 address of filename
; out: all flags clobbered
; all registers clobbered
; stack set to next instruction after parameters
;------------------------------------------------------------------------------
LoadFile
+PARAMS_ON_STACK 2
+LDPARAM 1
+STAY namlo ; set filename
+STAY gPrefix ; remember path
2018-10-28 18:04:52 +00:00
jsr traverse ; go to subdirectory, set up filename for read
lda #cmdread ; read (instead of write)
sta reqcmd
lda #0 ; 0 = read into main memory
sta auxreq
lda #$FF ; read entire file (ProRWTS2 will figure out exact size)
sta sizehi
jmp hddopendir ; exit via ProRWTS2
;------------------------------------------------------------------------------
; LoadDHRFile
; load .A2FC file (uncompressed double hi-res graphics) into memory
; all at once, using ProRWTS2
; first $2000 bytes of file are loaded into auxiliary memory $2000..$3FFF
; second $2000 bytes of file are loaded into main memory $2000..$3FFF
2018-11-10 15:08:14 +00:00
; supports paths, see note
2018-10-28 18:04:52 +00:00
;
; in: stack contains 2 bytes of parameters:
; +1 address of filename
; out: all flags clobbered
; all registers clobbered
; stack set to next instruction after parameters
;------------------------------------------------------------------------------
LoadDHRFile
+PARAMS_ON_STACK 2
+LDPARAM 1
+STAY namlo ; set filename
jsr traverse ; go to subdirectory, set up filename for read
lda #$00 ; read first $2000 bytes
sta sizelo
lda #$20
sta sizehi
lda #1 ; 1 = read into aux memory
sta auxreq
lda #cmdread ; read (instead of write)
sta reqcmd
jsr hddopendir ; call ProRWTS2
lda #$20 ; read next $2000 bytes
sta sizehi
dec auxreq ; 0 = read into main memory
clc ; not a subdirectory
2018-10-28 18:04:52 +00:00
jmp hddrdwrpart ; call ProRWTS2
2018-11-10 15:08:14 +00:00
;------------------------------------------------------------------------------
; SaveSmallFile
; Save a file into memory all at once, using ProRWTS2.
; /!\ Only first block (512 bytes) is written. Keep those files small. /!\
; /!\ All 512 bytes are written to disk. Clear buffer before calling. /!\
; supports paths, see note
;
; in: stack contains 4 bytes of parameters:
; +1 address of filename
; +3 address of data buffer
; out: all flags clobbered
; all registers clobbered
; stack set to next instruction after parameters
;------------------------------------------------------------------------------
SaveSmallFile
+PARAMS_ON_STACK 4
+LDPARAM 1
+STAY namlo ; set filename for ProRWTS2
+STAY gPrefix ; remember path
+LDPARAM 3
+STAY ldrlo ; set data buffer address for ProRWTS2
jsr traverse ; go to subdirectory, set up filename for read
lda #cmdwrite ; write (instead of read)
sta reqcmd
lda #0 ; 0 = data buffer is in main memory (instead of auxmem)
sta auxreq
jmp hddopendir ; exit via ProRWTS2
;------------------------------------------------------------------------------
; traverse [private]
;
; in: (namlo) points to length-prefixed pathname+filename
; out: all flags clobbered
; all registers clobbered
;------------------------------------------------------------------------------
2018-10-28 18:04:52 +00:00
traverse
2018-10-28 15:44:26 +00:00
+LDAY gRootDirectory
sta @myreadblock+1
sty @myreadblock+3 ; reset 'root' directory (saved at program start)
;search for '/' character in filename
ldx #0
ldy #0
lda (namlo), y
tay
- inx
dey
bmi @go ; no '/', just do the read
lda (namlo), y
cmp #'/'
bne -
sty sizelo
txa
pha
@myreadblock
@myx80_parms
ldx #2
lda #0
jsr hddreaddirsel
lda #NAME_LENGTH
sta bloklo
lda #>(hdddirbuf - 1)
sta blokhi
;there can be only one page crossed, so we can increment here
@mynextent1
inc blokhi
@mynextent
ldy #0
lda (bloklo), y
pha
and #$0f
tax
-- iny
lda (bloklo), y
cmp (namlo), y
beq @myfoundname
;match failed, move to next directory in this block, if possible
- pla
@myskiphdr
clc
lda bloklo
adc #ENTRY_SIZE
sta bloklo
bcs @mynextent1
cmp #$ff ;4 + ($27 * $0d)
bne @mynextent
;read next directory block when we reach the end of this block
lda hdddirbuf + NEXT_BLOCK_LO
ldx hdddirbuf + NEXT_BLOCK_HI
bcs +
@myfoundname
dex
bne --
;parse path until last directory is seen
iny
lda (namlo), y
cmp #'/'
bne -
pla
and #$20 ;Volume Directory Header XOR subdirectory
bne @myskiphdr
tya
eor #$ff
adc sizelo
sta sizelo
clc
tya
adc namlo
sta namlo
;cache block number of current directory
;as starting position for subsequent searches
ldy #(KEY_POINTER + 1)
lda (bloklo), y
tax
dey
lda (bloklo), y
sta (reloc + unrhddblocklo - unrelochdd) + 1
stx (reloc + unrhddblockhi - unrelochdd) + 1
+ sta @myx80_parms + 1
stx @myx80_parms + 3
++ lda sizelo
bne @myreadblock
tay
pla
sta (namlo), y
@go
2018-10-28 18:04:52 +00:00
rts
promote
!pseudopc $bf00 {
lda $c08b
clc
bcc @do_enter
;$bf06
rts ;clock interface, must be RTS on real ProDOS if program uses $20x
@do_enter
lda $c08b
jmp ProDOS_enter
!text "q4!"
;$bf10
!word $c1d1, $c2d1, $c3d1, $c4d1, $c5d1, $c6d1, $c7d1
ProDOS_exit
lda $c081
pla ;saved inside ProDOS_enter
tay
pla
tax
lda #0
rts
ProDOS_fatal ;only for debugging, will be removed
2018-11-11 04:25:50 +00:00
pha
lda $c081
jsr $fe89
jsr $fe93
2018-11-11 04:25:50 +00:00
pla
jsr $fdda
jmp $ff59
ProDOS_prefix=$bfd0
; !fill $2e
}
end_promote
;------------------------------------------------------------------------------
; ProDOS_enter
; intercept certain ProDOS requests
; wrap them to ProRWTS2 file requests
;
; in: return address+1 is command and pointer to parameter block
; out: all flags clobbered
; A=0, X and Y preserved
; stack set to next instruction after parameters
;
; to do: preserve non-$4x zpage locations for titles that open files after start
;------------------------------------------------------------------------------
packet = $40 ;word
buffer = $42 ;word
ProDOS_enter
pla
sta @fetchaddr+1
pla
sta @fetchaddr+2
jsr @fetchbyte
sta @request+1
jsr @fetchbyte
sta packet
jsr @fetchbyte
sta packet+1
lda @fetchaddr+2
pha
lda @fetchaddr+1
pha
txa
pha
tya
pha
@request
lda #$d1
2018-11-11 04:25:50 +00:00
cmp #$c4
beq @do_getattrib
cmp #$c7
beq @do_prefix
cmp #$c8
beq @do_open
cmp #$ca
beq @do_read
cmp #$cb
beq @do_write
cmp #$cc
beq @do_close
cmp #$ce
beq @do_seek
;;any others??
jmp ProDOS_fatal
2018-11-11 04:25:50 +00:00
@do_getattrib
jsr @imp_getattrib
jmp ProDOS_exit
@do_prefix
jsr @imp_prefix
jmp ProDOS_exit
@do_open
jsr @imp_open
jmp ProDOS_exit
@do_read
jsr @imp_read
jmp ProDOS_exit
@do_write
jsr @imp_write
jmp ProDOS_exit
@do_close
jsr @imp_close
jmp ProDOS_exit
@do_seek
jsr @imp_seek
jmp ProDOS_exit
2018-11-11 04:25:50 +00:00
@imp_getattrib
lda packet+1
pha
lda packet
pha
ldx #namlo
jsr @setbuffer1
lda #$60
sta attribpatch
jsr hddopendir
lda #$10
sta attribpatch
pla
sta packet
pla
sta packet+1
ldy #5
lda ldrlo2
sta (packet), y
iny
lda ldrlo2+1
sta (packet), y
rts
@imp_prefix
ldx #buffer
jsr @setbuffer1
2018-11-06 06:16:35 +00:00
ldy ProDOS_prefix
@copy_prefix
2018-11-06 06:16:35 +00:00
lda ProDOS_prefix, y
sta (buffer), y
dey
2018-11-06 06:16:35 +00:00
bpl @copy_prefix
rts
@imp_open
ldx #namlo
jsr @setbuffer1
iny
inc @handles+1
@handles
ldx #0
iny
lda (packet), y
sta @handle-1, x
tax
jsr @patch_buffer
iny
lda #1
sta (packet), y
lda #0
sta reqcmd
sta sizehi
sta sizelo
jsr hddopendir
ldx encbufpatch1+1
inx
stx @block_index2+2
lda #0
beq @block_index2 ;always
@imp_seek
lda #cmdseek
!byte $2c
@imp_read
lda #cmdread
!byte $2c
@imp_write
lda #cmdwrite
sta reqcmd
jsr @set_rdwrbuff
ldx encbufpatch1+1
inx
stx @block_index1+2
stx @block_index2+2
@block_index1
lda $d1ff
sta blkidx
clc ;not a subdirectory
jsr hddrdwrpart
lda blkidx
@block_index2
sta $d1ff
rts
@imp_close
dec @handles+1
bne @close_ret
lda #>hddencbuf
@patch_buffer
sta encbufpatch1+1
sta encbufpatch2+1
tax
inx
stx dirbufpatch1+1
inx
stx dirbufpatch2+2
stx dirbufpatch3+2
stx dirbufpatch4+2
stx dirbufpatch6+1
stx dirbufpatch7+2
stx dirbufpatch9+2
stx dirbufpatch10+1
inx
stx dirbufpatch5+2
stx dirbufpatch8+2
@close_ret
rts
@fetchbyte
inc @fetchaddr+1
bne @fetchaddr
lda @fetchaddr+2
@fetchaddr
lda $d1d1
rts
@set_rdwrbuff
ldy #1
lda (packet), y
tax
lda @handle-1, x
tax
jsr @patch_buffer
ldx #ldrlo
iny
jsr @setbuffer
ldx #sizelo
iny
!byte $2c
@setbuffer1
ldy #1
@setbuffer
lda (packet), y
sta $0,x
iny
lda (packet), y
sta $1,x
rts
@handle
!byte 0, 0 ;only up to two handles at a time