mirror of
https://github.com/a2-4am/passport.git
synced 2024-11-08 22:10:32 +00:00
527 lines
15 KiB
Plaintext
Executable File
527 lines
15 KiB
Plaintext
Executable File
; MLI command codes
|
|
CMD_CREATE = $C0 ; create new file
|
|
CMD_DESTROY = $C1 ; delete a file
|
|
CMD_SETPREFIX = $C6 ; change default pathname prefix
|
|
CMD_OPEN = $C8 ; open a file
|
|
CMD_NEWLINE = $C9 ; set line-by-line read mode
|
|
CMD_READ = $CA ; read an open file
|
|
CMD_WRITE = $CB ; write to an open file
|
|
CMD_CLOSE = $CC ; close an open file
|
|
CMD_SETMARK = $CE ; change position in an open file
|
|
|
|
; MLI parameter counts
|
|
PC_CREATE = $07
|
|
PC_DESTROY = $01
|
|
PC_SETPREFIX = $01
|
|
PC_OPEN = $03
|
|
PC_NEWLINE = $03
|
|
PC_READ = $04
|
|
PC_WRITE = $04
|
|
PC_CLOSE = $01
|
|
PC_SETMARK = $02
|
|
|
|
PRODOSMLI = $BF00 ; [callable] MLI entry point
|
|
|
|
; MLI error codes
|
|
ERR_FNF = $46
|
|
ERR_EOF = $4C
|
|
|
|
;-------------------------------
|
|
; WriteTrackMLI - write the contents of
|
|
; BASEPAGE data buffer to disk
|
|
; in: @SLOT contains (slot x 16) + $30
|
|
; @DRIVE contains drive + $30
|
|
; @gTrack contains track number
|
|
; @BASEPAGE contains data to write ($1000 bytes)
|
|
; out: if C set, write failed (A contains MLI error code)
|
|
; if C clear, write succeeded (A is clobbered)
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
;-------------------------------
|
|
!zone {
|
|
WriteTrackMLI
|
|
jsr SwapProDOS
|
|
jsr ReorderBuffer
|
|
lda #$81 ; 'write block' command
|
|
sta mlicmd
|
|
lda DRIVE ; ProDOS "unit number" is
|
|
sec
|
|
sbc #$30
|
|
lsr ; DSSS0000, where D is the
|
|
asl ; drive number (0=drive 1,
|
|
asl ; 1=drive 2) and SSS is
|
|
asl ; the slot number (1-7).
|
|
asl ; "Beneath Apple ProDOS"
|
|
asl ; page 6-19
|
|
asl
|
|
asl
|
|
sta mliparam+1
|
|
lda SLOT
|
|
sec
|
|
sbc #$30
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
clc
|
|
adc mliparam+1
|
|
sta mliparam+1
|
|
lda #$00
|
|
sta mliparam+2 ; lo byte of data buffer
|
|
lda #$08
|
|
sta .blockcount
|
|
lda gTrack
|
|
asl
|
|
asl
|
|
asl
|
|
sta mliparam+4 ; lo byte of block number
|
|
rol
|
|
and #$01
|
|
sta mliparam+5 ; hi byte of block number
|
|
lda #BASEPAGE ; hi byte of data buffer
|
|
sta mliparam+3
|
|
.writeloop
|
|
lda mlicmd
|
|
ldy #$03 ; parameter count
|
|
jsr mli
|
|
bcs .writeerr
|
|
inc mliparam+3 ; 2 pages per block
|
|
inc mliparam+3
|
|
inc mliparam+4
|
|
dec .blockcount
|
|
bne .writeloop
|
|
clc
|
|
bcc .writedone
|
|
.writeerr
|
|
.writedone
|
|
php
|
|
pha
|
|
jsr ReorderBuffer
|
|
jsr SwapProDOS
|
|
pla
|
|
plp
|
|
rts
|
|
|
|
.blockcount !byte $FF
|
|
}
|
|
;-------------------------------
|
|
; ReorderBuffer - convert data
|
|
; buffer between ProDOS and
|
|
; DOS 3.3 ordering (use after
|
|
; read or before write under
|
|
; ProDOS)
|
|
; in: none
|
|
; out: all flags clobbered
|
|
; all registers clobbered
|
|
; @cmp1, @cmp2 clobbered
|
|
;-------------------------------
|
|
!zone {
|
|
ReorderBuffer
|
|
lda #$00
|
|
sta cmp1
|
|
sta cmp2
|
|
tay
|
|
lda #$01
|
|
clc
|
|
adc #BASEPAGE
|
|
sta cmp1+1
|
|
lda #$0E
|
|
clc
|
|
adc #BASEPAGE
|
|
sta cmp2+1
|
|
ldx #$07
|
|
.L lda (cmp1),y
|
|
pha
|
|
lda (cmp2),y
|
|
sta (cmp1),y
|
|
pla
|
|
sta (cmp2),y
|
|
iny
|
|
bne .L
|
|
inc cmp1+1
|
|
dec cmp2+1
|
|
dex
|
|
bne .L
|
|
rts
|
|
}
|
|
|
|
;-------------------------------
|
|
; SaveFile1Shot
|
|
; 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 and A contains error code
|
|
; from open or write
|
|
; if C clear, save succeeded
|
|
; all other flags clobbered
|
|
; all registers clobbered
|
|
; stack set to next instruction after parameters
|
|
;-------------------------------
|
|
!zone {
|
|
SaveFile1Shot
|
|
pla
|
|
sta $00
|
|
pla
|
|
sta $01
|
|
tax
|
|
lda #$0B
|
|
clc
|
|
adc $00
|
|
bcc .noinc
|
|
inx
|
|
.noinc
|
|
tay
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
|
|
ldy #$01
|
|
lda ($00),y ; lo byte of pathname
|
|
sta mliparam+1
|
|
iny
|
|
lda ($00),y ; hi byte of pathname
|
|
sta mliparam+2
|
|
jsr DeleteFile ; don't care if this fails
|
|
ldy #$03
|
|
lda ($00),y ; file type
|
|
sta mliparam+4
|
|
iny
|
|
lda ($00),y ; lo byte of aux file type
|
|
sta mliparam+5
|
|
iny
|
|
lda ($00),y ; hi byte of aux file type
|
|
sta mliparam+6
|
|
jsr CreateFile
|
|
bcs .savefile1s
|
|
|
|
ldy #$0A
|
|
lda ($00),y ; lo byte of ProDOS file buffer
|
|
sta mliparam+3
|
|
iny
|
|
lda ($00),y ; hi byte of ProDOS file buffer
|
|
sta mliparam+4
|
|
jsr OpenFile
|
|
bcs .savefile1s
|
|
|
|
pha ; push file reference number
|
|
ldy #$06
|
|
lda ($00),y ; lo address of data buffer
|
|
sta mliparam+2
|
|
iny
|
|
lda ($00),y ; hi address of data buffer
|
|
sta mliparam+3
|
|
iny
|
|
lda ($00),y ; lo data length
|
|
sta mliparam+4
|
|
iny
|
|
lda ($00),y ; hi data length
|
|
sta mliparam+5
|
|
pla ; pull file reference number
|
|
jsr WriteFile
|
|
php ; save flags from writefile
|
|
pha
|
|
jsr CloseFile ; always close whether write worked or not
|
|
pla
|
|
plp ; restore flags from write
|
|
; (so caller gets codes from write attempt,
|
|
; not close)
|
|
|
|
.savefile1s
|
|
rts
|
|
}
|
|
|
|
;-------------------------------
|
|
; LoadFile1Shot
|
|
; load a file into memory all at once,
|
|
; using ProDOS MLI calls
|
|
;
|
|
; in: stack contains 8 bytes of parameters:
|
|
; +1 address of pathname
|
|
; +3 address of data buffer (to receive file contents)
|
|
; +5 [word] maximum length of data to read
|
|
; +7 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
|
|
;-------------------------------
|
|
!zone {
|
|
LoadFile1Shot
|
|
pla
|
|
sta $00
|
|
pla
|
|
sta $01
|
|
tax
|
|
lda #$08
|
|
clc
|
|
adc $00
|
|
bcc .noinc
|
|
inx
|
|
.noinc
|
|
tay
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
|
|
ldy #$01
|
|
lda ($00),y ; lo byte of pathname
|
|
sta mliparam+1
|
|
iny
|
|
lda ($00),y ; hi byte of pathname
|
|
sta mliparam+2
|
|
ldy #$07
|
|
lda ($00),y ; lo byte of ProDOS file buffer
|
|
sta mliparam+3
|
|
iny
|
|
lda ($00),y ; hi byte of ProDOS file buffer
|
|
sta mliparam+4
|
|
|
|
jsr OpenFile
|
|
bcs .loadfile1s ; C set on error
|
|
|
|
pha ; push file reference number
|
|
ldy #$03
|
|
lda ($00),y ; lo address of data buffer
|
|
sta mliparam+2
|
|
iny
|
|
lda ($00),y ; hi address of data buffer
|
|
sta mliparam+3
|
|
iny
|
|
lda ($00),y ; lo data length
|
|
sta mliparam+4
|
|
iny
|
|
lda ($00),y ; hi data length
|
|
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)
|
|
.loadfile1s
|
|
rts
|
|
}
|
|
|
|
;-------------------------------
|
|
; open file via ProDOS MLI
|
|
;
|
|
; in: caller has filled @mliparam with address of
|
|
; pathname, address of data buffer, and maximum
|
|
; data length
|
|
; A = file reference number
|
|
; out: if C set, open failed and A contains error code
|
|
; if C clear, open succeeded and A contains
|
|
; file reference number
|
|
;-------------------------------
|
|
!zone {
|
|
OpenFile
|
|
lda #CMD_OPEN ; MLI command
|
|
ldy #PC_OPEN ; number of parameters for 'open' command
|
|
jsr mli
|
|
bcs .openfile
|
|
lda refnum ; caller should save file reference number
|
|
; as this memory location may be
|
|
; overwritten by later MLI calls
|
|
.openfile
|
|
rts
|
|
}
|
|
|
|
;-------------------------------
|
|
; set line-by-line mode via ProDOS MLI
|
|
;
|
|
; in: A = file reference number
|
|
; out: if C set, set failed and A contains error code
|
|
; if S clear, set succeeded and A contains the same
|
|
; file reference number that was passed in
|
|
;-------------------------------
|
|
lbl_mask = $7F
|
|
lbl_cr = $0D
|
|
|
|
!zone {
|
|
SetLineByLine
|
|
sta mliparam+1 ; store file reference number
|
|
lda #lbl_mask ; accept high bit set or clear
|
|
sta mliparam+2
|
|
lda #lbl_cr ; carriage return character
|
|
sta mliparam+3
|
|
lda #CMD_NEWLINE ; MLI 'newline' command to set read mode
|
|
ldy #PC_NEWLINE ; number of parameters for 'newline' command
|
|
jsr mli
|
|
bcs .setlinebylin
|
|
lda mliparam+1 ; if no error, return file reference number
|
|
.setlinebylin
|
|
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
|
|
;-------------------------------
|
|
!zone {
|
|
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 .readfile
|
|
lda mliparam+1 ; if no error, return file reference number
|
|
.readfile
|
|
rts
|
|
}
|
|
|
|
;-------------------------------
|
|
; change file position in an open file via ProDOS MLI
|
|
;
|
|
; in: A = file reference number
|
|
; caller has filled @mliparam+2/+3/+4 with
|
|
; new file position
|
|
; out: if C set, set_mark call failed and A contains error code
|
|
; if C clear, set_mark call succeeded and A contains
|
|
; the same file reference number that was passed in
|
|
;-------------------------------
|
|
!zone {
|
|
SetMark
|
|
sta mliparam+1 ; store file reference number
|
|
lda #CMD_SETMARK ; MLI set_mark command
|
|
ldy #PC_SETMARK ; number of params for 'set_mark' cmd
|
|
jsr mli
|
|
bcs .exit
|
|
lda mliparam+1 ; if no error, return file refnum
|
|
.exit rts
|
|
}
|
|
|
|
;-------------------------------
|
|
; write to an open file via ProDOS MLI
|
|
;
|
|
; in: A = file reference number
|
|
; caller has filled @mliparam with address of
|
|
; data buffer and data length
|
|
; out: if C set, write failed and A contains error code
|
|
; if C clear, write succeeded and A contains the same
|
|
; file reference number that was passed in
|
|
;-------------------------------
|
|
!zone {
|
|
WriteFile
|
|
sta mliparam+1 ; store file reference number
|
|
lda #CMD_WRITE ; MLI write command
|
|
ldy #PC_WRITE ; number of parameters for 'write' command
|
|
jsr mli
|
|
bcs .writefile
|
|
lda mliparam+1 ; if no error, return file reference number
|
|
.writefile
|
|
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
|
|
jsr mli
|
|
rts
|
|
|
|
;-------------------------------
|
|
; create a file via ProDOS MLI
|
|
; always sets access bits to $C3 (full access)
|
|
; always sets creation to 0 (current date/time)
|
|
; always sets storage type to 1 (file)
|
|
; in: caller has filled @mliparam
|
|
; with address of pathname,
|
|
; file type, aux file type
|
|
; out: if error, C set and A contains error code
|
|
; if success, C clear
|
|
;-------------------------------
|
|
accessbits = $C3 ; full access
|
|
|
|
CreateFile
|
|
lda #accessbits
|
|
sta mliparam+3 ; access bits (full access)
|
|
lda #1
|
|
sta mliparam+7 ; storage type (file)
|
|
lda #0
|
|
sta mliparam+8 ; creation date (current)
|
|
sta mliparam+9
|
|
sta mliparam+10 ; creation time (current)
|
|
sta mliparam+11
|
|
lda #CMD_CREATE ; MLI create command
|
|
ldy #PC_CREATE ; number of parameters for 'create' command
|
|
jsr mli
|
|
rts
|
|
|
|
;-------------------------------
|
|
; delete a file using ProDOS MLI
|
|
; in: caller has filled @mliparam
|
|
; with address of pathname
|
|
; out: if error, C set and A contains error code
|
|
; if success, C clear
|
|
;-------------------------------
|
|
DeleteFile
|
|
lda #CMD_DESTROY ; MLI destroy command
|
|
ldy #PC_DESTROY ; number of parameters for 'destroy' command
|
|
jsr mli
|
|
rts
|
|
|
|
;-------------------------------
|
|
; change current directory (set prefix)
|
|
; using ProDOS MLI
|
|
; in: caller has filled @mliparam
|
|
; with address of pathname
|
|
; out: if error, C set and A contains error code
|
|
; if success, C clear
|
|
;-------------------------------
|
|
SetPrefix
|
|
lda #CMD_SETPREFIX
|
|
ldy #PC_SETPREFIX
|
|
jsr mli
|
|
rts
|
|
|
|
;-------------------------------
|
|
; 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,$FE
|
|
refnum !byte $FE ; file refnum (set by MLI open)
|
|
mlilen !byte $FE,$FE ; file length (set by MLI read)
|
|
!byte $FE,$FE,$FE,$FE
|
|
; used by createfile
|