Merged JGH's memory reorganization changes.

This commit is contained in:
Bobbi Webber-Manners 2021-08-30 19:08:22 -04:00
parent 367d50454b
commit 39d6fad471
8 changed files with 462 additions and 226 deletions

Binary file not shown.

View File

@ -40,18 +40,6 @@ A2IRQV EQU $3FE
MLI EQU $BF00
* IO Buffer for reading file (1024 bytes)
*IOBUF0 EQU $4000 ; For loading/saving, OSFILE, *.
*IOBUF1 EQU $4400 ; Four open files for langs
*IOBUF2 EQU $4800
*IOBUF3 EQU $4C00
*IOBUF4 EQU $5000
*IOBUF0 EQU $5000 ; For loading/saving, OSFILE, *.
*IOBUF1 EQU $5400 ; Four open files for langs
*IOBUF2 EQU $5800
*IOBUF3 EQU $5C00
*IOBUF4 EQU $6000
IOBUF0 EQU $0C00 ; For loading/saving, OSFILE, *.
IOBUF1 EQU $1000 ; Four open files for langs
IOBUF2 EQU $1400
@ -59,11 +47,8 @@ IOBUF3 EQU $1800
IOBUF4 EQU $1C00
* 512 byte buffer sufficient for one disk block
*BLKBUF EQU $5200
*BLKBUFEND EQU $5400
BLKBUF EQU $6200 ; Is this ever used at same time
BLKBUFEND EQU $6400 ; as IOBUF0?
BLKBUF EQU $5000 ; Can't use $400 as ProDOS uses
BLKBUFEND EQU $5200 ; 'hidden' bytes within screen
* Address in aux memory where ROM will be loaded
AUXADDR EQU $8000
@ -190,5 +175,6 @@ MAINZP MAC
PUT AUXMEM.CHARIO
PUT AUXMEM.MISC
* Automatically save the object file:
SAV APPLECORN

View File

