4cade/src/prodos.impl.a

665 lines
15 KiB
Plaintext
Raw Normal View History

2019-09-06 22:12:17 +00:00
;license:MIT
2019-09-11 04:26:00 +00:00
;(c) 2019 by 4am & qkumba
2019-09-06 22:12:17 +00:00
;
; Pseudo-ProDOS environment
;
;------------------------------------------------------------------------------
; 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
;------------------------------------------------------------------------------
2019-09-29 15:08:57 +00:00
ipacket = first_zp ;word
2019-09-06 22:12:17 +00:00
buffer = first_zp+2 ;word
ProDOS_enter
!set CloseHandles = @imp_close
2019-09-24 00:01:42 +00:00
stx ProDOS_savedX+1
sty ProDOS_savedY+1
jsr @swap_zp
pla
tay
pla
sta @fetchaddr+1
pla
sta @fetchaddr+2
jsr @fetchbyte
sta @request+1
jsr @fetchbyte
2019-09-29 15:08:57 +00:00
sta ipacket
2019-09-24 00:01:42 +00:00
jsr @fetchbyte
2019-09-29 15:08:57 +00:00
sta ipacket+1
2019-09-24 00:01:42 +00:00
lda @fetchaddr+2
pha
lda @fetchaddr+1
pha
tya
pha
2019-09-06 22:12:17 +00:00
@request
2019-09-24 00:01:42 +00:00
lda #$d1
cmp #$80
beq @do_readblock
cmp #$81
beq @do_writeblock
cmp #$c4
beq @do_getattrib
cmp #$c6
beq @do_nothing
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
cmp #$d1
;; bne @do_fatal
2019-09-20 19:42:02 +00:00
@do_eof
2019-09-24 00:01:42 +00:00
jmp @imp_eof
2019-09-06 22:12:17 +00:00
@do_readblock
@do_writeblock
2019-09-24 00:01:42 +00:00
jmp @imp_rdwrblock
2019-09-06 22:12:17 +00:00
@do_getattrib
2019-09-24 00:01:42 +00:00
jmp @imp_getattrib
2019-09-06 22:12:17 +00:00
@do_nothing
2019-09-24 00:01:42 +00:00
jmp @restore_zp
2019-09-06 22:12:17 +00:00
@do_prefix
2019-09-24 00:01:42 +00:00
jmp @imp_prefix
2019-09-06 22:12:17 +00:00
@do_open
2019-09-24 00:01:42 +00:00
jmp @imp_open
2019-09-06 22:12:17 +00:00
@do_read
2019-09-24 00:01:42 +00:00
jmp @imp_read
2019-09-06 22:12:17 +00:00
@do_write
2019-09-24 00:01:42 +00:00
jmp @imp_write
2019-09-06 22:12:17 +00:00
@do_close
2019-09-24 00:01:42 +00:00
jsr @imp_close ;subroutine special case because of dual-use
jmp @restore_zp
2019-09-06 22:12:17 +00:00
@do_seek
2019-09-24 00:01:42 +00:00
jmp @imp_seek
2019-09-20 19:42:02 +00:00
@do_fatal
2019-09-24 00:01:42 +00:00
;; jmp ProDOS_fatal
2019-09-06 22:12:17 +00:00
@imp_rdwrblock
2019-09-24 00:01:42 +00:00
and #$7f
tay
iny
sty @rdwrop+1
ldx #$44
ldy #2
jsr @setbuffer
iny
2019-09-29 15:08:57 +00:00
lda (ipacket), y
2019-09-24 00:01:42 +00:00
tax
iny
2019-09-29 15:08:57 +00:00
lda (ipacket), y
2019-09-06 22:12:17 +00:00
@rdwrop
2019-09-24 00:01:42 +00:00
ldy #$d1 ; SMC
jsr hddseekrd+2
bcc @jmp_zp2 ;always
2019-09-06 22:12:17 +00:00
@imp_getattrib
2019-09-29 15:08:57 +00:00
lda ipacket+1
2019-09-24 00:01:42 +00:00
pha
2019-09-29 15:08:57 +00:00
lda ipacket
2019-09-24 00:01:42 +00:00
pha
ldx #namlo
jsr @setbuffer1
lda #$60
sta attribpatch
jsr hddopendir
lda #$10
sta attribpatch
pla
2019-09-29 15:08:57 +00:00
sta ipacket
2019-09-24 00:01:42 +00:00
pla
2019-09-29 15:08:57 +00:00
sta ipacket+1
2019-09-24 00:01:42 +00:00
ldy #5
lda ldrlo2
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-24 00:01:42 +00:00
iny
lda ldrlo2+1
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-24 00:01:42 +00:00
ldy #$13
lda (bloklo), y
tax
iny
lda (bloklo), y
ldy #9
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-24 00:01:42 +00:00
txa
dey
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-06 22:12:17 +00:00
@jmp_zp2
2019-09-24 00:01:42 +00:00
jmp @restore_zp
2019-09-06 22:12:17 +00:00
@imp_prefix
2019-09-24 00:01:42 +00:00
ldx #buffer
jsr @setbuffer1
ldy ProDOS_prefix
iny
iny
tya
pha
dey
2019-09-06 22:12:17 +00:00
@copy_prefix
2019-09-24 00:01:42 +00:00
lda ProDOS_prefix, y
iny
sta (buffer), y
dey
dey
bne @copy_prefix
pla
sta (buffer), y
lda #'/'
iny
sta (buffer), y
bne @jmp_zp2
2019-09-06 22:12:17 +00:00
@imp_open
2019-09-24 00:01:42 +00:00
ldx #namlo
jsr @setbuffer1
iny
inc @handles+1
2019-09-06 22:12:17 +00:00
@handles
2019-09-24 00:01:42 +00:00
ldx #0
iny
2019-09-29 15:08:57 +00:00
lda (ipacket), y
2019-09-24 00:01:42 +00:00
sta @handle-1, x
jsr @patch_buffer
iny
lda #1
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-24 00:01:42 +00:00
lda #0
sta reqcmd
sta sizehi
sta sizelo
jsr hddopendir
lda #0
sta blkidx
beq @jmp_zp ;always
2019-09-06 22:12:17 +00:00
@imp_seek
2019-09-24 00:01:42 +00:00
jsr @set_rdwrbuff
lda #0
sta blkidx
sta blkofflo
sta blkoffhi
sta reqcmd
jsr @reset
ldx sizelo
beq @seek64
sta sizehi
sta sizelo
jsr @seekreset
inc ldrlo
bne @seek64
inc ldrhi
2019-09-06 22:12:17 +00:00
@seek64
2019-09-24 00:01:42 +00:00
lda ldrhi
sta sizehi
lda ldrlo
sta sizelo
jsr @seekreset
lda ldrhi
ora ldrlo
bne @jmp_zp
dec blkidx
beq @jmp_zp ;always
2019-09-06 22:12:17 +00:00
@seekreset
2019-09-24 00:01:42 +00:00
jsr hddrdwrpart
2019-09-06 22:12:17 +00:00
@reset
2019-09-24 00:01:42 +00:00
lda #$ff
sta blefthi
sta bleftlo
rts
2019-09-06 22:12:17 +00:00
@imp_read
2019-09-24 00:01:42 +00:00
clc
2019-09-06 22:12:17 +00:00
@imp_write
2019-09-24 00:01:42 +00:00
php
lda #cmdread
adc #0
sta reqcmd
jsr @set_rdwrbuff
plp
bcc @skip_align
lda sizelo
adc #$fe
lda sizehi
adc #1
and #$fe
sta sizehi
lda bleftlo
adc #$ff
lda blefthi
adc #1
and #$fe
sta blefthi
2019-09-06 22:12:17 +00:00
@skip_align
2019-09-24 00:01:42 +00:00
jsr hddrdwrpart
ldy #6
lda sizelo2
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-24 00:01:42 +00:00
iny
lda sizehi2
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-06 22:12:17 +00:00
@jmp_zp
2019-09-24 00:01:42 +00:00
jmp @restore_zp
2019-09-06 22:12:17 +00:00
@imp_eof
2019-09-24 00:01:42 +00:00
ldy #2
lda bleftlo
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-24 00:01:42 +00:00
iny
lda blefthi
2019-09-29 15:08:57 +00:00
sta (ipacket), y
2019-09-24 00:01:42 +00:00
bcs @restore_zp ;always
2019-09-06 22:12:17 +00:00
@imp_close
2019-09-24 00:01:42 +00:00
lda @handles+1
beq @close_ret
dec @handles+1
bne @close_ret
lda #>hddencbuf
2019-09-06 22:12:17 +00:00
@patch_buffer
2019-09-24 00:01:42 +00:00
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
2019-09-06 22:12:17 +00:00
@close_ret
2019-09-24 00:01:42 +00:00
rts
2019-09-06 22:12:17 +00:00
@fetchbyte
2019-09-24 00:01:42 +00:00
inc @fetchaddr+1
bne @fetchaddr
inc @fetchaddr+2
2019-09-06 22:12:17 +00:00
@fetchaddr
2019-09-24 00:01:42 +00:00
lda $d1d1
rts
2019-09-06 22:12:17 +00:00
@set_rdwrbuff
2019-09-24 00:01:42 +00:00
ldy #1
2019-09-29 15:08:57 +00:00
lda (ipacket), y
2019-09-24 00:01:42 +00:00
tax
lda @handle-1, x
jsr @patch_buffer
ldx #ldrlo
iny
jsr @setbuffer
ldx #sizelo
iny
!byte $2c
2019-09-06 22:12:17 +00:00
@setbuffer1
2019-09-24 00:01:42 +00:00
ldy #1
2019-09-06 22:12:17 +00:00
@setbuffer
2019-09-29 15:08:57 +00:00
lda (ipacket), y
2019-09-24 00:01:42 +00:00
sta $0,x
iny
2019-09-29 15:08:57 +00:00
lda (ipacket), y
2019-09-24 00:01:42 +00:00
sta $1,x
rts
2019-09-06 22:12:17 +00:00
@swap_zp
2019-09-24 00:01:42 +00:00
ldx #last_zp-first_zp
2019-09-06 22:12:17 +00:00
@save_zp
2019-09-24 00:01:42 +00:00
lda first_zp,x
ldy @saved_zp,x
sta @saved_zp,x
sty first_zp,x
dex
bpl @save_zp
rts
2019-09-06 22:12:17 +00:00
@restore_zp
2019-09-24 00:01:42 +00:00
jsr @swap_zp
jmp ProDOS_exit
2019-09-06 22:12:17 +00:00
@handle
2019-09-24 00:01:42 +00:00
!byte 0, 0 ;only up to two handles at a time
2019-09-06 22:12:17 +00:00
@saved_zp
2019-09-24 00:01:42 +00:00
!fill (last_zp - first_zp) + 1
2019-09-09 21:28:13 +00:00
;------------------------------------------------------------------------------
; traverse [private]
;
; in: (namlo) points to length-prefixed pathname+filename
; out: all flags clobbered
; all registers clobbered
;------------------------------------------------------------------------------
traverse
+LDAY gRootDirectory
sta (reloc + unrhddblocklo - unrelochdd) + 1
sty (reloc + unrhddblockhi - unrelochdd) + 1
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
rts
;------------------------------------------------------------------------------
; promote [private]
;
; tiny ProDOS-style interface for ProRWTS
; in: whatever ProDOS expects for the supported functions
; out: carry clear, A=0
; X, Y, and other flags clobbered
;------------------------------------------------------------------------------
promote
!pseudopc $bf00 {
php
sei
2019-09-24 00:01:42 +00:00
bit $c083
!byte $24
2019-09-09 21:28:13 +00:00
!if * != $bf06 {
!error "$BF06 misplaced (",*,")"
}
rts ;clock interface, must be RTS on real ProDOS if program uses $20x
2019-09-24 00:01:42 +00:00
bit $c083
jmp ProDOS_enter
2019-09-20 19:42:02 +00:00
ProDOS_exit
ProDOS_savedX
2019-09-24 00:01:42 +00:00
ldx #$d1
2019-09-20 19:42:02 +00:00
plp
clc
2019-09-24 00:01:42 +00:00
bcc ProDOS_savedY
2019-09-09 21:28:13 +00:00
!if * != $bf13 {
!error "$BF13 misplaced (",*,")"
}
!byte $c1
!word $c2d1, $c3d1, $c4d1, $c5d1, $c6d1, $c7d1
ProDOS_savedY
2019-09-24 00:01:42 +00:00
ldy #$d1
sta $c082
lda #0
2019-09-20 19:42:02 +00:00
rts
!if * > $bf30 {
2019-09-09 21:28:13 +00:00
!error "$BF30 misplaced (",*,")"
2019-09-20 19:42:02 +00:00
} else {
!if * != $bf30 {
2019-09-24 00:01:42 +00:00
!fill $bf30-*
2019-09-20 19:42:02 +00:00
}
2019-09-09 21:28:13 +00:00
}
2019-09-20 23:53:43 +00:00
ProDOS_unit
2019-09-24 00:01:42 +00:00
!byte $d1
2019-09-09 21:28:13 +00:00
ProDOS_fatal ;only for debugging, will be removed
2019-09-24 00:01:42 +00:00
;; bit $c081
;; pha
;; jsr $fe89
;; jsr $fe93
;; pla
;; jsr $fdda
;; jmp $ff65
2019-09-20 19:42:02 +00:00
;;*=$bf58
2019-09-24 00:01:42 +00:00
;; !fill $18 ;filled by init instead
2019-09-09 21:28:13 +00:00
ProDOS_prefix=$bfd0
2019-09-24 00:01:42 +00:00
; !fill $2e
2019-09-09 21:28:13 +00:00
}
end_promote
2019-09-10 16:51:04 +00:00
;------------------------------------------------------------------------------
; SaveOrRestoreScreenHoles
; preserve screen hole contents across demo execution
; to avoid crashing later on disk access
;
; in: nothing
; out: all flags clobbered
; all registers clobbered
;------------------------------------------------------------------------------
SaveOrRestoreScreenHoles
2019-09-24 00:01:42 +00:00
lda #4
sta namhi
ldx #0
stx namlo
sta bloklo
-- ldy #$78
- lda (namlo),y
pha
lda holey_stuff,x
2019-09-10 16:51:04 +00:00
holepatch ;sta->lda
2019-09-24 00:01:42 +00:00
lda (namlo),y
pla
sta holey_stuff,x
inx
tya
eor #$80
tay
bmi -
iny
bpl -
inc namhi
dec bloklo
bne --
rts
2019-09-10 16:51:04 +00:00
holey_stuff
2019-09-24 00:01:42 +00:00
!fill 64
2019-09-10 18:52:00 +00:00
LoadFileInternal
+LDADDR gPathname
+STAY namlo ; set filename
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 ldrlo+1
bne + ; if caller provided a load address, use it
sta sizelo ; otherwise query the load address from file metadata
sta sizehi ; 0 = query load address
jsr hddopendir ; call ProRWTS2
+LDAY ldrlo2
+STAY ldrlo
+ lda #$FF ; read entire file (ProRWTS2 will figure out exact size)
sta sizehi
jmp hddopendir ; exit via ProRWTS2
LoadDHRFileInternal
+LDADDR gPathname
+STAY namlo ; set filename
jsr traverse ; go to subdirectory, set up filename for read
lda #$00 ; read first $2000 bytes
sta sizelo
sta ldrlo
lda #$20
sta sizehi
asl
sta ldrhi ; into $4000
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
asl
sta ldrhi ; into $4000
dec auxreq ; 0 = read into main memory
clc ; not a subdirectory
jmp hddrdwrpart ; call ProRWTS2
SaveSmallFileInternal
+LDADDR gPathname
+STAY namlo ; set filename for ProRWTS2
jsr traverse ; go to subdirectory, set up filename for read
;;if the write address is always a fixed value then we can discard the query
lda #cmdread ; read (instead of write)
sta reqcmd
lda #0 ; 0 = read into main memory
sta sizelo
sta sizehi ; 0 = query load address
jsr hddopendir ; call ProRWTS2
lda ldrlo2
sta ldrlo
lda ldrhi2
sta ldrhi
lda #cmdwrite ; write (instead of read)
sta reqcmd
2019-09-29 15:08:57 +00:00
sta sizehi ; 512 bytes
2019-09-10 18:52:00 +00:00
jmp hddopendir ; exit via ProRWTS2 (must re-open the file after query)
LaunchInternal
jsr SaveOrRestoreScreenHoles ; save screen hole contents
ldy #$F1
- lda $100,y
2019-09-30 18:18:57 +00:00
sta STACKBASE - $F0,y ; back up stack
iny
bne -
tsx ; back up stack pointer
2019-09-30 18:18:57 +00:00
stx STACKBASE
sty RestoreStackNextTime + 1
; tell |Reenter| to restore the stack and stack pointer
ldx #(end_promote-promote-1)
- lda promote,x ; copy ProDOS shim to main memory
sta $bf00,x
dex
bpl -
tya
ldy #$18
- sta $bf57,y
dey
bne -
jmp $106 ; jump to pre-launch code
EnableAcceleratorAndSwitchToBank1
jsr EnableAccelerator
jmp SwitchToBank1
DisableAcceleratorAndSwitchToBank1
jsr DisableAccelerator
jmp SwitchToBank1