mirror of
https://github.com/a2-4am/pitch-dark.git
synced 2024-09-27 19:57:56 +00:00
488 lines
16 KiB
Plaintext
488 lines
16 KiB
Plaintext
;license:MIT
|
|
;(c) 2017-8 by 4am
|
|
;
|
|
; ProDOS - file and other MLI routines
|
|
;
|
|
; Public functions
|
|
; - LoadFile
|
|
; - LoadDHRFile
|
|
; - LoadSHRFile
|
|
; - SaveFile
|
|
; - SetPrefix
|
|
; - GetFileInfo
|
|
;
|
|
|
|
; MLI command codes
|
|
CMD_QUIT = $65 ; quit to ProDOS
|
|
CMD_CREATE = $C0 ; create new file
|
|
CMD_DESTROY = $C1 ; delete a file
|
|
CMD_SETFILEINFO= $C3 ; set file info
|
|
CMD_GETFILEINFO= $C4 ; get file (or volume) info
|
|
CMD_SETPREFIX = $C6 ; change default pathname prefix
|
|
CMD_OPEN = $C8 ; open a file
|
|
CMD_READ = $CA ; read an open file
|
|
CMD_WRITE = $CB ; write to an open file
|
|
CMD_CLOSE = $CC ; close an open file
|
|
|
|
; MLI parameter counts
|
|
PC_QUIT = $04
|
|
PC_CREATE = $07
|
|
PC_DESTROY = $01
|
|
PC_SETFILEINFO = $07
|
|
PC_GETFILEINFO = $0A
|
|
PC_SETPREFIX = $01
|
|
PC_OPEN = $03
|
|
PC_READ = $04
|
|
PC_WRITE = $04
|
|
PC_CLOSE = $01
|
|
|
|
; ROM addresses
|
|
PRODOSMLI = $BF00 ; [callable] MLI entry point
|
|
MACHID = $BF98 ; machine identification byte
|
|
|
|
kAccessBits = $C3 ; full access (used in SaveFile)
|
|
|
|
;-------------------------------
|
|
; LoadFile
|
|
; load a file into memory all at once, using ProDOS MLI calls
|
|
;
|
|
; in: stack contains 6 bytes of parameters:
|
|
; +1 address of pathname
|
|
; +3 address of data buffer (to receive file contents)
|
|
; +5 address of ProDOS file buffer
|
|
; out: if C set, load failed and A contains error code
|
|
; from open or read
|
|
; if C clear, load succeeded and ($02) contains
|
|
; data loaded from file
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
; stack set to next instruction after parameters
|
|
;-------------------------------
|
|
LoadFile
|
|
+PARAMS_ON_STACK 6
|
|
|
|
+LDPARAM 1
|
|
+STAY mliparam+1 ; pathname
|
|
+LDPARAM 5
|
|
+STAY mliparam+3 ; ProDOS file buffer
|
|
|
|
jsr _openfile
|
|
bcs @exit ; C set on error
|
|
|
|
pha ; push file reference number
|
|
+LDPARAM 3
|
|
+STAY mliparam+2 ; data buffer
|
|
lda #$FF
|
|
sta mliparam+4 ; max data length (unlimited, YOLO)
|
|
sta mliparam+5
|
|
pla ; pull file reference number
|
|
jsr _readfile
|
|
php ; save flags from readfile
|
|
pha
|
|
jsr _closefile ; always close whether read worked or not
|
|
pla
|
|
plp ; restore flags from readfile
|
|
; (so caller gets codes from read attempt,
|
|
; not close)
|
|
@exit rts
|
|
|
|
;-------------------------------
|
|
; LoadDHRFile
|
|
; load uncompressed DHR file into memory from .A2FC file
|
|
; 1. load first half ($2000 bytes)
|
|
; 2. copy to auxmem
|
|
; 3. load second half ($2000 bytes)
|
|
;
|
|
; always loads into graphics page 1 ($2000/main and $2000/aux)
|
|
;
|
|
; in: stack contains 4 bytes of parameters:
|
|
; +1 address of pathname
|
|
; +3 address of ProDOS file buffer
|
|
; out: if C set, load failed
|
|
; if C clear, load succeeded
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
; stack set to next instruction after parameters
|
|
;-------------------------------
|
|
LoadDHRFile
|
|
+PARAMS_ON_STACK 4
|
|
|
|
ldy #$04
|
|
- lda (PARAM),y
|
|
sta mliparam,y
|
|
dey
|
|
bne -
|
|
|
|
jsr _openfile
|
|
bcs @exit ; C set on error
|
|
sta @saverefnum ; store file refnum
|
|
|
|
ldy #$20
|
|
stz mliparam+2 ; read into $2000 in main mem
|
|
sty mliparam+3
|
|
stz mliparam+4 ; read length = $2000 bytes (first half of file)
|
|
sty mliparam+5
|
|
|
|
jsr _readfile
|
|
bcs @close
|
|
|
|
sta $C000
|
|
ldx #$20 ; copy $2000 bytes to auxmem
|
|
stx @copya+2
|
|
stx @copyb+2
|
|
ldy #0
|
|
@writeToAuxLoop
|
|
sta $C005
|
|
@copya lda $FF00, y
|
|
@copyb sta $FF00, y
|
|
iny
|
|
bne @copya
|
|
sta $C004
|
|
inc @copya+2
|
|
inc @copyb+2
|
|
dex
|
|
bne @writeToAuxLoop
|
|
|
|
lda @saverefnum
|
|
jsr _readfile ; read another $2000 bytes into $2000 (stays in main mem)
|
|
|
|
@close php ; save flags from readfile
|
|
@saverefnum=*+1
|
|
lda #$FD ; file refnum (SMC)
|
|
jsr _closefile
|
|
plp ; restore flags from readfile
|
|
@exit rts
|
|
|
|
;-------------------------------
|
|
; LoadSHRFile
|
|
; load uncompressed SHR file into memory from .PIC file
|
|
; 1. load first quarter ($2000 bytes)
|
|
; 2. copy to graphics memory
|
|
; 3. load second quarter ($2000 bytes)
|
|
; 4. copy to graphics memory
|
|
; 5. load third quarter ($2000 bytes)
|
|
; 6. copy to graphics memory
|
|
; 7. load fourth quarter ($2000 bytes)
|
|
; 8. copy to graphics memory
|
|
;
|
|
; in: stack contains 4 bytes of parameters:
|
|
; +1 address of pathname
|
|
; +3 address of ProDOS file buffer
|
|
; out: if C set, load failed
|
|
; if C clear, load succeeded
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
; stack set to next instruction after parameters
|
|
;-------------------------------
|
|
LoadSHRFile
|
|
+PARAMS_ON_STACK 4
|
|
|
|
ldy #$04
|
|
- lda (PARAM),y
|
|
sta mliparam,y
|
|
dey
|
|
bne -
|
|
|
|
jsr _openfile
|
|
bcs exit ; C set on error
|
|
sta saverefnum ; store file refnum
|
|
|
|
ldy #$20
|
|
stz mliparam+2 ; read into $2000 in main mem
|
|
sty mliparam+3
|
|
stz mliparam+4 ; read length = $2000 bytes (one quarter of file)
|
|
sty mliparam+5
|
|
sty shrdest+2
|
|
|
|
ldx #4 ; four quarters
|
|
- lda saverefnum ; file refnum
|
|
jsr _readfile
|
|
bcs close
|
|
phx
|
|
|
|
PatchVidHD
|
|
bcs copyvidhd
|
|
|
|
!cpu 65816
|
|
xce
|
|
rep #$30
|
|
!rl
|
|
!al
|
|
lda #$1FFF
|
|
tax
|
|
inx
|
|
shrdest ldy #$FD00 ; SMC
|
|
phb
|
|
mvn 0,$E1
|
|
plb
|
|
sty shrdest+1
|
|
!as
|
|
!rs
|
|
sec
|
|
xce
|
|
!cpu 65C02
|
|
resumeread
|
|
plx
|
|
dex
|
|
bne -
|
|
|
|
close php ; save flags from readfile
|
|
saverefnum=*+1
|
|
lda #$FD ; file refnum (SMC)
|
|
jsr _closefile
|
|
plp ; restore flags from readfile
|
|
exit rts
|
|
|
|
copyvidhd
|
|
lda $C035
|
|
and #$F7 ;Enable SHR shadowing
|
|
sta $C035
|
|
lda #$a0
|
|
sec
|
|
@calcdest
|
|
sbc #$20
|
|
dex
|
|
bne @calcdest
|
|
sta $45
|
|
stx $44
|
|
ldx #$20
|
|
ldy #0
|
|
stx $43
|
|
sty $42
|
|
sta $C005 ;CPU writes go to aux 64K
|
|
@copyshr
|
|
lda ($42), y
|
|
sta ($44), y
|
|
iny
|
|
bne @copyshr
|
|
inc $43
|
|
inc $45
|
|
dex
|
|
bne @copyshr
|
|
sta $C004 ;CPU writes go to main 64K
|
|
clc
|
|
bcc resumeread
|
|
|
|
; SaveFile
|
|
; save a file to disk all at once, using ProDOS MLI calls
|
|
;
|
|
; in: stack contains 11 ($0B) bytes of parameters:
|
|
; +1 address of pathname
|
|
; +3 [byte] file type
|
|
; +4 [word] aux file type
|
|
; +6 address of data buffer
|
|
; +8 [word] length of data buffer
|
|
; +A address of ProDOS file buffer
|
|
; out: if C set, save failed
|
|
; if C clear, save succeeded
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
; stack set to next instruction after parameters
|
|
;-------------------------------
|
|
SaveFile
|
|
+PARAMS_ON_STACK $0B
|
|
+LDPARAM 1
|
|
+STAY mliparam+1 ; pathname
|
|
lda #CMD_DESTROY ; MLI destroy command
|
|
ldy #PC_DESTROY ; number of parameters for 'destroy' command
|
|
jsr mli ; don't care if this fails
|
|
|
|
ldy #$03
|
|
lda (PARAM),y ; file type
|
|
sta mliparam+4
|
|
+LDPARAM 4
|
|
+STAY mliparam+5 ; aux file type
|
|
lda #kAccessBits
|
|
sta mliparam+3 ; access bits (full access)
|
|
ldy #1
|
|
sty mliparam+7 ; storage type (file)
|
|
dey
|
|
sty mliparam+8 ; creation date (current)
|
|
sty mliparam+9
|
|
sty mliparam+10 ; creation time (current)
|
|
sty mliparam+11
|
|
lda #CMD_CREATE ; MLI create command
|
|
ldy #PC_CREATE ; number of parameters for 'create' command
|
|
jsr mli
|
|
bcs @exit
|
|
|
|
+LDPARAM 10
|
|
+STAY mliparam+3 ; PrODOS file buffer
|
|
jsr _openfile
|
|
bcs @exit
|
|
|
|
sta mliparam+1 ; store file reference number
|
|
+LDPARAM 6
|
|
+STAY mliparam+2 ; data buffer
|
|
+LDPARAM 8
|
|
+STAY mliparam+4 ; data length
|
|
lda #CMD_WRITE ; MLI write command
|
|
ldy #PC_WRITE ; number of parameters for 'write' command
|
|
jsr mli
|
|
php ; save flags from write command
|
|
jsr _closefile ; always close whether write worked or not
|
|
plp ; restore flags from write
|
|
; (so caller gets codes from write attempt,
|
|
; not close)
|
|
@exit rts
|
|
|
|
;-------------------------------
|
|
; SetAuxFileType
|
|
; set auxiliary file information only
|
|
; access bits and file-type are hard-coded
|
|
; intended for updating save-games only
|
|
;
|
|
; in: stack contains 4 bytes of parameters:
|
|
; +1 address of pathname
|
|
; +3 auxiliary type to set
|
|
; out: if C set, MLI call failed and A contains error code
|
|
; from set
|
|
; if C clear, MLI call succeeded
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
; stack set to next instruction after parameters
|
|
;-------------------------------
|
|
SetAuxFileType
|
|
+PARAMS_ON_STACK 4
|
|
+LDPARAM 1
|
|
+STAY mliparam+1 ; pathname
|
|
+LDPARAM 3
|
|
+STAY mliparam+5 ; aux type
|
|
lda #%11000011
|
|
sta mliparam+3 ; access bits
|
|
lda #4
|
|
sta mliparam+4 ; file type
|
|
lda #0
|
|
sta extra+0 ; date
|
|
sta extra+1 ; date
|
|
sta extra+2 ; time
|
|
sta extra+3 ; time
|
|
lda #CMD_SETFILEINFO ; MLI command
|
|
ldy #PC_SETFILEINFO ; number of parameters for 'setfileinfo' command
|
|
bra mli
|
|
|
|
;-------------------------------
|
|
; SetPrefix
|
|
; set current directory
|
|
;
|
|
; in: stack contains 2 bytes of parameters:
|
|
; +1 address of pathname
|
|
; out: if C set, call failed and A contains error code
|
|
; if C clear, call succeeded
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
; stack set to next instruction after parameters
|
|
;-------------------------------
|
|
SetPrefix
|
|
+PARAMS_ON_STACK 2
|
|
+LDPARAM 1
|
|
+STAY mliparam+1 ; pathname
|
|
lda #CMD_SETPREFIX
|
|
ldy #PC_SETPREFIX
|
|
bra mli
|
|
|
|
;-------------------------------
|
|
; GetFileInfo
|
|
; just what it says on the tin
|
|
;
|
|
; in: stack contains 2 bytes of parameters:
|
|
; +1 address of pathname
|
|
; out: if C set, MLI call failed and A contains error code
|
|
; from open or read
|
|
; if C clear, MLI call succeeded and mliparam contains
|
|
; all the info
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
; stack set to next instruction after parameters
|
|
;-------------------------------
|
|
GetFileInfo
|
|
+PARAMS_ON_STACK 2
|
|
+LDPARAM 1
|
|
+STAY mliparam+1 ; pathname
|
|
lda #CMD_GETFILEINFO ; MLI command
|
|
ldy #PC_GETFILEINFO ; number of parameters for 'getfileinfo' command
|
|
bra mli
|
|
|
|
;-------------------------------
|
|
; open file via ProDOS MLI
|
|
;
|
|
; in: caller has filled @mliparam with address of
|
|
; pathname, address of data buffer, and maximum
|
|
; data length
|
|
; out: if C set, open failed and A contains error code
|
|
; if C clear, open succeeded and A contains
|
|
; file reference number
|
|
;-------------------------------
|
|
_openfile
|
|
lda #CMD_OPEN ; MLI command
|
|
ldy #PC_OPEN ; number of parameters for 'open' command
|
|
jsr mli
|
|
bcs @exit
|
|
lda refnum ; caller should save file reference number
|
|
; as this memory location may be
|
|
; overwritten by later MLI calls
|
|
@exit rts
|
|
|
|
;-------------------------------
|
|
; read an open file via ProDOS MLI
|
|
;
|
|
; in: A = file reference number
|
|
; caller has filled @mliparam with address of
|
|
; data buffer and maximum data length
|
|
; out: if C set, read failed and A contains error code
|
|
; if C clear, read succeeded and A contains the same
|
|
; file reference number that was passed in
|
|
;-------------------------------
|
|
_readfile
|
|
sta mliparam+1 ; store file reference number
|
|
lda #CMD_READ ; MLI read command
|
|
ldy #PC_READ ; number of parameters for 'read' command
|
|
jsr mli
|
|
bcs @exit
|
|
lda mliparam+1 ; if no error, return file reference number
|
|
@exit rts
|
|
|
|
;-------------------------------
|
|
; close an open file
|
|
; in: A = file reference number
|
|
; out: if error, C set and A contains error code
|
|
; if success, C clear
|
|
;-------------------------------
|
|
_closefile
|
|
sta mliparam+1 ; store file reference number
|
|
lda #CMD_CLOSE ; MLI close command
|
|
ldy #PC_CLOSE ; number of parameters for 'close' command
|
|
bra mli
|
|
|
|
QuitToProDOS
|
|
lda #CMD_QUIT
|
|
ldy #PC_QUIT
|
|
; execution falls through here
|
|
;-------------------------------
|
|
; low-level MLI wrapper
|
|
; in: A = MLI command code
|
|
; Y = number of MLI parameters
|
|
; caller has filled @mliparam
|
|
; with all relevant parameters
|
|
; out: returns immediately after
|
|
; calling MLI, so whatever
|
|
; state the MLI routine sets,
|
|
; the caller will see it
|
|
; verbatim
|
|
;-------------------------------
|
|
mli sta mlicmd ; store command code
|
|
sty mliparam ; number of parameters
|
|
jsr PRODOSMLI ; call ProDOS
|
|
mlicmd !byte 00 ; command number
|
|
!word mliparam ; address of parameter table
|
|
rts
|
|
mliparam !byte $FE,$FE,$FE,$FE
|
|
filetype !byte $FE ; file type (set by MLI get_file_info)
|
|
auxtype ; auxiliary file type (2 bytes, set by MLI get_file_info)
|
|
refnum !byte $FE ; file refnum (set by MLI open)
|
|
mlilen !byte $FE,$FE ; file length (set by MLI read)
|
|
blocks !byte $FE,$FE ; blocks used (set by getvolumeinfo/getfileinfo)
|
|
; member is also used by createfile
|
|
extra !byte $FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE
|
|
; used by get_file_info
|