@ -5,6 +5,8 @@
* 29-Aug-2021 Generalised CHKERROR routone, checks for and
* translates ProDOS errors into Acorn errors
* Set &E0=&FF for testing to report ProDOS errors
* 30-Aug-2021 FSC commands moved to here
* Command line set by *RUN, and read by OSARGS
FSXREG EQU $B0
@ -13,6 +15,7 @@ FSAREG EQU $B2
FSCTRL EQU FSXREG
FSPTR1 EQU $B4
FSPTR2 EQU $B6
FSCMDLINE EQU $CE
* OSFIND - open/close a file for byte access
@ -100,31 +103,54 @@ OSBGETRET
* OSARGS - adjust file arguments
* On entry, A=action
* Y<>0 A=FF Flush channel Y
* A=00 Read PTR#Y
* A=01 Write PTR#Y
* A=02 Read EXT#Y
* A=03 Write EXT#Y
* Y=0 A=FF Flush all channels
* A=00 Return filing system number in A
* A=01 Read command line address
* X=>4 byte ZP control block
* Y=file handle
ARGSHND PHA
PHX
* On exit, A=0 - implemented (except ARGS 0,0)
* A - preserved=unimplemented
* X,Y - preserved
* control block updated for 'read' calls
* control block preserved otherwise
*
ARGSHND PHX
PHY
PHA
CPY #$00
BNE :HASFILE
CMP #$00 ; Y=0,A=0 => current file sys
BNE :S1
PLY
PLX
PLA
LDA #105 ; 105=AppleFS filing system
PLY
PLX
RTS
:S1 CMP #$01 ; Y=0,A=1 => addr of CLI
BNE :S2
* TODO: Implement this for *RUN and *command
JSR BEEP
BRA :IEXIT
LDA FSCMDLINE+0
STA $00,X
LDA FSCMDLINE+1
STA $01,X
LDA #$FF
STA $02,X
STA $03,X
JMP OSARGSDONE ; Implemented
:S2 CMP #$FF ; Y=0,A=FF => flush all files
BNE :IEXIT
>>> WRTMAIN
STZ MOSFILE ; Zero means flush all
>>> WRTAUX
BRA :IFLUSH
JMP :FLUSH
:IEXIT JMP :EXIT ; Exit preserved
:HASFILE >>> WRTMAIN
STY MOSFILE ; File ref num
STX MOSFILE+1 ; Pointer to ZP control block
@ -135,8 +161,7 @@ ARGSHND PHA
STZ MOSFILE+2 ; 0 means get pos
>>> WRTAUX
>>> XF2MAIN,TELL
:IEXIT BRA :IEXIT2
:IFLUSH BRA :FLUSH
:S3 CMP #$01 ; Y!=0,A=1 => write seq ptr
BNE :S4
>>> WRTMAIN
@ -148,25 +173,28 @@ ARGSHND PHA
STA MOSFILE+4
>>> WRTAUX
>>> XF2MAIN,SEEK
:IEXIT2 BRA :EXIT
:S4 CMP #$02 ; Y!=0,A=2 => read file len
BNE :S5
>>> WRTMAIN
STA MOSFILE+2 ; Non-zero means get len
>>> WRTAUX
>>> XF2MAIN,TELL
:S5 CMP #$FF ; Y!=0,A=FF => flush file
BNE :EXIT
:FLUSH >>> XF2MAIN,FLUSH
:EXIT PLY
PLX
PLA
RTS
OSARGSRET
>>> ENTAUX
:EXIT PLA ; Unimplemented
PLY
PLX
RTS
OSARGSRET >>> ENTAUX
OSARGSDONE PLA
LDA #0 ; Implemented
PLY
PLX
PLA
RTS
@ -245,7 +273,7 @@ FILEHND PHX
BEQ :LOAD ; A=FF -> LOAD
CMP #$06
BEQ :DELETE ; A=06 -> DELETE
* BCC :INFO ; A=01-05 -> INFO
BCC :JMPINFO ; A=01-05 -> INFO
CMP #$08
BEQ :MKDIR ; A=08 -> MKDIR
* LDA #<OSFILEM ; If not implemented, print msg
@ -261,13 +289,13 @@ FILEHND PHX
PLY
PLX
RTS
:INFO
* TO DO >>> XF2MAIN,INFOFILE
:JMPINFO JMP :INFO
:SAVE >>> XF2MAIN,SAVEFILE
:LOAD >>> XF2MAIN,LOADFILE
:DELETE >>> XF2MAIN,DELFILE
:MKDIR >>> XF2MAIN,MAKEDIR
:INFO >>> XF2MAIN,INFOFILE
* On return here, A<$20 return to caller, A>$1F ProDOS error
OSFILERET
@ -387,6 +415,37 @@ OSFSCM ASC 'OSFSC.'
DB $00
* FSC Command Table
*******************
* These are commands specific to the filing system that can't be
* called via OSFILE, OSFSC, etc.
*
FSCCOMMAND ASC 'CHDIR'
DB $C0
DW FSCCHDIR-1 ; Change directory, XY=>params
ASC 'CD'
DB $C0
DW FSCCHDIR-1 ; Change directory, XY=>params
ASC 'DIR'
DB $C0
DW FSCCHDIR-1 ; Change directory, XY=>params
* TO DO, CHDIR should be $80 for LPTR=>params
ASC 'DRIVE'
DB $80
DW FSCDRIVE-1 ; Select drive, LPTR=>params
ASC 'FREE'
DB $80
DW FSCFREE-1 ; FREE (<drive)>, LPTR=>params
ASC 'ACCESS'
DB $80
DW FSCACCESS-1 ; ACCESS <obj> <access), LPTR=>params
ASC 'TITLE'
DB $80
DW FSCTITLE-1 ; TITLE (<drive>) <title>, LPTR=>params
*
DB $FF ; Terminator
* OSFSC - miscellanous file system calls
*****************************************
* On entry, A=action, XY=>command line
@ -397,33 +456,35 @@ OSFSCM ASC 'OSFSC.'
*
* TO DO: use jump table
FSCHND
CMP #$40
BEQ FSCCHDIR
CMP #$41
BEQ FSCDRIVE
CMP #$42
BEQ FSCFREE
CMP #$43
BEQ FSCACCESS
CMP #$42
BEQ FSCTITLE
* CMP #$40
* BEQ FSCCHDIR
* CMP #$41
* BEQ FSCDRIVE
* CMP #$42
* BEQ FSCFREE
* CMP #$43
* BEQ FSCACCESS
* CMP #$42
* BEQ FSCTITLE
CMP #$0C
BEQ FSCREN ; A=12 - *RENAME
CMP #$00
BEQ FSOPT ; A=0 - *OPT
CMP #$01
BEQ CHKEOF ; A=1 - Read EOF
CMP #$02
BEQ FSCRUN ; A=2 - */filename
CMP #$03
BEQ FSC03 ; A=3 - *command
CMP #$04
BEQ FSCRUN ; A=4 - *RUN
CMP #$05
BEQ FSCCAT ; A=5 - *CAT
BEQ JMPCAT ; A=5 - *CAT
CMP #$09
BEQ FSCCAT ; A=9 - *EX
BEQ JMPCAT ; A=9 - *EX
CMP #$0A
BEQ FSCCAT ; A=10 - *INFO
BEQ JMPCAT ; A=10 - *INFO
CMP #$0C
BEQ FSCREN ; A=12 - *RENAME
FSCDRIVE
FSCFREE
FSCACCESS
@ -435,8 +496,29 @@ FSCUKN PHA
PLA
FSCNULL RTS
JMPCAT JMP FSCCAT
FSC03 JSR XYtoLPTR
LDX #<FSCCOMMAND
LDY #>FSCCOMMAND
JSR CLILOOKUP
BEQ FSCNULL
JSR LPTRtoXY
*
FSCRUN STX OSFILECB ; Pointer to filename
STY OSFILECB+1
JSR XYtoLPTR
FSCRUNLP LDA (OSLPTR),Y ; Look for command line
INY
CMP #'!'
BCS FSCRUNLP
DEY
JSR SKIPSPC
JSR LPTRtoXY
STX FSCMDLINE+0 ; Set CMDLINE=>command line
STY FSCMDLINE+1 ; Collected by OSARGS 1,0
*
* *BUG* OSFILE &FF should give error if trying to load a directory!
LDA #$FF ; OSFILE load flag
STA OSFILECB+6 ; Use file's address
LDX #<OSFILECB ; Pointer to control block
@ -445,12 +527,12 @@ FSCRUN STX OSFILECB ; Pointer to filename
JSR :CALL
LDA #$00 ; A=0 on return
RTS
:CALL JMP (OSFILECB+6) ; Jump to EXEC addr
RTS
:CALL LDA #$01 ; A=1 - entering code
SEC ; Not from RESET
JMP (OSFILECB+6) ; Jump to EXEC addr
FSCREN JSR XYtoLPTR ; Pointer to command line
JSR RENAME
RTS
JMP RENAME
FSCCHDIR STX ZP1+0
STY ZP1+1
@ -811,14 +893,15 @@ MKERROR4
* $55 - Volume Control Block table full.
* $56 - Bad buffer address.
* $57 - Duplicate volume.
* ($58) $27 - I/O error
* ($59) $28 - No device connected Disk not present
* ($58) $27 - I/O error (disk not formatted)
* ($59) $28 - No device connected (drive not present) Disk not present
* $5A ($29) - Bit map disk address is impossible. Sector not found
* $5B $2A -
* ($5C) $2B - Disk write protected. Disk write protected
* $5D ($2C) - (EOF during load or save) Data lost
* $5E ($2D) - (Couldn't open to save) Can't save
* ($5F) $2E - Disk switched Disk changed
* $2F - Device is offline (drive empty)
*
* AcornOS ProDOS

View File

@ -43,19 +43,20 @@ CMDTABLE ASC 'CAT' ; Must be first command so matches '*.'
ASC 'CDIR'
DB $88
DW STARFILE-1 ; CDIR -> OSFILE 08, CBLK=>filename
* other filing commands
ASC 'CHDIR'
DB $C0
DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
ASC 'CD'
DB $C0
DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
ASC 'DIR'
DB $C0
DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
ASC 'DRIVE'
DB $C1
DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
* filing-system-specific commands
* Moved to HostFS
* ASC 'CHDIR'
* DB $C0
* DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
* ASC 'CD'
* DB $C0
* DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
* ASC 'DIR'
* DB $C0
* DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
* ASC 'DRIVE'
* DB $C1
* DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
* FREE (<drive>)
* ACCESS <file> <access>
* TITLE (<drive>) <title>
@ -83,7 +84,79 @@ CMDTABLE ASC 'CAT' ; Must be first command so matches '*.'
* TYPE <file>
* BUILD <file>
* terminator
DB $00
DB $FF
* Command table lookup
* On entry, (OSLPTR)=>command string
* XY=>command table
* On exit, A=0 done, command called
* A<>0 no match
*
* Search command table
CLILOOKUP STX OSTEXT+0 ; Start of command table
STY OSTEXT+1
LDX #0 ; (ZP,X)=>command table
CLILP4 LDY #0 ; Start of command line
CLILP5 LDA (OSTEXT,X)
BMI CLIMATCH ; End of table string
EOR (OSLPTR),Y
AND #$DF ; Force upper case match
BNE CLINOMATCH
JSR CLISTEP ; Step to next table char
INY ; Step to next command char
BNE CLILP5 ; Loop to check
CLINOMATCH LDA (OSLPTR),Y
CMP #'.' ; Abbreviation?
BEQ CLIDOT
CLINEXT JSR CLISTEP ; No match, step to next entry
BPL CLINEXT
CLINEXT2 JSR CLISTEP ; Step past byte, address
JSR CLISTEP
JSR CLISTEP
BPL CLILP4 ; Loop to check next
RTS ; Exit, A>$7F
CLIDOT LDA (OSTEXT,X)
BMI CLINEXT2 ; Dot after full word, no match
CLIDOT2 JSR CLISTEP ; Step to command address
BPL CLIDOT2
INY ; Step past dot
BNE CLIMATCH2 ; Jump to this command
CLIMATCH LDA (OSLPTR),Y
CMP #'.'
BEQ CLINEXT ; Longer abbreviation, eg 'CAT.'
CMP #'A'
BCS CLINEXT ; More letters, eg 'HELPER'
CLIMATCH2 JSR CLIMATCH3 ; Call the routine
LDA #0
RTS ; Return A=0 to claim
CLIMATCH3 JSR SKIPSPC ; (OSLPTR),Y=>parameters
LDA (OSTEXT,X) ; Command byte
PHA
JSR CLISTEP ; Address low byte
STA OSTEMP
JSR CLISTEP ; Address high byte
PLX ; Get command byte
PHA ; Push address high
LDA OSTEMP
PHA ; Push address low
TXA ; Command byte
PHA
ASL A ; Drop bit 7
BEQ CLICALL ; If $80 don't convert LPTR
JSR LPTRtoXY ; XY=>parameters
CLICALL PLA ; A=command parameter
CLIDONE RTS ; Call command routine
CLISTEP INC OSTEXT+0,X ; Point to next table byte
BNE CLISTEP2
INC OSTEXT+1,X
CLISTEP2 LDA (OSTEXT,X) ; Get next byte
RTS
* OSCLI HANDLER
@ -113,56 +186,11 @@ CLILP2 LDA (OSLPTR),Y
DEY
JSR LPTRtoXY ; Add Y to LPTR
JSR XYtoLPTR ; LPTR=>start of actual command
*
* Search command table
LDX #0 ; Start of command table
CLILP4 LDY #0 ; Start of command line
CLILP5 LDA CMDTABLE,X
BEQ CLIUNKNOWN ; End of command table
BMI CLIMATCH ; End of table string
EOR (OSLPTR),Y
AND #$DF ; Force upper case match
BNE CLINOMATCH
INX ; Step to next table char
INY ; Step to next command char
BNE CLILP5 ; Loop to check
CLINOMATCH LDA (OSLPTR),Y
CMP #'.' ; Abbreviation?
BEQ CLIDOT
CLINEXT INX ; No match, step to next entry
LDA CMDTABLE,X
BPL CLINEXT
CLINEXT2 INX ; Step past byte, address
INX
INX
BNE CLILP4 ; Loop to check next
CLIDOT LDA CMDTABLE,X
BMI CLINEXT2 ; Dot after full word, no match
CLIDOT2 INX ; Step to command address
LDA CMDTABLE,X
BPL CLIDOT2
INY ; Step past dot
BNE CLIMATCH2 ; Jump to this command
CLIMATCH LDA (OSLPTR),Y
CMP #'.'
BEQ CLINEXT ; Longer abbreviation, eg 'CAT.'
CMP #'A'
BCS CLINEXT ; More letters, eg 'HELPER'
CLIMATCH2 JSR SKIPSPC ; (OSLPTR),Y=>parameters
LDA CMDTABLE+2,X ; Push destination address
PHA
LDA CMDTABLE+1,X
PHA
LDA CMDTABLE+0,X ; A=command parameter
PHA
ASL A ; Drop bit 7
BEQ CLICALL ; If $80 don't convert LPTR
JSR LPTRtoXY ; XY=>parameters
CLICALL PLA ; A=command parameter
CLIDONE RTS
LDX #<CMDTABLE ; XY=>command table
LDY #>CMDTABLE
JSR CLILOOKUP ; Look for command
BNE CLIUNKNOWN ; No match
RTS
CLISLASH JSR SKIPSPC
BEQ CLIDONE ; */<cr>
@ -347,7 +375,7 @@ STARHELP1 LDX #0
JSR OSWRCH
STARHELPLP1 LDY #10
LDA CMDTABLE,X
BEQ STARHELP4
BMI STARHELP4
STARHELPLP2 LDA CMDTABLE,X
BMI STARHELP3
JSR OSWRCH

14
import Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
# For importing JGH's files into Github
for i in *.s; do
fromdos $i
sed -i s/^\;/\*/ $i
cadius outdentfile $i
cadius sethighbit $i
mv $i $i#040000
cadius deletefile applecorn.po /APPLECORN/$i
cadius addfile applecorn.po /APPLECORN $i#040000
done

View File

@ -6,8 +6,9 @@
* Loads Acorn ROM file (16KB) from disk and writes it
* to aux memory starting at $08000. Copies Applecorn MOS
* to aux memory starting at AUXMOS1 and jumps to it.
* (Note that the MOS code will relocate itself to $D000.)
* (Note that the MOS code will copy itself to $D000.)
START JSR ROMMENU
STZ :BLOCKS
LDX #$00
:S1 JSR CROUT

260
mainmem.s
View File

@ -9,9 +9,33 @@
* 27-Aug-2021 Delete and MkDir return ProDOS result to caller
* 29-Aug-2021 All calls (seem to) return ProDOS result to caller
* Set ?&E0=255 for testing to report ProDOS result
* 30-Aug-2021 INFOFILE semi-implemented, UPDFB returns moddate
* Lots of tidying up possible once confirmed code working
* *BUG* LOAD loads full 512 bytes from last sector even when < 512
* ProDOS string buffers
RTCBUF EQU $0200 ; Use by RTC calls, 40 bytes
* ; $0228-$023D
DRVBUF1 EQU $023E
DRVBUF2 EQU $023F ; Prefix on current drive, len+64
CMDPATH EQU $0280 ; Path used to start Applecorn
* Filename string buffers
MOSFILE1 EQU $0300 ; length + 64 bytes
MOSFILE2 EQU $0341 ; length + 64 bytes
MOSFILE EQU MOSFILE1
* $0382 ; $3C bytes here
*
FILEBLK EQU $03BE
FBPTR EQU FILEBLK+0 ; Pointer to name (in aux)
FBLOAD EQU FILEBLK+2 ; Load address
FBEXEC EQU FILEBLK+6 ; Exec address
FBSIZE EQU FILEBLK+10 ; Size
FBSTRT EQU FILEBLK+10 ; Start address for SAVE
FBATTR EQU FILEBLK+14 ; Attributes
FBEND EQU FILEBLK+14 ; End address for SAVE
* ProDOS MLI command numbers
QUITCMD EQU $65
GTIMECMD EQU $82
@ -49,20 +73,20 @@ SETPRFX LDA #GPFXCMD
:L1 JSR MLI
:OPC7 DB $00
DW GSPFXPL
LDX $0300
LDX DRVBUF1 ; was $0300
BNE RTSINST
LDA $BF30
STA ONLNPL+1 ; Device number
JSR MLI
DB ONLNCMD
DW ONLNPL
LDA $0301
LDA DRVBUF2 ; was $0301
AND #$0F
TAX
INX
STX $0300
STX DRVBUF1 ; was $0300
LDA #$2F
STA $0301
STA DRVBUF2 ; was $0301
DEC :OPC7
BNE :L1
RTSINST RTS
@ -88,16 +112,16 @@ DISCONN LDA $BF98
BPL :L1
BMI :S1
:S3 LDA $BF32,Y
STA $0302
STA DRVBUF2+1 ; was $0302
:L2 LDA $BF33,Y
STA $BF32,Y
BEQ :S4
INY
BNE :L2
:S4 LDA $BF26
STA $0300
STA DRVBUF1 ; was $0300
LDA $BF27
STA $0301
STA DRVBUF2 ; was $0301
LDA $BF10
STA $BF26
LDA $BF11
@ -147,11 +171,24 @@ COPYAUXBLK
CLI
RTS
* TO DO: All OSFILE calls combined and dispatch in here
* All start with PREPATH, UPDFB, COPYFB then branch
* to relevent routine.
INFOFILE >>> ENTMAIN
* TO DO: call PREPATH to check for drive, up, etc
JSR UPDFB ; Update FILEBLK
JSR COPYFB ; Copy back to aux mem
>>> XF2AUX,OSFILERET
* ProDOS file handling to delete a file
* Called by AppleMOS OSFILE
* Return A=0 no object, A=1 file deleted, A=2 dir deleted
* A>$1F ProDOS error
DELFILE >>> ENTMAIN
* TO DO: call PREPATH to check for drive, up, etc
JSR UPDFB ; Update FILEBLK
JSR COPYFB ; Copy back to aux mem
PHA ; Save object type
@ -190,23 +227,26 @@ DESTROY LDA #<MOSFILE ; Attempt to destroy file
* Return A=02 on success (ie: 'directory')
* A>$1F ProDOS error, translated by OSFILE handler
MAKEDIR >>> ENTMAIN
* TO DO: call PREPATH to check for drive, up, etc
JSR UPDFB ; Update FILEBLK
JSR COPYFB ; Copy back to aux mem
CMP #$02
BEQ :EXIT ; Dir already exists
* Make into a subroutine
LDA #$0D ; 'Directory'
STA CREATEPL+7 ; ->Storage type
LDA #$0F ; 'Directory'
STA CREATEPL+4 ; ->File type
* subroutine....
LDA #<MOSFILE
STA CREATEPL+1
LDA #>MOSFILE
STA CREATEPL+2
LDA #$C3 ; 'Default access'
STA CREATEPL+3 ; ->Access
LDA #$0F ; 'Directory'
STA CREATEPL+4 ; ->File type
STZ CREATEPL+5 ; Aux type LSB
STZ CREATEPL+6 ; Aux type MSB
LDA #$0D ; 'Directory'
STA CREATEPL+7 ; ->Storage type
* Don't we have to make a call to update BF90-BF93?
LDA $BF90 ; Current date
STA CREATEPL+8
LDA $BF91
@ -216,6 +256,7 @@ MAKEDIR >>> ENTMAIN
LDA $BF93
STA CREATEPL+11
JSR CRTFILE
* ...
BCS :EXIT ; Failed, exit with ProDOS result
JSR UPDFB ; Update FILEBLK
JSR COPYFB ; Copy FILEBLK to aux mem
@ -245,10 +286,15 @@ DORENAME LDA #<MOSFILE
OFILE >>> ENTMAIN
PHA ; Preserve arg for later
* TO DO: Mustn't write to a directory
* TO DO: call PREPATH to check for drive, up, etc
CMP #$80 ; Write mode
BNE :S0
JSR DESTROY
* Make into a subroutine
LDA #$01 ; Storage type - file
STA CREATEPL+7
LDA #$06 ; Filetype BIN
STA CREATEPL+4
LDA #<MOSFILE ; Attempt to create file
STA CREATEPL+1
STA OPENPL+1
@ -257,14 +303,10 @@ OFILE >>> ENTMAIN
STA OPENPL+2
LDA #$C3 ; Access unlocked
STA CREATEPL+3
LDA #$06 ; Filetype BIN
STA CREATEPL+4
LDA #$00 ; Auxtype
STA CREATEPL+5
LDA #$00
STA CREATEPL+6
LDA #$01 ; Storage type - file
STA CREATEPL+7
LDA $BF90 ; Current date
STA CREATEPL+8
LDA $BF91
@ -274,7 +316,7 @@ OFILE >>> ENTMAIN
LDA $BF93
STA CREATEPL+11
JSR CRTFILE
* ...
:S0 LDA #$00 ; Look for empty slot
JSR FINDBUF
STX BUFIDX
@ -474,12 +516,14 @@ TELL >>> ENTMAIN
>>> MAINZP ; Alt ZP off, ROM back in
BRA :EXIT
* ProDOS file handling for MOS OSFILE LOAD call
* Invoked by AppleMOS OSFILE
* Return A=01 if successful (meaning 'file')
* A>$1F ProDOS error, translated by FILERET
* TO DO: If object not a file, return $46 - File not found
LOADFILE >>> ENTMAIN
* TO DO: call PREPATH to check for drive, up, etc
STZ :BLOCKS
LDA #<MOSFILE
STA OPENPL+1
@ -530,6 +574,8 @@ LOADFILE >>> ENTMAIN
INC
DEX
BRA :L2
* *BUG* This is copy all 512 bytes of last block instead of
* just the bytes used
:S2 STA A4H
SEC ; Main -> AUX
JSR AUXMOVE
@ -574,6 +620,7 @@ COPYFB PHA
* A>$1F ProDOS error translated by FILERET
* TO DO: If dir exists, return $41
SAVEFILE >>> ENTMAIN
* TO DO: call PREPATH to check for drive, up, etc
* TO DO: MUSTN'T OVERWITE A DIRECTORY
LDA #<MOSFILE ; Attempt to destroy file
STA DESTPL+1
@ -584,6 +631,11 @@ SAVEFILE >>> ENTMAIN
DW DESTPL
STZ :BLOCKS
* TO DO: Make this a subroutine
LDA #$01 ; Storage type - file
STA CREATEPL+7
LDA #$06 ; Filetype BIN
STA CREATEPL+4
* subroutine....
LDA #<MOSFILE
STA CREATEPL+1
STA OPENPL+1
@ -592,14 +644,10 @@ SAVEFILE >>> ENTMAIN
STA OPENPL+2
LDA #$C3 ; Access unlocked
STA CREATEPL+3
LDA #$06 ; Filetype BIN
STA CREATEPL+4
LDA FBLOAD ; Auxtype = load address
STA CREATEPL+5
LDA FBLOAD+1
STA CREATEPL+6
LDA #$01 ; Storage type - file
STA CREATEPL+7
LDA $BF90 ; Current date
STA CREATEPL+8
LDA $BF91
@ -609,6 +657,7 @@ SAVEFILE >>> ENTMAIN
LDA $BF93
STA CREATEPL+11
JSR CRTFILE
* ...
BCS :FWD1 ; :CANTOPEN error
JSR OPENFILE
BCS :FWD1 ; :CANTOPEN error
@ -728,8 +777,10 @@ UPDFB LDA #<MOSFILE
JSR MLI ; Call GET_FILE_INFO
DB GINFOCMD
DW GINFOPL
BCS :ERR
LDA GINFOPL+5 ; Aux type LSB
BCC :UPDFB1
JMP CHKNOTFND
:UPDFB1 LDA GINFOPL+5 ; Aux type LSB
STA FBLOAD
STA FBEXEC
LDA GINFOPL+6 ; Aux type MSB
@ -739,6 +790,7 @@ UPDFB LDA #<MOSFILE
STZ FBEXEC+2
STZ FBLOAD+3
STZ FBEXEC+3
*
LDA GINFOPL+3 ; Access byte
CMP #$40 ; Locked?
AND #$03 ; ------wr
@ -753,8 +805,37 @@ UPDFB LDA #<MOSFILE
ORA #$08 ; --wrl---
:UPDFB2 ORA FBATTR+0 ; --wrl-wr
STA FBATTR+0
STZ FBATTR+1 ; TO DO: get mdate
STZ FBATTR+2
*
LDA GINFOPL+11 ; yyyyyyym
PHA
ROR A ; ?yyyyyyy m
LDA GINFOPL+10 ; mmmddddd m
PHA
ROR A ; mmmmdddd
LSR A ; -mmmmddd
LSR A ; --mmmmdd
LSR A ; ---mmmmd
LSR A ; ----mmmm
STA FBATTR+2
PLA ; mmmddddd
AND #31 ; ---ddddd
STA FBATTR+1
PLA ; yyyyyyym
SEC
SBC #81*2 ; Offset from 1981
BCS :UPDFB3 ; 1981-1999 -> 00-18
ADC #100*2 ; 2000-2080 -> 19-99
:UPDFB3 PHA ; yyyyyyym
AND #$E0 ; yyy-----
ORA FBATTR+1 ; yyyddddd
STA FBATTR+1
PLA ; yyyyyyym
AND #$FE ; yyyyyyy0
ASL A ; yyyyyy00
ASL A ; yyyyy000
ASL A ; yyyy0000
ORA FBATTR+2 ; yyyymmmm
STA FBATTR+2
STZ FBATTR+3
JSR OPENFILE ; Open file
@ -777,9 +858,9 @@ UPDFB LDA #<MOSFILE
LDA #$01 ; Prepare A=file
LDX GINFOPL+7
CPX #$0D ; Is it a directory?
BNE :UPDFB3
BNE :UPDFB5
LDA #$02 ; Return A=directory
:UPDFB3 RTS
:UPDFB5 RTS
:ERR
CHKNOTFND CMP #$44 ; Convert ProDOS 'not found'
@ -838,35 +919,7 @@ CATALOGRET
* dir/file.ext filesystem, so '..' means parent dir (eg: '../SOMEDIR')
* Also allows '^' as '^' is illegal character
* Carry set on error, clear otherwise
* TO DO: drv: prefix, drv:/dir/file
PREPATH LDX MOSFILE ; Length
BEQ :EXIT ; If zero length
LDA MOSFILE+1 ; 1st char of filename
CMP #$3A ; Is it ':'?
BNE :NOTCLN ; Nope
CPX #$03 ; Len at least 3?
BCC :ERR ; Nope!
LDA MOSFILE+3 ; Drive
SEC
SBC #'1'
TAX
LDA MOSFILE+2 ; Slot
SEC
SBC #'0'
JSR DRV2PFX ; Slt/Drv->pfx in MOSFILE2
JSR DEL1CHAR ; Delete ':' from MOSFILE
JSR DEL1CHAR ; Delete the two digits
JSR DEL1CHAR
LDA MOSFILE ; Is there more?
BEQ :APPEND ; Only ':sd'
CMP #$02 ; Len at least 2?
BCC :ERR ; Nope!
LDA MOSFILE+1 ; 1st char of filename
CMP #$2F ; '/'
BNE :ERR
JSR DEL1CHAR ; Delete '/' from MOSFILE
BRA :APPEND
:NOTCLN JSR GETPREF ; Current pfx -> MOSFILE2
PREPATH JSR GETPREF ; Current pfx -> MOSFILE2
:REENTER LDA MOSFILE+1 ; First char of dirname
CMP #'.'
BEQ :UPDIR1
@ -874,7 +927,7 @@ PREPATH LDX MOSFILE ; Length
BEQ :CARET ; If '^'
CMP #$2F ; '/' char - abs path
BEQ :EXIT ; Nothing to do
BRA :APPEND
BRA :PARENT
:UPDIR1 LDA MOSFILE+2
CMP #'.' ; '..'
@ -883,7 +936,7 @@ PREPATH LDX MOSFILE ; Length
:CARET JSR DEL1CHAR ; Delete '^' from MOSFILE
JSR PARENT ; Parent dir -> MOSFILE2
LDA MOSFILE ; Is there more?
BEQ :APPEND ; Only '^'
BEQ :PARENT ; Only '^'
CMP #$02 ; Len at least two?
BCC :ERR ; Nope!
LDA MOSFILE+1 ; What is next char?
@ -891,7 +944,7 @@ PREPATH LDX MOSFILE ; Length
BNE :ERR ; Nope!
JSR DEL1CHAR ; Delete '/' from MOSFILE
BRA :REENTER ; Go again!
:APPEND JSR APPMF2 ; Append MOSFILE->MOSFILE2
:PARENT JSR APPMF2 ; Append MOSFILE->MOSFILE2
JSR COPYMF2 ; Copy back to MOSFILE
:EXIT CLC
RTS
@ -966,34 +1019,39 @@ PARENT LDX MOSFILE2 ; Length of string
* Convert slot/drive to prefix
* Expect slot number (1..7) in A, drive (0..1) in X
* Puts prefix (or empty string) in MOSFILE2
DRV2PFX ASL
ASL
ASL
ASL
CPX #$00
BEQ :S1 ; Drive 1
ORA #$80 ; Drive 2
:S1 STA ONLNPL+1 ; Device number
* Puts prefix (or empty string) in MOSFILE
DRV2PFX
* ASL
* ASL
* ASL
* ASL
* STX :TEMP ; Gets 0SSS000D
* ORA :TEMP ; Shouldn't this be DSSS00000 ?
CLC ; Cy=0 A=00000sss
ROR A ; s 000000ss
ROR A ; s s000000s
ROR A ; s ss000000
ROR A ; s sss00000
CPX #1 ; d sss00000
ROR A ; 0 dsss0000
STA ONLNPL+1 ; Device number
JSR MLI ; Call ON_LINE
DB ONLNCMD
DW ONLNPL ; Buffer set to $301
LDA $301 ; Slot/Drive/Length
DW ONLNPL ; Buffer set to DRVBUF2 (was $301)
LDA DRVBUF2 ; was $301 ; Slot/Drive/Length
AND #$0F ; Mask to get length
STA MOSFILE ; Store length
TAX
INC ; Plus '/' at each end
INC
STA MOSFILE2 ; Store length
LDA #$2F ; '/'
STA MOSFILE2+1
STA MOSFILE2+2,X
:L1 CPX #$00 ; Copy -> MOSFILE2
:L1 CPX #$00 ; Copy -> MOSFILE
BEQ :EXIT
LDA $301,X
STA MOSFILE2+1,X
DEX
LDA DRVBUF2,X ; was $301,X
STA MOSFILE,X ; Should be able to read
DEX ; directly to MOSFILE
BRA :L1
:EXIT RTS
* :TEMP DB $00
* Delete first char of MOSFILE
DEL1CHAR LDX MOSFILE ; Length
@ -1088,10 +1146,10 @@ FLSHPL HEX 01 ; Number of parameters
ONLNPL HEX 02 ; Number of parameters
DB $00 ; Unit num
DW $301 ; Buffer
DW DRVBUF2 ; was $301 ; Buffer
GSPFXPL HEX 01 ; Number of parameters
DW $300 ; Buffer
DW DRVBUF1 ; was $300 ; Buffer
GPFXPL HEX 01 ; Number of parameters
DW MOSFILE2 ; Buffer
@ -1129,25 +1187,25 @@ QUITPL HEX 04 ; Number of parameters
DB $00
DW $0000
* Buffer for Acorn MOS filename
* Pascal string
MOSFILE DS 65 ; 64 bytes max prefix/file len
** Buffer for Acorn MOS filename
** Pascal string
*MOSFILE DS 65 ; 64 bytes max prefix/file len
*
** Buffer for second filename (for rename)
** Pascal string
*MOSFILE2 DS 65 ; 64 bytes max prefix/file len
* Buffer for second filename (for rename)
* Pascal string
MOSFILE2 DS 65 ; 64 bytes max prefix/file len
* Acorn MOS format OSFILE param list
FILEBLK
FBPTR DW $0000 ; Pointer to name (in aux)
FBLOAD DW $0000 ; Load address
DW $0000
FBEXEC DW $0000 ; Exec address
DW $0000
FBSIZE
FBSTRT DW $0000 ; Size / Start address for SAVE
DW $0000
FBATTR
FBEND DW $0000 ; Attributes / End address for SAVE
DW $0000
** Acorn MOS format OSFILE param list
*FILEBLK
*FBPTR DW $0000 ; Pointer to name (in aux)
*FBLOAD DW $0000 ; Load address
* DW $0000
*FBEXEC DW $0000 ; Exec address
* DW $0000
*FBSIZE
*FBSTRT DW $0000 ; Size / Start address for SAVE
* DW $0000
*FBATTR
*FBEND DW $0000 ; Attributes / End address for SAVE
* DW $0000

66
memmap.txt Normal file
View File

@ -0,0 +1,66 @@
* Memory layout in main memory
*
* ; $0000-$00FF Zero page
* ; $0100-$01FF Stack
* ; $0200-$02FF ProDOS string buffers
* ; $0200-$022F Overwritten by RTC routines
* ; $0228-$023D
DRVBUF1 EQU $023E ; $023E Drive
DRVBUF2 EQU $023F ; $022F Prefix on current drive
CMDPATH EQU $0280 ; $0280 Path used to start Applecorn
*
* ; $0300-$03CF File system core workspace
* ; $0300-$0382 Filename string buffers
MOSFILE1 EQU $0300 ; $0300 length
* ; $0301 64 byte string
MOSFILE2 EQU $0341 ; $0341 length
* ; $0342 64 byte string
* ; $0382-$03BD $3C spare bytes
* ;
* ; $03BE-$03CF: local copy of control block
* ; $03BE FPTR FPTR
* ; $03BF CHANNEL
* ; $03C0 LOAD LOAD ADDR
* ; $03C4 EXEC EXEC COUNT
* ; $03C8 SIZE START OFFSET
* ; $03CC ATTR END
* ; $03D0-$03FF: ProDOS vectors, etc.
* ; $03D0-$03D2 JMP WARM
* ; $03D3-$03D5 JMP WARM
* ; $03D6-$03EC ProDOS
* ; $03ED-$03DE XFER address
* ; $03EF ProDOS
* ; $03F0-$03D1 BRKV
* ; $03F2-$03D3 RESETV
* ; $03F4 RESETV ACK
* ; $03F5-$03F7 JMP AMP
* ; $03F8-$03FA JMP USER
* ; $03FB-$03FD JMP MON
* ; $03FE-$03FF IRQV
*
* EQU $0400 ; $0400- Can't use as ProDOS uses 'hidden' bytes
* ; -$07FF within screen for workspace
SCREEN EQU $0800 ; $0800-$0BFF half 80-col screen or 40-col screen
IOBUF0 EQU $0C00 ; $0C00-$0FFF For loading ROM, OSFILE, *.
IOBUF1 EQU $1000 ; $1000-$13FF Four open files for langs
IOBUF2 EQU $1400 ; $1400-$17FF
IOBUF3 EQU $1800 ; $1800-$1BFF
IOBUF4 EQU $1C00 ; $1C00-$1FFF
* ; $2000- Code, to do: make code move itself
* -$4FFF
BLKBUF EQU $5000 ; $5000-$53FF 512-byte buffer plus channel data
BLKBUFEND EQU $5200
* To do later:
* ; $2000-$3FFF Hi-Res screen 1
* ; $4000-$5FFF Hi-Res screen 2
* ; $6000- available
* ; -$95FF available
* ; $9600-$BDFF ProDOS buffers
* ; $BE00-$BEFF MLI Global workspace
* ; $BF00-$BFFF MLI API interface
I think $0300-$03DF can be usefully used as filing system workspace,
the mainmem copies of the filename and control block, MOSNAME and CBFILE,
and later for OSGBPB.