From 949a6902e81fff0e449f6a7accafe77fbe487044 Mon Sep 17 00:00:00 2001 From: John Snape Date: Mon, 24 Apr 2023 15:02:59 -0700 Subject: [PATCH] Add files via upload --- source/PARALLEL_CARD.txt | 261 + source/PRODOS8.TXT | 11355 +++++++++++++++++++++++++++++++++++++ 2 files changed, 11616 insertions(+) create mode 100644 source/PARALLEL_CARD.txt create mode 100644 source/PRODOS8.TXT diff --git a/source/PARALLEL_CARD.txt b/source/PARALLEL_CARD.txt new file mode 100644 index 0000000..1cbc9e8 --- /dev/null +++ b/source/PARALLEL_CARD.txt @@ -0,0 +1,261 @@ + org $1000 +********************************* +* PRINTER CARD I FIRMWARE * +* * +* P1-2 (341-0005) * +* * +* WOZ 11/1/77 * +* APPLE COMPUTER INC. * +* ALL RIGHTS RESERVED * +* * +* REVISED 3 / 17 / 1978 * +* HUSTON AND SANDER * +* * +* --------------------------- * +* PROM ADDRESSING * +* --------------------------- * +* * +* $CN00.CN3F --> $CN40.CN7F * +* $CN40.CN7F --> $CN00.CN3F * +* $CN80.CNBF --> $CNC0.CNFF * +* $CNC0.CNFF --> $CN80.CNBF * +* * +* --------------------------- * +* DEFAULT SETTINGS * +* --------------------------- * +* * +* ESCAPE CHARACTER IS CTRL-I * +* VIDEO-ALSO AND CRLF ON * +* * +* --------------------------- * +* AFTER ESCAPE CHARACTER * +* --------------------------- * +* * +* (OPTIONAL SET PRINTER WIDTH) * +* * +* I: SET VIDEO ALSO * +* J: CLR CRLF, VID-ALSO * +* K: CLR CRLF * +* L: SET CRLF * +* M: SET CRLF, VID-ALSO * +* N: CLR VIDEO ALSO * +* * +********************************* +* +CH EQU $24 ;CURSOR HORIZONTAL INDEX +CSWL EQU $36 ;LOW ORDER COUT SWITCH BYTE +PWDTH EQU $4B8 ;PRINTER WIDTH +MSTRT EQU $538 ;MARGIN START +MODE EQU $5B8 ;AFTER ESC CHAR +ESCHAR EQU $638 ;CURRENT ESC CHAR +FLAGS EQU $6B8 ;B7=VID-ALSO, B0=CRLF +COL EQU $738 ;COLUMN COUNT +DEV EQU $C080 ;+$N0 ACTIVATES THE DEV LINE +COUT1 EQU $FDF0 ;VIDEO OUTPUT ENTRY +IORTS EQU $FF58 ;FIXED RTS INSTRUCTION +* +* +ENT0 CLC ;DEFAULT ENTRY + HEX BO +ENT1 SEC ;NORMAL ENTRY + PHA + TXA + PHA + TYA + PHA + PHP + SEI ;DISABLE INTERRUPTS + JSR IORTS ;RETURNS $CN ABOVE STACK + TSX + PLA + PLA + PLA + PLA + TAY ;CHAR TO Y-REGISTER + DEX + TXS ;GET $CN FROM ABOVE STACK + PLA + PLP ;RESTORE STATUS + TAX ;$CN TO REG X + BCC DEFAULT + LDA MODE,X ;AFTER ESC CHAR? + BPL ESCTEST ;BRANCH IF NO + TYA + AND #$7F ;MASK OUT BIT 7 + EOR #$30 ;ALTER BITS + CMP #$0A ;"0"-"9"? + BCC DIG ;BRANCH IF YES + CMP #$78 ;"H"-"O"? + BCS SETFLG ;YES, SET OR CLR FLAGS + EOR #$3D ;CHECK FOR CARRIAGE RETURN + BEQ ESCTEST ;DON'T CHANGE ESC CHAR IF CR + TYA ;GET ORIGINAL CHAR AGAIN + AND #$9F ;MAKE IT A CTRL CHAR + STA ESCHAR,X ;STORE NEW ESC CHAR + BCC DONE ;BRANCH ALWAYS TAKEN +* +* +ESCTEST LDA FLAGS,X + BMI ESCTST + LDA CH + CMP COL,X + BCS ESCTST + CMP #$11 + BCS ESCTST + ORA #$F0 + AND COL,X + ASC CH + STA CH +ESCTST LSR ;MAKE IT POSITIVE +DEFAULT SEC + BCS ESCTST1 ;BRANCH ALWAYS TAKEN +* +* +SETFLG CLC + ROR + AND FLAGS,X + BCC SETFLG1 + EOR #$81 +SETFLG1 STA FLAGS,X + BNE DONE +* +* +DIG LDY #$0A +DLOOP ADC MSTRT,X ;ADD 10*MSTRT TO DIG AND STORE + DEY ; IN PRINTER WIDTH (MARGIN) + BNE DLOOP + STA PWDTH,X +MINIT STA MSTRT,X ;UPDATE MARGIN START + SEC ; INDICATE 'AFTER ESC CHAR' + BCS DONE1 ;BRANCH ALWAYS +* +* +VIDEO EQU * ;MUST KEEP CURSOR HORIZ. + CMP CH ;IN RANGE OF PRWDTH + BCC SETCH ;BRANCH IF >40 + PLA + TAY + PLA + TAX ;RESTORE REGISTERS AND + PLA ;END WITH VIDEO OUT + JMP COUT1 +* +* + ORG ENT0+#$80 + BCC * ;IMAGE 'WAIT FOR READY' + BCS * ;IMAGE (ESCTST & DEFAULT) +* +* +* +* +OUT STA DEV,Y ;OUTPUT CHAR TO PRINTER + BCC PRNT ;LOOP IF WAS TAB + EOR #$7 ;IF CR, MAKE IT LF + TAY ; COPY TO REG,Y + EOR #$0A + ASL ;CARRIAGE RETURN IN 7 LSB'S? + BNE FINISH ;BRANCH IF NOT CR + CLV ; INDICATE THAT IT WAS CR + STA CH ;RESET CURSOR HORIZ. + STA COL,X ;CLEAR COLUMN COUNT +FINISH LDA FLAGS,X ;FOR CRLF CHECK (BIT 0) + LSR + BVS FINISH1 ;BRANCH IF LAST CHAR NOT CR + BCS ESCTST1 +FINISH1 ASL ;CHECK HI ORDER BIT OF FLAGS + ASL + LDA #$27 ;LOADED JUST FOR VIDEO MODE + BCS VIDEO + LDA COL,X ;CHECK FOR WITHIN 8 CHARS + SBC PWDTH,X ;OF PRINTER WIDTH + CMP #$F8 + BCC SETCH ;IF NO, THEN DONE + ADC #$27 ;ADD 32 (FORMING 32-29) + LDY IORTS ;DUMMY LDY ABSOLUTE + ORG *-2 +SETCH LDA #$00 + STA CH +DONE CLC +DONE1 ROR MODE,X + PLA + TAY + PLA + TAX + PLA + RTS +* +* + ORG ENT0+#$C0 +PRNT BCC PRNT1 ;TAKEN WHEN PRINTER READY +ESCTST1 BCS *+2 + BPL ESCTST2 +* +* + LDA #$89 ;DEFAULT CHARACTER (CONTROL-I) + STA ESCHAR,X + STA FLAGS,C ;VIDEO ALSO, CRLF ON + LDA #$28 + STA PWDTH,X + LDA #>ENT1 + STA CSWL ;SET FOR NORMAL ENTRY +ESCTST2 TYA ; MOVE CHAR TO REG-A + EOR ESCHAR,X + ASL ;ESC CHAR? (7LSB'S) + BEQ MINIT ;BRANCH IF YES + LSR MODE,X ;NO, CLR 'AFTER ESC CHAR' + TYA + PHA ; SAVE CHAR ON THE STACK + TXA + ASL + ASL ;GENERATE N*$10 AS AN INDEX TO + ASL ; THE DEVICE LINE (REG-Y) + ASL + TAY +PRNT1 LDA COL,X + CMP CH ;IF COLUMN>= CURSOR HORIZ + PLA ; THEN USE CHAR + BCS CTLTST + PHA + AND #$80 ;ELSE GEN BLANK (7 LSB'S) + ORA #$20 ; FOR TAB CATCH-UP +CTLTST BIT IORTS + BEQ PRNT2 ;INCR COLUMN COUNT + INC COL,X ; IF NOT A CONTROL CHAR +PRNT2 BVS OUT ;TAKEN WHEN PRINTER READY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/PRODOS8.TXT b/source/PRODOS8.TXT new file mode 100644 index 0000000..d407aa6 --- /dev/null +++ b/source/PRODOS8.TXT @@ -0,0 +1,11355 @@ + 2 + 3 *------------------------------------------------- + 4 * This make file will generate the P8 SYS file + 5 * automatically. + 6 * + 7 * Requirements for Assembly: + 8 * Merlin16+ v4.08 + 9 + 10 USES mli.src/mli.macs + >1 _ReadTimeHex MAC + >2 Tool $D03 + >3 <<< + >4 _Int2Hex MAC + >5 Tool $220B + >6 <<< + >7 _TLTextMountVol MAC + >8 Tool $1201 + >9 <<< + >10 _MessageCenter MAC + >11 Tool $1501 + >12 <<< + >13 _MMStartUp MAC + >14 Tool $202 + >15 <<< + >16 _MMShutDown MAC + >17 Tool $302 + >18 <<< + >19 _NewHandle MAC + >20 Tool $902 + >21 <<< + >22 _DisposeHandle MAC + >23 Tool $1002 + >24 <<< + >25 PushLong MAC + >26 IF #=]1 + >27 PushWord #^]1 + >28 ELSE + >29 PushWord ]1+2 + >30 FIN + >31 PushWord ]1 + >32 <<< + >33 PushWord MAC + >34 IF #=]1 + >35 PEA ]1 + >36 ELSE + >37 IF MX/2 + >38 LDA ]1+1 + >39 PHA + >40 FIN + >41 LDA ]1 + >42 PHA + >43 FIN + >44 <<< + >45 _PtrToHand MAC + >46 Tool $2802 + >47 <<< + >48 Tool MAC + >49 LDX #]1 + >50 JSL $E10000 + >51 <<< + 11 USES 8:Tool.Equates:E16.Memory + >1 + >2 ; File: E16.Memory + >3 ; + >4 ; + >5 ; Copyright Apple Computer, Inc. 1986, 1987 + >6 ; All Rights Reserved + >7 ; + >8 ; + >9 + =0201 >10 memErr equ $0201 ; error - unable to allocate block + =0202 >11 emptyErr equ $0202 ; error - illegal operation, empty handle + =0203 >12 notEmptyErr equ $0203 ; error - an empty handle was expected for + >13 ; this operation + =0204 >14 lockErr equ $0204 ; error - illegal operation on a locked block + =0205 >15 purgeErr equ $0205 ; error - attempt to purge an unpurgable bloc + >16 ;k + =0206 >17 handleErr equ $0206 ; error - an invalid handle was given + =0207 >18 idErr equ $0207 ; error - an invalid owner ID was given + =0208 >19 attrErr equ $0208 ; error - operation illegal on block with give + >20 ;n attributes + >21 + =0000 >22 attrNoPurge equ $0000 ; Handle Attribute Bits - Not purgeable + =0001 >23 attrBank equ $0001 ; Handle Attribute Bits - fixed bank + =0002 >24 attrAddr equ $0002 ; Handle Attribute Bits - fixed address + =0004 >25 attrPage equ $0004 ; Handle Attribute Bits - page aligned + =0008 >26 attrNoSpec equ $0008 ; Handle Attribute Bits - may not use speci + >27 ;al memory + =0010 >28 attrNoCross equ $0010 ; Handle Attribute Bits - may not cross ba + >29 ;nks + =0100 >30 attrPurge1 equ $0100 ; Handle Attribute Bits - Purge level 1 + =0200 >31 attrPurge2 equ $0200 ; Handle Attribute Bits - Purge level 2 + =0300 >32 attrPurge3 equ $0300 ; Handle Attribute Bits - Purge level 3 + =0300 >33 attrPurge equ $0300 ; Handle Attribute Bits - test or set both p + >34 ;urge bits + =1000 >35 attrHandle equ $1000 ; Handle Attribute Bits - block of master p + >36 ;ointers + =2000 >37 attrSystem equ $2000 ; Handle Attribute Bits - system handle + =4000 >38 attrFixed equ $4000 ; Handle Attribute Bits - not movable + =8000 >39 attrLocked equ $8000 ; Handle Attribute Bits - locked + 12 USES 8:Tool.Equates:E16.GSOS + >1 * File: E16.GSOS + >2 * + >3 * These equates can be used with the GSOS.MACS in the MACRO.LIBRARY + >4 * directory. You can also copy the data structures at the end of this + >5 * file directly into your own source files. + >6 * + >7 *----------------------------------------------- + >8 * File access - CreateRec, OpenRec access and requestAccess fields + >9 + =0001 >10 readEnable = $0001 ;read enable bit: + =0002 >11 writeEnable = $0002 ;write enable bit: + =0004 >12 fileInvisible = $0004 ;file invisible bit: + =0020 >13 backupNeeded = $0020 ;backup needed bit:must be '0' in requestAccess field ) + =0040 >14 renameEnable = $0040 ;rename enable bit: + =0080 >15 destroyEnable = $0080 ;read enable bit: + >16 + >17 * base - > setMark = ... + >18 + =0000 >19 startPlus = $0000 ;base - setMark = displacement + =0001 >20 eofMinus = $0001 ;base - setMark = eof - displacement + =0002 >21 markPlus = $0002 ;base - setMark = mark + displacement + =0003 >22 markMinus = $0003 ;base - setMark = mark - displacement + >23 + >24 * cachePriority + >25 + =0000 >26 noCache = $0000 ;cachePriority - do not cache blocks invloved in this read + =0001 >27 cache = $0001 ;cachePriority - cache blocks invloved in this read if possible + >28 + >29 *----------------------------------------------- + >30 * GS/OS Error codes + >31 + =0001 >32 badSystemCall = $0001 ;bad system call number + =0004 >33 invalidPcount = $0004 ;invalid parameter count + =0007 >34 gsosActive = $0007 ;GS/OS already active + =0010 >35 devNotFound = $0010 ;device not found + =0011 >36 invalidDevNum = $0011 ;invalid device number + =0020 >37 drvrBadReq = $0020 ;bad request or command + =0021 >38 drvrBadCode = $0021 ;bad control or status code + =0022 >39 drvrBadParm = $0022 ;bad call parameter + =0023 >40 drvrNotOpen = $0023 ;character device not open + =0024 >41 drvrPriorOpen = $0024 ;character device already open + =0025 >42 irqTableFull = $0025 ;interrupt table full + =0026 >43 drvrNoResrc = $0026 ;resources not available + =0027 >44 drvrIOError = $0027 ;I/O error + =0028 >45 drvrNoDevice = $0028 ;device not connected + =0029 >46 drvrBusy = $0029 ;call aborted, driver is busy + =002B >47 drvrWrtProt = $002B ;device is write protected + =002C >48 drvrBadCount = $002C ;invalid byte count + =002D >49 drvrBadBlock = $002D ;invalid block address + =002E >50 drvrDiskSwitch = $002E ;disk has been switched + =002F >51 drvrOffLine = $002F ;device off line/ no media present + =0040 >52 badPathSyntax = $0040 ;invalid pathname syntax + =0043 >53 invalidRefNum = $0043 ;invalid reference number + =0044 >54 pathNotFound = $0044 ;subdirectory does not exist + =0045 >55 volNotFound = $0045 ;volume not found + =0046 >56 fileNotFound = $0046 ;file not found + =0047 >57 dupPathname = $0047 ;create or rename with existing name + =0048 >58 volumeFull = $0048 ;volume full error + =0049 >59 volDirFull = $0049 ;volume directory full + =004A >60 badFileFormat = $004A ;version error (incompatible file format) + =004B >61 badStoreType = $004B ;unsupported (or incorrect) storage type + =004C >62 eofEncountered = $004C ;end-of-file encountered + =004D >63 outOfRange = $004D ;position out of range + =004E >64 invalidAccess = $004E ;access not allowed + =004F >65 buffTooSmall = $004F ;buffer too small + =0050 >66 fileBusy = $0050 ;file is already open + =0051 >67 dirError = $0051 ;directory error + =0052 >68 unknownVol = $0052 ;unknown volume type + =0053 >69 paramRangeErr = $0053 ;parameter out of range + =0054 >70 outOfMem = $0054 ;out of memory + =0057 >71 dupVolume = $0057 ;duplicate volume name + =0058 >72 notBlockDev = $0058 ;not a block device + =0059 >73 invalidLevel = $0059 ;specifield level outside legal range + =005A >74 damagedBitMap = $005A ;block number too large + =005B >75 badPathNames = $005B ;invalid pathnames for ChangePath + =005C >76 notSystemFile = $005C ;not an executable file + =005D >77 osUnsupported = $005D ;Operating System not supported + =005F >78 stackOverflow = $005F ;too many applications on stack + =0060 >79 dataUnavail = $0060 ;Data unavailable + =0061 >80 endOfDir = $0061 ;end of directory has been reached + =0062 >81 invalidClass = $0062 ;invalid FST call class + =0063 >82 resNotFound = $0063 ;file does not contain required resource + >83 + >84 *----------------------------------------------- + >85 * FileSysID's + >86 + =0001 >87 proDOS = $0001 ;ProDOS/SOS + =0002 >88 dos33 = $0002 ;DOS 3.3 + =0003 >89 dos32 = $0003 ;DOS 3.2 + =0003 >90 dos31 = $0003 ;DOS 3.1 + =0004 >91 appleIIPascal = $0004 ;Apple II Pascal + =0005 >92 mfs = $0005 ;Macintosh (flat file system) + =0006 >93 hfs = $0006 ;Macintosh (hierarchical file system) + =0007 >94 lisa = $0007 ;Lisa file system + =0008 >95 appleCPM = $0008 ;Apple CP/M + =0009 >96 charFST = $0009 ;Character FST + =000A >97 msDOS = $000A ;MS/DOS + =000B >98 highSierra = $000B ;High Sierra + >99 + >100 * fileSysID (NEW FOR GSOS 5.0) + >101 + =0001 >102 ProDOSFSID = $01 ;ProDOS/SOS + =0002 >103 dos33FSID = $02 ;DOS 3.3 + =0003 >104 dos32FSID = $03 ;DOS 3.2 + =0003 >105 dos31FSID = $03 ;DOS 3.1 + =0004 >106 appleIIPascalFSID = $04 ;Apple II Pascal + =0005 >107 mfsFSID = $05 ;Macintosh (flat file system) + =0006 >108 hfsFSID = $06 ;Macintosh (hierarchical file system) + =0007 >109 lisaFSID = $07 ;Lisa file system + =0008 >110 appleCPMFSID = $08 ;Apple CP/M + =0009 >111 charFSTFSID = $09 ;Character FST + =000A >112 msDOSFSID = $0A ;MS/DOS + =000B >113 highSierraFSID = $0B ;High Sierra + =000C >114 ISO9660FSID = $0C ;ISO 9660 + =000D >115 AppleShare = $0D ;AppleShare + >116 + >117 * FSTInfo.attributes + >118 + =4000 >119 characterFST = $4000 ;character FST + =8000 >120 ucFST = $8000 ;SCM should upper case pathnames before + >121 ; passing them to the FST + >122 * QuitRec.flags + >123 + =8000 >124 onStack = $8000 ;place state information about quitting + >125 ; program on the quit return stack + =4000 >126 restartable = $4000 ;the quitting program is capable of being + >127 ; restarted from its dormant memory + >128 * StorageType + >129 + =0001 >130 seedling = $0001 ;standard file with seedling structure + =0001 >131 standardFile = $01 ;standard file type (no resource fork) + =0002 >132 sapling = $0002 ;standard file with sapling structure + =0003 >133 tree = $0003 ;standard file with tree structure + =0004 >134 pascalRegion = $0004 ;UCSD Pascal region on a partitioned disk + =0005 >135 extendedFile = $0005 ;extended file type (with resource fork) + =000D >136 directoryFile = $000D ;volume directory or subdirectory file + >137 + >138 * version + >139 + =00FF >140 minorRelNum = $00FF ;version - minor release number + =7F00 >141 majorRelNum = $7F00 ;version - major release number + =8000 >142 finalRel = $8000 ;version - final release + >143 + =8000 >144 isFileExtended = $8000 + >145 + >146 *----------------------------------------------- + >147 * GSOS Call ID numbers, as is for class '0' + >148 * + >149 * 'OR' these numbers with $2000 for class '1' + >150 * See the macros iGSOS and sGSOS. + >151 * + >152 * NOTE: The v4.0 and v5.0 calls are identical with + >153 * the exception that the APW v5.0 macros have + >154 * 'GS' appended to the end of each call name. + >155 + =0001 >156 _Create = $0001 + =0002 >157 _Destroy = $0002 + =2003 >158 _OSShutdown = $2003 ;class '1' only + =0004 >159 _ChangePath = $0004 + =0005 >160 _SetFileInfo = $0005 + =0006 >161 _GetFileInfo = $0006 + =0008 >162 _Volume = $0008 + =0009 >163 _SetPrefix = $0009 + =000A >164 _GetPrefix = $000A + =000B >165 _ClearBackupBit = $000B + =200C >166 _SetSysPrefs = $200C ;class '1' only + =200D >167 _Null = $200D ;class '1' only + =200E >168 _ExpandPath = $200E ;class '1' only + =200F >169 _GetSysPrefs = $200F ;class '1' only + =0010 >170 _Open = $0010 + =0011 >171 _Newline = $0011 + =0012 >172 _Read = $0012 + =0013 >173 _Write = $0013 + =0014 >174 _Close = $0014 + =0015 >175 _Flush = $0015 + =0016 >176 _SetMark = $0016 + =0017 >177 _GetMark = $0017 + =0018 >178 _SetEOF = $0018 + =0019 >179 _GetEOF = $0019 + =001A >180 _SetLevel = $001A + =001B >181 _GetLevel = $001B + =001C >182 _GetDirEntry = $001C + =201D >183 _BeginSession = $201D ;class '1' only + =201E >184 _EndSession = $201E ;class '1' only + =201F >185 _SessionStatus = $201F ;class '1' only + =0020 >186 _GetDevNumber = $0020 + =0021 >187 _GetLastDev = $0021 + =0022 >188 _ReadBlock = $0022 ;class '0' only + =0023 >189 _WriteBlock = $0023 ;class '0' only + =0024 >190 _Format = $0024 + =0025 >191 _EraseDisk = $0025 + =2026 >192 _ResetCache = $2026 ;class '1' only + =0027 >193 _GetName = $0027 + =0028 >194 _GetBootVol = $0028 + =0029 >195 _Quit = $0029 + =002A >196 _GetVersion = $002A + =202B >197 _GetFSTInfo = $202B ;class '1' only + =002C >198 _DInfo = $002C + =202D >199 _DStatus = $202D ;class '1' only + =202E >200 _DControl = $202E ;class '1' only + =202F >201 _DRead = $202F ;class '1' only + =2030 >202 _DWrite = $2030 ;class '1' only + =0031 >203 _AllocInterrupt = $0031 ;P16 call + =2031 >204 _BindInt = $2031 ;GS/OS call + =0032 >205 _DeallocInterrupt = $0032 ;P16 call + =2032 >206 _UnbindInt = $2032 'GS/OS call + =2034 >207 _AddNotifyProc = $2034 ;class '1' only + =2035 >208 _DelNotifyProc = $2035 ;class '1' only + =2036 >209 _DRename = $2036 ;class '1' only + =2037 >210 _GetStdRefNum = $2037 ;class '1' only + =2038 >211 _GetRefNum = $2038 ;class '1' only + =2039 >212 _GetRefInfo = $2039 ;class '1' only + >213 + >214 + >215 *=============================================== + >216 * Class 1 parameter tables. + >217 * (partial listing for reference only.) + >218 * (also refer to the class_1 help file) + >219 + >220 DUM 0 ; Currently set so the following doesn't + >221 ; generate any code if you include this + >222 ; entire file in your source file with + >223 ; a PUT or USE. + >224 +000000: 00 00 >225 ChangePathRec DA 0 ;pCount +000002: 00 00 00 00 >226 ADRL 0 ;pathname +000006: 00 00 00 00 >227 ADRL 0 ;newPathname + >228 +00000A: 00 00 >229 CreateRec DA 0 ;pCount +00000C: 00 00 00 00 >230 ADRL 0 ;pathname +000010: 00 00 >231 DA 0 ;access +000012: 00 00 >232 DA 0 ;fileType +000014: 00 00 00 00 >233 ADRL 0 ;auxType +000018: 00 00 >234 DA 0 ;storageType +00001A: 00 00 00 00 >235 ADRL 0 ;eof +00001E: 00 00 00 00 >236 ADRL 0 ;resourceEOF + >237 +000022: 00 00 >238 DAccessRec DA 0 ;pCount +000024: 00 00 >239 DA 0 ;devNum +000026: 00 00 >240 DA 0 ;code +000028: 00 00 00 00 >241 ADRL 0 ;list +00002C: 00 00 00 00 >242 ADRL 0 ;requestCount +000030: 00 00 00 00 >243 ADRL 0 ;transferCount + >244 +000034: 00 00 >245 DevNumRec DA 0 ;pCount +000036: 00 00 00 00 >246 ADRL 0 ;devName +00003A: 00 00 >247 DA 0 ;devNum + >248 +00003C: 00 00 >249 DInfoRec DA 0 ;pCount +00003E: 00 00 >250 DA 0 ;devNum +000040: 00 00 00 00 >251 ADRL 0 ;devName +000044: 00 00 >252 DA 0 ;characteristics +000046: 00 00 00 00 >253 ADRL 0 ;totalBlocks +00004A: 00 00 >254 DA 0 ;slotNum +00004C: 00 00 >255 DA 0 ;unitNum +00004E: 00 00 >256 DA 0 ;version +000050: 00 00 >257 DA 0 ;deviceID +000052: 00 00 >258 DA 0 ;headLink +000054: 00 00 >259 DA 0 ;forwardLink + >260 +000056: 00 00 >261 DIORec DA 0 ;pCount +000058: 00 00 >262 DA 0 ;devNum +00005A: 00 00 00 00 >263 ADRL 0 ;buffer +00005E: 00 00 00 00 >264 ADRL 0 ;requestCount +000062: 00 00 00 00 >265 ADRL 0 ;startingBlock +000066: 00 00 >266 DA 0 ;blockSize +000068: 00 00 00 00 >267 ADRL 0 ;transferCount + >268 +00006C: 00 00 >269 DirEntryRec DA 0 ;pCount +00006E: 00 00 >270 DA 0 ;refNum +000070: 00 00 >271 DA 0 ;flags +000072: 00 00 >272 DA 0 ;base +000074: 00 00 >273 DA 0 ;displacement +000076: 00 00 00 00 >274 ADRL 0 ;name +00007A: 00 00 >275 DA 0 ;entryNum +00007C: 00 00 >276 DA 0 ;fileType +00007E: 00 00 00 00 >277 ADRL 0 ;eof +000082: 00 00 00 00 >278 ADRL 0 ;blockCount +000086: 00 00 00 00 >279 DS 8 ;createDateTime +00008E: 00 00 00 00 >280 DS 8 ;modDateTime +000096: 00 00 >281 DA 0 ;access +000098: 00 00 00 00 >282 ADRL 0 ;auxType +00009C: 00 00 >283 DA 0 ;fileSysID +00009E: 00 00 00 00 >284 ADRL 0 ;optionList +0000A2: 00 00 00 00 >285 ADRL 0 ;resourceEof +0000A6: 00 00 00 00 >286 ADRL 0 ;resourceBlocks + >287 +0000AA: 00 00 >288 ExpandPathRec DA 0 ;pCount +0000AC: 00 00 00 00 >289 ADRL 0 ;inputPath +0000B0: 00 00 00 00 >290 ADRL 0 ;outputPath +0000B4: 00 00 >291 DA 0 ;flags + >292 +0000B6: 00 00 >293 FileInfoRec DA 0 ;pCount +0000B8: 00 00 00 00 >294 ADRL 0 ;pathname +0000BC: 00 00 >295 DA 0 ;access +0000BE: 00 00 >296 DA 0 ;fileType +0000C0: 00 00 00 00 >297 ADRL 0 ;auxType +0000C4: 00 00 >298 DA 0 ;null/storageType +0000C6: 00 00 00 00 >299 DS 8 ;createDateTime +0000CE: 00 00 00 00 >300 DS 8 ;modDateTime +0000D6: 00 00 00 00 >301 ADRL 0 ;optionList +0000DA: 00 00 00 00 >302 ADRL 0 ;null/eof +0000DE: 00 00 00 00 >303 ADRL 0 ;null/blocksUsed +0000E2: 00 00 00 00 >304 ADRL 0 ;null/resourceEOF +0000E6: 00 00 00 00 >305 ADRL 0 ;null/resourceBlocks + >306 +0000EA: 00 00 >307 FormatRec DA 0 ;pCount +0000EC: 00 00 00 00 >308 ADRL 0 ;devName +0000F0: 00 00 00 00 >309 ADRL 0 ;volName +0000F4: 00 00 >310 DA 0 ;fileSysID + >311 +0000F6: 00 00 >312 FSTInfoRec DA 0 ;pCount +0000F8: 00 00 >313 DA 0 ;fstNum +0000FA: 00 00 >314 DA 0 ;fileSysId +0000FC: 00 00 00 00 >315 ADRL 0 ;fstName +000100: 00 00 >316 DA 0 ;version +000102: 00 00 >317 DA 0 ;attributes +000104: 00 00 >318 DA 0 ;blockSize +000106: 00 00 00 00 >319 ADRL 0 ;maxVolSize +00010A: 00 00 00 00 >320 ADRL 0 ;maxFileSize + >321 +00010E: 00 00 >322 InterruptRec DA 0 ;pCount +000110: 00 00 >323 DA 0 ;intNum +000112: 00 00 >324 DA 0 ;vrn +000114: 00 00 00 00 >325 ADRL 0 ;intCode + >326 +000118: 00 00 >327 IORec DA 0 ;pCount +00011A: 00 00 >328 DA 0 ;refNum +00011C: 00 00 00 00 >329 ADRL 0 ;dataBuffer +000120: 00 00 00 00 >330 ADRL 0 ;requestCount +000124: 00 00 00 00 >331 ADRL 0 ;transferCount +000128: 00 00 >332 DA 0 ;cachePriority + >333 +00012A: 00 00 >334 LevelRec DA 0 ;pCount +00012C: 00 00 >335 DA 0 ;level + >336 +00012E: 00 00 >337 NameRec DA 0 ;pCount +000130: 00 00 00 00 >338 ADRL 0 ;pathname + >339 +000134: 00 00 >340 NewlineRec DA 0 ;pCount +000136: 00 00 >341 DA 0 ;refNum +000138: 00 00 >342 DA 0 ;enableMask +00013A: 00 00 >343 DA 0 ;numChars +00013C: 00 00 00 00 >344 ADRL 0 ;newlineTable + >345 +000140: 00 00 >346 OpenRec DA 0 ;pCount +000142: 00 00 >347 DA 0 ;refNum +000144: 00 00 00 00 >348 ADRL 0 ;pathname +000148: 00 00 >349 DA 0 ;requestAccess +00014A: 00 00 >350 DA 0 ;resourceNumber +00014C: 00 00 >351 DA 0 ;access +00014E: 00 00 >352 DA 0 ;fileType +000150: 00 00 00 00 >353 ADRL 0 ;auxType +000154: 00 00 >354 DA 0 ;storageType +000156: 00 00 00 00 >355 DS 8 ;createDateTime +00015E: 00 00 00 00 >356 DS 8 ;modDateTime +000166: 00 00 00 00 >357 ADRL 0 ;optionList +00016A: 00 00 00 00 >358 ADRL 0 ;eof +00016E: 00 00 00 00 >359 ADRL 0 ;blocksUsed +000172: 00 00 00 00 >360 ADRL 0 ;resourceEOF +000176: 00 00 00 00 >361 ADRL 0 ;resourceBlocks + >362 +00017A: 00 00 >363 PositionRec DA 0 ;pCount +00017C: 00 00 >364 DA 0 ;refNum +00017E: 00 00 00 00 >365 ADRL 0 ;position + >366 +000182: 00 00 >367 PrefixRec DA 0 ;pCount +000184: 00 00 >368 DA 0 ;prefixNum +000186: 00 00 00 00 >369 ADRL 0 ;prefix + >370 +00018A: 00 00 >371 QuitRec DA 0 ;pCount +00018C: 00 00 00 00 >372 ADRL 0 ;pathname +000190: 00 00 >373 DA 0 ;flags + >374 +000192: 00 00 >375 RefNumRec DA 0 ;pCount +000194: 00 00 >376 DA 0 ;refNum + >377 +000196: 00 00 >378 SetPositionRec DA 0 ;pCount +000198: 00 00 >379 DA 0 ;refNum +00019A: 00 00 >380 DA 0 ;base +00019C: 00 00 00 00 >381 ADRL 0 ;displacement + >382 +0001A0: 00 00 >383 ShutdownRec DA 0 ;pCount +0001A2: 00 00 >384 DA 0 ;flag + >385 +0001A4: 00 >386 TimeRec DB 0 ;second +0001A5: 00 >387 DB 0 ;minute +0001A6: 00 >388 DB 0 ;hour +0001A7: 00 >389 DB 0 ;year +0001A8: 00 >390 DB 0 ;day +0001A9: 00 >391 DB 0 ;month +0001AA: 00 >392 DB 0 ;extra +0001AB: 00 >393 DB 0 ;weekDay + >394 +0001AC: 00 00 >395 VersionRec DA 0 ;pCount +0001AE: 00 00 >396 DA 0 ;version + >397 +0001B0: 00 00 >398 VolumeRec DA 0 ;pCount +0001B2: 00 00 00 00 >399 ADRL 0 ;devName +0001B6: 00 00 00 00 >400 ADRL 0 ;volName +0001BA: 00 00 00 00 >401 ADRL 0 ;totalBlocks +0001BE: 00 00 00 00 >402 ADRL 0 ;freeBlocks +0001C2: 00 00 >403 DA 0 ;fileSysID +0001C4: 00 00 >404 DA 0 ;blockSize + >405 + >406 DEND ; End of dummy section... + 13 TR ON + 14 EXP OFF + 15 TYPE SYS + 16 ; lst on + 17 ; lst file,/blank/p8.lst + 18 PUT mli.src/Equates + >1 *------------------------------------------------- + >2 * Disassembler: The Flaming Bird Disassembler + >3 * Assembler : Merlin16+ + >4 * Merlin16+ is chosen because it can assemble + >5 * 65816 opcodes unlike EdAsm (ProDOS) which is + >6 * an 8-bit assembler. Furthermore, local labels + >7 * may be used; that should ease the need to + >8 * create trivial labels. + >9 * NB. Merlin16+ defaults to case-sensitive labels + >10 * & using blank lines should improve readibility. + >11 * Most of the comments and labels are from the + >12 * source code of ProDOS v1.7 + >13 * Whenever possible a more descriptive label is + >14 * used in place of the original. + >15 *------------------------------------------------- + >16 * Global Equates + >17 + =07F8 >18 MSLOT EQU $07F8 + =C000 >19 KBD EQU $C000 + =C000 >20 CLR80COL EQU $C000 ;Disable 80-column memory mapping (Write) + =C001 >21 SET80COL EQU $C001 ;Enable 80-column memory mapping (WR-only) + =C002 >22 RDMAINRAM EQU $C002 + =C003 >23 RDCARDRAM EQU $C003 + =C004 >24 WRMAINRAM EQU $C004 ;Write data to main ram + =C005 >25 WRCARDRAM EQU $C005 ;Write data to card ram + =C008 >26 SETSTDZP EQU $C008 ;Enable regular ZP,STK,LC + =C009 >27 SETALTZP EQU $C009 ;Enable alternate ZP,STK,LC + =C00A >28 SETINTC3ROM EQU $C00A ;Internal 80-col card ROM + =C00B >29 SETSLOTC3ROM EQU $C00B ;External slot 3 ROM + =C00C >30 CLR80VID EQU $C00C ;Disable 80 column hardware. + =C00E >31 CLRALTCHAR EQU $C00E ;Switch in primary character set. + =C010 >32 KBDSTROBE EQU $C010 + =C018 >33 RD80COL EQU $C018 + =C029 >34 NEWVIDEO EQU $C029 + =C030 >35 SPKR EQU $C030 + =C051 >36 TXTSET EQU $C051 + =C054 >37 TXTPAGE1 EQU $C054 + =C055 >38 TXTPAGE2 EQU $C055 + =C068 >39 STATEREG EQU $C068 ;Cortland memory state register + =C081 >40 ROMIN2 EQU $C081 ;swap rom in w/o w-prot ram + =C082 >41 RDROM2 EQU $C082 ;swap rom in, write protect ram + =C083 >42 LCBANK2 EQU $C083 ;Enable 2nd bank of LC + =C08B >43 LCBANK1 EQU $C08B ;Enable 1st bank of LC + =CFFF >44 CLRROM EQU $CFFF + >45 + >46 * 80 col card subroutines + >47 + =C311 >48 AuxMove EQU $C311 ;monitor move data routine + =C314 >49 Xfer EQU $C314 ;monitor XFER control + >50 + >51 * Apple // Monitor subroutines + >52 + =FA41 >53 ROMIrq EQU $FA41 ;monitor rom irq entry + =FB2F >54 Init EQU $FB2F ;Text pg1;text mode;sets 40/80 col + =FB39 >55 SETTXT EQU $FB39 + =FB5B >56 TABV EQU $FB5B + =FB6F >57 SETPWRC EQU $FB6F + =FBB3 >58 VERSION EQU $FBB3 + =FBDD >59 BELL1 EQU $FBDD + =FC58 >60 HOME EQU $FC58 + =FC9C >61 CLREOL EQU $FC9C + =FD0C >62 RDKEY EQU $FD0C + =FD8E >63 CROUT EQU $FD8E + =FDED >64 COUT EQU $FDED + =FE1F >65 IDroutine EQU $FE1F ;IIgs ID routine + =FE80 >66 SetInv EQU $FE80 + =FE84 >67 SetNorm EQU $FE84 ;Normal white text on black backround. + =FE89 >68 SetKBD EQU $FE89 ;Does an IN#1. + =FE93 >69 SetVid EQU $FE93 ;Puts COUT1 in CSW. + =FF3A >70 BELL EQU $FF3A + =FF59 >71 OLDRST EQU $FF59 ;monitor reset entry + >72 + >73 * GS/OS vectors/flags + >74 + =E100A8 >75 GSOS EQU $E100A8 + =E100B0 >76 GSOS2 EQU $E100B0 + =E100BD >77 OS_BOOT EQU $E100BD + >78 + =0200 >79 inBuf EQU $0200 ;Input buffer + =0280 >80 pnBuf EQU $0280 ;pathname buffer + =0200 >81 EnterCard EQU $0200 ;AuxMem + =0200 >82 RAMdest EQU $0200 ;AuxMem + =5100 >83 RAMsrc EQU $5100 ;Load addr + =FF00 >84 LCdest EQU $FF00 ;Execution addr of RAM disk handler + >85 + >86 * Page 3 vectors + >87 + =03F2 >88 SOFTEV EQU $03F2 + =03F4 >89 PWREDUP EQU $03F4 + =03FB >90 NMI EQU $03FB + =03ED >91 PassIt EQU $03ED + >92 + >93 * load addr exec addr Description + >94 *========================================================================================= + =2000 >95 MLI_0 EQU $2000 ;$2000-$2c7F $2000-$2c7F MLI loader/relocater + =2C80 >96 RAM_1 EQU MLI_0+$C80 ;$2c80-$2cff $2c80-$2cbc installer for /RAM + =2D00 >97 RAM_2 EQU RAM_1+$080 ;$2d00-$2d8f $ff00-$ff8f /RAM driver in main lc + =2D9B >98 MLI_3 EQU RAM_2+$09B ;$2d9b-$2dff $ff9b-$ffff interrupts + =2E00 >99 MLI_1 EQU MLI_3+$065 ;$2E00-$2eff $bf00-bfff global page + =2F00 >100 TCLOCK_0 EQU MLI_1+$100 ;$2f00-$2f7f $d742-$d7be TCLOCK driver + =2F80 >101 CCLOCK_0 EQU TCLOCK_0+$080 ;$2f80-$2fff $d742-$d7be CCLOCK driver + =3000 >102 MLI_2 EQU CCLOCK_0+$080 ;$3000-$4fff $de00-$feff MLI itself + =5100 >103 RAM_0 EQU MLI_2+$2100 ;$5100-$52ff $0200-$03ff /RAM driver in aux mem + =5300 >104 XRW_0 EQU RAM_0+$200 ;$5300-$59FF $d000-$d6ff disk core routines + =5A00 >105 SEL_0 EQU XRW_0+$700 ;$5A00-$5cff $1000-$12ff original dispatcher + =5D00 >106 SEL_1 EQU SEL_0+$300 ;$5d00-$5fff $1000-$12ff better bye dispatcher + =6000 >107 SEL_2 EQU SEL_1+$300 ;$6000-$2c7F $1000-$12ff gs/os dispatcher + >108 + >109 * ProDOS 8 equates + >110 + =0C00 >111 ABuf EQU $0C00 ;Temporary buffer + =0E00 >112 VBlock1 EQU $0E00 ;Where the Vol Dir goes + =0F00 >113 VolNameStr EQU $0F00 ;Use by SEL2 (p-string) + =1000 >114 DispAdr EQU $1000 ;Execution address of dispatcher + =D000 >115 RWTS EQU $D000 ;Addr of Disk ][ driver + =1C00 >116 IOBuf EQU $1C00 + =2C80 >117 Srce EQU $2C80 + =2D00 >118 LCSrc EQU Srce+$80 + =FF00 >119 LCDest EQU $FF00 + =D742 >120 ClockBegin EQU $D742 ;Entry address of clock + >121 + =0800 >122 LoadIntrp EQU $0800 ;Execution addr of load interpreter + =D700 >123 orig EQU $D700 + =DE00 >124 orig1 EQU $DE00 + =BF00 >125 Globals EQU $BF00 ;ProDOS's global page + =FF9B >126 IntHandler EQU $FF9B ;Start of interrupt handler + =D700 >127 pathBuf EQU orig + =D800 >128 fcb EQU orig+$100 ;File Control Blocks + =D900 >129 vcb EQU orig+$200 ;Volume Control Blocks + =DA00 >130 bmBuf EQU orig+$300 ;Bitmap buffer + =DC00 >131 genBuf EQU pathBuf+$500 ;General purpose buffer + >132 * + >133 * Constants + >134 * + =0020 >135 preTime EQU $20 ;command needs current date/time stamp + =0040 >136 preRef EQU $40 ;command requires fcb address and verification + =0080 >137 prePath EQU $80 ;command has pathname to preprocess + >138 * + >139 * volume status constants (bits) + >140 * + >141 * file status constants + >142 * + =0001 >143 dataAloc EQU $1 ;data block not allocated. + =0002 >144 idxAloc EQU $2 ;index not allocated + =0004 >145 topAloc EQU $4 ;top index not allocated + =0008 >146 storTypMod EQU $8 ;storage type modified + =0010 >147 useMod EQU $10 ;file usage modified + =0020 >148 eofMod EQU $20 ;end of file modified + =0040 >149 dataMod EQU $40 ;data block modified + =0080 >150 idxMod EQU $80 ;index block modified + =0080 >151 fcbMod EQU $80 ;has fcb/directory been modified? (flush) + >152 * + >153 * header index constants + >154 * + =0000 >155 hNamLen EQU $0 ;header name length (offset into header) + =0001 >156 hName EQU $1 ;header name + =0010 >157 hPassEnable EQU $10 ;password enable byte + =0011 >158 hPassWord EQU $11 ;encoded password + =0018 >159 hCreDate EQU $18 ;header creation date + >160 * hCreTime EQU $1A ;header creation time + =001C >161 hVer EQU $1C ;sos version that created directory + =001D >162 hComp EQU $1D ;backward compatible with sos version + =001E >163 hAttr EQU $1E ;header attributes- protect etc. + =001F >164 hEntLen EQU $1F ;length of each entry + =0020 >165 hMaxEnt EQU $20 ;maximum number of entries/block + =0021 >166 hFileCnt EQU $21 ;current number of files in directory + =0023 >167 hOwnerBlk EQU $23 ;owner's directory disk address + =0025 >168 hOwnerEnt EQU $25 ;owner's directory entry number + =0026 >169 hOwnerLen EQU $26 ;owner's directory entry length + =0023 >170 vBitMap EQU hOwnerBlk + =0025 >171 vTotBlk EQU hOwnerEnt ;(used for root directory only) + >172 * + >173 * Volume Control Block index constants + >174 * + =0020 >175 vcbSize EQU $20 ;Current VCB is 32 bytes per entry (ver 0) + =0000 >176 vcbNamLen EQU 0 ;Volume name length byte + =0001 >177 vcbName EQU 1 ;Volume name + =0010 >178 vcbDevice EQU $10 ;Volume's device # + =0011 >179 vcbStatus EQU $11 ;Volume status. (80=files open. 40=disk switched.) + =0012 >180 vcbTotBlks EQU $12 ;Total blocks on this volume + =0014 >181 vcbFreeBlks EQU $14 ;Number of unused blocks + =0016 >182 vcbRoot EQU $16 ;Root directory (disk) address + >183 *vcbBitMapOrg EQU $18 ;map organization (not supported by v 0) + >184 *vcbBitMapBuf EQU $19 ;bit map buf num + =001A >185 vcbBitMap EQU $1A ;First (disk) address of bitmap(s) + =001C >186 vcbCurrBitMap EQU $1C ;Rel addr of bitmap w/space (add to vcbBitMap) + >187 *vcbmnum EQU $1D ; relative bit map currently in memory + =001E >188 vcbOpenCnt EQU $1E ;Current number of open files. + >189 *vcbaddr EQU $1F reserved + >190 * + >191 * File Control Block index constants + >192 * + =0020 >193 fcbSize EQU $20 ;Current FCB is 32 bytes per entry (ver 0) + =0000 >194 fcbRefNum EQU 0 ;file reference number (position sensitive) + =0001 >195 fcbDevNum EQU 1 ;device (number) on which file resides + >196 *fcbHead EQU 2 ;block address of file's directory header + >197 *fcbDirBlk EQU 4 ;block address of file's directory + =0006 >198 fcbEntNum EQU 6 ;file entry number within dir block + =0007 >199 fcbStorTyp EQU 7 ;storage type - seed, sapling, tree, etc. + =0008 >200 fcbStatus EQU 8 ;status - index/data/eof/usage/type modified. + =0009 >201 fcbAttr EQU 9 ;attributes - read/write enable, newline enable. + =000A >202 fcbNewLin EQU $A ;new line terminator (all 8 bits significant). + =000B >203 fcbFileBuf EQU $B ;buffer number + =000C >204 fcbFirst EQU $C ;first block of file (Master index/key blk) + =000E >205 fcbIdxBlk EQU $E ;curr block address of index (0 if no index) + =0010 >206 fcbDataBlk EQU $10 ;curr block address of data + =0012 >207 fcbMark EQU $12 ;current file marker. + =0015 >208 fcbEOF EQU $15 ;logical end of file. + =0018 >209 fcbBlksUsed EQU $18 ;actual number of blocks allocated to this file. + >210 *fcbAddr EQU $1a reserved + =001B >211 fcbLevel EQU $1B ;level at which this file was opened + =001C >212 fcbDirty EQU $1C ;fcb marked as modified + =001F >213 fcbNLMask EQU $1F ;NewLine enabled mask + >214 * + >215 * zero page stuff + >216 * + =000A >217 look EQU $0A + =000C >218 apple EQU $0C + =0010 >219 relocTbl EQU $10 + =0010 >220 idxl EQU $10 + =0010 >221 indrcn EQU $10 + =0012 >222 devID EQU $12 + =0012 >223 src EQU $12 + =0014 >224 dst EQU $14 + =0016 >225 cnt EQU $16 + =0018 >226 code EQU $18 + =001A >227 endCode EQU $1A + =0020 >228 WNDLFT EQU $20 + =0021 >229 WNDWDTH EQU $21 + =0022 >230 WNDTOP EQU $22 + =0023 >231 WNDBTM EQU $23 + =0024 >232 CH EQU $24 + =0025 >233 CV EQU $25 + =0032 >234 INVFLG EQU $32 + =003C >235 A1 EQU $3C ;SOURCE OF TRANSFER + =003E >236 A2 EQU $3E ;END OF SOURCE + =0040 >237 A3 EQU $40 + =0042 >238 A4 EQU $42 ;DESTINATION OF TRANSFER + =0045 >239 Acc EQU $45 + =00DE >240 ErrNum EQU $DE + =057B >241 OURCH EQU $057B ;80-col horizontal coord + >242 + >243 * ProDOS block I/O equates + =0000 >244 statCmd EQU $00 ;request status, no error=ready + =0001 >245 rdCmd EQU $1 + =0002 >246 wrtCmd EQU $2 + >247 DUM $40 +000040: 00 00 >248 parm DS 2,0 +000042: 00 >249 device DS 1,0 ;parm+2 + =0042 >250 dhpCmd EQU device ;Command from ProDOS8 +000043: 00 >251 unitNum DS 1,0 ;Unit # from ProDOS 8 (DSSS 0000) +000044: 00 00 >252 bufPtr DS 2,0 ;512-byte user's I/O buffer +000046: 00 00 >253 blockNum DS 2,0 ;block # requested + >254 DEND + >255 * + =0042 >256 intCmd EQU dhpCmd ;Interrupt command + >257 * + >258 DUM parm+8 +000048: 00 00 >259 zTemps DS 2,0 + =0048 >260 tPath EQU zTemps + =0048 >261 dirBufPtr EQU zTemps + =0048 >262 tIndex EQU zTemps ;Ptr to index blk buffer +00004A: 00 00 >263 dataPtr DS 2,0 ;Ptr to data blk buffer +00004C: 00 00 >264 posPtr DS 2,0 ;Position marker +00004E: 00 00 >265 userBuf DS 2,0 ;Ptr to user's buffer + >266 DEND + >267 * + >268 * xdos parameters: + >269 * + =0000 >270 c_pCnt EQU $0 ; (count) + =0001 >271 c_devNum EQU $1 ; (value) + =0001 >272 c_refNum EQU $1 ; (value) + =0001 >273 c_intNum EQU $1 ; (value) + =0001 >274 c_path EQU $1 ;&2 (pointer) + =0002 >275 c_isNewln EQU $2 ; (mask) + =0002 >276 c_dataBuf EQU $2 ;&3 (value) + =0002 >277 c_bufAdr EQU $2 ;&3 (address) + =0002 >278 c_intAdr EQU $2 ;&3 (address) + =0002 >279 c_mark EQU $2 ;->4 (value) + =0002 >280 c_eof EQU $2 ;->4 (value) + =0003 >281 c_attr EQU $3 ; (flags) + =0003 >282 c_newl EQU $3 ; (character) + =0003 >283 c_bufPtr EQU $3 ;&4 (pointer) + =0003 >284 c_newPath EQU $3 ;&4 (pointer) + =0004 >285 c_fileID EQU $4 ; (value) + =0004 >286 c_reqCnt EQU $4 ;&5 (value) + =0004 >287 c_blkNum EQU $4 ;&5 (address) + =0005 >288 c_outRef EQU $5 + =0005 >289 c_auxID EQU $5 ;&6 (value) + =0006 >290 c_xferCnt EQU $6 ;&7 (value) + =0007 >291 c_fileKind EQU $7 ; (value) + =0008 >292 c_date EQU $8 ;&9 (value) + =0008 >293 c_outBlk EQU $8 ;&9 (count) + =000A >294 c_time EQU $a ;&b (value) + =000A >295 c_modDate EQU $a ;&b (value) + =000C >296 c_modTime EQU $c ;&d (value) + =000E >297 c_creDate EQU $e ;&f (value) + =0010 >298 c_creTime EQU $10 ;&11 (value) + >299 + >300 * Starting addresses of screen lines + >301 + =0600 >302 SLIN04 EQU $0600 ;4th line of screen (starting from 0) + =04A8 >303 SLIN09 EQU $04A8 + =0528 >304 SLIN10 EQU $0528 + =05A8 >305 SLIN11 EQU $05A8 + =0628 >306 SLIN12 EQU $0628 + =06A8 >307 SLIN13 EQU $06A8 + =07A8 >308 SLIN15 EQU $07A8 + =0750 >309 SLIN22 EQU $0750 + =07D0 >310 SLIN23 EQU $07D0 + >311 + >312 * Error Codes specific to ProDOS 8 + >313 * Other error codes are in the GS/OS equate file + >314 + =0001 >315 unclaimedIntErr EQU $01 + =000A >316 vcbUnusable EQU $0A + =000B >317 fcbUnusable EQU $0B + =000C >318 badBlockErr EQU $0C ;Block allocated illegally + =0042 >319 fcbFullErr EQU $42 + =0055 >320 vcbFullErr EQU $55 + =0056 >321 badBufErr EQU $56 + 19 PUT mli.src/ProLdr + >2 + >3 *---------------------------------------------------------* + >4 * Disassembled with The Flaming Bird Disassembler * + >5 * (c) Phoenix corp. 1992,93 - All rights reserved * + >6 *---------------------------------------------------------* + >7 ORG $2000 + >8 MX %11 + >9 + >10 * There are 3 boot entry points here + >11 +002000: 4C 7C 20 >12 NormalBoot JMP ProStart ;Normal boot entry point... +002003: 4C 79 20 >13 JMP NetBootP8 ;Network booted into P8 +002006: 4C 76 20 >14 JMP NetBootGSOS ;Network-booted into GS/OS + >15 + >16 *------------------------------------------------- + >17 * Messages + >18 +002009: C1 F0 F0 EC >19 apple2Msg ASC "Apple II" +002011: D0 F2 EF C4 >20 p8VerMsg ASC "ProDOS 8 V2.0.3 06-May-93" +00202F: A0 A0 A0 A0 >21 blanks ASC " " +00203B: C3 EF F0 F9 >22 cpyRhtMsg ASC "Copyright Apple Computer, Inc., 1983-93" +002062: C1 EC EC A0 >23 rsvdMsg ASC "All Rights Reserved." + =2076 >24 endGreetMsg EQU * + =000F >25 grtLnZ EQU blanks-p8VerMsg/2 + =0006 >26 grtLnZZ EQU cpyRhtMsg-blanks/2 + =000A >27 grtLnZZZ EQU endGreetMsg-rsvdMsg/2 + >28 +002076: EE 66 22 >29 NetBootGSOS INC SetupRTS ;Setup and +002079: EE 66 22 >30 NetBootP8 INC SetupRTS ; RTS entry point... + >31 + >32 *------------------------------------------------- +00207C: A5 43 >33 ProStart LDA unitNum ;Get boot device number +00207E: 8D 1D 23 >34 STA bUnit ;Save it for later 'prefix' +002081: 20 22 26 >35 JSR Greet ;Put up greeting message +002084: F8 >36 SED +002085: A9 99 >37 LDA #$99 ;Check we have a 65C02 +002087: 18 >38 CLC +002088: 69 01 >39 ADC #$01 ; by using chip's decimal mode +00208A: D8 >40 CLD +00208B: 30 31 =20BE >41 BMI m48K ;Error + >42 +00208D: A9 01 >43 LDA #$01 +00208F: 1C 68 C0 >44 TRB STATEREG +002092: A2 2B >45 LDX #46 LDY #>tablIntrp +002096: 20 F9 29 >47 JSR Reloc +002099: B0 23 =20BE >48 BCS m48K ;Branch if error + >49 +00209B: A0 00 >50 LDY #$00 +00209D: A9 FF >51 LDA #$FF ;Make sure there is +00209F: 8D FF BF >52 STA $BFFF ; at least 48K +0020A2: 4D FF BF >53 EOR $BFFF +0020A5: 38 >54 SEC +0020A6: D0 16 =20BE >55 BNE m48K ;Branch if not +0020A8: 8D FF BF >56 STA $BFFF ;Try again. Once may have been lucky! +0020AB: AD FF BF >57 LDA $BFFF +0020AE: D0 0E =20BE >58 BNE m48K +0020B0: AD 82 C0 >59 LDA RDROM2 ;Enable Motherboard ROM +0020B3: 20 92 25 >60 JSR WhichROM ;Get preliminary system configuration +0020B6: B0 06 =20BE >61 BCS m48K ;Branch if apple /// emulation +0020B8: A5 0C >62 LDA apple ;Test for 48K configuration +0020BA: 29 20 >63 AND #$20 ; by testing for 64K plus +0020BC: D0 03 =20C1 >64 BNE m64K ;Branch if >48k +0020BE: 4C EB 22 >65 m48K JMP ReqEnh2 ;Must have at least 64K + >66 +0020C1: A2 67 >67 m64K LDX #68 LDY #>tabl64 +0020C5: 20 F9 29 >69 JSR Reloc +0020C8: AD FF BF >70 LDA kVersion ;Get current revision number +0020CB: 8D 16 FE >71 STA XDOSver ; & save it for directory use +0020CE: 90 03 =20D3 >72 NoGood0 BCC :1 +0020D0: 4C BA 22 >73 JMP NoGood + >74 +0020D3: AD 82 C0 >75 :1 LDA RDROM2 ;Enable Motherboard ROM +0020D6: AE B3 FB >76 LDX VERSION ;Look for //e family +0020D9: E0 06 >77 CPX #$06 +0020DB: D0 40 =211D >78 BNE ItsAIIe +0020DD: A9 E0 >79 LDA #%11100000 ;phylum check on high 2 bits +0020DF: 2C C0 FB >80 BIT $FBC0 ;Another approved location +0020E2: 08 >81 PHP ;Save the results from the bit +0020E3: A5 0C >82 LDA apple +0020E5: 29 37 >83 AND #%00110111 ;Mask off bits 7,6 and 3 +0020E7: 28 >84 PLP ;Get results back +0020E8: 50 02 =20EC >85 BVC Set3 ;//c or //x +0020EA: 30 0F =20FB >86 BMI Set7 ;Branch if //e + >87 +0020EC: 08 >88 Set3 PHP ;Save the results from the bit again +0020ED: 09 08 >89 ORA #%00001000 ;Set bit 3 on +0020EF: 28 >90 PLP +0020F0: 10 04 =20F6 >91 BPL Mach2 ;Branch if //c +0020F2: 09 40 >92 ORA #%01000000 +0020F4: 10 07 =20FD >93 BPL SaveMach ;Always... + >94 +0020F6: EE 41 09 >95 Mach2 INC cFlag-LIcode+LoadIntrp ;Make it easy to see if we're on //c later +0020F9: 70 02 =20FD >96 BVS SaveMach +0020FB: 09 80 >97 Set7 ORA #%10000000 ;Set bit 7 on + >98 +0020FD: 85 0C >99 SaveMach STA apple +0020FF: AD 82 C0 >100 LDA RDROM2 ;Enable ROM for Cortland ID routine +002102: 38 >101 SEC ;Carry will determine if cortland or not +002103: 20 1F FE >102 JSR IDroutine ;RTS in all a //'s prior to Cortland +002106: B0 15 =211D >103 BCS ItsAIIe ;Branch if really a //e +002108: EE 29 23 >104 INC cortLand ;Set loader's cortland flag! +00210B: 9C FB 04 >105 STZ $04FB ;Screenhole +00210E: 20 93 FE >106 JSR SetVid + >107 + >108 * If SetupRTS is zero, zero out OS_BOOT for AppleTalk. + >109 * (SetupRTS reflects whether we're ProDOS 8 regular or + >110 * running with the GSOS.) + >111 +002111: AD 66 22 >112 LDA SetupRTS +002114: D0 07 =211D >113 BNE ItsP8 +002116: 8F BD 00 E1 >114 STAL OS_BOOT ;Flag system was booted w/P8 +00211A: 20 E6 2B >115 JSR GSPatches ;Patch GS/OS vectors + =211D >116 ItsP8 EQU * +00211D: AD 1D 23 >117 ItsAIIe LDA bUnit ;Place boot devnum in globals +002120: 8D 24 23 >118 STA bbUnit +002123: 8D 30 BF >119 STA DevNum +002126: 20 8D 26 >120 JSR DevSrch ;Finish setting up globals +002129: AD 24 23 >121 LDA bbUnit +00212C: 8D 30 BF >122 STA DevNum +00212F: 20 8B 25 >123 JSR LC1In +002132: A2 89 >124 LDX #125 LDY #>TClkStuff +002136: 20 F9 29 >126 JSR Reloc +002139: B0 93 =20CE >127 NoGood1 BCS NoGood0 ;Give up any time we got problems + >128 + >129 * Dispatcher 1 must go in bank 2 of language card + >130 * in a 64K or larger system. + >131 +00213B: A9 C8 >132 LDA #133 STA jSpare+1 ;Put dispatcher relocator address +002140: A9 FC >134 LDA #>CallDisp ; into jspare vector +002142: 8D 05 BF >135 STA jSpare+2 +002145: AD 83 C0 >136 LDA LCBANK2 +002148: AD 83 C0 >137 LDA LCBANK2 ;Switch in bank 2 +00214B: A2 58 >138 LDX #139 LDY #>DispGS +00214F: AD 66 22 >140 LDA SetupRTS +002152: C9 02 >141 CMP #$02 ;GS/OS boot? +002154: F0 18 =216E >142 BEQ RelocDisp ;Yes + >143 +002156: A2 50 >144 LDX #145 LDY #>DispBB +00215A: AD 98 BF >146 LDA MachID +00215D: 89 00 >147 BIT #$00 +00215F: D0 0D =216E >148 BNE RelocDisp ;Never! +002161: 29 C2 >149 AND #%1100_0010 ;IIe/III emul/IIc +002163: C9 82 >150 CMP #%1000_0010 ;IIe/IIc & 80-col card? +002165: F0 07 =216E >151 BEQ RelocDisp ;Go install BB dispatcher +002167: A2 48 >152 LDX #153 LDY #>Disp64 +00216B: EE 2A 23 >154 INC No80Col + >155 +00216E: 20 F9 29 >156 RelocDisp JSR Reloc +002171: A9 EE >157 LDA #$EE ;Nonsense byte to distinguish bank 2 +002173: 8D 00 D0 >158 STA $D000 +002176: 20 8B 25 >159 JSR LC1In ;Switch bank 1 back in +002179: B0 BE =2139 >160 BCS NoGood1 + >161 + >162 * Test for 128K so /RAM disk can be installed + >163 +00217B: AD 98 BF >164 ChkRAM LDA MachID +00217E: 29 30 >165 AND #$30 +002180: 49 30 >166 EOR #$30 +002182: D0 16 =219A >167 BNE NoRAMdsk + >168 + >169 ************ see rev note #45 ************* + >170 +002184: A2 FF >171 LDX #$FF ;X used to init Aux SP to $FF +002186: 08 >172 PHP ;Save interrupt status +002187: 68 >173 PLA ; in A-reg +002188: 78 >174 SEI ;No interrupts for safety's sake +002189: 8D 09 C0 >175 STA SETALTZP ;Swap in Aux LC & zp & stack +00218C: 8E 01 01 >176 STX $0101 ;Init Aux SP to $FF +00218F: 8D 08 C0 >177 STA SETSTDZP ;Back to main LC, zp, and stack +002192: 48 >178 PHA ;Restore +002193: 28 >179 PLP ; interrupt status +002194: 8D 0A C0 >180 STA SETINTC3ROM ;Make sure internal slot 3 ROM is in +002197: 20 80 2C >181 JSR RAM_1 ;Go install /RAM + >182 + >183 * Now check for interrupt vector. If vector <$D000 then we + >184 * have new ROMs and should re-point vector in language card to + >185 * ROM vector and set a flag byte. If vector is >$D000, reset + >186 * flag byte and do nothing. + >187 +00219A: AD 81 C0 >188 NoRAMdsk LDA ROMIN2 ;Switch in ROM +00219D: AC FE FF >189 LDY IrqVect +0021A0: AE FF FF >190 LDX IrqVect+1 ;Get hi byte of irq vector + >191 + >192 * The jsr LC1In was moved here from after the BCS Chk4Card so the + >193 * sta IrqFlag is written to the proper bank. + >194 +0021A3: 20 8B 25 >195 JSR LC1In + >196 + >197 *--------------------- see rev note #29 ------------------------ + >198 +0021A6: E0 D0 >199 CPX #$D0 ;Is it >$D000 (old ROMs) +0021A8: A9 00 >200 LDA #$00 ;Anticipate not +0021AA: B0 19 =21C5 >201 BCS Chk4Card ; but branch if they are old ROMs +0021AC: 8D 09 C0 >202 STA SETALTZP ;Swap Aux LC, zpg and stack +0021AF: A9 FF >203 LDA #$FF ;Set Aux stack pointer at $FF +0021B1: 8D 01 01 >204 STA $0101 ; while we're here +0021B4: 8E FF FF >205 STX IrqVect+1 +0021B7: 8C FE FF >206 STY IrqVect ;Save ROM vector in Aux lang. card +0021BA: 8D 08 C0 >207 STA SETSTDZP ;Swap in main lc, zpg and stack +0021BD: 8E FF FF >208 STX IrqVect+1 +0021C0: 8C FE FF >209 STY IrqVect ;Save ROM vector in main lang. card +0021C3: A9 01 >210 LDA #$01 ;Set IrqFlag to show new ROMs +0021C5: 8D E0 DF >211 Chk4Card STA IrqFlag +0021C8: 9C FF FE >212 STZ cortFlag ;Assume we're not on a cortland +0021CB: AD 29 23 >213 LDA cortLand ;Are we running on a cortland? +0021CE: F0 05 =21D5 >214 BEQ NoCort ;If not branch, and muck w/slot 3! +0021D0: EE FF FE >215 INC cortFlag ;Make it a one if we're on cortland +0021D3: 80 6A =223F >216 BRA DoCard + >217 + >218 * Check for a ROM in slot 3. Switch in internal + >219 * $C300 firmware if no ROM seen + >220 +0021D5: 8D 0A C0 >221 NoCort STA SETINTC3ROM ;Start with internal firmware switched in +0021D8: AD 99 BF >222 LDA SltByt ;Get slots ROM pattern +0021DB: 29 08 >223 AND #%00001000 ;Mask off all but slot 3 +0021DD: D0 02 =21E1 >224 BNE IsROMin3 ;Branch if there is rom in slot three +0021DF: 80 66 =2247 >225 BRA NoSlot3ROM ;Continue with boot.... + >226 + >227 * We've seen a ROM in slot 3. Is it an external, identifiable + >228 * 80-col card with interrupt routines? If so, enable it. + >229 * If not, switch in the internal $C300 firmware. + >230 +0021E1: 8D 0B C0 >231 IsROMin3 STA SETSLOTC3ROM ;Switch in slot 3 ROM +0021E4: AD 05 C3 >232 LDA $C305 ;1st generic terminal card ID byte +0021E7: C9 38 >233 CMP #$38 +0021E9: D0 27 =2212 >234 BNE HitSwtch ;Branch if not a terminal card +0021EB: AD 07 C3 >235 LDA $C307 ;2nd generic terminal card ID byte +0021EE: C9 18 >236 CMP #$18 +0021F0: D0 20 =2212 >237 BNE HitSwtch ;Branch if not a terminal card +0021F2: AD 0B C3 >238 LDA $C30B ;3rd generic terminal card ID byte +0021F5: C9 01 >239 CMP #$01 +0021F7: D0 19 =2212 >240 BNE HitSwtch ;Branch if not a terminal card +0021F9: AD 0C C3 >241 LDA $C30C ;Is it an Apple 80-col card compatible? +0021FC: 29 F0 >242 AND #$F0 ;Mask off lo nibble +0021FE: C9 80 >243 CMP #$80 ; and check for $8n +002200: D0 10 =2212 >244 BNE HitSwtch ;Branch if not an 80-col card +002202: AD 98 BF >245 LDA MachID ;Get the machine ID +002205: 29 C8 >246 AND #%11001000 +002207: C9 C0 >247 CMP #$C0 ;Is it a //+? +002209: F0 34 =223F >248 BEQ DoCard ;Branch if it is +00220B: AD FA C3 >249 LDA $C3FA ;Check for interrupt handler routine +00220E: C9 2C >250 CMP #$2C ; in the magic $C3FA spot +002210: F0 2D =223F >251 BEQ DoCard ;Branch if interrupt handler is there! +002212: 8D 0A C0 >252 HitSwtch STA SETINTC3ROM ;Switch in internal $C300 ROM + >253 + >254 * Verify that the card in the aux slot is actually there. + >255 +002215: 8D 01 C0 >256 STA SET80COL ;80-store on +002218: 8D 55 C0 >257 STA TXTPAGE2 +00221B: A9 EE >258 LDA #$EE +00221D: 8D 00 04 >259 STA $0400 +002220: 0A >260 ASL +002221: 0E 00 04 >261 ASL $0400 +002224: CD 00 04 >262 CMP $0400 +002227: D0 07 =2230 >263 BNE Maybee ;Branch if not there +002229: 4A >264 LSR +00222A: 4E 00 04 >265 LSR $0400 +00222D: CD 00 04 >266 CMP $0400 +002230: 8D 54 C0 >267 Maybee STA TXTPAGE1 ;Main memory +002233: 8D 00 C0 >268 STA CLR80COL ;80-store off +002236: F0 07 =223F >269 BEQ DoCard ;Branch if card is there +002238: AD 98 BF >270 LDA MachID ;Get machine id byte +00223B: 29 FD >271 AND #%11111101 ;Mask off 80-col bit +00223D: D0 05 =2244 >272 BNE DoCard1 + >273 + >274 * OK, the card's good. Leave it enabled and update the MachID + >275 +00223F: AD 98 BF >276 DoCard LDA MachID +002242: 09 02 >277 ORA #%00000010 +002244: 8D 98 BF >278 DoCard1 STA MachID +002247: AD 29 23 >279 NoSlot3ROM LDA cortLand ;Are we running on a cortland? +00224A: F0 11 =225D >280 BEQ NotCortLand ;Branch if not +00224C: A9 4C >281 LDA #$4C ;Enable clock routine by +00224E: 8D 06 BF >282 STA DateTime ; putting a JMP in front of clock vector +002251: A2 9C >283 LDX #284 LDY #>cortClock ; the cortland clock driver +002255: 20 F9 29 >285 JSR Reloc ; and relocate it +002258: A9 01 >286 LDA #$01 ;Denote clock present in MachID byte! +00225A: 0C 98 BF >287 TSB MachID ; bit 0 set to 1 +00225D: AD 66 22 >288 NotCortLand LDA SetupRTS ;Get value of setup entry point flag... +002260: F0 05 =2267 >289 BEQ NoRTS ;Branch if normal boot... +002262: AD 82 C0 >290 LDA RDROM2 ;Make sure the ROM is in for consistency... +002265: 60 >291 RTS ;Return to the caller at the setup entry point. ($2003/$2006) + >292 +002266: 00 >293 SetupRTS DB $00 ;0-Normal Boot, 1-Ret 2-Ret to GS/OS + >294 + =2267 >295 NoRTS EQU * + >296 ************************************************* + >297 * Now set prefix to boot device. + >298 * +002267: 20 00 BF >299 JSR GoPro ;First 'online'(was labled bootpfx,#en3) +00226A: C5 >300 DB $C5 +00226B: 1C 23 >301 DA olParm +00226D: B0 4B =22BA >302 BCS NoGood ;Branch if problems +00226F: AD 81 02 >303 LDA pnBuf+1 ;Get volume name length +002272: 29 0F >304 AND #$0F ;strip devnum +002274: F0 44 =22BA >305 BEQ NoGood ;Branch if error +002276: 1A >306 INC ;Add 1 for leading '/' +002277: 8D 80 02 >307 STA pnBuf ;Save prefix length +00227A: A9 2F >308 LDA #'/' ;Place leading '/' in path name buf +00227C: 8D 81 02 >309 STA pnBuf+1 +00227F: 20 00 BF >310 JSR GoPro ;Set prefix +002282: C6 >311 DB $C6 +002283: 20 23 >312 DA PfxParm +002285: B0 33 =22BA >313 BCS NoGood ;Branch if problems +002287: AA >314 TAX ;(A) = 0 after successful MLI call +002288: 86 14 >315 STX dst ;(Zerored) +00228A: A0 02 >316 LDY #$02 ;Read root directory into buffer +00228C: A9 0C >317 LDA #>ABuf ; starting at $0C00 +00228E: 85 15 >318 RdDirBlks STA dst+1 +002290: 8D 26 23 >319 STA dbBufr+1 ;(using a pointer in zero page also) +002293: 8C 27 23 >320 STY dbBlock +002296: 8E 28 23 >321 STX dbBlock+1 +002299: 20 00 BF >322 JSR GoPro +00229C: 80 >323 DB $80 ;Block read +00229D: 23 23 >324 DA dbParms +00229F: B0 19 =22BA >325 BCS NoGood + >326 +0022A1: A0 03 >327 LDY #$03 ;Get next block number from link +0022A3: B1 14 >328 LDA (dst),Y +0022A5: AA >329 TAX +0022A6: 88 >330 DEY +0022A7: 11 14 >331 ORA (dst),Y ;If both bytes are the same i.e. 0, 0 +0022A9: F0 0C =22B7 >332 BEQ ExitDirBlkRd ; then no more blocks of directory +0022AB: B1 14 >333 LDA (dst),Y +0022AD: A8 >334 TAY +0022AE: A5 15 >335 LDA dst+1 +0022B0: 18 >336 CLC +0022B1: 69 02 >337 ADC #$02 ;Add $200 to buffer pointer until +0022B3: C9 14 >338 CMP #$14 ; it points past $13FF +0022B5: 90 D7 =228E >339 BCC RdDirBlks ;If ok, read next block +0022B7: 4C 00 08 >340 ExitDirBlkRd JMP LoadIntrp ;All is well, load interpreter!!! + >341 +0022BA: 8D 82 C0 >342 NoGood STA RDROM2 ;Make sure rom is there +0022BD: 20 58 FC >343 JSR HOME ;Clear video +0022C0: A0 1D >344 LDY #mesLen ;Print message centered on screen +0022C2: B9 CD 22 >345 :loop LDA errMess,Y +0022C5: 99 AC 05 >346 STA SLIN11+4,Y +0022C8: 88 >347 DEY +0022C9: 10 F7 =22C2 >348 BPL :loop +0022CB: 30 FE =22CB >349 Hang BMI Hang + >350 + =001D >351 mesLen EQU 29 +0022CD: D2 E5 EC EF >352 errMess ASC "Relocation/Configuration Error" + >353 +0022EB: A0 23 >354 ReqEnh2 LDY #mes2Len +0022ED: B9 F8 22 >355 :loop2 LDA errMess2,Y ;Requires enhanced // +0022F0: 99 AA 06 >356 STA SLIN13+2,Y +0022F3: 88 >357 DEY +0022F4: 10 F7 =22ED >358 BPL :loop2 +0022F6: 30 FE =22F6 >359 Hang2 BMI Hang2 + >360 + >361 *------------------------------------------------- + =0023 >362 mes2Len EQU 35 +0022F8: D2 C5 D1 D5 >363 errMess2 ASC "REQUIRES ENHANCED APPLE IIE OR LATER" + >364 +00231C: 02 >365 olParm DB $02 +00231D: 60 >366 bUnit DB $60 ;Boot Unit +00231E: 81 02 >367 DA pnBuf+1 + >368 +002320: 01 >369 PfxParm DB $01 +002321: 80 02 >370 DA pnBuf + >371 + >372 * Dir block read + >373 +002323: 03 >374 dbParms DB $03 +002324: 00 >375 bbUnit DB $00 +002325: 00 00 >376 dbBufr DA $0000 +002327: 00 00 >377 dbBlock DW $0000 + >378 +002329: 00 >379 cortLand DB $00 ;Non-zero if IIgs +00232A: 00 >380 No80Col DB $00 ;Flag 40-col dispatcher to be installed + >381 + >382 *------------------------------------------------- + =03F0 >383 AuxGo EQU $03F0 ;Entry point to Aux LC driver call routine + =0000 >384 cZero EQU $00 + =0001 >385 cMove EQU $01 + =0004 >386 cReloc EQU $04 + =00FF >387 cDone EQU $FF + =0C23 >388 entLen EQU $0C23 + >389 + >390 * Code move tables are explained in file Reloc.s + >391 +00232B: 01 >392 tablIntrp DB cMove ;Move interpreter loader code & tables +00232C: 00 08 >393 DA LoadIntrp ;Code is address independent +00232E: D7 01 >394 DW pcLen +002330: A4 23 >395 DA LIcode + >396 +002332: 01 >397 Pg3Tbl DB cMove +002333: F0 03 >398 DA AuxGo ;was $3D6 +002335: 10 00 >399 DW $0010 ; and $002A +002337: 7B 25 >400 DA pg3Stuff + >401 +002339: 01 >402 DB cMove +00233A: 0A 00 >403 DA look ;dest addr +00233C: 02 00 >404 DW $0002 ;# of bytes to move +00233E: 14 00 >405 DA dst ;src addr + >406 +002340: 01 >407 DB cMove ;Move 128K test to zero page +002341: 80 00 >408 DA Test128 +002343: 46 00 >409 DW End128 +002345: DC 25 >410 DA Strt128 +002347: FF >411 DB cDone + >412 +002348: 01 >413 Disp64 DB cMove +002349: 00 D1 >414 DW $D100 ;lang card bank 2 +00234B: 00 03 >415 DW $0300 ;3 pages +00234D: 00 5A >416 DA SEL_0 ;$5A00 +00234F: FF >417 DB cDone + >418 +002350: 01 >419 DispBB DB cMove +002351: 00 D1 >420 DA $D100 ;lang card bank 2 +002353: 00 03 >421 DW $0300 +002355: 00 5D >422 DA SEL_1 ;$5D00 +002357: FF >423 DB cDone + >424 +002358: 01 >425 DispGS DB cMove +002359: 00 D1 >426 DA $D100 ;lang card bank 2 +00235B: 00 03 >427 DW $0300 +00235D: 00 60 >428 DA SEL_2 ;$6000 + >429 +00235F: 01 >430 DB cMove +002360: 00 10 >431 DA DispAdr ;$1000 +002362: 00 03 >432 DW $0300 +002364: 00 60 >433 DA SEL_2 ;$6000 +002366: FF >434 DB cDone + >435 + >436 *------------------------------------------------- + >437 * The following table is for moving the 64K version of + >438 * the MLI to its execution address. + >439 +002367: 01 >440 tabl64 DB cMove ;Relocate the interrupt/break/reset +002368: 9B FF >441 DA IntHandler ; handler and associated vectors +00236A: 65 00 >442 DW $0065 ;Number of bytes to relocate +00236C: 9B 2D >443 DA MLI_3 ;Source address of code to relocate + >444 +00236E: 01 >445 DB cMove ;Move preset 64K version of globals +00236F: 00 BF >446 DA Globals +002371: 00 01 >447 DW $0100 +002373: 00 2E >448 DA MLI_1 + >449 +002375: 00 >450 DB cZero ;Clear buffers/workspace +002376: 00 D7 >451 DA orig ;dest +002378: 00 07 >452 DW $0700 ;# of bytes to zero + >453 +00237A: 01 >454 DB cMove ;Move 64k version of MLI to language card +00237B: 00 DE >455 DA orig1 ;See #45..put rwts in lc bnk2 to make MLI_2 +00237D: 00 21 >456 DW $2100 ;MLI length +00237F: 00 30 >457 DA MLI_2 + >458 +002381: 01 >459 DB cMove ;Move 64K version of +002382: 00 D0 >460 DA RWTS ; Disk ][ routines +002384: 00 07 >461 DW $0700 +002386: 00 53 >462 DA XRW_0 +002388: FF >463 DB cDone ;Clock moved later + >464 +002389: 01 >465 TClkStuff DB cMove ;Lastly move/relocate thunderclock +00238A: 42 D7 >466 DA ClockBegin ; whether needed or not +00238C: 7D 00 >467 DW $007D +00238E: 00 2F >468 DW TCLOCK_0 +002390: 04 >469 DB cReloc ;Adjust slot addresses +002391: 42 D7 >470 DA ClockBegin +002393: 69 00 >471 DW $0069 +002395: 42 D7 >472 DA ClockBegin +002397: 00 >473 DB $00 + =239A >474 clock64 EQU *+2 +002398: C1 >475 DB $C1 ;Last changed by DevSrch to correct slot# +002399: C1 >476 DB $C1 +00239A: 00 >477 DB $00 +00239B: FF >478 DB cDone + >479 + >480 ********** see rev note #50 ********* + >481 +00239C: 01 >482 cortClock DB cMove ;Cortland clock relocating table +00239D: 42 D7 >483 DA ClockBegin ;Destination address +00239F: 7D 00 >484 DW $007D ;Length of 125 bytes +0023A1: 80 2F >485 DW CCLOCK_0 ;Source load address of driver +0023A3: FF >486 DB cDone + >487 + >488 ****************** see rev note #56 ************* + >489 * + >490 * Let's load and jsr to the appletalk configuaration file "atinit" + >491 * if it is found. If it is not found, just continue with the loading + >492 * and running of the ".SYSTEM" file. + >493 + =23A4 >494 LIcode EQU * +0023A4: 20 00 BF >495 JSR GoPro ;Make a get file info call to make +0023A7: C4 >496 DB $C4 ; atInit file is there and is +0023A8: 67 08 >497 DA gfiList ; of the proper file type +0023AA: 90 06 =23B2 >498 BCC GFI_ok ;Branch if call successful... +0023AC: C9 46 >499 CMP #fileNotFound ;Was error "file not found"? +0023AE: F0 2F =23DF >500 BEQ LoadInt +0023B0: D0 30 =23E2 >501 BNE ATLoadErr ;Otherwise fatal i/o error in loading atInit +0023B2: AD 6B 08 >502 GFI_ok LDA gfiType ;Now see if atInit file is of proper type... +0023B5: C9 E2 >503 CMP #$E2 ;Is it the correct file type? +0023B7: D0 29 =23E2 >504 BNE ATLoadErr ;Error if wrong file type! + >505 +0023B9: 20 00 BF >506 JSR GoPro ;Open atInit file +0023BC: C8 >507 DB $C8 +0023BD: 79 08 >508 DA atOpen ; parameter list... +0023BF: D0 21 =23E2 >509 BNE ATLoadErr ; branch if error... +0023C1: A9 9F >510 LDA #$9F ;39.75K +0023C3: 8D C4 09 >511 STA rdLen+1 +0023C6: 9C C3 09 >512 STZ rdLen +0023C9: 20 00 BF >513 JSR GoPro +0023CC: CA >514 DB $CA +0023CD: BF 09 >515 DA rdParm +0023CF: D0 11 =23E2 >516 BNE ATLoadErr +0023D1: 20 00 BF >517 JSR GoPro +0023D4: CC >518 DB $CC +0023D5: C7 09 >519 DA clParm +0023D7: D0 09 =23E2 >520 BNE ATLoadErr +0023D9: AD 82 C0 >521 LDA RDROM2 ;Put ROM on line for atInit.... +0023DC: 20 00 20 >522 JSR $2000 ;Call the atInit routine to set up appletalk stuff +0023DF: 4C 86 08 >523 LoadInt JMP GoLoadInt ;Go execute the .SYSTEM file + >524 +0023E2: AE F0 23 >525 ATLoadErr LDX atErr +0023E5: BD F0 23 >526 :1 LDA atErr,X +0023E8: 9D A8 07 >527 STA SLIN15,X +0023EB: CA >528 DEX +0023EC: D0 F7 =23E5 >529 BNE :1 +0023EE: F0 FE =23EE >530 ATerrHang BEQ ATerrHang +0023F0: 1A D5 EE E1 >531 atErr STR "Unable to load ATInit file" + >532 + =0867 >533 gfiList EQU *-LIcode+LoadIntrp +00240B: 0A >534 DB $0A ;Parameter count +00240C: 7F 08 >535 DA atInitName ;Pointer to "atinit" file name +00240E: 00 >536 DB $00 ;access + =086B >537 gfiType EQU *-LIcode+LoadIntrp +00240F: 00 >538 DB $00 ;File type +002410: 00 00 00 00 >539 DS 13,0 ;Space for rest of parameters... + >540 + =0879 >541 atOpen EQU *-LIcode+LoadIntrp +00241D: 03 >542 DB $03 +00241E: 7F 08 >543 DW atInitName ;Pointer to "atinit" file name +002420: 00 14 >544 DA $1400 ;Address of I/O buffer +002422: 01 >545 DB $01 ;Reference number hard coded since no other files + >546 + =087F >547 atInitName EQU *-LIcode+LoadIntrp +002423: 06 E1 F4 E9 >548 STR "atinit" ;Name of appletalk config file + >549 + =0886 >550 GoLoadInt EQU *-LIcode+LoadIntrp +00242A: A9 0C >551 LDA #>ABuf ;Search directory already in +00242C: 85 11 >552 STA idxl+1 ; memory between $0C00 & $13FF +00242E: A9 04 >553 LDA #554 BNE AddEntLen ;Always +002432: A5 10 >555 NxtEntry LDA idxl ;Calc next entry posn +002434: 18 >556 AddEntLen CLC +002435: 6D 23 0C >557 ADC entLen ;Bump to next entry address +002438: 85 10 >558 STA idxl +00243A: B0 15 =2451 >559 BCS PageCros ;Branch if page cross +00243C: 6D 23 0C >560 ADC entLen ;Test for end of block +00243F: 90 12 =2453 >561 BCC NoCros ;Branch if definitely not page cross +002441: A5 11 >562 LDA idxl+1 +002443: 4A >563 LSR ;End of block? +002444: 90 0D =2453 >564 BCC NoCros ;Branch if not +002446: C9 09 >565 CMP #$09 ;End of directory? +002448: D0 03 =244D >566 BNE :1 ;Branch if an interpreter file +00244A: 4C 42 09 >567 JMP JustQuit ;No interpreter file + >568 +00244D: A9 04 >569 :1 LDA #$04 ;Reset index to first entry in next block +00244F: 85 10 >570 STA idxl +002451: E6 11 >571 PageCros INC idxl+1 ;Bump to next page +002453: A0 10 >572 NoCros LDY #$10 ;First off, check file type +002455: A9 FF >573 LDA #$FF ;Must be ProDOS SYS file +002457: 51 10 >574 EOR (idxl),Y +002459: D0 D7 =2432 >575 BNE NxtEntry ;Branch if not +00245B: A8 >576 TAY ;else check to see if active +00245C: B1 10 >577 LDA (idxl),Y ;(Y)=0 (stortype/namelen) +00245E: F0 D2 =2432 >578 BEQ NxtEntry ;Branch if deleted file +002460: 29 0F >579 AND #$0F ;Strip file 'kind' +002462: 8D 80 02 >580 STA pnBuf ;Save name's length +002465: C9 08 >581 CMP #$08 ;Must be at least 'x.SYSTEM' +002467: 90 C9 =2432 >582 BCC NxtEntry ;Otherwise, ignore it + >583 +002469: A8 >584 TAY ;Compare last 7 characters for '.SYSTEM' +00246A: A2 06 >585 LDX #7-1 +00246C: B1 10 >586 LookIntrp LDA (idxl),Y +00246E: 5D D0 09 >587 EOR iterP,X +002471: 0A >588 ASL +002472: D0 BE =2432 >589 BNE NxtEntry ;Branch if something else +002474: 88 >590 DEY +002475: CA >591 DEX +002476: 10 F4 =246C >592 BPL LookIntrp + >593 +002478: A0 00 >594 LDY #$00 ;Move name to pathname buffer +00247A: C8 >595 MovIntrp INY +00247B: B1 10 >596 LDA (idxl),Y +00247D: 99 80 02 >597 STA pnBuf,Y +002480: 09 80 >598 ORA #$80 ;Make it printable in case of error +002482: 99 A0 09 >599 STA ioMess+$11,Y +002485: CC 80 02 >600 CPY pnBuf ;All characters moved? +002488: D0 F0 =247A >601 BNE MovIntrp ;Nope + >602 +00248A: A9 A0 >603 LDA #" " ;Save a space after name +00248C: 99 A1 09 >604 STA ioMess+$12,Y +00248F: 98 >605 TYA ;Update error message length +002490: 69 13 >606 ADC #$13 ;(carry was set) +002492: 8D B3 09 >607 STA ioErrLen +002495: 20 00 BF >608 JSR GoPro ;Open interpreter file +002498: C8 >609 DB $C8 +002499: B4 09 >610 DA opParm +00249B: D0 4F =24EC >611 BNE BadLoad +00249D: 20 00 BF >612 JSR GoPro ;Get file's length +0024A0: D1 >613 DB $D1 +0024A1: BA 09 >614 DA efParm +0024A3: D0 47 =24EC >615 BNE BadLoad + >616 +0024A5: AD BE 09 >617 LDA eof+2 ;Make sure file will fit +0024A8: D0 5C =2506 >618 BNE TooLong +0024AA: AD BD 09 >619 LDA eof+1 +0024AD: C9 9F >620 CMP #$9F ;Max size is 39.75K +0024AF: B0 55 =2506 >621 BCS TooLong +0024B1: 8D C4 09 >622 STA rdLen+1 +0024B4: AD BC 09 >623 LDA eof ;Read entire file +0024B7: 8D C3 09 >624 STA rdLen +0024BA: 20 00 BF >625 JSR GoPro +0024BD: CA >626 DB $CA +0024BE: BF 09 >627 DA rdParm +0024C0: F0 06 =24C8 >628 BEQ GoClos ;Branch if successful read +0024C2: C9 56 >629 CMP #badBufErr ;Memory conflict? +0024C4: F0 40 =2506 >630 BEQ TooLong +0024C6: D0 24 =24EC >631 BNE BadLoad ;Report i/o error +0024C8: 20 00 BF >632 GoClos JSR GoPro +0024CB: CC >633 DB $CC +0024CC: C7 09 >634 DA clParm +0024CE: D0 1C =24EC >635 BNE BadLoad ;(branch never, we hope) + >636 + >637 *************************************************** + >638 * If we are booting on a //c and an escape is in the keyboard buffer + >639 * then clear it so we dont interfere with start application + >640 * (pizza accelerator chip requires ESC to shift speed down) + >641 +0024D0: AD 41 09 >642 LDA cFlag-LIcode+LoadIntrp ;Booting on a 2c? +0024D3: F0 0A =24DF >643 BEQ Going ;Branch if not +0024D5: AD 00 C0 >644 LDA KBD ;Fetch last key in board (pending or not) +0024D8: C9 9B >645 CMP #$9B ;ESCAPE character? (with bit 7 on) +0024DA: D0 03 =24DF >646 BNE Going ;Branch if not +0024DC: 8D 10 C0 >647 STA KBDSTROBE ;Clear keyboard strobe + >648 +0024DF: AD 82 C0 >649 Going LDA RDROM2 ;Enable Motherboard ROM +0024E2: 4C 00 20 >650 JMP $2000 ;GoInterP + >651 +0024E5: 00 >652 cFlag DB $00 ;=1 if an apple 2c + >653 + >654 *------------------------------------------------- + >655 * Transfer control to the dispatch/selector + >656 + =0942 >657 JustQuit EQU *-LIcode+LoadIntrp +0024E6: 20 00 BF >658 JSR GoPro +0024E9: 65 >659 DB $65 +0024EA: C9 09 >660 DW quitParm + >661 +0024EC: AC B3 09 >662 BadLoad LDY ioErrLen ;Center the bad news +0024EF: A9 27 >663 LDA #$27 ;Report no interpreter +0024F1: 38 >664 SEC +0024F2: ED B3 09 >665 SBC ioErrLen +0024F5: 4A >666 LSR +0024F6: 6D B3 09 >667 ADC ioErrLen +0024F9: AA >668 TAX +0024FA: B9 8F 09 >669 :NoItrp LDA ioMess,Y +0024FD: 9D A8 07 >670 STA SLIN15,X +002500: CA >671 DEX +002501: 88 >672 DEY +002502: 10 F6 =24FA >673 BPL :NoItrp +002504: 30 0B =2511 >674 BMI Hang10 + >675 +002506: A0 1E >676 TooLong LDY #$1E +002508: B9 6F 09 >677 :loop LDA lgMess,Y +00250B: 99 AD 07 >678 STA SLIN15+5,Y +00250E: 88 >679 DEY +00250F: 10 F7 =2508 >680 BPL :loop +002511: 30 FE =2511 >681 Hang10 BMI Hang10 + >682 + >683 *------------------------------------------------- + =096F >684 lgMess EQU *-LIcode+LoadIntrp +002513: AA AA A0 A0 >685 ASC "** System program too large **" + =098F >686 ioMess EQU *-LIcode+LoadIntrp +002533: AA AA A0 D5 >687 ASC "** Unable to load X.System *********" + =09B3 >688 ioErrLen EQU *-LIcode+LoadIntrp +002557: 00 >689 DB $00 + >690 + =09B4 >691 opParm EQU *-LIcode+LoadIntrp +002558: 03 >692 DB $03 +002559: 80 02 >693 DA pnBuf ;pathname +00255B: 00 14 >694 DA $1400 +00255D: 01 >695 DB $01 + >696 + =09BA >697 efParm EQU *-LIcode+LoadIntrp +00255E: 02 >698 DB $02 +00255F: 01 >699 DB $01 + =09BC >700 eof EQU efParm+2 +002560: 00 00 00 >701 HEX 000000 + >702 + =09BF >703 rdParm EQU *-LIcode+LoadIntrp +002563: 04 >704 DB $04 +002564: 01 >705 DB $01 +002565: 00 20 >706 DA $2000 + =09C3 >707 rdLen EQU rdParm+4 +002567: 00 00 >708 DW $0000 +002569: 00 00 >709 DW $0000 + >710 + =09C7 >711 clParm EQU *-LIcode+LoadIntrp +00256B: 01 >712 DB $01 +00256C: 00 >713 DB $00 + >714 + =09C9 >715 quitParm EQU *-LIcode+LoadIntrp +00256D: 04 >716 DB $04 +00256E: 00 >717 DB $00 ;=$EE for enhanced quit +00256F: 00 00 >718 DW $0000 ;addr of pathname +002571: 00 >719 DB $00 ;reserved +002572: 00 00 >720 DW $0000 ;reserved + >721 + =09D0 >722 iterP EQU *-LIcode+LoadIntrp +002574: AE D3 D9 D3 >723 ASC ".SYSTEM" + =01D7 >724 pcLen EQU *-LIcode + >725 + =257B >726 pg3Stuff EQU * ;This stuff goes on page 3 + >727 * ------------------- see rev note 15 -------------------------- + >728 * + >729 * Locate between vectors in page 3 starting at $3F0 + >730 * + >731 * Note: since this is treated as a subroutine from the MLI, + >732 * nothing may use the stack in main ram area!! + >733 * + >734 * x = 5 from calling routine to move parameter bytes in the call + >735 +00257B: 59 FA >736 DW $FA59 ;mon_Break +00257D: 59 FF >737 DW $FF59 ;mon_Reset +00257F: 5A >738 DB $5A ;Powerup byte +002580: 4C 59 FF >739 JMP OLDRST ;'&' vector +002583: 4C 59 FF >740 JMP OLDRST ;mon_ctrl-Y vector +002586: 00 40 00 >741 DB $00,$40,$00 ;mon_nmi +002589: EB BF >742 DA IrqEnt ;Interrupt vector to global page + >743 +00258B: AD 8B C0 >744 LC1In LDA LCBANK1 ;Swap LC bank1 in +00258E: AD 8B C0 >745 LDA LCBANK1 +002591: 60 >746 RTS + >747 + >748 *------------------------------------------------- +002592: 64 0C >749 WhichROM STZ apple ;Assume standard apple ][ first +002594: AE B3 FB >750 LDX VERSION ;Look at the approved location... +002597: E0 38 >751 CPX #$38 ;Apple ][? (actually is it autostart ROM?) +002599: F0 23 =25BE >752 BEQ TestLCRAM ;Yes +00259B: A9 80 >753 LDA #$80 ;else try for apple //e +00259D: E0 06 >754 CPX #$06 +00259F: F0 1B =25BC >755 BEQ MuchRAM ;Yes, //e +0025A1: A9 40 >756 LDA #$40 ;If that fails, try ][+ +0025A3: E0 EA >757 CPX #$EA ;Must be one of these values... +0025A5: D0 0F =25B6 >758 BNE WhatsIt +0025A7: AE 1E FB >759 LDX $FB1E ;If it passes as ][+, then +0025AA: E0 AD >760 CPX #$AD ; it might be /// in emulation +0025AC: F0 0E =25BC >761 BEQ MuchRAM +0025AE: A9 D0 >762 LDA #$D0 ;Mark it as 48k /// emulation! +0025B0: E0 8A >763 CPX #$8A ; if it passes the test +0025B2: D0 02 =25B6 >764 BNE WhatsIt ;Branch always, well, maybe +0025B4: 38 >765 NSMach SEC ;48K not allowed so apple /// +0025B5: 60 >766 RTS ; emulation is not sufficient memory + >767 +0025B6: A9 02 >768 WhatsIt LDA #$02 ;Machine unknown if we land here +0025B8: 91 14 >769 STA (dst),Y +0025BA: D0 1D =25D9 >770 BNE FindRAM ;branch always + >771 +0025BC: 85 0C >772 MuchRAM STA apple ;Save ROM id +0025BE: 20 8B 25 >773 TestLCRAM JSR LC1In ;Test for the presence of +0025C1: A9 AA >774 LDA #$AA ; 'language' card RAM +0025C3: 8D 00 D0 >775 STA $D000 +0025C6: 4D 00 D0 >776 EOR $D000 ;If it is there, result is zero +0025C9: D0 E9 =25B4 >777 BNE NSMach ;Branch if it is not +0025CB: 4E 00 D0 >778 LSR $D000 ;else check twice just to be sure +0025CE: A9 55 >779 LDA #$55 +0025D0: 4D 00 D0 >780 EOR $D000 +0025D3: D0 DF =25B4 >781 BNE NSMach ;Non-standard machine +0025D5: A9 20 >782 LDA #$20 ;Indicate at LC RAM available +0025D7: 05 0C >783 ORA apple +0025D9: 4C 80 00 >784 FindRAM JMP Test128 ;Go test for 128K + >785 + >786 *------------------------------------------------- + >787 * The code below is moved to $80 before execution + >788 + =0080 >789 Test128 EQU $80 ;Use zpage for this routine +0025DC: 85 0C >790 Strt128 STA apple ;Save accumulated value +0025DE: 10 35 =2615 >791 BPL Not128 ;Branch if sure it's less than 128K +0025E0: A9 EE >792 LDA #$EE ;First try storing in Aux Mem +0025E2: 8D 05 C0 >793 STA WRCARDRAM ;Write to aux while on main ZPage +0025E5: 8D 03 C0 >794 STA RDCARDRAM ;Set to read aux ram +0025E8: 8D 00 0C >795 STA $0C00 ;Check for sparse mem mapping +0025EB: 8D 00 08 >796 STA $0800 +0025EE: AD 00 0C >797 LDA $0C00 ;See if sparse memory -same value +0025F1: C9 EE >798 CMP #$EE ; 1K away +0025F3: D0 0E =2603 >799 BNE NoAux +0025F5: 0E 00 0C >800 ASL $0C00 ;May be sparse mem so change value +0025F8: 0A >801 ASL ; & see what happens +0025F9: CD 00 0C >802 CMP $0C00 +0025FC: D0 05 =2603 >803 BNE NoAux +0025FE: CD 00 08 >804 CMP $0800 +002601: D0 03 =2606 >805 BNE AuxMem +002603: 38 >806 NoAux SEC ;Sparse mapping so no aux mem +002604: B0 01 =2607 >807 BCS Back2Main +002606: 18 >808 AuxMem CLC ;There is aux mem +002607: 8D 04 C0 >809 Back2Main STA WRMAINRAM ;Switch back to write main ram +00260A: 8D 02 C0 >810 STA RDMAINRAM ;Switch back main ram read +00260D: B0 06 =2615 >811 BCS Not128 ;Branch if not 128K +00260F: A5 0C >812 LDA apple ;else update identity of machine +002611: 09 30 >813 ORA #$30 ;Indicate 128K present +002613: 85 0C >814 STA apple +002615: A5 0B >815 Not128 LDA look+1 ;Futs with pointer for apple test +002617: 38 >816 SEC +002618: E9 05 >817 SBC #$05 ;Should result in $FB if zpage is ok +00261A: 85 0B >818 STA look+1 +00261C: B0 02 =2620 >819 BCS *+4 ;(to the CLC) +00261E: C6 0A >820 DEC look +002620: 18 >821 CLC +002621: 60 >822 RTS + =0046 >823 End128 EQU *-Strt128 ;Byte count for routine move to zpage + 20 PUT mli.src/DevSrch + >1 *********************************************************** +002622: AD 30 C0 >2 Greet LDA SPKR ;Give a 'click' +002625: 8D 0C C0 >3 STA CLR80VID ;Disable 80 columns (rev-e) +002628: 8D 00 C0 >4 STA CLR80COL ;Disable '80store' +00262B: 20 84 FE >5 JSR SetNorm +00262E: 20 2F FB >6 JSR Init +002631: 20 93 FE >7 JSR SetVid +002634: 20 89 FE >8 JSR SetKBD +002637: D8 >9 CLD + >10 + >11 * Note: interrupts are not turn off + >12 +002638: 20 58 FC >13 JSR HOME ;Clear screen +00263B: A2 07 >14 LDX #p8VerMsg-apple2Msg-1 ;Move greeting to screen +00263D: BD 09 20 >15 :loop1 LDA apple2Msg,X ;"apple ii" +002640: 9D B8 04 >16 STA SLIN09+20-4,X ;$4A8 starts the line +002643: CA >17 DEX +002644: 10 F7 =263D >18 BPL :loop1 + >19 +002646: A2 1D >20 LDX #blanks-p8VerMsg-1 +002648: BD 11 20 >21 :loop2 LDA p8VerMsg,X ;"prodos (version) (date)" +00264B: 9D AD 05 >22 STA SLIN11+20-grtLnZ,X +00264E: CA >23 DEX +00264F: 10 F7 =2648 >24 BPL :loop2 + >25 +002651: A2 0B >26 LDX #cpyRhtMsg-blanks-1 +002653: BD 2F 20 >27 :loop3 LDA blanks,X ;(blank line) +002656: 9D B6 06 >28 STA SLIN13+20-grtLnZZ,X +002659: CA >29 DEX +00265A: 10 F7 =2653 >30 BPL :loop3 + >31 +00265C: A2 26 >32 LDX #rsvdMsg-cpyRhtMsg-1 +00265E: BD 3B 20 >33 :loop4 LDA cpyRhtMsg,X ;Copyright Message +002661: 9D 50 07 >34 STA SLIN22,X +002664: CA >35 DEX +002665: 10 F7 =265E >36 BPL :loop4 + >37 +002667: A2 13 >38 LDX #endGreetMsg-rsvdMsg-1 +002669: BD 62 20 >39 :loop5 LDA rsvdMsg,X ;Rights message +00266C: 9D DA 07 >40 STA SLIN23+20-grtLnZZZ,X +00266F: CA >41 DEX +002670: 10 F7 =2669 >42 BPL :loop5 + >43 +002672: 38 >44 SEC +002673: 20 1F FE >45 JSR IDroutine +002676: B0 05 =267D >46 BCS NotIIgs ;Not IIgs +002678: A9 80 >47 LDA #$80 +00267A: 1C 29 C0 >48 TRB NEWVIDEO ;Enable SuperHires +00267D: AD 30 C0 >49 NotIIgs LDA SPKR +002680: 60 >50 RTS + >51 *************************************************** + >52 * + >53 * This routine finds all disk devices plugged into the + >54 * system's slots that follow apple's disk id convention. + >55 * The routine sets up the address and device table in + >56 * ProDOS's system global page. 13-sector disk ]['s are + >57 * not configured since they may not function properly in + >58 * the 16 sector mode... + >59 * + >60 * Profiles, and other intelligent devices, are expected to + >61 * have ROMs containing the disk I/O drivers. + >62 * + >63 * This routine was revved 8/21/86 to make sure that correct number + >64 * of smartport devices are installed, and that disk ][s are always + >65 * searched last by placing them at the end of the list. Disk ][ unit + >66 * numbers are stacked at the end of the device table, while regular + >67 * devices are stacked at the beginning. After all slots have been + >68 * searched the two lists are combined. see note 60. + >69 * + =2681 >70 statusList EQU * + =2681 >71 spDevStatus EQU * +002681: 00 00 00 00 >72 numDevices DS 8,0 ;Eight bytes for smartport call + >73 + =2689 >74 maxUnitP1 EQU * ;# of units connected to SP+1 +002689: 00 00 >75 driverAdr DA $0000 +00268B: 00 >76 dsk2Idx DB $00 +00268C: 00 >77 diskInSlot2 DB $00 ;msb set if drive in slot 2 + >78 + >79 *------------------------------------------------- +00268D: 64 14 >80 DevSrch STZ dst +00268F: 64 15 >81 STZ dst+1 +002691: 64 10 >82 STZ indrcn ;Set up for search +002693: A2 FF >83 LDX #$FF +002695: 8E 31 BF >84 STX DevCnt ;Device count=none +002698: A9 0E >85 LDA #14 ;Start disk ][ area at the end of devlist +00269A: 8D 8B 26 >86 STA dsk2Idx + >87 *********************** see note #65 *********************** + >88 * + >89 * Make a quick check of slot 2. If there is a disk card there, + >90 * clear the msb of diskInSlot2. This will limit the number of + >91 * devices in any slot 5 smartport card to 2. + >92 * +00269D: A9 C2 >93 LDA #$C2 +00269F: 85 11 >94 STA indrcn+1 ;Check slot 2 +0026A1: 20 F1 28 >95 JSR CmpID ;Is there a disk card in slot 2? +0026A4: 6E 8C 26 >96 ROR diskInSlot2 ;Clear msb if so, set otherwise +0026A7: A9 C7 >97 LDA #$C7 ;Search slots from high to low +0026A9: 85 11 >98 STA indrcn+1 + =26AB >99 FindDsk EQU * + >100 + >101 ***************** code here became a subroutine **************** + >102 ************************* see note #65 ************************* + >103 +0026AB: 20 F1 28 >104 JSR CmpID +0026AE: B0 5C =270C >105 BCS NxtDsk ;Carry set means no card this slot +0026B0: B1 10 >106 LDA (indrcn),Y ;Check last byte of $Cn ROM +0026B2: F0 25 =26D9 >107 BEQ DiskII ;If =00 then 16 sector disk ][ +0026B4: C9 FF >108 CMP #$FF ;If =ff then 13 sector disk ][ +0026B6: B0 54 =270C >109 BCS NxtDsk ;Ignore if 13 sector boot ROM +0026B8: 8D 89 26 >110 STA driverAdr ;else, assume it's an intelligent disk for now. + >111 +0026BB: A0 07 >112 LDY #$07 ;Check for a SmartPort device +0026BD: B1 10 >113 LDA (indrcn),Y +0026BF: D0 03 =26C4 >114 BNE NoSPort +0026C1: 4C 6E 28 >115 JMP SmartPort + >116 + >117 * Ref ProDOS Tech Ref (ROM Code conventions) + >118 +0026C4: A0 FE >119 NoSPort LDY #$FE ;Get attributes byte & verify it +0026C6: B1 10 >120 LDA (indrcn),Y +0026C8: 29 03 >121 AND #$03 ; provides read, write, and status calls +0026CA: C9 03 >122 CMP #$03 ; (should be #$07) +0026CC: 38 >123 SEC ;Assume it is a bozo brand disk... +0026CD: D0 3D =270C >124 BNE NxtDsk +0026CF: 20 E6 28 >125 JSR SetDevID +0026D2: 18 >126 CLC +0026D3: 08 >127 PHP ;Remember that it's not a disk ][ +0026D4: 4A >128 LSR ;Move # of units (0=1, 1=2) to carry +0026D5: A5 11 >129 LDA indrcn+1 ;(driverAdr)=low entry addr, save hi addr +0026D7: D0 0D =26E6 >130 BNE ADevice ;Always + >131 +0026D9: 85 12 >132 DiskII STA devID ;Disk ]['s have null attributes +0026DB: 38 >133 SEC +0026DC: 08 >134 PHP ;Remember it's a disk ][ +0026DD: AD 02 28 >135 LDA D2BlkIO +0026E0: 8D 89 26 >136 STA driverAdr +0026E3: AD 03 28 >137 LDA D2BlkIO+1 + >138 + >139 * The carry is already set telling InstallDev + >140 * to install two devices for disk ][s. + >141 +0026E6: 8D 8A 26 >142 ADevice STA driverAdr+1 +0026E9: 20 3E 28 >143 JSR InstallDev ;Install one or two devices this slot +0026EC: 28 >144 PLP ;Get back if it's disk ][ +0026ED: 90 1C =270B >145 BCC NoDisk2 +0026EF: CA >146 DEX ;Move the list pointer back +0026F0: CA >147 DEX ;(installdev left X set) +0026F1: 8E 31 BF >148 STX DevCnt +0026F4: CE 8B 26 >149 DEC dsk2Idx ;Increase the disk ][ index +0026F7: CE 8B 26 >150 DEC dsk2Idx +0026FA: AC 8B 26 >151 LDY dsk2Idx +0026FD: E8 >152 INX ;Increase X in case =$FF +0026FE: BD 33 BF >153 LDA DevLst+1,X +002701: 99 32 BF >154 STA DevLst,Y +002704: BD 32 BF >155 LDA DevLst,X +002707: 99 33 BF >156 STA DevLst+1,Y +00270A: CA >157 DEX ;Back to DevCnt again + >158 + =270B >159 NoDisk2 EQU * +00270B: 18 >160 NxtDsk2 CLC +00270C: 20 95 27 >161 NxtDsk JSR SlotROM ;Test for clock & other devices +00270F: C6 11 >162 DEC indrcn+1 ;Set up for next lower slot +002711: A5 11 >163 LDA indrcn+1 ;Have all slots been checked? +002713: 29 07 >164 AND #$07 +002715: D0 94 =26AB >165 BNE FindDsk ;No + >166 +002717: 20 19 29 >167 JSR ScanAll4SP ;Mirror smartport devices + >168 + >169 * Now copy the disk ][ list to the end of the regular list + >170 * start by making the device count include disk ][s + >171 +00271A: AE 31 BF >172 LDX DevCnt ;Load up current devcnt-1 +00271D: A9 0E >173 LDA #14 +00271F: 38 >174 SEC +002720: ED 8B 26 >175 SBC dsk2Idx +002723: F0 22 =2747 >176 BEQ D2Snone ;If there were no disk ][s, forget it +002725: 18 >177 CLC +002726: 6D 31 BF >178 ADC DevCnt ;Sum of disk ][s and others +002729: 8D 31 BF >179 STA DevCnt +00272C: E8 >180 INX ;Move to open space in regular list + >181 +00272D: A0 0D >182 LDY #13 ;First disk ][ entry +00272F: B9 32 BF >183 MLab LDA DevLst,Y +002732: 48 >184 PHA +002733: BD 32 BF >185 LDA DevLst,X +002736: 99 32 BF >186 STA DevLst,Y +002739: 68 >187 PLA +00273A: 9D 32 BF >188 STA DevLst,X +00273D: E8 >189 INX +00273E: 88 >190 DEY +00273F: 8C 8B 26 >191 STY dsk2Idx ;Use as a temp +002742: EC 8B 26 >192 CPX dsk2Idx +002745: 90 E8 =272F >193 BCC MLab ;Continue 'til indices cross... + >194 +002747: A0 00 >195 D2Snone LDY #$00 +002749: AE 31 BF >196 LDX DevCnt ;Now change the device order +00274C: BD 32 BF >197 :loop LDA DevLst,X ; so that the boot device +00274F: 48 >198 PHA +002750: 29 7F >199 AND #$7F +002752: 4D 30 BF >200 EOR DevNum ; will have highest priority +002755: 0A >201 ASL +002756: D0 02 =275A >202 BNE :1 +002758: 68 >203 PLA +002759: C8 >204 INY +00275A: CA >205 :1 DEX +00275B: 10 EF =274C >206 BPL :loop + >207 +00275D: AE 31 BF >208 LDX DevCnt ;Now reverse order of search, hi to lo +002760: 98 >209 TYA ;Was boot device found? +002761: F0 14 =2777 >210 BEQ :2 ;No +002763: AD 30 BF >211 LDA DevNum ;Make boot device first in search order +002766: 9D 32 BF >212 STA DevLst,X +002769: CA >213 DEX +00276A: 30 12 =277E >214 BMI DevSrchEnd ;Branch if only one device +00276C: 88 >215 DEY ;Is this a 2-drive device? +00276D: F0 08 =2777 >216 BEQ :2 ;No +00276F: 49 80 >217 EOR #$80 ;Make boot device, drive 2 next +002771: 9D 32 BF >218 STA DevLst,X +002774: CA >219 DEX +002775: 30 07 =277E >220 BMI DevSrchEnd ;Branch if only one device, 2 drives +002777: 68 >221 :2 PLA +002778: 9D 32 BF >222 STA DevLst,X +00277B: CA >223 DEX +00277C: 10 F9 =2777 >224 BPL :2 + >225 +00277E: 20 14 28 >226 DevSrchEnd JSR Fndtrd ;Save accumuated machine ID +002781: F0 04 =2787 >227 BEQ WhosIt +002783: 8D 98 BF >228 STA MachID +002786: 60 >229 RTS +002787: 4C B6 25 >230 WhosIt JMP WhatsIt + >231 +00278A: 05 12 >232 staDrv ORA devID ;Combine with attributes (0SSS IIII) +00278C: AE 31 BF >233 LDX DevCnt +00278F: E8 >234 INX ;Put device number into device list +002790: 9D 32 BF >235 STA DevLst,X +002793: 0A >236 ASL ;Now form drive 2 device number, if any (SSSI III0) +002794: 60 >237 RTS + >238 +002795: 90 5C =27F3 >239 SlotROM BCC IsROM ;Branch if disk drive +002797: A0 06 >240 LDY #$06 ;Test this slot for clock card +002799: B1 10 >241 :1 LDA (indrcn),Y +00279B: D9 04 28 >242 CMP clkID,Y ;Branch if not clock +00279E: D0 1A =27BA >243 BNE NotClk +0027A0: 88 >244 DEY +0027A1: 88 >245 DEY +0027A2: 10 F5 =2799 >246 BPL :1 + >247 +0027A4: A5 11 >248 LDA indrcn+1 ;transfer high slot addr minus $c1 (default) +0027A6: E9 C1 >249 SBC #$C1 ; to relocate references to clock ROM +0027A8: 8D 9A 23 >250 STA clock64 +0027AB: A9 4C >251 LDA #$4C ;Also enable jump vector in globals +0027AD: 8D 06 BF >252 STA DateTime +0027B0: A5 0C >253 LDA apple ;Mark clock as present +0027B2: F0 CA =277E >254 BEQ DevSrchEnd +0027B4: 09 01 >255 ORA #$01 +0027B6: 85 0C >256 STA apple +0027B8: D0 39 =27F3 >257 BNE IsROM ;Always + >258 +0027BA: A0 05 >259 NotClk LDY #$05 ;Test for 80-col card +0027BC: B1 10 >260 LDA (indrcn),Y ;One byte at a time +0027BE: C9 38 >261 CMP #$38 +0027C0: D0 22 =27E4 >262 BNE NotCons +0027C2: A0 07 >263 LDY #$07 ;Test values are same as Pascal's +0027C4: B1 10 >264 LDA (indrcn),Y +0027C6: C9 18 >265 CMP #$18 +0027C8: D0 1A =27E4 >266 BNE NotCons +0027CA: A0 0B >267 LDY #$0B +0027CC: B1 10 >268 LDA (indrcn),Y +0027CE: 3A >269 DEC +0027CF: D0 13 =27E4 >270 BNE NotCons +0027D1: C8 >271 INY +0027D2: B1 10 >272 LDA (indrcn),Y +0027D4: 29 F0 >273 AND #$F0 ;Mask off low nibble +0027D6: C9 80 >274 CMP #$80 ;Generic for 80-col card +0027D8: D0 0A =27E4 >275 BNE NotCons +0027DA: A5 0C >276 LDA apple +0027DC: F0 A0 =277E >277 BEQ DevSrchEnd +0027DE: 09 02 >278 ORA #$02 +0027E0: 85 0C >279 STA apple ;Mark config for 80 col. present +0027E2: D0 0F =27F3 >280 BNE IsROM +0027E4: A2 00 >281 NotCons LDX #$00 ;Test for any ROM +0027E6: B2 10 >282 LDA (indrcn) +0027E8: C9 FF >283 CMP #$FF ;Test for apple /// non slot +0027EA: F0 15 =2801 >284 BEQ NoROM ;Branch if invalid ROM + >285 +0027EC: D2 10 >286 TestROM CMP (indrcn) ;Look for floating bus +0027EE: D0 11 =2801 >287 BNE NoROM +0027F0: E8 >288 INX ;Loop 256 times +0027F1: D0 F9 =27EC >289 BNE TestROM + >290 +0027F3: A5 11 >291 IsROM LDA indrcn+1 ;Mark a bit in slot byte +0027F5: 29 07 >292 AND #$07 ; to indicate rom present +0027F7: AA >293 TAX +0027F8: BD 0C 28 >294 LDA SltBit,X +0027FB: 0D 99 BF >295 ORA SltByt +0027FE: 8D 99 BF >296 STA SltByt +002801: 60 >297 NoROM RTS + >298 + >299 *------------------------------------------------- +002802: 00 D0 >300 D2BlkIO DA RWTS ;Addr of Disk ][ driver rtn + =2804 >301 diskID EQU * +002804: 08 20 28 00 >302 clkID HEX 082028005803703C +00280C: 00 02 04 08 >303 SltBit HEX 0002040810204080 + >304 + >305 *------------------------------------------------- + >306 * Compute autostart ROM checksum + >307 +002814: 18 >308 Fndtrd CLC +002815: AC 0C 28 >309 LDY SltBit ;Should be zero +002818: B1 0A >310 :loop LDA (look),Y ;Point to $FB09 ("APPLE II" in ROM) +00281A: 29 DF >311 AND #%11011111 ;To uppercase +00281C: 6D 0C 28 >312 ADC SltBit +00281F: 8D 0C 28 >313 STA SltBit +002822: 2E 0C 28 >314 ROL SltBit +002825: C8 >315 INY +002826: CC 0F 28 >316 CPY SltBit+3 ;Do for 8 bytes +002829: D0 ED =2818 >317 BNE :loop + >318 +00282B: 98 >319 TYA ;(A)=$08 now +00282C: 0A >320 ASL +00282D: 0A >321 ASL +00282E: 0A >322 ASL +00282F: 0A >323 ASL +002830: A8 >324 TAY +002831: 4D 0C 28 >325 EOR SltBit ;Turn msb on +002834: 69 0B >326 ADC #$0B ;Add a fudge factor +002836: D0 03 =283B >327 BNE :1 ;That's a clone +002838: A5 0C >328 LDA apple ;Pass the test +00283A: 60 >329 RTS + >330 +00283B: A9 00 >331 :1 LDA #$00 +00283D: 60 >332 RTS + >333 + >334 *------------------------------------------------- + >335 * Install the appropriate device-driver + >336 * address in the system global page + >337 * (driverAdr)= addr of driver + >338 + =283E >339 InstallDev EQU * ;Made a sub and +00283E: 08 >340 PHP ; how many drives (carry) +00283F: A5 11 >341 LDA indrcn+1 ;Get index to global device table +002841: 29 07 >342 AND #$07 ; for this slot +002843: 0A >343 ASL +002844: A8 >344 TAY ; ... into Y-reg +002845: 0A >345 ASL +002846: 0A >346 ASL ;Now form device number +002847: 0A >347 ASL ;(A)=0SSS 0000 +002848: 20 8A 27 >348 JSR staDrv +00284B: 28 >349 PLP +00284C: 6A >350 ROR ;If 2 drives, then bit7=1 (DSSS IIII) +00284D: 10 04 =2853 >351 BPL :1 ;Branch if a 1-drive device (i.e. profile) +00284F: E8 >352 INX ; else presume that second drive is present +002850: 9D 32 BF >353 STA DevLst,X + >354 +002853: 8E 31 BF >355 :1 STX DevCnt ;Save updated device count +002856: 0A >356 ASL ;Shift # of drives back into carry +002857: AD 89 26 >357 LDA driverAdr ;Get low address of device driver +00285A: 99 10 BF >358 STA DevAdr01,Y +00285D: 90 03 =2862 >359 BCC :2 ;Branch if single drive +00285F: 99 20 BF >360 STA DevAdr02,Y +002862: AD 8A 26 >361 :2 LDA driverAdr+1 ;Get high address of device driver +002865: 99 11 BF >362 STA DevAdr01+1,Y +002868: 90 03 =286D >363 BCC :Ret +00286A: 99 21 BF >364 STA DevAdr02+1,Y +00286D: 60 >365 :Ret RTS + >366 + >367 *------------------------------------------------- + >368 * + >369 * This piece of code (not a subroutine) is branched to if the slot + >370 * search code finds a smartport device. It does a smartport status + >371 * call (code = 0) to determine the number of devices connected to + >372 * the "card". It then installs from 0..4 units in the table. + >373 * +00286E: 20 E6 28 >374 SmartPort JSR SetDevID ;Set up the devID byte from attributes + >375 * + >376 * Only map more than two devices if card is in slot 5 + >377 * +002871: A5 11 >378 LDA indrcn+1 ;indrcn+1 +002873: 8D 8A 26 >379 STA driverAdr+1 ;Didn't set this yet + >380 + >381 * Do the call to smartport to get the number of devices + >382 +002876: AD 89 26 >383 LDA driverAdr +002879: 8D 9E 28 >384 STA psCall+1 ;Modify operand +00287C: 18 >385 CLC +00287D: 69 03 >386 ADC #$03 +00287F: 8D 17 29 >387 STA spCall+1 +002882: AD 8A 26 >388 LDA driverAdr+1 ;No page cross possible +002885: 8D 18 29 >389 STA spCall+2 + >390 ********************************************* + >391 * patch 74 + >392 ********************************************* +002888: 8D 9F 28 >393 STA psCall+2 ;Modify operand +00288B: 0A >394 ASL ;Convert $Cn to $n0 +00288C: 0A >395 ASL +00288D: 0A >396 ASL +00288E: 0A >397 ASL +00288F: 85 43 >398 STA unitNum +002891: 64 42 >399 STZ dhpCmd ;Force a ProDOS status call +002893: 64 44 >400 STZ bufPtr ;Dummy pointer +002895: 64 46 >401 STZ blockNum ;Number of bytes to transfer +002897: 64 47 >402 STZ blockNum+1 ;Number of bytes to transfer +002899: A9 10 >403 LDA #$10 ;Dummy pointer should be <>0 +00289B: 85 45 >404 STA bufPtr+1 ;Dummy pointer + >405 ********************************************* + >406 * patch 74 + >407 ********************************************* + =289D >408 psCall EQU * ;ProDOS status call +00289D: 20 00 00 >409 JSR $0000 ;Filled in by above code +0028A0: A0 FB >410 LDY #$FB +0028A2: B1 10 >411 LDA (indrcn),Y ;SmartPort ID type byte +0028A4: 29 02 >412 AND #$02 ;Is it a SCSI card? +0028A6: F0 09 =28B1 >413 BEQ :1 ;No + >414 +0028A8: 8D 05 29 >415 STA unitNbr ;=2 +0028AB: 20 16 29 >416 JSR spCall +0028AE: 00 >417 DB $00 ; Do status call on SCSI unit +0028AF: 04 29 >418 DA spCallParms + >419 + >420 * Determine how many devices are connected + >421 * to the interface @ this slot + >422 * Ref SmartPort TN #20, #21 + >423 +0028B1: 9C 05 29 >424 :1 STZ unitNbr ;Get status of the +0028B4: 20 16 29 >425 JSR spCall ; SmartPort host +0028B7: 00 >426 DB $00 +0028B8: 04 29 >427 DA spCallParms + >428 + >429 * Don't add devices if there are none connected + >430 +0028BA: AD 81 26 >431 LDA numDevices ;Get dev cnt +0028BD: F0 24 =28E3 >432 BEQ DoneSP + >433 + >434 * Do the first and second device if they exist + >435 +0028BF: C9 02 >436 CMP #$02 ;C=1 if if 2,3,4 +0028C1: 20 3E 28 >437 JSR InstallDev + >438 + >439 * Do the third and fourth drives if they exist + >440 * They cannot exist for any card other than one in slot 5 + >441 +0028C4: A5 11 >442 LDA indrcn+1 +0028C6: C9 C5 >443 CMP #$C5 ;If not slot 5, no mirroring +0028C8: D0 19 =28E3 >444 BNE DoneSP + >445 ********************* see note #65 ********************* + >446 * + >447 * If this is slot 5, and if there is a disk card in slot 2, + >448 * only install 2 devices this slot. Thank you. + >449 +0028CA: 2C 8C 26 >450 BIT diskInSlot2 ;If there a disk card in slot 2? +0028CD: 10 14 =28E3 >451 BPL DoneSP ;Yes + >452 +0028CF: AD 81 26 >453 LDA numDevices +0028D2: C9 03 >454 CMP #$03 ;More than 2 devices in slot 5? +0028D4: 90 0D =28E3 >455 BCC DoneSP ;No (C=1 if 3,4,...) +0028D6: C9 04 >456 CMP #$04 ;C=1 if 4,5,6,...(More than 3 devices are connected) +0028D8: A9 C2 >457 LDA #$C2 ;Make it think it's slot 2 +0028DA: 85 11 >458 STA indrcn+1 +0028DC: 20 3E 28 >459 JSR InstallDev +0028DF: A9 C5 >460 LDA #$C5 ;Reset back to slot 5 +0028E1: 85 11 >461 STA indrcn+1 +0028E3: 4C 0B 27 >462 DoneSP JMP NxtDsk2 ;We know it's a disk device + >463 + >464 * Ref ProDOS Tech Ref (ROM Code conventions) + >465 * pg 7-14 BAP + >466 +0028E6: A0 FE >467 SetDevID LDY #$FE +0028E8: B1 10 >468 SetDevIDZ LDA (indrcn),Y ;Get attribute byte +0028EA: 4A >469 LSR +0028EB: 4A >470 LSR +0028EC: 4A >471 LSR +0028ED: 4A >472 LSR +0028EE: 85 12 >473 STA devID +0028F0: 60 >474 RTS + >475 ************** see note #65 **************** + >476 * + >477 * input: indrcn - point to $Cn00 of mystery card + >478 * output: carry clear if disk card here, set ow + >479 * y $ff + >480 * +0028F1: AD FF CF >481 CmpID LDA CLRROM ;Release $C800 space from previous slot +0028F4: A0 05 >482 LDY #$05 +0028F6: B1 10 >483 :loop LDA (indrcn),Y ;Compare ID bytes +0028F8: D9 04 28 >484 CMP diskID,Y ;$Cn07=don't care +0028FB: 38 >485 SEC +0028FC: D0 05 =2903 >486 BNE :Ret ;($Cn05)=03 +0028FE: 88 >487 DEY ;($Cn03)=00 +0028FF: 88 >488 DEY ;($Cn01)=20 +002900: 10 F4 =28F6 >489 BPL :loop ;Loop until all 4 ID bytes match +002902: 18 >490 CLC +002903: 60 >491 :Ret RTS + >492 + >493 *------------------------------------------------- + >494 * SmartPort parameter area + >495 +002904: 03 >496 spCallParms DB $03 ;number of parameters +002905: 00 >497 unitNbr DB $00 ;=$00,$01-$7E +002906: 81 26 >498 DA statusList +002908: 00 >499 DB $00 ;status code = 0 (code for general status) + >500 + >501 * Each offsets below can be considered as 000D SSS0 + >502 * Offsets for slot 0 dr1/2 & slot 3 dr 2 + >503 * are not represented here + >504 * Slot 3 dr 2 is reserved for /RAM + >505 + =2909 >506 mapOffset EQU * +002909: 06 >507 DB $06 ;slot 3, dr 1 +00290A: 1E >508 DB $1E ;slot 7, dr 2 +00290B: 0E >509 DB $0E ;slot 7, dr 1 +00290C: 1C >510 DB $1C ;slot 6, dr 2 +00290D: 0C >511 DB $0C ;slot 6, dr 1 +00290E: 1A >512 DB $1A ;slot 5, dr 2 +00290F: 0A >513 DB $0A ;slot 5, dr 1 +002910: 14 >514 DB $14 ;slot 2, dr 2 +002911: 04 >515 DB $04 ;slot 2, dr 1 +002912: 12 >516 DB $12 ;slot 1, dr 2 +002913: 02 >517 DB $02 ;slot 1, dr 1 +002914: 18 >518 DB $18 ;slot 4, dr 2 +002915: 08 >519 DB $08 ;slot 4, dr 1 + >520 +002916: 4C 00 00 >521 spCall JMP $0000 + >522 + >523 *------------------------------------------------- + >524 * This routine will scan all slots for SmartPort + >525 * interfaces. If more than 2 block devices are + >526 * connected to the SmartPort Host, it will mirror + >527 * at most 2 more block devices + >528 +002919: 64 10 >529 ScanAll4SP STZ indrcn +00291B: A9 C7 >530 LDA #$C7 ;Start w/slot 7 +00291D: 85 11 >531 STA indrcn+1 +00291F: 20 EB 29 >532 ScanLoop JSR Chk4SP ;Does slot have a SP host? +002922: B0 50 =2974 >533 BCS ChkNxtSlot ;No + >534 +002924: A0 FF >535 LDY #$FF +002926: B1 10 >536 LDA (indrcn),Y ;Get LSB of block dev driver +002928: 18 >537 CLC +002929: 69 03 >538 ADC #$03 ;Add 3 to get the +00292B: 8D 17 29 >539 STA spCall+1 ; SmartPort entry point +00292E: A5 11 >540 LDA indrcn+1 +002930: 8D 18 29 >541 STA spCall+2 +002933: 88 >542 DEY ;=$FE +002934: 20 E8 28 >543 JSR SetDevIDZ ;Get attributes +002937: 9C 05 29 >544 STZ unitNbr ;Get status of SmartPort Host +00293A: 20 16 29 >545 JSR spCall +00293D: 00 >546 DB $00 +00293E: 04 29 >547 DA spCallParms + >548 +002940: AD 81 26 >549 LDA numDevices +002943: C9 03 >550 CMP #$03 ;More than 2 devices? +002945: 90 2D =2974 >551 BCC ChkNxtSlot ;No +002947: 1A >552 INC ;1 more for easier comparision +002948: 8D 89 26 >553 STA maxUnitP1 ;=4,5,6,... +00294B: A9 03 >554 LDA #$03 +00294D: AE 18 29 >555 LDX spCall+2 +002950: E0 C5 >556 CPX #$C5 ;Slot 5? +002952: D0 07 =295B >557 BNE ChkDevLoop ;No +002954: 2C 8C 26 >558 BIT diskInSlot2 ;If there a disk card in slot 2? +002957: 10 02 =295B >559 BPL ChkDevLoop ;Yes + >560 + >561 * Slot 5 and no disk card in slot 2. + >562 * 4 of the devices connected to this + >563 * slot had already been dealt with. + >564 +002959: A9 05 >565 LDA #$05 +00295B: CD 89 26 >566 ChkDevLoop CMP maxUnitP1 +00295E: B0 14 =2974 >567 BCS ChkNxtSlot + >568 +002960: 8D 05 29 >569 STA unitNbr ;Get device status of this unit +002963: 20 16 29 >570 JSR spCall ;Ref pg 122 IIGS Firmware +002966: 00 >571 DB $00 +002967: 04 29 >572 DA spCallParms +002969: AD 81 26 >573 LDA spDevStatus ;Is it block dev? +00296C: 30 0F =297D >574 BMI MirrorDev ;Yes + >575 + >576 * No, it's a char dev + >577 +00296E: AD 05 29 >578 CkNxtChnDev LDA unitNbr +002971: 1A >579 INC +002972: 80 E7 =295B >580 BRA ChkDevLoop ;Loop to check next dev in chain + >581 +002974: C6 11 >582 ChkNxtSlot DEC indrcn+1 ;Set up for next lower slot +002976: A5 11 >583 LDA indrcn+1 +002978: C9 C0 >584 CMP #$C0 ;Have all slots been checked? +00297A: D0 A3 =291F >585 BNE ScanLoop ;No +00297C: 60 >586 RTS + >587 + >588 *------------------------------------------------- + >589 * We have more than 2 devices connected to + >590 * the SmartPort Host in this slot + >591 +00297D: A2 0C >592 MirrorDev LDX #12 ;Search thru 13 entries +00297F: BC 09 29 >593 MirrorLoop LDY mapOffset,X ;Get offset +002982: B9 10 BF >594 LDA DevAdr01,Y ;Check if there is an +002985: C9 A5 >595 CMP #596 BNE NoMapping ;No, already filled +002989: B9 11 BF >597 LDA DevAdr01+1,Y +00298C: C9 DE >598 CMP #>gNoDev +00298E: F0 04 =2994 >599 BEQ MapDevice ;Got an available entry +002990: CA >600 NoMapping DEX +002991: 10 EC =297F >601 BPL MirrorLoop +002993: 60 >602 RTS + >603 + >604 *------------------------------------------------- + >605 * Install SmartPort driver for additional + >606 * block devices connected to slot + >607 +002994: A5 11 >608 MapDevice LDA indrcn+1 ;Save slot # +002996: 48 >609 PHA +002997: DA >610 PHX +002998: 5A >611 PHY +002999: 98 >612 TYA +00299A: 4A >613 LSR ;0000 DSSS +00299B: 29 07 >614 AND #$07 ;0000 0SSS +00299D: 09 C0 >615 ORA #$C0 +00299F: 85 11 >616 STA indrcn+1 ;Chk if there is a SmartPort +0029A1: 20 EB 29 >617 JSR Chk4SP ; Host in this slot +0029A4: 7A >618 PLY +0029A5: FA >619 PLX +0029A6: 68 >620 PLA +0029A7: 85 11 >621 STA indrcn+1 +0029A9: 90 E5 =2990 >622 BCC NoMapping ;Yes, don't mirror the dev + >623 +0029AB: 20 8B 25 >624 JSR LC1In ;Switch in LC bank 1 +0029AE: 98 >625 TYA ;000D SSS0 +0029AF: 4A >626 LSR +0029B0: AA >627 TAX ;0000 DSSS ($01-$0F; $00,$08,$0B-invalid) +0029B1: AD 05 29 >628 LDA unitNbr +0029B4: 9D EF D6 >629 STA spUnits-1,X +0029B7: AD 17 29 >630 LDA spCall+1 ;Save actual SmartPort driver +0029BA: 9D 6E FD >631 STA spDrvAdrL-1,X +0029BD: AD 18 29 >632 LDA spCall+2 +0029C0: 9D 7D FD >633 STA spDrvAdrH-1,X +0029C3: AD 82 C0 >634 LDA RDROM2 +0029C6: EE 31 BF >635 INC DevCnt +0029C9: AE 31 BF >636 LDX DevCnt +0029CC: 98 >637 TYA +0029CD: 4A >638 LSR ;0000 DSSS +0029CE: C9 08 >639 CMP #$08 +0029D0: 90 04 =29D6 >640 BCC :1 ;Drive 1 +0029D2: E9 08 >641 SBC #$08 +0029D4: 09 08 >642 ORA #$08 ;Add back drive 2 bit +0029D6: 0A >643 :1 ASL +0029D7: 0A >644 ASL +0029D8: 0A >645 ASL +0029D9: 0A >646 ASL +0029DA: 05 12 >647 ORA devID ;DSSS IIII +0029DC: 9D 32 BF >648 STA DevLst,X +0029DF: A9 08 >649 LDA #650 STA DevAdr01,Y ; handles the mirrored devices +0029E4: A9 FD >651 LDA #>MirrorDevEntry +0029E6: 99 11 BF >652 STA DevAdr01+1,Y +0029E9: 80 83 =296E >653 BRA CkNxtChnDev + >654 + >655 *------------------------------------------------- + >656 * Exit + >657 * C=0 if there is a SmartPort card/interface + >658 * in the slot + >659 +0029EB: 20 F1 28 >660 Chk4SP JSR CmpID +0029EE: B0 08 =29F8 >661 BCS :Rtn ;No disk card in this slot +0029F0: 38 >662 SEC +0029F1: A0 07 >663 LDY #$07 ;Is this the SmartPort +0029F3: B1 10 >664 LDA (indrcn),Y ; signature byte? +0029F5: D0 01 =29F8 >665 BNE :Rtn ;No +0029F7: 18 >666 CLC +0029F8: 60 >667 :Rtn RTS + 21 PUT mli.src/Reloc + >1 ******************************************************* + >2 * Program/data relocation routine is driven by a table + >3 * describing program, vectors, and data segments. The + >4 * table has the general format: + >5 * (1)command: 0= zero destinaton range. + >6 * 1= move data to from src to dst. + >7 * 2= high address ref tbl, relocate & move. + >8 * 3= lo-hi addr ref tbl, relocate & move. + >9 * 4= program, relocate & move. + >10 * >4= end of table. + >11 * (2)dest addr: address of where segment is to be moved. + >12 * (2)byte count: length of segment. + >13 * (2)source addr: start address segment to be operated on, + >14 * n/a if type=0, code does not have to be + >15 * assembled at this address. + >16 * (1)segments: number of address ranges to be tested + >17 * and altered, n/a if type=0 or 1. + >18 * limit and offset lists should each + >19 * contain segments+1 (s) bytes. + >20 * (s)limitlow: list of low page addresses to be tested. + >21 * (s)limithigh: list of high page addresses to be tested. + >22 * (s)offset: list of amounts to be added if + >23 * low & high limits have been met. + >24 * + >25 * on entry: (X)=table address low, (Y)=table address high + >26 * on exit: carry clear if no error; else carry set, + >27 * (X)=addrLo, (Y)=addrHi of error causing source. + >28 * (A)=0 if input table error, =$ff if illegal opcode. + >29 ******************************************************* + >30 +0029F9: 86 10 >31 Reloc STX relocTbl +0029FB: 84 11 >32 STY relocTbl+1 ;Save address of control table +0029FD: B2 10 >33 RelLoop LDA (relocTbl) ;Get relocation command +0029FF: C9 05 >34 CMP #$05 ;If 5 or greater then done... +002A01: B0 72 =2A75 >35 BCS RelocEnd ;Branch if done +002A03: AA >36 TAX +002A04: A0 01 >37 LDY #$01 ;Move destination address to +002A06: B1 10 >38 LDA (relocTbl),Y ; zero page for indirect access +002A08: 85 14 >39 STA dst +002A0A: C8 >40 INY +002A0B: B1 10 >41 LDA (relocTbl),Y +002A0D: 85 15 >42 STA dst+1 +002A0F: C8 >43 INY +002A10: B1 10 >44 LDA (relocTbl),Y ;Also the length (byte count) +002A12: 85 16 >45 STA cnt ; of the destination area +002A14: C8 >46 INY +002A15: B1 10 >47 LDA (relocTbl),Y +002A17: 85 17 >48 STA cnt+1 +002A19: 30 5C =2A77 >49 BMI RelocErr ;Branch if >=32K +002A1B: 8A >50 TXA ;Request to zero out destination? +002A1C: F0 61 =2A7F >51 BEQ Zero ;Branch if it is +002A1E: C8 >52 INY +002A1F: B1 10 >53 LDA (relocTbl),Y ;Now get the source address +002A21: 85 12 >54 STA src +002A23: 85 18 >55 STA code ;src is used for the move, 'code' is +002A25: C8 >56 INY ; used for relocation +002A26: 18 >57 CLC ;Add length to get final address +002A27: 65 16 >58 ADC cnt +002A29: 85 1A >59 STA endCode +002A2B: B1 10 >60 LDA (relocTbl),Y +002A2D: 85 13 >61 STA src+1 +002A2F: 85 19 >62 STA code+1 +002A31: 65 17 >63 ADC cnt+1 +002A33: 85 1B >64 STA endCode+1 +002A35: CA >65 DEX ;Now that set-up is done, test for 'move' +002A36: F0 6B =2AA3 >66 BEQ MovEm ;Branch if move only (no relocation) + >67 +002A38: 8E CC 2B >68 STX wSize ;Save element size (1,2,3) +002A3B: C8 >69 INY +002A3C: B1 10 >70 LDA (relocTbl),Y ;Now get the number of ranges +002A3E: 8D CD 2B >71 STA segCnt ; that are valid relocation target addresses +002A41: AA >72 TAX ;Separate serial range groups into tables +002A42: C8 >73 RLimLo INY ;Transfer low limits to 'limlo' table +002A43: B1 10 >74 LDA (relocTbl),Y +002A45: 9D CE 2B >75 STA LimLo,X +002A48: CA >76 DEX +002A49: 10 F7 =2A42 >77 BPL RLimLo + >78 +002A4B: AE CD 2B >79 LDX segCnt +002A4E: C8 >80 RLimHi INY +002A4F: B1 10 >81 LDA (relocTbl),Y ;Transfer high limits to 'limhi' table +002A51: 9D D6 2B >82 STA LimHi,X +002A54: CA >83 DEX +002A55: 10 F7 =2A4E >84 BPL RLimHi + >85 +002A57: AE CD 2B >86 LDX segCnt +002A5A: C8 >87 Rofset INY +002A5B: B1 10 >88 LDA (relocTbl),Y ;Transfer offsets to 'ofset' table +002A5D: 9D DE 2B >89 STA Ofset,X +002A60: CA >90 DEX +002A61: 10 F7 =2A5A >91 BPL Rofset + >92 +002A63: 20 A8 2A >93 JSR AdjTbl ;Adjust 'relocTbl' to point at next spec +002A66: AE CC 2B >94 LDX wSize ;Test for machine code relocation +002A69: E0 03 >95 CPX #$03 +002A6B: F0 0D =2A7A >96 BEQ RelCode ;Branch if program relocation + >97 + >98 * 2/3 - Relocate addresses + >99 +002A6D: 20 0A 2B >100 JSR RelAdr ;Otherwise, relocate addresses in +002A70: 20 B3 2A >101 RelocEnd1 JSR Move ; one or two byte tables, then move to destination +002A73: 80 88 =29FD >102 BRA RelLoop ;Do next table entry... +002A75: 18 >103 RelocEnd CLC +002A76: 60 >104 RTS +002A77: 4C 40 2B >105 RelocErr JMP TblErr + >106 + >107 *------------------------------------------------- + >108 * 4 - Relocate instructions + >109 +002A7A: 20 1C 2B >110 RelCode JSR RelProg ;Go relocate machine code references +002A7D: 80 F1 =2A70 >111 BRA RelocEnd1 + >112 + >113 * 0 - Zero block + >114 +002A7F: 20 A8 2A >115 Zero JSR AdjTbl ;Adjust 'relocTbl' pointer to next entry +002A82: A9 00 >116 LDA #$00 ;Fill destination range with zeros +002A84: A4 17 >117 LDY cnt+1 ;Is it at least a page? +002A86: F0 0C =2A94 >118 BEQ ZPart ;Branch if less than 256 bytes +002A88: A8 >119 TAY +002A89: 91 14 >120 :ZeroLoop STA (dst),Y +002A8B: C8 >121 INY +002A8C: D0 FB =2A89 >122 BNE :ZeroLoop +002A8E: E6 15 >123 INC dst+1 ;bump to next page +002A90: C6 17 >124 DEC cnt+1 +002A92: D0 F5 =2A89 >125 BNE :ZeroLoop +002A94: A4 16 >126 ZPart LDY cnt ;any bytes left to zero? +002A96: F0 08 =2AA0 >127 BEQ Zeroed ;branch if not +002A98: A8 >128 TAY +002A99: 91 14 >129 :loop STA (dst),Y +002A9B: C8 >130 INY +002A9C: C4 16 >131 CPY cnt +002A9E: 90 F9 =2A99 >132 BCC :loop +002AA0: 4C FD 29 >133 Zeroed JMP RelLoop + >134 + >135 * 1 - Copy block + >136 +002AA3: 20 A8 2A >137 MovEm JSR AdjTbl +002AA6: 80 C8 =2A70 >138 BRA RelocEnd1 + >139 + >140 *------------------------------------------------- + >141 * Advance table ptr + >142 +002AA8: 98 >143 AdjTbl TYA ;Add previous table length to 'relocTbl' +002AA9: 38 >144 SEC ; to get position of next entry in table +002AAA: 65 10 >145 ADC relocTbl +002AAC: 85 10 >146 STA relocTbl +002AAE: 90 02 =2AB2 >147 BCC :Rtn +002AB0: E6 11 >148 INC relocTbl+1 +002AB2: 60 >149 :Rtn RTS + >150 + >151 *------------------------------------------------- + >152 +002AB3: A5 13 >153 Move LDA src+1 ;Determine if move is up, down +002AB5: C5 15 >154 CMP dst+1 ; or not at all +002AB7: 90 0B =2AC4 >155 BCC MovUp ;Branch if definitely up... +002AB9: D0 2C =2AE7 >156 BNE MovDown ;Branch if definitely down... +002ABB: A5 12 >157 LDA src +002ABD: C5 14 >158 CMP dst +002ABF: 90 03 =2AC4 >159 BCC MovUp ;Branch if definitely up... +002AC1: D0 24 =2AE7 >160 BNE MovDown ;Branch if definitely down... +002AC3: 60 >161 RTS ;Otherwise, don't move nuting + >162 + >163 *------------------------------------------------- + >164 * src addr < dest addr + >165 +002AC4: A4 17 >166 MovUp LDY cnt+1 ;Calc highest page of move up +002AC6: 98 >167 TYA +002AC7: 18 >168 CLC +002AC8: 65 13 >169 ADC src+1 +002ACA: 85 13 >170 STA src+1 ; & adjust src & dst accordingly +002ACC: 98 >171 TYA +002ACD: 18 >172 CLC +002ACE: 65 15 >173 ADC dst+1 +002AD0: 85 15 >174 STA dst+1 +002AD2: A4 16 >175 LDY cnt ;Move partial page first +002AD4: F0 08 =2ADE >176 BEQ :1 ;Branch if no partial pages +002AD6: 88 >177 :MovLoop DEY +002AD7: B1 12 >178 LDA (src),Y +002AD9: 91 14 >179 STA (dst),Y +002ADB: 98 >180 TYA ;End of page transfer? +002ADC: D0 F8 =2AD6 >181 BNE :MovLoop ;No +002ADE: C6 15 >182 :1 DEC dst+1 +002AE0: C6 13 >183 DEC src+1 +002AE2: C6 17 >184 DEC cnt+1 ;Done with all pages? +002AE4: 10 F0 =2AD6 >185 BPL :MovLoop ;Branch if not +002AE6: 60 >186 RTS + >187 + >188 *------------------------------------------------- + >189 * src addr > dest addr + >190 +002AE7: A0 00 >191 MovDown LDY #$00 +002AE9: A5 17 >192 LDA cnt+1 ;Partial page move only? +002AEB: F0 0F =2AFC >193 BEQ :1 ;Branch if less than a page to be moved +002AED: B1 12 >194 :MovLoop1 LDA (src),Y +002AEF: 91 14 >195 STA (dst),Y +002AF1: C8 >196 INY +002AF2: D0 F9 =2AED >197 BNE :MovLoop1 +002AF4: E6 15 >198 INC dst+1 ;Bump addresses +002AF6: E6 13 >199 INC src+1 +002AF8: C6 17 >200 DEC cnt+1 ;More pages? +002AFA: D0 F1 =2AED >201 BNE :MovLoop1 ;Branch if more pages +002AFC: A5 16 >202 :1 LDA cnt ;Move partial page +002AFE: F0 09 =2B09 >203 BEQ :Rtn ;Branch if no more to move +002B00: B1 12 >204 :MovLoop2 LDA (src),Y +002B02: 91 14 >205 STA (dst),Y +002B04: C8 >206 INY +002B05: C4 16 >207 CPY cnt +002B07: D0 F7 =2B00 >208 BNE :MovLoop2 +002B09: 60 >209 :Rtn RTS ;All done... + >210 + >211 *------------------------------------------------- + >212 * Address/page relocate + >213 +002B0A: AC CC 2B >214 RelAdr LDY wSize ;Determine 1 or 2 byte reference +002B0D: 88 >215 DEY +002B0E: B1 18 >216 LDA (code),Y +002B10: 20 48 2B >217 JSR AdjAdr ;Relocate reference +002B13: AD CC 2B >218 LDA wSize ;Update and test 'code' pointer +002B16: 20 64 2B >219 JSR AdjCode +002B19: 90 EF =2B0A >220 BCC RelAdr ;Branch if more to do +002B1B: 60 >221 RTS + >222 + >223 *------------------------------------------------- + >224 * Instructions relocate + >225 +002B1C: A0 00 >226 RelProg LDY #$00 ;Fetch next opcode +002B1E: B1 18 >227 LDA (code),Y +002B20: 20 77 2B >228 JSR GetOpLen ;Determine if it's a 3-byte instruction +002B23: F0 11 =2B36 >229 BEQ RPerr ;Branch if not an opcode +002B25: C9 03 >230 CMP #$03 +002B27: D0 07 =2B30 >231 BNE :1 +002B29: A0 02 >232 LDY #$02 +002B2B: 20 48 2B >233 JSR AdjAdr ;Relocate address +002B2E: A9 03 >234 LDA #$03 +002B30: 20 64 2B >235 :1 JSR AdjCode ;Update and test 'code' for done +002B33: 90 E7 =2B1C >236 BCC RelProg ;Loop if more to do +002B35: 60 >237 RTS + >238 + >239 *------------------------------------------------- + >240 * Error handling... + >241 +002B36: 68 >242 RPerr PLA ;Return bad code address +002B37: 68 >243 PLA ;First un-do stack +002B38: A6 18 >244 LDX code +002B3A: A4 19 >245 LDY code+1 +002B3C: A9 FF >246 LDA #$FF ;Indicate bad opcode +002B3E: 38 >247 SEC ;Indicate error +002B3F: 60 >248 RTS + >249 + >250 *------------------------------------------------- + >251 * Error return + >252 +002B40: A6 10 >253 TblErr LDX relocTbl ;Return table address error +002B42: A4 11 >254 LDY relocTbl+1 +002B44: A9 00 >255 LDA #$00 ;Indicate input table error +002B46: 38 >256 SEC +002B47: 60 >257 RTS + >258 + >259 *------------------------------------------------- + >260 * Relocate absolute addr + >261 +002B48: B1 18 >262 AdjAdr LDA (code),Y ;Get page address +002B4A: AE CD 2B >263 LDX segCnt ; and test against limits +002B4D: DD CE 2B >264 :AdjLoop CMP LimLo,X ;Is it >= low? +002B50: 90 07 =2B59 >265 BCC :Next ;Branch if not +002B52: DD D6 2B >266 CMP LimHi,X ;Is it =< highest page limit +002B55: 90 06 =2B5D >267 BCC :1 ;Branch if it is +002B57: F0 04 =2B5D >268 BEQ :1 +002B59: CA >269 :Next DEX ;Try next limit set +002B5A: 10 F1 =2B4D >270 BPL :AdjLoop +002B5C: 60 >271 RTS ;Teturn without adjustment + >272 +002B5D: 18 >273 :1 CLC ;Add offset to form relocated +002B5E: 7D DE 2B >274 ADC Ofset,X ; page address +002B61: 91 18 >275 STA (code),Y ; & replace old address with result +002B63: 60 >276 RTS + >277 + >278 *------------------------------------------------- + >279 * Bump ptr to next addr + >280 +002B64: 18 >281 AdjCode CLC ;Update 'code' pointer +002B65: 65 18 >282 ADC code +002B67: A4 19 >283 LDY code+1 +002B69: 90 01 =2B6C >284 BCC :1 ;Branch if not page cross +002B6B: C8 >285 INY ;Update high order address too +002B6C: C4 1B >286 :1 CPY endCode+1 ;Has all code/data been processed? +002B6E: 90 02 =2B72 >287 BCC :2 ;Branch if definitely not +002B70: C5 1A >288 CMP endCode ;If carry results set, end of code +002B72: 85 18 >289 :2 STA code +002B74: 84 19 >290 STY code+1 ;Save updated values +002B76: 60 >291 RTS ;Return result (carry set=done) + >292 + >293 *------------------------------------------------- + >294 * Compute instruction len + >295 +002B77: 48 >296 GetOpLen PHA ;Form index to table and which 2-bit group +002B78: 29 03 >297 AND #$03 ;Low 2 bits specify group +002B7A: A8 >298 TAY +002B7B: 68 >299 PLA +002B7C: 4A >300 LSR ;Upper 6 bits specify byte in table +002B7D: 4A >301 LSR +002B7E: AA >302 TAX +002B7F: BD 8C 2B >303 LDA OpCodeLen,X +002B82: 88 >304 NxtGroup DEY ;Is opcode length in lowest 2 bits of A-reg? +002B83: 30 04 =2B89 >305 BMI RtnLen ;Branch if it is +002B85: 4A >306 LSR +002B86: 4A >307 LSR ;Shift to next group +002B87: D0 F9 =2B82 >308 BNE NxtGroup ;If len=0 then error... +002B89: 29 03 >309 RtnLen AND #$03 ;Strip other garbage +002B8B: 60 >310 RTS ;If z-flag true, then error!!! + >311 + >312 *------------------------------------------------- + >313 * The following table contains the length of each + >314 * machine instruction (in two-bit groups). + >315 +002B8C: 09 28 19 3C >316 OpCodeLen HEX 0928193C +002B90: 0A 28 0D 3C >317 HEX 0A280D3C +002B94: 0B 2A 19 3F >318 HEX 0B2A193F +002B98: 0A 28 0D 3C >319 HEX 0A280D3C +002B9C: 09 28 19 3F >320 HEX 0928193F +002BA0: 0A 28 0D 3C >321 HEX 0A280D3C +002BA4: 09 28 19 3F >322 HEX 0928193F +002BA8: 0A 28 0D 3C >323 HEX 0A280D3C +002BAC: 08 2A 11 3F >324 HEX 082A113F +002BB0: 0A 2A 1D 0C >325 HEX 0A2A1D0C +002BB4: 2A 2A 19 3F >326 HEX 2A2A193F +002BB8: 0A 2A 1D 3F >327 HEX 0A2A1D3F +002BBC: 0A 2A 19 3F >328 HEX 0A2A193F +002BC0: 0A 28 0D 3C >329 HEX 0A280D3C +002BC4: 0A 2A 19 3F >330 HEX 0A2A193F +002BC8: 0A 28 0D 3C >331 HEX 0A280D3C + >332 + >333 *------------------------------------------------- + >334 * Relocation Data + >335 +002BCC: 00 >336 wSize DB $00 +002BCD: 00 >337 segCnt DB $00 +002BCE: 00 00 00 00 >338 LimLo HEX 0000000000000000 ;Start of range pages +002BD6: 00 00 00 00 >339 LimHi HEX 0000000000000000 ;End of pages+1 +002BDE: 00 00 00 00 >340 Ofset HEX 0000000000000000 ;Additive factors + >341 + >342 *------------------------------------------------- + >343 * Install an exit code + >344 * The locations GSOS($E100A8) & GSOS2 ($E100B0) + >345 * are patched if the boot OS is P8 + >346 +002BE6: 08 >347 GSPatches PHP +002BE7: 78 >348 SEI +002BE8: 18 >349 CLC +002BE9: FB >350 XCE +002BEA: C2 30 >351 REP #$30 +002BEC: 8B >352 PHB +002BED: 48 >353 PHA +002BEE: 48 >354 PHA ;long result +002BEF: >355 PushLong #ZZSize ;size 16 bytes +002BF5: >356 PushWord #$3101 ;userID +002BF8: >357 PushWord #attrLocked+attrNoCross+attrNoSpec +002BFB: 48 >358 PHA +002BFC: 48 >359 PHA +002BFD: >360 _NewHandle +002C04: A3 01 >361 LDA $01,S ;Let handle remain on stack +002C06: AA >362 TAX ; since we need it later but +002C07: A3 03 >363 LDA $03,S ; move a copy to (Y,X) +002C09: A8 >364 TAY +002C0A: >365 PushLong #ExitPatch ; srcPtr +002C10: 5A >366 PHY +002C11: DA >367 PHX ;destHndl +002C12: >368 PushLong #ZZSize ;# of bytes to be copied +002C18: >369 _PtrToHand +002C1F: FA >370 PLX ;Put 24 bits of the 32-bit +002C20: AB >371 PLB ; handle that was left on stack +002C21: BD 01 00 >372 LDA |$0001,X ; deref +002C24: A8 >373 TAY ;mid & hi-byte of 24-bit ptr +002C25: BD 00 00 >374 LDA |$0000,X ; low 16-bit of 24-bit ptr +002C28: 29 FF 00 >375 AND #$00FF ; Mask off mid byte +002C2B: EB >376 XBA ;Lobyte of ptr to Hi-byte in ACC +002C2C: 09 5C 00 >377 ORA #$005C ;Add in JMPL inst +002C2F: 8F B0 00 E1 >378 STAL GSOS2 ;$5C xx +002C33: 18 >379 CLC +002C34: 69 0B 00 >380 ADC #$000B ; ADC[] +002C37: 8F A8 00 E1 >381 STAL GSOS +002C3B: 98 >382 TYA ; mid & hi byte of 24-bit ptr +002C3C: 8F B2 00 E1 >383 STAL GSOS2+2 ;yy zz +002C40: 69 00 00 >384 ADC #$0000 +002C43: 8F AA 00 E1 >385 STAL GSOS+2 +002C47: AB >386 PLB ;Discard the rest of the handle +002C48: AB >387 PLB +002C49: 38 >388 SEC +002C4A: FB >389 XCE +002C4B: 28 >390 PLP +002C4C: 60 >391 RTS + >392 + >393 *------------------------------------------------- + >394 * Remove 3 words & adjust stack + >395 * to return to caller + >396 + >397 MX %00 +002C4D: A3 01 >398 ExitPatch LDA $01,S ;RTL-1 addr +002C4F: 83 07 >399 STA $07,S +002C51: A3 02 >400 LDA $02,S +002C53: 83 08 >401 STA $07+1,S +002C55: 68 >402 PLA +002C56: 68 >403 PLA +002C57: 68 >404 PLA +002C58: A9 FF 00 >405 LDA #$00FF +002C5B: 38 >406 SEC +002C5C: 6B >407 RTL + =0010 >408 ZZSize EQU *-ExitPatch +002C5D: 00 00 00 00 >409 DS $23,0 + 22 PUT mli.src/RAM1 + >1 ************************************************** + >2 ORG Srce + >3 MX %11 + >4 + >5 * Move LCSrc to LCDest + >6 +002C80: A0 99 >7 LDY #$99 ;Move $9A bytes +002C82: B9 00 2D >8 :MovLoop LDA LCSrc,Y ;Get a byte of source +002C85: 99 00 FF >9 STA LCDest,Y +002C88: 88 >10 DEY +002C89: C0 FF >11 CPY #$FF +002C8B: D0 F5 =2C82 >12 BNE :MovLoop + >13 + >14 * Move RAMSrc to RAMDest + >15 +002C8D: A2 00 >16 LDX #17 STX A1 ;Source low +002C91: CA >18 DEX ;Source end low +002C92: 86 3E >19 STX A2 +002C94: A2 51 >20 LDX #>RAMsrc ;Source high +002C96: 86 3D >21 STX A1+1 +002C98: E8 >22 INX +002C99: 86 3F >23 STX A2+1 ;End high +002C9B: A9 00 >24 LDA #25 STA A4 +002C9F: A9 02 >26 LDA #>RAMdest +002CA1: 85 43 >27 STA A4+1 +002CA3: 38 >28 SEC ;RAM to Card +002CA4: 20 11 C3 >29 JSR AuxMove ;Use built-in rtn to move + >30 + >31 * Now install it into the system + >32 +002CA7: A9 00 >33 LDA #34 STA DevAdr32 ; Slot 3, drive 2 +002CAC: A9 FF >35 LDA #>LCdest +002CAE: 8D 27 BF >36 STA DevAdr32+1 +002CB1: EE 31 BF >37 INC DevCnt +002CB4: AE 31 BF >38 LDX DevCnt +002CB7: A9 BF >39 LDA #%10110000+$F ;Unit # of /RAM ($B0+$F) +002CB9: 9D 32 BF >40 STA DevLst,X ;NB. $B0 ($30+hi-bit set) +002CBC: 60 >41 RTS + >42 +002CBD: 00 00 00 00 >43 DS \,0 ;Pad to end of mem page + 23 PUT mli.src/RAM2 + >1 ************************************************** + >2 * Ram Disk function Handler + >3 + >4 ORG LCDest + >5 MX %11 +00FF00: D8 >6 EnterRAM CLD ;/RAM entry point +00FF01: A2 0B >7 LDX #12-1 ;Save 12 bytes of params +00FF03: B5 3C >8 :CpyLoop1 LDA A1,X +00FF05: 9D 84 FF >9 STA A1L1,X +00FF08: CA >10 DEX +00FF09: 10 F8 =FF03 >11 BPL :CpyLoop1 + >12 +00FF0B: A2 01 >13 LDX #1 ;Save XFER Vectors too +00FF0D: BD ED 03 >14 :CpyLoop2 LDA PassIt,X +00FF10: 9D 82 FF >15 STA SP1,X +00FF13: CA >16 DEX +00FF14: 10 F7 =FF0D >17 BPL :CpyLoop2 + >18 +00FF16: A5 42 >19 LDA dhpCmd ;Get command +00FF18: F0 2A =FF44 >20 BEQ STAT ;0=STATUS +00FF1A: C9 04 >21 CMP #$04 ;Check for command too high +00FF1C: B0 1D =FF3B >22 BCS IOErr ;If it is, IO ERR +00FF1E: 49 03 >23 EOR #$03 ;0=FORMAT,2=READ,1=WRITE +00FF20: 85 42 >24 STA $42 ;CMD=>0=Format,2=Read,1=Write +00FF22: F0 08 =FF2C >25 BEQ Format ;Format the volume + >26 +00FF24: A4 47 >27 LDY blockNum+1 ;Check for enormous blocknum +00FF26: D0 13 =FF3B >28 BNE IOErr ;I/O error if too big +00FF28: A5 46 >29 LDA blockNum +00FF2A: 30 0F =FF3B >30 BMI IOErr ;Largest block is $7F + >31 + >32 * At this point, control is passed to the code in the + >33 * alternate 64K. It is used for read, write, and + >34 * format. After the request is completed, control + >35 * is always passed back to NoErr. + >36 +00FF2C: A9 00 >37 Format LDA #38 STA PassIt ;Figure it out on card +00FF31: A9 02 >39 LDA #>EnterCard +00FF33: 8D EE 03 >40 GoCard STA PassIt+1 ;Also used by MainWrt +00FF36: 38 >41 SEC ;RAM->Card +00FF37: B8 >42 CLV ;start with original z.p. +00FF38: 4C 14 C3 >43 JMP Xfer ;transfer control + >44 +00FF3B: A9 27 >45 IOErr LDA #drvrIOError ;Get err num +00FF3D: D0 02 =FF41 >46 BNE ErrOut ; & return (always) + >47 +00FF3F: A9 2B >48 WPErr LDA #drvrWrtProt +00FF41: 38 >49 ErrOut SEC ;Flag error +00FF42: B0 03 =FF47 >50 BCS Restore ;Restore cmd and unitnum + >51 + =FF44 >52 STAT EQU * +00FF44: A9 00 >53 NoErr LDA #$00 ;No error +00FF46: 18 >54 CLC ;Flag no error + >55 +00FF47: 08 >56 Restore PHP ;Save status +00FF48: 48 >57 PHA ;Save error code + >58 +00FF49: A2 0B >59 LDX #12-1 ;Restore 12 bytes of params +00FF4B: BD 84 FF >60 :CpyLoop LDA A1L1,X +00FF4E: 95 3C >61 STA A1,X +00FF50: CA >62 DEX +00FF51: 10 F8 =FF4B >63 BPL :CpyLoop + >64 +00FF53: AD 82 FF >65 LDA SP1 ;Restore XFER params +00FF56: 2C 60 60 >66 BIT $6060 ;This instruction is to put +00FF59: 8D ED 03 >67 STA PassIt ; an RTS at $FF58 as in ROM +00FF5C: AD 83 FF >68 LDA SP1+1 +00FF5F: 8D EE 03 >69 STA PassIt+1 + >70 + >71 * -------------------- See rev note 21 ----------------------- + >72 +00FF62: 68 >73 PLA ;Get error +00FF63: 28 >74 PLP ;Get status +00FF64: 60 >75 RTS + >76 + >77 *------------------------------------------------- + >78 * Write file buffer in MAIN to AUX block + >79 * Assume A1,A2,A3,A4 ptrs are set in Aux Driver + >80 +00FF65: 8D 05 C0 >81 MainWrt STA WRCARDRAM ;Xfer data to card +00FF68: A0 00 >82 LDY #$00 +00FF6A: B1 3C >83 :MovLoop LDA (A1),Y ;Pointers set in card by SETPTR +00FF6C: 91 42 >84 STA (A4),Y +00FF6E: B1 3E >85 LDA (A2),Y +00FF70: 91 40 >86 STA (A3),Y +00FF72: 88 >87 DEY +00FF73: D0 F5 =FF6A >88 BNE :MovLoop +00FF75: 8D 04 C0 >89 STA WRMAINRAM ;Done writing Card + >90 +00FF78: A9 DA >91 LDA #92 STA PassIt +00FF7D: A9 02 >93 LDA #>DoneWrt +00FF7F: 4C 33 FF >94 JMP GoCard + >95 +00FF82: 00 00 >96 SP1 DS 2,0 +00FF84: 00 00 00 00 >97 A1L1 DS 12,0 ;12 bytes of storage +00FF90: 00 00 00 00 >98 DS 11,0 ;Pad to int handler + 24 PUT mli.src/ROM + >2 + >3 *********************************************************** + >4 * This code is used when an IRQ happens while the RAM + >5 * at $D000-$FFFF is switched on (inside an MLI + >6 * call, for example) if we have the "new style" + >7 * monitor ROMs + >8 + >9 ORG $FF9B + >10 +00FF9B: 48 >11 LanIrq PHA +00FF9C: A5 45 >12 LDA Acc ;Save ($45) +00FF9E: 8D 56 BF >13 STA old45 ;Now put A-reg into loc $45 +00FFA1: 68 >14 PLA +00FFA2: 85 45 >15 STA Acc +00FFA4: 68 >16 PLA ;Get status register from stack +00FFA5: 48 >17 PHA ; (and restore it!) +00FFA6: 29 10 >18 AND #$10 ;Is it a break or interupt +00FFA8: D0 18 =FFC2 >19 BNE lBreak ;Branch if break +00FFAA: AD 00 D0 >20 LDA $D000 ;Get bankID +00FFAD: 49 D8 >21 EOR #$D8 ;Is the system active? (CLD) +00FFAF: F0 02 =FFB3 >22 BEQ SysActv ;Branch if it is +00FFB1: A9 FF >23 LDA #$FF ;In $D000 bank 2 +00FFB3: 8D 8D BF >24 SysActv STA IntBankID ;Update bank ID (=$00/$FF) +00FFB6: 8D 57 BF >25 STA afBank +00FFB9: A9 BF >26 LDA #>aftIrq ;Push fake "RTI" vector +00FFBB: 48 >27 PHA ; with IRQ disabled +00FFBC: A9 50 >28 LDA #29 PHA +00FFBF: A9 04 >30 LDA #$04 ;Status reg w/int flag set +00FFC1: 48 >31 PHA +00FFC2: A9 FA >32 lBreak LDA #>ROMIrq ;Push ROM entry also +00FFC4: 48 >33 PHA +00FFC5: A9 41 >34 LDA #35 PHA +00FFC8: 8D 82 C0 >36 GoROM STA RDROM2 ;Switch to ROM (hits RTS immediately) + >37 +00FFCB: AD D7 FF >38 lReset LDA rReset+1 +00FFCE: 48 >39 PHA ;Since reset, Acc can be destroyed +00FFCF: AD D6 FF >40 LDA rReset +00FFD2: 48 >41 PHA +00FFD3: 4C C8 FF >42 JMP GoROM + >43 +00FFD6: 61 FA >44 rReset DA $FA62-1 ;Monitor reset-1 + >45 + >46 *------------------------------------------------- + >47 +00FFD8: 8D 88 BF >48 fix45 STA IntAReg ;Preserve the Acc +00FFDB: AD 56 BF >49 LDA old45 +00FFDE: 85 45 >50 STA Acc +00FFE0: AD 8B C0 >51 LDA LCBANK1 +00FFE3: AD 8B C0 >52 LDA LCBANK1 ;Switch RAM in for write & read +00FFE6: AD 57 BF >53 LDA afBank +00FFE9: 4C D3 BF >54 JMP IrqXit0 + >55 + >56 * (Y)=0 + >57 +00FFEC: 8C 97 BF >58 ZeroPfxPtrs STY NewPfxPtr ;Fix AppleTalk PFI bug +00FFEF: 8C 9A BF >59 STY PfixPtr ;Flag not an active prefix +00FFF2: 60 >60 RTS + >61 + >62 *(A)=flag + >63 +00FFF3: 8D 97 BF >64 SetPfxPtrs STA NewPfxPtr +00FFF6: 8D 9A BF >65 STA PfixPtr +00FFF9: 60 >66 RTS + >67 +00FFFA: FB 03 >68 DA NMI +00FFFC: CB FF >69 DA lReset +00FFFE: 9B FF >70 IrqVect DA LanIrq + 25 PUT mli.src/Globals + >2 + >3 ORG Globals + >4 ************************************************** + >5 +00BF00: 4C 4B BF >6 GoPro JMP mliEnt1 ;MLI call entry point + >7 + >8 ************ see rev note #36 ******************** + >9 * Jump vector to cold start/selector program, etc. Will + >10 * be changed to point to dispatcher caller by the loader + >11 +00BF03: 4C 03 BF >12 jSpare JMP jSpare + >13 *------------------------------------------------- +00BF06: 60 >14 DateTime DB $60 ;Changed to $4C (JMP) if clock present +00BF07: 42 D7 >15 DA ClockBegin ;Clock routine entry address +00BF09: 4C 04 E0 >16 SysErr JMP SysErr1 ;Error reporting hook +00BF0C: 4C 0B E0 >17 SysDeath JMP SysDeath1 ;System failure hook +00BF0F: 00 >18 SErr DB $00 ;Error code, 0=no error + >19 + >20 *------------------------------------------------- + =BF10 >21 DevAdr01 EQU * +00BF10: A5 DE >22 DA gNoDev ;slot zero reserved +00BF12: A5 DE >23 DA gNoDev ;slot 1, drive 1 +00BF14: A5 DE >24 DA gNoDev ;slot 2, drive 1 +00BF16: A5 DE >25 DA gNoDev ;slot 3, drive 1 +00BF18: A5 DE >26 DA gNoDev ;slot 4, drive 1 +00BF1A: A5 DE >27 DA gNoDev ;slot 5, drive 1 +00BF1C: A5 DE >28 DA gNoDev ;slot 6, drive 1 +00BF1E: A5 DE >29 DA gNoDev ;slot 7, drive 1 +00BF20: A5 DE >30 DevAdr02 DA gNoDev ;slot zero reserved +00BF22: A5 DE >31 DA gNoDev ;slot 1, drive 2 +00BF24: A5 DE >32 DA gNoDev ;slot 2, drive 2 +00BF26: A5 DE >33 DevAdr32 DA gNoDev ;slot 3, drive 2 +00BF28: A5 DE >34 DA gNoDev ;slot 4, drive 2 +00BF2A: A5 DE >35 DA gNoDev ;slot 5, drive 2 +00BF2C: A5 DE >36 DA gNoDev ;slot 6, drive 2 +00BF2E: A5 DE >37 DA gNoDev ;slot 7, drive 2 + >38 + >39 *------------------------------------------------- + >40 * Configured device list by device number + >41 * Access order is last in list first. + >42 +00BF30: 00 >43 DevNum DB $00 ;Most recently accessed device +00BF31: FF >44 DevCnt DB $FF ;Number of on-line devices (minus 1) +00BF32: 00 00 00 00 >45 DevLst HEX 0000000000 ;Up to 14 units may be active +00BF37: 00 00 00 00 >46 HEX 0000000000 +00BF3C: 00 00 00 00 >47 HEX 00000000 +00BF40: 00 >48 DB 0 ;Unused? +00BF41: 28 43 29 41 >49 ASC '(C)APPLE ' ; AppleTALK writes over this area! DO NOT MOVE! + >50 + >51 *------------------------------------------------- +00BF4B: 08 >52 mliEnt1 PHP +00BF4C: 78 >53 SEI ;Disable interrupts +00BF4D: 4C B7 BF >54 JMP mliCont +00BF50: 8D 8B C0 >55 aftIrq STA LCBANK1 +00BF53: 4C D8 FF >56 JMP fix45 ;Restore $45 after interrupt in lang card* + >57 +00BF56: 00 >58 old45 DB $00 +00BF57: 00 >59 afBank DB $00 + >60 + >61 *------------------------------------------------- + >62 * Memory map of the lower 48K. Each bit represents one page + >63 * (256 bytes) of memory. Protected areas are marked with a + >64 * 1, unprotected with a 0. ProDOS dis-allows reading or + >65 * buffer allocation in protected areas. + >66 +00BF58: C0 00 00 00 >67 memTabl HEX C000000000000000 +00BF60: 00 00 00 00 >68 HEX 0000000000000000 +00BF68: 00 00 00 00 >69 HEX 0000000000000001 + >70 + >71 * The addresses contained in this table are buffer addresses + >72 * for currently open files. These are informational only, + >73 * and should not be changed by the user except through the + >74 * MLI call setbuf. + >75 +00BF70: 00 00 >76 GblBuf DA $0000 ;file number 1 +00BF72: 00 00 >77 DA $0000 ;file number 2 +00BF74: 00 00 >78 DA $0000 ;file number 3 +00BF76: 00 00 >79 DA $0000 ;file number 4 +00BF78: 00 00 >80 DA $0000 ;file number 5 +00BF7A: 00 00 >81 DA $0000 ;file number 6 +00BF7C: 00 00 >82 DA $0000 ;file number 7 +00BF7E: 00 00 >83 DA $0000 ;file number 8 + >84 + >85 *------------------------------------------------- + >86 * Interrupt vectors are stored here. Again, this area is + >87 * informational only, and should be changed only by calls + >88 * to the MLI to allocate_interrupt. Values of the A, X, Y, + >89 * stack, and status registers at the time of the most recent + >90 * interrupt are also stored here. In addition, the address + >91 * interrupted is also preserved. These may be used for + >92 * performance studies and debugging, but should not be changed + >93 * by the user. + >94 +00BF80: 00 00 >95 Intrup1 DA $0000 ;interupt routine 1 +00BF82: 00 00 >96 Intrup2 DA $0000 ;interupt routine 2 +00BF84: 00 00 >97 Intrup3 DA $0000 ;interupt routine 3 +00BF86: 00 00 >98 Intrup4 DA $0000 ;interupt routine 4 +00BF88: 00 >99 IntAReg DB $00 ;A-register +00BF89: 00 >100 IntXReg DB $00 ;X-register +00BF8A: 00 >101 IntYReg DB $00 ;Y-register +00BF8B: 00 >102 IntSReg DB $00 ;Stack register +00BF8C: 00 >103 IntPReg DB $00 ;Status register +00BF8D: 01 >104 IntBankID DB $01 ;ROM, RAM1, or RAM2 ($D000 in LC) +00BF8E: 00 00 >105 IntAddr DA $0000 ;program counter return addr + >106 + >107 *------------------------------------------------- + >108 * The user may change the following options + >109 * prior to calls to the MLI. + >110 +00BF90: 00 00 >111 DateLo DW $0000 ;bits 15-9=yr, 8-5=mo, 4-0=day +00BF92: 00 00 >112 TimeLo DW $0000 ;bits 12-8=hr, 5-0=min; low-hi format +00BF94: 00 >113 Level DB $00 ;File level: used in open, flush, close +00BF95: 00 >114 BUBit DB $00 ;Backup bit disable, setfileinfo only +00BF96: 00 >115 Spare1 DB $00 ; Used to save A reg +00BF97: 00 >116 NewPfxPtr DB $00 ;Used as AppleTalk alternate prefix ptr + >117 + >118 * The following are informational only. MachID identifies + >119 * the system attributes: + >120 * (bit 3 off) bits 7,6- 00=ii 01=ii+ 10=iie 11=/// emulation + >121 * (bit 3 on) bits 7,6- 00=na 01=na 10=//c 11=na + >122 * bits 5,4- 00=na 01=48k 10=64k 11=128k + >123 * bit 3 modifier for machid bits 7,6. + >124 * bit 2 reserved for future definition. + >125 * bit 1=1- 80 column card + >126 * bit 0=1- recognizable clock card + >127 * + >128 * SltByt indicates which slots are determined to have ROMs. + >129 * PfixPtr indicates an active prefix if it is non-zero. + >130 * mliActv indicates an mli call in progress if it is non-zero. + >131 * CmdAdr is the address of the last mli call's parameter list. + >132 * SaveX and SaveY are the values of x and y when the MLI + >133 * was last called. + >134 +00BF98: 00 >135 MachID DB $00 ;Machine identification +00BF99: 00 >136 SltByt DB $00 ;'1' bits indicate rom in slot(bit#) +00BF9A: 00 >137 PfixPtr DB $00 ;If = 0, no prefix active... +00BF9B: 00 >138 mliActv DB $00 ;If <> 0, MLI call in progress +00BF9C: 00 00 >139 CmdAdr DA $0000 ;Return address of last call to MLI +00BF9E: 00 >140 SaveX DB $00 ;X-reg on entry to MLI +00BF9F: 00 >141 SaveY DB $00 ;Y-reg on entry to MLI + >142 + >143 *------------------------------------------------- + >144 * The following space is reserved for language card bank + >145 * switching routines. All routines and addresses are + >146 * subject to change at any time without notice and will, + >147 * in fact, vary with system configuration. + >148 * The routines presented here are for 64K systems only. + >149 +00BFA0: 4D 00 E0 >150 Exit EOR $E000 ;Test for ROM enable +00BFA3: F0 05 =BFAA >151 BEQ Exit1 ;Branch if RAM enabled +00BFA5: 8D 82 C0 >152 STA RDROM2 ;else enable ROM and return +00BFA8: D0 0B =BFB5 >153 BNE Exit2 ;Branch always + >154 +00BFAA: AD F5 BF >155 Exit1 LDA BnkByt2 ;For alternate RAM enable +00BFAD: 4D 00 D0 >156 EOR $D000 ; (mod by mliEnt1) +00BFB0: F0 03 =BFB5 >157 BEQ Exit2 ;Branch if not alternate RAM +00BFB2: AD 83 C0 >158 LDA LCBANK2 ;else enable alt $D000 + >159 +00BFB5: 68 >160 Exit2 PLA ;Restore return code +00BFB6: 40 >161 RTI ;Re-enable interrupts and return + >162 +00BFB7: 38 >163 mliCont SEC +00BFB8: 6E 9B BF >164 ROR mliActv ;Indicate to interrupt routines MLI active +00BFBB: AD 00 E0 >165 rpmCont LDA $E000 ;Preserve language card / ROM +00BFBE: 8D F4 BF >166 STA BnkByt1 ; orientation for proper +00BFC1: AD 00 D0 >167 LDA $D000 ; restoration when MLI exits... +00BFC4: 8D F5 BF >168 STA BnkByt2 +00BFC7: AD 8B C0 >169 LDA LCBANK1 ;Now force ram card on +00BFCA: AD 8B C0 >170 LDA LCBANK1 ; with RAM write allowed +00BFCD: 4C 00 DE >171 JMP EntryMLI + >172 +00BFD0: AD 8D BF >173 irqXit LDA IntBankID ;Determine state of RAM card +00BFD3: F0 0D =BFE2 >174 IrqXit0 BEQ IrqXit2 ; if any. Branch if enabled +00BFD5: 30 08 =BFDF >175 BMI IrqXit1 ;Branch if alternate $D000 enabled +00BFD7: 4A >176 LSR ;Determine if no RAM card present +00BFD8: 90 0D =BFE7 >177 BCC ROMXit ;Branch if ROM only system +00BFDA: AD 81 C0 >178 LDA ROMIN2 ;else enable ROM first +00BFDD: B0 08 =BFE7 >179 BCS ROMXit ;Branch always taken... +00BFDF: AD 83 C0 >180 IrqXit1 LDA LCBANK2 ;Enable alternate $D000 +00BFE2: A9 01 >181 IrqXit2 LDA #$01 ;Preset bankid for ROM +00BFE4: 8D 8D BF >182 STA IntBankID ;(reset if RAM card interupt) +00BFE7: AD 88 BF >183 ROMXit LDA IntAReg ;Restore accumulator... +00BFEA: 40 >184 RTI ; and exit! + >185 +00BFEB: 2C 8B C0 >186 IrqEnt BIT LCBANK1 ;This entry only used when ROM +00BFEE: 2C 8B C0 >187 BIT LCBANK1 ; was enabled at time of interupt +00BFF1: 4C 3D DF >188 JMP IrqRecev ; A-reg is stored at $45 in zpage + >189 + >190 *------------------------------------------------- +00BFF4: 00 >191 BnkByt1 DB $00 +00BFF5: 00 >192 BnkByt2 DB $00 +00BFF6: 00 00 00 00 >193 DS $BFFA-*,0 ; pad +00BFFA: 04 >194 DB $04 ;Referenced by GS/OS +00BFFB: 00 >195 DB $00 + >196 +00BFFC: 00 >197 iBakVer DB $00 ;Reserved +00BFFD: 00 >198 iVersion DB $00 ;Version # of currently running interpreter +00BFFE: 00 >199 kBakVer DB $00 ;Undefined: reserved for future use +00BFFF: 23 >200 kVersion DB $23 ;Represents release 2.03 + 26 PUT mli.src/TClock + >1 *********************************************************** + >2 * * + >3 * PRODOS 8 CLOCK DRIVER INTERFACE ROUTINE * + >4 * * + >5 * COPYRIGHT APPLE COMPUTER, INC., 1983-86 * + >6 * * + >7 * ALL RIGHTS RESERVED * + >8 * * + >9 *********************************************************** + >10 DUM $3A + =003A >11 TENS EQU * ;NO CONFLICT SINCE MONTH IS LAST PROCESSED. +00003A: 00 >12 MONTH DS 1 +00003B: 00 >13 WKDAY DS 1 +00003C: 00 >14 DAY DS 1 +00003D: 00 >15 HOUR DS 1 +00003E: 00 >16 MINUTE DS 1 + >17 DEND + >18 + =C10B >19 WrtTCP EQU $C10B + =C108 >20 RdTCP EQU $C108 ;CLOCK READ ENTRY POINTS + =0538 >21 ClkMode EQU $0538 ;(+$CN=$5F8+N) + >22 + >23 ORG ClockBegin + >24 +00D742: AE 50 D7 >25 ReadClk LDX ClkSlt ;PRESERVE CURRENT MODE FOR THUNDERCLOCK +00D745: BD 38 05 >26 LDA ClkMode,X +00D748: 48 >27 PHA +00D749: A9 A3 >28 LDA #$A3 ;SEND NUMERIC MODE BYTE TO THUNDERCLOCK +00D74B: 20 0B C1 >29 JSR WrtTCP + =D750 >30 ClkSlt EQU *+2 +00D74E: 20 08 C1 >31 JSR RdTCP ;READ MONTH, DAY OF WEEK, DAY OF MONTH +00D751: 18 >32 CLC ; AND TIME INTO INPUT BUFFER +00D752: A2 04 >33 LDX #$04 ;INDEX FOR 5 VALUES +00D754: A0 0C >34 LDY #$0C ;READ MINUTES FIRST, MONTH LAST +00D756: B9 00 02 >35 Convrt LDA inBuf,Y ;CONVERT VALUES TO BINAR +00D759: 29 07 >36 AND #$07 ;NO VALUE > 5 DECIMAL +00D75B: 85 3A >37 STA TENS ;MULTIPLY 'TENS' PLACE VALUE +00D75D: 0A >38 ASL +00D75E: 0A >39 ASL +00D75F: 65 3A >40 ADC TENS ;NOW IT'S TIMES 5 +00D761: 0A >41 ASL ;NOW IT IS TIMES 10! +00D762: 79 01 02 >42 ADC inBuf+1,Y ;ADD TO ASCII 'ONES' PLACE +00D765: 38 >43 SEC ;AND SUBTRACT OUT THE ASCII... +00D766: E9 B0 >44 SBC #"0" +00D768: 95 3A >45 STA MONTH,X ;SAVE CONVERTED VALUE +00D76A: 88 >46 DEY ;INDEX TO NEXT LOWER VALUE +00D76B: 88 >47 DEY +00D76C: 88 >48 DEY +00D76D: CA >49 DEX ;ARE THERE MORE VALUES? +00D76E: 10 E6 =D756 >50 BPL Convrt ;BRANCH IF THERE ARE + >51 +00D770: A8 >52 TAY ;A STILL CONTAINS MONTH, SAVE IN Y FOR NOW +00D771: 4A >53 LSR +00D772: 6A >54 ROR +00D773: 6A >55 ROR +00D774: 6A >56 ROR ;(HI BIT OF MONTH HELD IN CARRY) +00D775: 05 3C >57 ORA DAY +00D777: 8D 90 BF >58 STA DateLo ;SAVE LOW VALUE OF DATE +00D77A: 08 >59 PHP ;SAVE HI BIT OF MONTH FOR NOW +00D77B: 29 1F >60 AND #$1F ;ISOLATE DAY AGAIN + >61 ; (WHEN MONTH >7 CARRY SET ACCOUNTED FOR IN FOLLOWING ADD) +00D77D: 79 AB D7 >62 ADC TDays-1,Y ;REMEMBER THAT Y=MONTH +00D780: 90 02 =D784 >63 BCC :1 ;BRANCH NOT SEPT 13 THRU 30 +00D782: 69 03 >64 ADC #$03 ;ADJUST FOR MOD 7 WHEN DAY > 256 +00D784: 38 >65 :1 SEC +00D785: E9 07 >66 :loop SBC #$07 +00D787: B0 FC =D785 >67 BCS :loop ;LOOP UNTIL LESS THAN 0 +00D789: 69 07 >68 ADC #$07 ;NOW MAKE IT IN THE RANGE OF 0-6 +00D78B: E5 3B >69 SBC WKDAY ; THE DELTA PROVIDES YEARS OFFSET +00D78D: B0 02 =D791 >70 BCS :2 ;BRANCH IF POSITIVE +00D78F: 69 07 >71 ADC #$07 ;ELSE MAKE IT POSITIVE AGAIN +00D791: A8 >72 :2 TAY ;LOOK UP YEAR! +00D792: B9 B8 D7 >73 LDA YrAdj,Y +00D795: 28 >74 PLP ;LASTLY, COMBINE WITH HI BIT OF MONTH +00D796: 2A >75 ROL +00D797: 8D 91 BF >76 STA DateLo+1 ;AND SAVE IT +00D79A: A5 3D >77 LDA HOUR +00D79C: 8D 93 BF >78 STA TimeLo+1 ;MOVE HOUR AND MINUTE TO PRODOS GLOBALS +00D79F: A5 3E >79 LDA MINUTE +00D7A1: 8D 92 BF >80 STA TimeLo +00D7A4: 68 >81 PLA +00D7A5: AE 50 D7 >82 LDX ClkSlt ;RESTORE PREVIOUS MODE +00D7A8: 9D 38 05 >83 STA ClkMode,X +00D7AB: 60 >84 RTS ;ALL DONE... + >85 +00D7AC: 00 1F 3B 5A >86 TDays HEX 001F3B5A +00D7B0: 78 97 B5 D3 >87 HEX 7897B5D3 +00D7B4: F2 14 33 51 >88 HEX F2143351 + >89 +00D7B8: 60 5F 5E 5D >90 YrAdj HEX 605F5E5D +00D7BC: 62 61 60 >91 HEX 626160 +00D7BF: 00 00 00 >92 DS $80-$7D,0 + 27 PUT mli.src/CClock + >1 *********************************************************** + >2 * + >3 * ProDOS 8 CORTLAND CLOCK DRIVER + >4 * + >5 * COPYRIGHT APPLE COMPUTER, INC., 1986 + >6 * + >7 * ALL RIGHTS RESERVED + >8 * + >9 * Written by Kerry Laidlaw, 2/12/86 + >10 * Modified by Mike Askins, 9/6/86 + >11 * Modified by Fern Bachman, 9/7/86 + >12 * + >13 *********************************************************** + >14 * + >15 * This is the ProDOS8 Cortland built-in clock driver. + >16 * Its sole function in life is to fetch the time from the Cortland + >17 * clock via the Read Hex Time misc. tool call, and transfer this + >18 * time into the ProDOS global page time format. + >19 * + >20 * This routine will IGNORE any errors passed back to it from the + >21 * Read Hex Time call. This was done since existing ProDOS8 programs + >22 * cannot deal with some new time error code. + >23 * Thus the only way that a user can tell if his Cortland clock is + >24 * broken, is by noticing that the date and time fields are zeroed. + >25 * + >26 * Note: There are some interesting facts to know regarding the + >27 * slot clock driver for ProDOS8 and the built-in + >28 * Cortland clock. The year value returned from the Cortland clock + >29 * is an offset from the year 1900. Thus Cortland is capable of + >30 * reporting the year correctly until 1900+255=2155. Only 7 bits + >31 * are used for the year in the ProDOS8 global page, so theoretically + >32 * 1900+127=2027 is the last year that ProDOS could represent on a + >33 * Cortland. But this is only if the ProDOS8 year value is interpreted + >34 * as being an offset from 1900. + >35 * + >36 * Historically, the year value has been interpreted as the binary + >37 * representation of the last two digits of the year 19xx. + >38 * So this means that programs that display the year as a concatenation + >39 * of 19 and the ascii equivalent of the year value will work until 1999. + >40 * And programs that just display the last two digits of the year will + >41 * still work correctly until (20)27 if they convert the year value + >42 * correctly, but ignore any hundredths place digit. + >43 * + >44 * Apple //e's that use slot clocks that utilize the slot clock + >45 * driver have further restrictions of the year value. The slot + >46 * clock driver calculates the year given the position of the day + >47 * of the week in the month. This algorithm then uses a year look + >48 * up table that has seven possible values. Leap years are repeated + >49 * in the table. Since 1988 is a leap year, then the updated slot + >50 * clock driver (file TCLOCK) will yield the six year offset values + >51 * rather then seven. + >52 * So before 1992, if ProDOS8 still exists, the slot clock driver + >53 * routine must be updated again! + >54 * + >55 * So, we now have the following definition: + >56 * The value placed in the year field is defined as the + >57 * number of years past the year 1900. + >58 * Numerically speaking: Current Year = 1900 + year value. + >59 + >60 MX %11 + >61 + >62 ORG ClockBegin + >63 + >64 * This mod will force read/write main memory for the tool + >65 * call by resetting the read/write auxillary memory bits + >66 * in the state register (statereg). + >67 + >68 MX %11 + =D742 >69 IIgsClock EQU * +00D742: E2 30 >70 SEP #$30 ;Make sure we're in 8 bit mode +00D744: AD 68 C0 >71 LDA STATEREG ;Get the state reg +00D747: 8D 98 D7 >72 STA SaveState ;Keep for restore after tool call +00D74A: 29 CF >73 AND #%11001111 ;Clear the Read/Write aux memory bits +00D74C: 8D 68 C0 >74 STA STATEREG ;Make it real + >75 + >76 * First off, lets get into native mode with 16 bit m & x. + >77 + >78 MX %00 +00D74F: 18 >79 CLC ;Set e = 0, to set native mode +00D750: FB >80 XCE +00D751: C2 30 >81 REP #$30 ;Zero m & x for 16-bit mode +00D753: A9 00 00 >82 LDA #$0000 ;Zero out result space +00D756: 48 >83 PHA ; Push 4 words for hex time result... +00D757: 48 >84 PHA +00D758: 48 >85 PHA +00D759: 48 >86 PHA +00D75A: >87 _ReadTimeHex + >88 + >89 * Note that no error condition is checked for, so the date will + >90 * be zeroed by default if an error indeed happened. + >91 * + >92 * Back to 8 bit m to access results on stack... + >93 MX %10 +00D761: E2 20 >94 SEP #$20 +00D763: AD 98 D7 >95 LDA SaveState ;Restore the state register +00D766: 8D 68 C0 >96 STA STATEREG + >97 + >98 * Now let's pull the time off the stack and stick it in the global page. + >99 +00D769: 68 >100 PLA ;Pull off Seconds, and ignore +00D76A: 68 >101 PLA ;Pull off Minutes +00D76B: 8D 92 BF >102 STA TimeLo ;Store in global page +00D76E: 68 >103 PLA ;Pull off Hours +00D76F: 8D 93 BF >104 STA TimeLo+1 ;Store in global page +00D772: 68 >105 PLA ;Pull off Year value + >106 +00D773: C9 64 >107 :loop1 CMP #100 ;Adjust for +00D775: 90 04 =D77B >108 BCC :1 +00D777: E9 64 >109 SBC #100 ; year 2000 +00D779: 80 F8 =D773 >110 BRA :loop1 + >111 +00D77B: 8D 91 BF >112 :1 STA DateLo+1 ; (year) +00D77E: 68 >113 PLA ;Pull off Day +00D77F: 1A >114 INC ;Increment day value for ProDOS8 format +00D780: 8D 90 BF >115 STA DateLo ;Store in global page +00D783: 68 >116 PLA ;Pull off Month +00D784: 1A >117 INC ;Incr month value for ProDOS8 format +00D785: 0A >118 ASL ;Shift month as it sits in between +00D786: 0A >119 ASL ; the year and day values +00D787: 0A >120 ASL +00D788: 0A >121 ASL +00D789: 0A >122 ASL +00D78A: 0D 90 BF >123 ORA DateLo ;Put all but the top bit of month value +00D78D: 8D 90 BF >124 STA DateLo ; in the day byte +00D790: 2E 91 BF >125 ROL DateLo+1 ;Put hi bit of mo. in lo bit of yr byte +00D793: 68 >126 PLA ;Pull off unused byte +00D794: 68 >127 PLA ;Pull off Day of Week. Stack now clean +00D795: 38 >128 SEC ;Now go back to emulation mode +00D796: FB >129 XCE ; to continue with ProDOS8 +00D797: 60 >130 RTS ;That's all + >131 +00D798: 00 >132 SaveState DB $00 ;Keep the state of state register +00D799: 4A 49 4D 4A >133 ASC 'JIMJAYKERRY&MIKE' + =D7A9 >134 ClockEnd EQU * +00D7A9: 00 00 00 00 >135 DS 125-ClockEnd+ClockBegin,0 ; Zero rest of 125 bytes + =007D >136 Size EQU *-ClockBegin ;MUST be $7D (125) bytes in length! +00D7BF: 00 00 00 >137 DS $80-Size,0 + 28 PUT mli.src/XDosMLI + >1 * * * * * * * * * * * * * * * * * + >2 * The xdos machine language * + >3 * interface (MLI) * + >4 * system call processor * + >5 * * * * * * * * * * * * * * * * * + >6 + >7 ORG orig1 + >8 MX %11 +00DE00: D8 >9 EntryMLI CLD ;Cannot deal with decimal mode!!! +00DE01: 68 >10 PLA ;Get processor status +00DE02: 8D 96 BF >11 STA Spare1 ;Save it on the global page temporarily +00DE05: 8C 9F BF >12 STY SaveY ;Preserve the y and x registers +00DE08: 8E 9E BF >13 STX SaveX +00DE0B: 68 >14 PLA ;Find out the address of the caller +00DE0C: 85 40 >15 STA parm +00DE0E: 18 >16 CLC ; & preserve the address of the call spec +00DE0F: 69 04 >17 ADC #$04 +00DE11: 8D 9C BF >18 STA CmdAdr +00DE14: 68 >19 PLA +00DE15: 85 41 >20 STA parm+1 +00DE17: 69 00 >21 ADC #$00 +00DE19: 8D 9D BF >22 STA CmdAdr+1 ;CmdAdr is in the globals + >23 + >24 * Check cmd code + >25 +00DE1C: AD 96 BF >26 LDA Spare1 +00DE1F: 48 >27 PHA +00DE20: 28 >28 PLP ;Pull processor to re-enable interrupts +00DE21: D8 >29 CLD ;No decimal! (** #46 **) +00DE22: A0 00 >30 LDY #$00 +00DE24: 8C 0F BF >31 STY SErr ;Clear any previous errors... + >32 + >33 * Hashing algorithm used here adds high nibble + >34 * (div by 16 first) to the whole cmd code + >35 * and then masks it to 5 lower bits + >36 * This compresses range of codes without any overlapping + >37 +00DE27: C8 >38 INY ;Find out if we've got a valid command +00DE28: B1 40 >39 LDA (parm),Y ;Get command # +00DE2A: 4A >40 LSR ;Hash it to a range of $00-$1F +00DE2B: 4A >41 LSR +00DE2C: 4A >42 LSR +00DE2D: 4A >43 LSR +00DE2E: 18 >44 CLC +00DE2F: 71 40 >45 ADC (parm),Y +00DE31: 29 1F >46 AND #$1F +00DE33: AA >47 TAX +00DE34: B1 40 >48 LDA (parm),Y ;Now see if result is a valid command number +00DE36: DD 94 FD >49 CMP scNums,X ;Should match if it is +00DE39: D0 6F =DEAA >50 BNE scnErr ;Branch if not + >51 + >52 * Get IOB address + >53 +00DE3B: C8 >54 INY ;Index to call spec parm list addr +00DE3C: B1 40 >55 LDA (parm),Y ;Make parm point to parameter count byte +00DE3E: 48 >56 PHA ; in parameter block +00DE3F: C8 >57 INY +00DE40: B1 40 >58 LDA (parm),Y +00DE42: 85 41 >59 STA parm+1 +00DE44: 68 >60 PLA +00DE45: 85 40 >61 STA parm + >62 + >63 * Check parm count + >64 +00DE47: A0 00 >65 LDY #c_pCnt ;Now make sure parameter list has the +00DE49: BD B4 FD >66 LDA pCntTbl,X ; proper number of parameters +00DE4C: F0 1B =DE69 >67 BEQ GoClock ;Clock has 0 parameters +00DE4E: D1 40 >68 CMP (parm),Y +00DE50: D0 5C =DEAE >69 BNE scpErr ;Report error if wrong count + >70 + >71 * Check class of function + >72 +00DE52: BD 94 FD >73 LDA scNums,X ;Get call number again +00DE55: C9 65 >74 CMP #$65 +00DE57: F0 0D =DE66 >75 BEQ Special +00DE59: 0A >76 ASL ;Carry set if bfm or dev mgr +00DE5A: 10 12 =DE6E >77 BPL GoDevMgr +00DE5C: B0 1A =DE78 >78 BCS GoBFMgr +00DE5E: 4A >79 LSR ;Shift back down for interupt mgr + >80 + >81 * Isolate type + >82 * 0-alloc, 1-dealloc, 2-special + >83 +00DE5F: 29 03 >84 AND #$03 ;Valid calls are 0 & 1 +00DE61: 20 F6 DE >85 JSR IntMgr +00DE64: 80 19 =DE7F >86 BRA ExitMLI ;Command processed, all done +00DE66: 4C 03 BF >87 Special JMP jSpare ;QUIT + >88 + >89 ************************************************** + >90 * Command $82 - Get the date and time + >91 +00DE69: 20 06 BF >92 GoClock JSR DateTime ;go read clock +00DE6C: 80 11 =DE7F >93 BRA ExitMLI ;No errors posible! + >94 + >95 ************************************************** + >96 * READBLOCK and WRITEBLOCK commands ($80 and $81) + >97 +00DE6E: 4A >98 GoDevMgr LSR ;Save command # +00DE6F: 69 01 >99 ADC #$01 ;Valid commands are 1 & 2 +00DE71: 85 42 >100 STA dhpCmd ;(READ & WRITE) +00DE73: 20 B5 DE >101 JSR DevMgr ;Execute read or write request +00DE76: 80 07 =DE7F >102 BRA ExitMLI + >103 + >104 *------------------------------------------------- + >105 * Commands $C0 thru $D3 + >106 +00DE78: 4A >107 GoBFMgr LSR +00DE79: 29 1F >108 AND #$1F ;Valid commands in range of $00-$13 +00DE7B: AA >109 TAX +00DE7C: 20 40 E0 >110 JSR BFMgr ;Go do it... + >111 +00DE7F: 9C 95 BF >112 ExitMLI STZ BUBit ;First clear bubit +00DE82: AC 0F BF >113 LDY SErr ;Y holds error code thru most of exit +00DE85: C0 01 >114 CPY #$01 ;If >0 then set carry +00DE87: 98 >115 TYA ; & set z flag +00DE88: 08 >116 PHP ;Disable interupts +00DE89: 78 >117 SEI ; until exit complete +00DE8A: 4E 9B BF >118 LSR mliActv ;Indicate MLI done.(** #46 **) (** #85 **) +00DE8D: FA >119 PLX ;Save status register in X +00DE8E: AD 9D BF >120 LDA CmdAdr+1 ; until return address is placed +00DE91: 48 >121 PHA ; on the stack returning is done via 'RTI' +00DE92: AD 9C BF >122 LDA CmdAdr ; so that the status register is +00DE95: 48 >123 PHA ; restored at the same time +00DE96: DA >124 PHX ;Place status back on the stack +00DE97: 98 >125 TYA ;Return error, if any +00DE98: AE 9E BF >126 LDX SaveX ;Restore x & y registers +00DE9B: AC 9F BF >127 LDY SaveY +00DE9E: 48 >128 ExitRPM PHA ; (exit point for rpm **en3**) +00DE9F: AD F4 BF >129 LDA BnkByt1 ;Restore language card status & return +00DEA2: 4C A0 BF >130 JMP Exit + >131 + >132 *------------------------------------------------- + >133 +00DEA5: A9 28 >134 gNoDev LDA #drvrNoDevice ;Report no device connected +00DEA7: 20 09 BF >135 JSR SysErr +00DEAA: A9 01 >136 scnErr LDA #badSystemCall ;Report no such command +00DEAC: D0 02 =DEB0 >137 BNE scErr1 ;Branch always +00DEAE: A9 04 >138 scpErr LDA #invalidPcount ;report parameter count is invalid +00DEB0: 20 DA DE >139 scErr1 JSR GoSysErr +00DEB3: B0 CA =DE7F >140 BCS ExitMLI ;Branch always taken + >141 + >143 + >144 *------------------------------------------------- + >145 * ProDOS device manager + >146 * Block I/O setup + >147 +00DEB5: A0 05 >148 DevMgr LDY #$05 ;The call spec for devices must +00DEB7: 08 >149 PHP ;(do not allow interupts) +00DEB8: 78 >150 SEI +00DEB9: B1 40 >151 :loop LDA (parm),Y ; be passed to drivers in zero page +00DEBB: 99 42 00 >152 STA |dhpCmd,Y ;dhpCmd,unitNum,bufPtr,blockNum +00DEBE: 88 >153 DEY +00DEBF: D0 F8 =DEB9 >154 BNE :loop +00DEC1: A6 45 >155 LDX bufPtr+1 +00DEC3: 86 4F >156 STX userBuf+1 +00DEC5: E8 >157 INX +00DEC6: E8 >158 INX ;Add 2 for 512 byte range +00DEC7: A5 44 >159 LDA bufPtr ;Is buffer page alligned? +00DEC9: F0 01 =DECC >160 BEQ :1 ;Branch if it is +00DECB: E8 >161 INX ;Else account for 3-page straddle... +00DECC: 20 82 FC >162 :1 JSR ValDBufZ ;Make sure user is not conflicting +00DECF: B0 08 =DED9 >163 BCS DevMgrErr ; with protected RAM +00DED1: 20 DD DE >164 JSR DMgr ;Call internal entry for device dispatch +00DED4: B0 03 =DED9 >165 BCS DevMgrErr ;Branch if error occured +00DED6: 28 >166 PLP +00DED7: 18 >167 CLC ;Make sure carry is clear (no error) +00DED8: 60 >168 RTS + >169 +00DED9: 28 >170 DevMgrErr PLP +00DEDA: 20 09 BF >171 GoSysErr JSR SysErr + >172 + >173 *------------------------------------------------- + >174 * NOTE: interrupts must always be off when entering here + >175 * Do block I/O rtn + >176 +00DEDD: A5 43 >177 DMgr LDA unitNum ;Get device number +00DEDF: 29 F0 >178 AND #$F0 ;Strip misc lower nibble +00DEE1: 85 43 >179 STA unitNum ; & save it back +00DEE3: 4A >180 LSR ;Use as index to device table +00DEE4: 4A >181 LSR +00DEE5: 4A >182 LSR +00DEE6: AA >183 TAX +00DEE7: BD 10 BF >184 LDA DevAdr01,X ;Fetch driver address +00DEEA: 8D EE FE >185 STA goAdr +00DEED: BD 11 BF >186 LDA DevAdr01+1,X +00DEF0: 8D EF FE >187 STA goAdr+1 +00DEF3: 6C EE FE >188 GoCmd JMP (goAdr) ;Goto driver (or error if no driver) + >189 + >191 *------------------------------------------------- + >192 * ProDOS interrupt manager + >193 * Handle ALLOC_INTERRUPTS ($40) and + >194 * DEALLOC_INTERRUPTS ($41) Calls + >195 +00DEF6: 85 42 >196 IntMgr STA intCmd ;Allocate intrupt or deallocate? +00DEF8: 4A >197 LSR ;(A=0, carry set=dealloc) +00DEF9: B0 2C =DF27 >198 BCS DeAlocInt ;Branch if deallocation +00DEFB: A2 03 >199 LDX #$03 ;Test for a free interupt space in table +00DEFD: BD 7E BF >200 AlocInt LDA Intrup1-2,X ;Test high addr for zero +00DF00: D0 16 =DF18 >201 BNE :1 ;Branch if spot occupied +00DF02: A0 03 >202 LDY #c_intAdr+1 ;Fetch addr of routine +00DF04: B1 40 >203 LDA (parm),Y ;Must not be in zero page!!!! +00DF06: F0 1A =DF22 >204 BEQ BadInt ;Branch if the fool tried it +00DF08: 9D 7E BF >205 STA Intrup1-2,X ;Save high address +00DF0B: 88 >206 DEY +00DF0C: B1 40 >207 LDA (parm),Y +00DF0E: 9D 7D BF >208 STA Intrup1-3,X ; & low address +00DF11: 8A >209 TXA ;Now return interupt # in range of 1 to 4 +00DF12: 4A >210 LSR +00DF13: 88 >211 DEY +00DF14: 91 40 >212 STA (parm),Y ;Pass back to user +00DF16: 18 >213 CLC ;Indicate success! +00DF17: 60 >214 RTS + >215 +00DF18: E8 >216 :1 INX +00DF19: E8 >217 INX ;Bump to next lower priority spot +00DF1A: E0 0B >218 CPX #$0B ;Are all four allocated already? +00DF1C: D0 DF =DEFD >219 BNE AlocInt ;Branch if not + >220 +00DF1E: A9 25 >221 LDA #irqTableFull ;Return news that four devices are active +00DF20: D0 02 =DF24 >222 BNE IntErr1 + >223 +00DF22: A9 53 >224 BadInt LDA #paramRangeErr ;Report invalid parameter +00DF24: 20 09 BF >225 IntErr1 JSR SysErr + >226 +00DF27: A0 01 >227 DeAlocInt LDY #c_intNum ;Zero out interupt vector +00DF29: B1 40 >228 LDA (parm),Y ; but make sure it is valid # +00DF2B: F0 F5 =DF22 >229 BEQ BadInt ;Branch if it's <1 +00DF2D: C9 05 >230 CMP #$05 ; or >4 +00DF2F: B0 F1 =DF22 >231 BCS BadInt +00DF31: 0A >232 ASL +00DF32: AA >233 TAX +00DF33: A9 00 >234 LDA #$00 ;Now zip it +00DF35: 9D 7E BF >235 STA Intrup1-2,X +00DF38: 9D 7F BF >236 STA Intrup1-1,X +00DF3B: 18 >237 CLC +00DF3C: 60 >238 RTS + >239 + >240 *------------------------------------------------- + >241 * IRQ Handler - If an IRQ occurs, we eventually get HERE + >242 +00DF3D: A5 45 >243 IrqRecev LDA Acc ;Get Acc from 0-page where old ROM put it +00DF3F: 8D 88 BF >244 STA IntAReg +00DF42: 8E 89 BF >245 STX IntXReg ;Entry point on RAM card interupt +00DF45: 8C 8A BF >246 STY IntYReg +00DF48: BA >247 TSX +00DF49: 8E 8B BF >248 STX IntSReg +00DF4C: AD E0 DF >249 LDA IrqFlag ;Irq flag byte = 0 if old ROMs +00DF4F: D0 0C =DF5D >250 BNE :1 ; and 1 if new ROMs +00DF51: 68 >251 PLA +00DF52: 8D 8C BF >252 STA IntPReg +00DF55: 68 >253 PLA +00DF56: 8D 8E BF >254 STA IntAddr +00DF59: 68 >255 PLA +00DF5A: 8D 8F BF >256 STA IntAddr+1 +00DF5D: 9A >257 :1 TXS ;Restore return addr & p-reg to stack +00DF5E: AD F8 07 >258 LDA MSLOT ;Set up to re-enable $cn00 rom +00DF61: 8D D6 DF >259 STA IrqDev+2 +00DF64: BA >260 TSX ;Make sure stack has room for 16 bytes +00DF65: 30 09 =DF70 >261 BMI NoStkSave ;Branch if stack safe +00DF67: A0 0F >262 LDY #16-1 +00DF69: 68 >263 StkSave PLA +00DF6A: 99 E2 DF >264 STA SvStack,Y +00DF6D: 88 >265 DEY +00DF6E: 10 F9 =DF69 >266 BPL StkSave + >267 +00DF70: A2 FA >268 NoStkSave LDX #$FA ;Save 6 bytes of zero page +00DF72: B5 00 >269 ZPgSave LDA $00,X +00DF74: 9D F8 DE >270 STA SvZeroPg-$FA,X +00DF77: E8 >271 INX +00DF78: D0 F8 =DF72 >272 BNE ZPgSave + >273 + >274 * Poll interupt routines for a claimer + >275 +00DF7A: AD 81 BF >276 LDA Intrup1+1 ;Test for valid routine +00DF7D: F0 05 =DF84 >277 BEQ :1 ;Branch if no routine +00DF7F: 20 F8 DF >278 JSR goInt1 +00DF82: 90 28 =DFAC >279 BCC IrqDone +00DF84: AD 83 BF >280 :1 LDA Intrup2+1 ;Test for valid routine +00DF87: F0 05 =DF8E >281 BEQ :2 ;Branch if no routine +00DF89: 20 FB DF >282 JSR goInt2 ;Execute routine +00DF8C: 90 1E =DFAC >283 BCC IrqDone +00DF8E: AD 85 BF >284 :2 LDA Intrup3+1 ;Test for valid routine +00DF91: F0 05 =DF98 >285 BEQ :3 ;Branch if no routine +00DF93: 20 FE DF >286 JSR goInt3 +00DF96: 90 14 =DFAC >287 BCC IrqDone +00DF98: AD 87 BF >288 :3 LDA Intrup4+1 ;Test for valid routine +00DF9B: F0 05 =DFA2 >289 BEQ IrqDeath ;Branch if no routine +00DF9D: 20 01 E0 >290 JSR goInt4 ;Execute routine +00DFA0: 90 0A =DFAC >291 BCC IrqDone + >292 + >293 *************** see rev note #35 ************************* + >294 +00DFA2: EE E1 DF >295 IrqDeath INC IrqCount ;Allow 255 unclaimed interrupts +00DFA5: D0 05 =DFAC >296 BNE IrqDone ; before going to system death... +00DFA7: A9 01 >297 LDA #unclaimedIntErr +00DFA9: 20 0C BF >298 JSR SysDeath + >299 + >300 * IRQ processing complete + >301 +00DFAC: A2 FA >302 IrqDone LDX #$FA +00DFAE: BD F8 DE >303 :loop LDA SvZeroPg-$FA,X +00DFB1: 95 00 >304 STA $00,X +00DFB3: E8 >305 INX +00DFB4: D0 F8 =DFAE >306 BNE :loop +00DFB6: AE 8B BF >307 LDX IntSReg ;Test for necessity of restoring stack elements +00DFB9: 30 0B =DFC6 >308 BMI :1 +00DFBB: A0 00 >309 LDY #$00 +00DFBD: B9 E2 DF >310 :loop2 LDA SvStack,Y +00DFC0: 48 >311 PHA +00DFC1: C8 >312 INY +00DFC2: C0 10 >313 CPY #16 +00DFC4: D0 F7 =DFBD >314 BNE :loop2 + >315 +00DFC6: AD E0 DF >316 :1 LDA IrqFlag ;Check for old ROMs +00DFC9: D0 12 =DFDD >317 BNE IrqDoneX ;Branch if new ROMs + >318 + >319 * Apple II or II+ monitor + >320 +00DFCB: AC 8A BF >321 LDY IntYReg ;Restore registers +00DFCE: AE 89 BF >322 LDX IntXReg +00DFD1: AD FF CF >323 LDA CLRROM ;Re-enable I/O card +00DFD4: AD 00 C1 >324 IrqDev LDA $C100 ;Warning, self modified +00DFD7: AD D6 DF >325 LDA IrqDev+2 ;Restore device ID +00DFDA: 8D F8 07 >326 STA MSLOT +00DFDD: 4C D0 BF >327 IrqDoneX JMP irqXit + >328 +00DFE0: 00 >329 IrqFlag DB $00 ;irq flag byte. 0=old ROMs; 1=new ROMs +00DFE1: 00 >330 IrqCount DB $00 ;Unclaimed interrupt counter.(note #35) +00DFE2: 00 00 00 00 >331 SvStack DS 16,0 +00DFF2: 00 00 00 00 >332 SvZeroPg DS 6,0 + >333 +00DFF8: 6C 80 BF >334 goInt1 JMP (Intrup1) +00DFFB: 6C 82 BF >335 goInt2 JMP (Intrup2) +00DFFE: 6C 84 BF >336 goInt3 JMP (Intrup3) +00E001: 6C 86 BF >337 goInt4 JMP (Intrup4) + >338 + >339 *------------------------------------------------- + >340 * System error handler + >341 +00E004: 8D 0F BF >342 SysErr1 STA SErr +00E007: FA >343 PLX +00E008: FA >344 PLX ;Pop 1 level of return +00E009: 38 >345 SEC +00E00A: 60 >346 RTS + >347 + >348 *------------------------------------------------- + >349 * System death handler + >350 +00E00B: AA >351 SysDeath1 TAX ;System death!!! +00E00C: 8D 0C C0 >352 STA CLR80VID ;Force 40 columns on rev-e +00E00F: AD 51 C0 >353 LDA TXTSET ;Text mode on +00E012: AD FF FE >354 LDA cortFlag ;Check if we're on a cortland +00E015: F0 03 =E01A >355 BEQ NoSupHires +00E017: 9C 29 C0 >356 STZ NEWVIDEO ;Force off SuperHires +00E01A: AD 54 C0 >357 NoSupHires LDA TXTPAGE1 ;Display page 1 on +00E01D: A0 13 >358 LDY #$13 +00E01F: A9 20 >359 DspDeath LDA #' ' +00E021: 99 32 05 >360 STA SLIN10+10,Y +00E024: 99 32 06 >361 STA SLIN12+10,Y +00E027: B9 44 FE >362 LDA Death,Y +00E02A: 99 B2 05 >363 STA SLIN11+10,Y +00E02D: 88 >364 DEY +00E02E: 10 EF =E01F >365 BPL DspDeath +00E030: 8A >366 TXA +00E031: 29 0F >367 AND #$0F +00E033: 09 B0 >368 ORA #"0" +00E035: C9 BA >369 CMP #"9"+1 +00E037: 90 02 =E03B >370 BCC :1 ;Branch if not >9 +00E039: 69 06 >371 ADC #$06 ;Bump to alpha A-F +00E03B: 8D C4 05 >372 :1 STA SLIN11+28 +00E03E: 80 FE =E03E >373 Halt BRA Halt ;Hold forever + 29 PUT mli.src/BFMgr + >2 ************************************************** + >3 * ProDOS block file manager + >4 * Perform filing or housekeeping functions + >5 * (X)=call # ($00-$13) + >6 +00E040: BD FC FD >7 BFMgr LDA Dispatch,X ;Translate into command address +00E043: 0A >8 ASL ;(bit 7 indicates a pathname to preprocess) +00E044: 8D C4 FE >9 STA cmdTmp +00E047: 29 3F >10 AND #$3F ;(bit6 is refnum preprocess, 5 is for time, so strip em.) +00E049: AA >11 TAX +00E04A: BD D4 FD >12 LDA cmdTable,X ;Move address for indirect jump +00E04D: 8D EE FE >13 STA goAdr +00E050: BD D5 FD >14 LDA cmdTable+1,X ;(high byte) +00E053: 8D EF FE >15 STA goAdr+1 +00E056: A9 20 >16 LDA #backupNeeded ;Init "backup bit flag" +00E058: 8D C5 FE >17 STA bkBitFlg ; to say "file modified" +00E05B: 90 05 =E062 >18 BCC NoPath + >19 + >20 * For MLI calls $C0-$C4, $C8 + >21 +00E05D: 20 7D E0 >22 JSR SetPath ;Go process pathname before calling command +00E060: B0 17 =E079 >23 BCS ErrorSys ;Branch if bad name + >24 +00E062: 0E C4 FE >25 NoPath ASL cmdTmp ;Test for refnum preprocessing +00E065: 90 05 =E06C >26 BCC NoPreRef + >27 + >28 * For MLI calls $C9-$CB, $CE-$D3 + >29 +00E067: 20 BD E1 >30 JSR FindFCB ;Go set up pointers to fcb and vcb of this file +00E06A: B0 0D =E079 >31 BCS ErrorSys ;branch if any errors are encountered + >32 +00E06C: 0E C4 FE >33 NoPreRef ASL cmdTmp ;Lastly check for necessity of time stamp +00E06F: 90 03 =E074 >34 BCC Execute + >35 + >36 * For MLI calls $C0-$C4, $CC, $CD + >37 +00E071: 20 06 BF >38 JSR DateTime ;(No error posible) + >39 +00E074: 20 F3 DE >40 Execute JSR GoCmd ;Execute command +00E077: 90 03 =E07C >41 BCC GoodOp ;Branch if successful + >42 +00E079: 20 09 BF >43 ErrorSys JSR SysErr ;Don't come back +00E07C: 60 >44 GoodOp RTS ;Good return + >45 + >46 *------------------------------------------------- + >47 * Check caller's pathname & copy to pathname buffer + >48 +00E07D: A0 01 >49 SetPath LDY #c_path +00E07F: B1 40 >50 LDA (parm),Y ;Get low pointer addr +00E081: 85 48 >51 STA tPath +00E083: C8 >52 INY +00E084: B1 40 >53 LDA (parm),Y +00E086: 85 49 >54 STA tPath+1 ; & hi pointer addr + >55 + =E088 >56 SynPath EQU * ;Entry used by rename for second pathname +00E088: A2 00 >57 LDX #$00 ;X-reg is used as index to pathBuf +00E08A: A0 00 >58 LDY #$00 ;Y-reg is index to input pathname +00E08C: 8E CC FE >59 STX prfxFlg ;Assume prefix is in use +00E08F: 8E 00 D7 >60 STX pathBuf ;Mark pathbuf to indicate nothing processed +00E092: B1 48 >61 LDA (tPath),Y ;Validate pathname length>0, and <65 +00E094: F0 58 =E0EE >62 BEQ ErrSyn +00E096: C9 41 >63 CMP #65 +00E098: B0 54 =E0EE >64 BCS ErrSyn +00E09A: 8D B0 FE >65 STA pathCnt ;This is used to compare for +00E09D: EE B0 FE >66 INC pathCnt ; end of pathname processing +00E0A0: C8 >67 INY ;Now check for full pathname... +00E0A1: B1 48 >68 LDA (tPath),Y ;(Full name if starts with "/") +00E0A3: 09 80 >69 ORA #$80 +00E0A5: C9 AF >70 CMP #"/" +00E0A7: D0 04 =E0AD >71 BNE NotFullPN ;Branch if prefix appended +00E0A9: 8D CC FE >72 STA prfxFlg ;Set prefix flag to indicate prefix not used +00E0AC: C8 >73 INY ;Index to first character of pathname + >74 +00E0AD: A9 FF >75 NotFullPN LDA #$FF ;Set current position of pathBuf +00E0AF: 9D 00 D7 >76 STA pathBuf,X ; to indicate end of pathname +00E0B2: 8D C8 FE >77 STA namCnt ;Also indicate no characters processed in local name +00E0B5: 8E CA FE >78 STX namPtr ;Preserve pointer to local name length byte + >79 +00E0B8: CC B0 FE >80 SynPath3 CPY pathCnt ;done with pathname processing? +00E0BB: B0 35 =E0F2 >81 BCS EndPath ;Yes +00E0BD: B1 48 >82 LDA (tPath),Y ;Get character +00E0BF: 29 7F >83 AND #$7F ;We're not interested in high order bit +00E0C1: E8 >84 INX ;Prepare for next character +00E0C2: C8 >85 INY +00E0C3: C9 2F >86 CMP #'/' ;Is it a slash delimiter? +00E0C5: F0 40 =E107 >87 BEQ EndName ;Branch if it is +00E0C7: C9 61 >88 CMP #'a' ;Is it lower case character? +00E0C9: 90 02 =E0CD >89 BCC NotLower ;Branch if not +00E0CB: 29 5F >90 AND #$5F ;Upshift to upper case +00E0CD: 9D 00 D7 >91 NotLower STA pathBuf,X ;Store charcter +00E0D0: EE C8 FE >92 INC namCnt ;Is it the first of a local name? +00E0D3: D0 05 =E0DA >93 BNE NotFirst ;Branch if not +00E0D5: EE C8 FE >94 INC namCnt ;Kick count to 1 +00E0D8: D0 0C =E0E6 >95 BNE TestAlfa ;First char. Must be alpha (branch always taken) + >96 +00E0DA: C9 2E >97 NotFirst CMP #'.' ;Is it "."? +00E0DC: F0 DA =E0B8 >98 BEQ SynPath3 ;It's ok if it is, do next char +00E0DE: C9 30 >99 CMP #'0' ;Is it at least "0"? +00E0E0: 90 0C =E0EE >100 BCC ErrSyn ;Report syntax error if not +00E0E2: C9 3A >101 CMP #'9'+1 ;Is it numeric? +00E0E4: 90 D2 =E0B8 >102 BCC SynPath3 ;ok if it is, do next character + >103 +00E0E6: C9 41 >104 TestAlfa CMP #'A' ;Is it at least an "a"? +00E0E8: 90 04 =E0EE >105 BCC ErrSyn ;Report err if not +00E0EA: C9 5B >106 CMP #'Z'+1 ;Is it g.t. "z"? +00E0EC: 90 CA =E0B8 >107 BCC SynPath3 ;Get next char if valid alpha +00E0EE: 38 >108 ErrSyn SEC ;Make sure carry set +00E0EF: A9 40 >109 LDA #badPathSyntax +00E0F1: 60 >110 RTS ;Report error + >111 +00E0F2: A9 00 >112 EndPath LDA #$00 ;End pathname with 0 +00E0F4: 2C C8 FE >113 BIT namCnt ;Also make sure name count is positive +00E0F7: 10 04 =E0FD >114 BPL :1 +00E0F9: 8D C8 FE >115 STA namCnt ;=0 +00E0FC: CA >116 DEX +00E0FD: E8 >117 :1 INX +00E0FE: 9D 00 D7 >118 STA pathBuf,X +00E101: F0 EB =E0EE >119 BEQ ErrSyn ;Report error if "/" only +00E103: 8E B0 FE >120 STX pathCnt ;Save true length of pathname +00E106: AA >121 TAX ;X=0 causes end of process, after endname + >122 +00E107: AD C8 FE >123 EndName LDA namCnt ;Validate local name <16 +00E10A: C9 10 >124 CMP #15+1 +00E10C: B0 E0 =E0EE >125 BCS ErrSyn +00E10E: DA >126 PHX ;Save current pointer +00E10F: AE CA FE >127 LDX namPtr ;Get index to beginning of local name +00E112: 9D 00 D7 >128 STA pathBuf,X ;Save local name's length +00E115: FA >129 PLX ;Restore x +00E116: D0 95 =E0AD >130 BNE NotFullPN ;Branch if more names to process + >131 +00E118: 18 >132 CLC ;Indicate success! +00E119: AD CC FE >133 LDA prfxFlg ; but make sure all pathnames are +00E11C: D0 05 =E123 >134 BNE EndRTS ; prefixed or begin with a "/" +00E11E: AD 97 BF >135 LDA NewPfxPtr ; must be non-zero +00E121: F0 CB =E0EE >136 BEQ ErrSyn +00E123: 60 >137 EndRTS RTS + >138 + >139 ************************************************** + >140 * SETPREFIX Call + >141 +00E124: 20 7D E0 >142 SetPrefix JSR SetPath ;Call is made here so a 'null' path may be detected +00E127: 90 0A =E133 >143 BCC :1 ;Branch if pathname ok +00E129: AC 00 D7 >144 LDY pathBuf ;Was it a nul pathname? +00E12C: D0 4C =E17A >145 BNE PfxErr ;Branch if true syntax error +00E12E: 20 EC FF >146 JSR ZeroPfxPtrs ;Indicate null prefix. NB. (Y)=0 +00E131: 18 >147 CLC +00E132: 60 >148 RTS + >149 +00E133: 20 72 E5 >150 :1 JSR FindFile ;Go find specified prefix directory +00E136: 90 04 =E13C >151 BCC :2 ;Branch if no error +00E138: C9 40 >152 CMP #badPathSyntax +00E13A: D0 3E =E17A >153 BNE PfxErr ;Branch if error is real (not root dir) + >154 +00E13C: AD 71 FE >155 :2 LDA d_file+d_stor ;Make sure last local name is DIR type +00E13F: 29 D0 >156 AND #directoryFile*16 ;(either root or sub) +00E141: 49 D0 >157 EOR #directoryFile*16 ;Is it a directory? +00E143: D0 33 =E178 >158 BNE PfxTypErr ;Report wrong type +00E145: AC CC FE >159 LDY prfxFlg ;New or appended prefix? +00E148: D0 03 =E14D >160 BNE :3 ;(A)=0 if branch taken +00E14A: AD 97 BF >161 LDA NewPfxPtr ;Append new prefix to old +00E14D: A8 >162 :3 TAY +00E14E: 38 >163 SEC ;Find new beginning of prefix +00E14F: ED B0 FE >164 SBC pathCnt +00E152: C9 C0 >165 CMP #$C0 ;Too long? ($100-$40) +00E154: 90 98 =E0EE >166 BCC ErrSyn ;Report it if so +00E156: AA >167 TAX +00E157: 20 F3 FF >168 JSR SetPfxPtrs +00E15A: AD 6B FE >169 LDA d_dev ;Save device number +00E15D: 8D B1 FE >170 STA pathDev +00E160: AD 82 FE >171 LDA d_file+d_first ; & addr of first block +00E163: 8D B2 FE >172 STA pathBlok +00E166: AD 83 FE >173 LDA d_file+d_first+1 +00E169: 8D B3 FE >174 STA pathBlok+1 +00E16C: B9 00 D7 >175 MovPrefix LDA pathBuf,Y +00E16F: 9D 00 D7 >176 STA pathBuf,X +00E172: C8 >177 INY +00E173: E8 >178 INX +00E174: D0 F6 =E16C >179 BNE MovPrefix +00E176: 18 >180 CLC ;Indicate good prefix +00E177: 60 >181 RTS + >182 +00E178: A9 4B >183 PfxTypErr LDA #badStoreType ;Report not a directory +00E17A: 38 >184 PfxErr SEC ;indicate error +00E17B: 60 >185 RTS + >186 + >187 ************************************************** + >188 * GETPREFIX Call + >189 +00E17C: 18 >190 GetPrefix CLC ;Calculate how big a buffer is needed to +00E17D: A0 01 >191 LDY #c_path ;Get index to user's pathname buffer +00E17F: B1 40 >192 LDA (parm),Y +00E181: 85 4E >193 STA userBuf +00E183: C8 >194 INY +00E184: B1 40 >195 LDA (parm),Y +00E186: 85 4F >196 STA userBuf+1 +00E188: 9C EA FE >197 STZ cBytes+1 ;Set buf length at max +00E18B: A9 40 >198 LDA #64 ;(64 characters max) +00E18D: 8D E9 FE >199 STA cBytes +00E190: 20 65 FC >200 JSR ValDBuf ;Go validate prefix buffer addr +00E193: B0 E5 =E17A >201 BCS PfxErr +00E195: A0 00 >202 LDY #$00 ;Y is indirect index to user buffer +00E197: AD 97 BF >203 LDA NewPfxPtr ;Get address of beginning of prefix +00E19A: AA >204 TAX +00E19B: F0 04 =E1A1 >205 BEQ NullPrefix ;Branch if null prefix +00E19D: 49 FF >206 EOR #$FF ;Get total length of prefix +00E19F: 69 02 >207 ADC #$02 ;Add 2 for leading and trailing slashes +00E1A1: 91 4E >208 NullPrefix STA (userBuf),Y ;Store length in user's buffer +00E1A3: F0 16 =E1BB >209 BEQ GotPrefix ;Branch if null prefix +00E1A5: C8 >210 SendPrefix INY ;Bump to next user buf loc +00E1A6: BD 00 D7 >211 LDA pathBuf,X ;Get next char of prefix +00E1A9: 91 4E >212 SndLimit STA (userBuf),Y ;Give character to user +00E1AB: 29 F0 >213 AND #$F0 ;Check for length descriptor +00E1AD: D0 04 =E1B3 >214 BNE :1 ;Branch if regular character +00E1AF: A9 2F >215 LDA #'/' ;Otherwise, substitute a slash +00E1B1: D0 F6 =E1A9 >216 BNE SndLimit ;Branch always + >217 +00E1B3: E8 >218 :1 INX +00E1B4: D0 EF =E1A5 >219 BNE SendPrefix ;Branch if more to send +00E1B6: C8 >220 INY +00E1B7: A9 2F >221 LDA #'/' ;End with slash +00E1B9: 91 4E >222 STA (userBuf),Y +00E1BB: 18 >223 GotPrefix CLC ;Indicate no error +00E1BC: 60 >224 RTS + >225 + >226 *------------------------------------------------- + >227 * Validity check the ref # passed by caller + >228 +00E1BD: A0 01 >229 FindFCB LDY #c_refNum ;Index to reference number +00E1BF: B1 40 >230 LDA (parm),Y ;Is it a valid file number? +00E1C1: F0 5A =E21D >231 BEQ ErrRefNum ;Must not be 0! +00E1C3: C9 09 >232 CMP #8+1 ;Must be 1 to 8 only +00E1C5: B0 56 =E21D >233 BCS ErrRefNum ;User must be stoned... +00E1C7: 48 >234 PHA +00E1C8: 3A >235 DEC ;(subtracts 1) +00E1C9: 4A >236 LSR ;Shift low 3 bits to high bits +00E1CA: 6A >237 ROR +00E1CB: 6A >238 ROR +00E1CC: 6A >239 ROR ;Effective multiply by 32 +00E1CD: 8D A4 FE >240 STA fcbPtr ;Later used as an index +00E1D0: A8 >241 TAY ; to FCB like now +00E1D1: 68 >242 PLA ;Restore refnum in A-reg +00E1D2: D9 00 D8 >243 CMP fcb+fcbRefNum,Y ;Is it an open reference? +00E1D5: D0 41 =E218 >244 BNE ErrNoRef ;Branch if not + >245 +00E1D7: B9 0B D8 >246 FndFCBuf LDA fcb+fcbFileBuf,Y ;Get page addr of file buffer +00E1DA: 20 22 FC >247 JSR GetBufAdr ;Get file's address into bufAddrL & H +00E1DD: AE ED FE >248 LDX bufAddrH ;(Y)=fcbptr - preserved +00E1E0: F0 27 =E209 >249 BEQ FCBDead ;Report FCB screwed up!!! +00E1E2: 86 4B >250 STX dataPtr+1 ;Save pointer to data area of buffer +00E1E4: E8 >251 INX +00E1E5: E8 >252 INX ;Index block always 2 pages after data +00E1E6: 86 49 >253 STX tIndex+1 +00E1E8: B9 01 D8 >254 LDA fcb+fcbDevNum,Y ;Also set up device number +00E1EB: 8D 30 BF >255 STA DevNum +00E1EE: AD EC FE >256 LDA bufAddrL +00E1F1: 85 4A >257 STA dataPtr ;Index and data buffers +00E1F3: 85 48 >258 STA tIndex ; always on page boundaries + >259 +00E1F5: AA >260 SrchVCBs TAX ;Search for associated VCB +00E1F6: BD 10 D9 >261 LDA vcb+vcbDevice,X +00E1F9: D9 01 D8 >262 CMP fcb+fcbDevNum,Y ;Is this VCB the same device? +00E1FC: F0 10 =E20E >263 BEQ TestVOpen ;If it is, make sure volume is active + >264 +00E1FE: 8A >265 NxtBufr TXA ;Adjust index to next VCB +00E1FF: 18 >266 CLC +00E200: 69 20 >267 ADC #vcbSize +00E202: 90 F1 =E1F5 >268 BCC SrchVCBs ;Loop until volume found +00E204: A9 0A >269 LDA #vcbUnusable ;Report open file has no volume... +00E206: 20 0C BF >270 JSR SysDeath ; & kill the system + >271 +00E209: A9 0B >272 FCBDead LDA #fcbUnusable ;Report FCB trashed +00E20B: 20 0C BF >273 JSR SysDeath ; & kill the system + >274 +00E20E: BD 00 D9 >275 TestVOpen LDA vcb,X ;Make sure this VCB is open +00E211: F0 EB =E1FE >276 BEQ NxtBufr ;Branch if it is not active +00E213: 8E A3 FE >277 STX vcbPtr ;Save pointer to good VCB +00E216: 18 >278 CLC ;Indicate all's well +00E217: 60 >279 RTS + >280 +00E218: A9 00 >281 ErrNoRef LDA #$00 ;Drop a zero into this FCB +00E21A: 99 00 D8 >282 STA fcb+fcbRefNum,Y ; to show free FCB + >283 +00E21D: A9 43 >284 ErrRefNum LDA #invalidRefNum ;Tell user that requested refnum +00E21F: 38 >285 SEC ; is illegal (out of range) for this call +00E220: 60 >286 RTS + >287 + >288 ************************************************** + >289 * ONLINE call + >290 +00E221: 20 D6 F1 >291 Online JSR MovDBuf ;Move user specified buffer pointer to usrbuf +00E224: 9C E9 FE >292 STZ cBytes ;Figure out how big buffer has to be +00E227: 9C EA FE >293 STZ cBytes+1 +00E22A: A0 01 >294 LDY #c_devNum +00E22C: B1 40 >295 LDA (parm),Y ;If zero then cbytes=$100, else =$010 for one device +00E22E: 29 F0 >296 AND #$F0 +00E230: 8D 30 BF >297 STA DevNum +00E233: F0 07 =E23C >298 BEQ :1 ;Branch if all devices +00E235: A9 10 >299 LDA #$10 +00E237: 8D E9 FE >300 STA cBytes +00E23A: D0 03 =E23F >301 BNE :2 ;Always +00E23C: EE EA FE >302 :1 INC cBytes+1 ;Allow for up to 16 devices +00E23F: 20 65 FC >303 :2 JSR ValDBuf ;Go validate buffer range against allocated memory +00E242: B0 2F =E273 >304 BCS OnlinErr +00E244: A9 00 >305 LDA #$00 ;Zero out user buffer space +00E246: AC E9 FE >306 LDY cBytes +00E249: 88 >307 :loop1 DEY +00E24A: 91 4E >308 STA (userBuf),Y ;Zero either 16 or 256 bytes +00E24C: D0 FB =E249 >309 BNE :loop1 ;Branch if more to zero +00E24E: 8D CA FE >310 STA namPtr ;Use namPtr as pointer to user buffer +00E251: AD 30 BF >311 LDA DevNum +00E254: D0 1E =E274 >312 BNE OnlineZ ;Branch if only 1 device to process +00E256: 20 2A E8 >313 JSR MovDevNums ;Get list of currently recognized devices +00E259: DA >314 :loop2 PHX ;Save index to last item on list +00E25A: BD D9 FE >315 LDA lookList,X ;Get next device # +00E25D: 8D 30 BF >316 STA DevNum +00E260: 20 74 E2 >317 JSR OnlineZ ;Log this volume and return it's name to user +00E263: AD CA FE >318 LDA namPtr +00E266: 18 >319 CLC +00E267: 69 10 >320 ADC #$10 +00E269: 8D CA FE >321 STA namPtr +00E26C: FA >322 PLX ;Restore index to device list +00E26D: CA >323 DEX ;Index to next device +00E26E: 10 E9 =E259 >324 BPL :loop2 ;Branch if there is another device +00E270: A9 00 >325 LDA #$00 ;No errors for muliple on-line +00E272: 18 >326 CLC ;Indicate good on all volumes +00E273: 60 >327 OnlinErr RTS + >328 + >329 * Generate return data for a specific device + >330 +00E274: 20 3C E8 >331 OnlineZ JSR ScanVCB ;See if it has already been logged in +00E277: B0 3B =E2B4 >332 BCS OnlinErr1 ;Branch if VCB is full +00E279: A2 00 >333 LDX #$00 ;Read in root (volume) directory +00E27B: A9 02 >334 LDA #$02 ;(X,A)=block # +00E27D: 20 B7 EB >335 JSR RdBlkAX ;Read it into general purpose buffer +00E280: AE A3 FE >336 LDX vcbPtr ;Use x as an index to the vcb entry + >337 + >338 * This fix is to remove VCB entries that correspond to devices that + >339 * are no longer in the device list (i.e. removed by the user). + >340 +00E283: 90 0F =E294 >341 BCC VolFound ;Branch if the read was ok +00E285: A8 >342 TAY ;Save error value in Y-reg +00E286: BD 11 D9 >343 LDA vcb+vcbStatus,X ;Don't take the VCB off line if +00E289: D0 06 =E291 >344 BNE RtrnErr ; there are active files present! +00E28B: 9D 00 D9 >345 STA vcb,X ;Now take the volume off line +00E28E: 9D 10 D9 >346 STA vcb+vcbDevice,X +00E291: 98 >347 RtrnErr TYA ;Now return error to A +00E292: B0 20 =E2B4 >348 BCS OnlinErr1 + >349 + >350 * 1st vol dir blk has been read successfully + >351 +00E294: BD 00 D9 >352 VolFound LDA vcb,X ;Has it been logged in before? +00E297: F0 05 =E29E >353 BEQ :1 ;Branch if not +00E299: BD 11 D9 >354 LDA vcb+vcbStatus,X ;It has, are there active files? +00E29C: 30 0C =E2AA >355 BMI :2 ;Branch if the volume is currently busy +00E29E: 20 B0 E8 >356 :1 JSR LogVCBZ ;Go log it in +00E2A1: B0 11 =E2B4 >357 BCS OnlinErr1 ;Branch if there is some problem (like notsos) +00E2A3: A9 57 >358 LDA #dupVolume ;Anticipate a duplicate active volume exists +00E2A5: 2C C6 FE >359 BIT duplFlag +00E2A8: 30 0A =E2B4 >360 BMI OnlinErr1 ;Branch if we guessed right +00E2AA: AE A3 FE >361 :2 LDX vcbPtr ;Restore vcbptr just in case we lost it +00E2AD: 20 06 E9 >362 JSR CmpVCB ;Does read in volume compare with logged volume? +00E2B0: A9 2E >363 LDA #drvrDiskSwitch ;Anticipate wrong volume mounted in active device +00E2B2: 90 1C =E2D0 >364 BCC Online2 ;Branch if no problem! + >365 + >366 * On fall thru, (A)=disk switch error + >367 * Store error code in user's data buffer + >368 +00E2B4: 48 >369 OnlinErr1 PHA ;Save error code +00E2B5: 20 E5 E2 >370 JSR SavDevNbr ;Tell user what device we looked at +00E2B8: 68 >371 PLA ;Get error code again +00E2B9: C8 >372 INY ;Tell user what error was encountered on this device +00E2BA: 91 4E >373 STA (userBuf),Y +00E2BC: C9 57 >374 CMP #dupVolume ;Was it a duplicate volume error? +00E2BE: D0 0E =E2CE >375 BNE :1 ;Branch if not, +00E2C0: C8 >376 INY ;Otherwise tell user which other device has same name +00E2C1: AE C7 FE >377 LDX vcbEntry +00E2C4: BD 10 D9 >378 LDA vcb+vcbDevice,X +00E2C7: 91 4E >379 STA (userBuf),Y +00E2C9: 9C C6 FE >380 STZ duplFlag ;Clear duplicate flag +00E2CC: A9 57 >381 LDA #dupVolume ;Restore error code +00E2CE: 38 >382 :1 SEC ;Indicate error +00E2CF: 60 >383 RTS + >384 + >385 * Make online volume entry + >386 +00E2D0: BD 00 D9 >387 Online2 LDA vcb,X ;Get volume name count +00E2D3: 8D C8 FE >388 STA namCnt +00E2D6: AC CA FE >389 LDY namPtr ;Index to user's buffer +00E2D9: BD 00 D9 >390 :loop LDA vcb,X ;Move name to user's buffer +00E2DC: 91 4E >391 STA (userBuf),Y +00E2DE: E8 >392 INX +00E2DF: C8 >393 INY +00E2E0: CE C8 FE >394 DEC namCnt ;Loop until all characters moved +00E2E3: 10 F4 =E2D9 >395 BPL :loop + >396 +00E2E5: AC CA FE >397 SavDevNbr LDY namPtr ;Index to first byte of this entry +00E2E8: AD 30 BF >398 LDA DevNum ;Put device number in upper nibble of this byte +00E2EB: 11 4E >399 ORA (userBuf),Y ;Lower nibble is name length +00E2ED: 91 4E >400 STA (userBuf),Y +00E2EF: 18 >401 CLC ;Indicate no errors +00E2F0: 60 >402 RTS + 30 PUT mli.src/Create + >1 ************************************************** + >2 * CREATE call + >3 +00E2F1: 20 85 E5 >4 Create JSR LookFile ;Check for duplicate / get free entry +00E2F4: B0 04 =E2FA >5 BCS TestFnF ;Error code in A-reg may be 'file not found' +00E2F6: A9 47 >6 LDA #dupPathname ;Tell 'em a file of that name already exists +00E2F8: 38 >7 CrErr1 SEC ;Indicate error encountered +00E2F9: 60 >8 RTS ;Return error in A-reg + >9 +00E2FA: C9 46 >10 TestFnF CMP #fileNotFound ;'file not found' is what we want +00E2FC: D0 FA =E2F8 >11 BNE CrErr1 ;Pass back other error +00E2FE: A0 07 >12 LDY #c_fileKind ;Test for "tree" or directory file +00E300: B1 40 >13 LDA (parm),Y ;No other kinds are legal +00E302: C9 04 >14 CMP #tree+1 ;Is it seed, sapling, or tree? +00E304: 90 04 =E30A >15 BCC :1 ;Branch if it is +00E306: C9 0D >16 CMP #directoryFile +00E308: D0 10 =E31A >17 BNE CrTypErr ;Report type error if not directory. + >18 +00E30A: AD 30 BF >19 :1 LDA DevNum ;Before proceeding, make sure destination +00E30D: 20 24 F4 >20 JSR TestWrProtZ ; device is not write protected... +00E310: B0 0B =E31D >21 BCS CrRtn +00E312: AD AD FE >22 LDA noFree ;Is there space in directory to add this file? +00E315: F0 07 =E31E >23 BEQ XtnDir ;Branch if not +00E317: 4C 9E E3 >24 JMP CreateZ ;Otherwise, go create file + >25 +00E31A: A9 4B >26 CrTypErr LDA #badStoreType +00E31C: 38 >27 SEC ;Indicate error +00E31D: 60 >28 CrRtn RTS + >29 +00E31E: AD 58 FE >30 XtnDir LDA ownersBlock ;Before extending directory, +00E321: 0D 59 FE >31 ORA ownersBlock+1 ; make sure it is a sub-directory!!! +00E324: D0 04 =E32A >32 BNE :11 +00E326: A9 49 >33 LDA #volDirFull ;Otherwise report directory full error. +00E328: 38 >34 SEC +00E329: 60 >35 RTS + >36 +00E32A: A5 46 >37 :11 LDA blockNum ;Preserve disk addr of current (last) +00E32C: 48 >38 PHA +00E32D: A5 47 >39 LDA blockNum+1 ; directory link, before allocating +00E32F: 48 >40 PHA ; an extend block +00E330: 20 90 EA >41 JSR Alloc1Blk ;Allocate a block for extending directory +00E333: FA >42 PLX +00E334: 86 47 >43 STX blockNum+1 ;Restore block addr of directory stuff in gbuf +00E336: FA >44 PLX +00E337: 86 46 >45 STX blockNum +00E339: B0 E2 =E31D >46 BCS CrRtn ;Branch if unable to allocate +00E33B: 8D 02 DC >47 STA genBuf+2 ;Save low block address in current directory +00E33E: 8C 03 DC >48 STY genBuf+3 ; & hi addr too +00E341: 20 C3 EB >49 JSR WrtGBuf ;Go update dir. block with new link +00E344: B0 D7 =E31D >50 BCS CrRtn ;(report any errors.) + >51 +00E346: A2 01 >52 LDX #$01 +00E348: B5 46 >53 SwapBloks LDA blockNum,X ;Now prepare new directory block +00E34A: 9D 00 DC >54 STA genBuf,X ;Use current block as back link +00E34D: BD 02 DC >55 LDA genBuf+2,X +00E350: 95 46 >56 STA blockNum,X ; & save new block as next to be written +00E352: CA >57 DEX +00E353: 10 F3 =E348 >58 BPL SwapBloks + >59 +00E355: E8 >60 INX ;Now X=0 +00E356: 8A >61 TXA ; and A=0 too +00E357: 9D 02 DC >62 ClrDir STA genBuf+2,X +00E35A: 9D 00 DD >63 STA genBuf+$100,X +00E35D: E8 >64 INX +00E35E: D0 F7 =E357 >65 BNE ClrDir + >66 +00E360: 20 C3 EB >67 JSR WrtGBuf ;Write prepared directory extension +00E363: B0 B8 =E31D >68 BCS CrRtn ;Report errors + >69 +00E365: AD 58 FE >70 LDA ownersBlock +00E368: AE 59 FE >71 LDX ownersBlock+1 +00E36B: 20 B7 EB >72 JSR RdBlkAX ;Read in 'parent' directory block +00E36E: AE 5A FE >73 LDX ownersEnt ;Prepare to calculate entry address +00E371: A9 DC >74 LDA #genBuf/256 +00E373: 85 49 >75 STA dirBufPtr+1 + >76 +00E375: A9 04 >77 LDA #$04 ;Skip 4-byte blk link ptrs +00E377: 18 >78 OCalc CLC +00E378: CA >79 DEX ;Has entry addr been computed? +00E379: F0 09 =E384 >80 BEQ :21 ;Branch if yes +00E37B: 6D 5B FE >81 ADC ownersLen ;Bump to next entry adr +00E37E: 90 F7 =E377 >82 BCC OCalc +00E380: E6 49 >83 INC dirBufPtr+1 ;Entry must be in second 256 of block +00E382: B0 F3 =E377 >84 BCS OCalc ;Branch always + >85 +00E384: 85 48 >86 :21 STA dirBufPtr +00E386: A0 13 >87 LDY #d_usage ;Index to block count +00E388: B1 48 >88 :loop LDA (dirBufPtr),Y +00E38A: 79 FD FD >89 ADC dIncTbl-d_usage,Y ;Add 1 to block count and +00E38D: 91 48 >90 STA (dirBufPtr),Y +00E38F: C8 >91 INY +00E390: 98 >92 TYA ; $200 to the directory's end of file +00E391: 49 18 >93 EOR #d_eof+3 ;Done with usage/eof update? +00E393: D0 F3 =E388 >94 BNE :loop ;Branch if not + >95 +00E395: 20 C3 EB >96 JSR WrtGBuf ;Go update parent +00E398: B0 03 =E39D >97 BCS :2 +00E39A: 4C F1 E2 >98 JMP Create +00E39D: 60 >99 :2 RTS + >100 + =E39E >101 CreateZ EQU * ;Build new file + >102 + >103 *------------------------------------------------- + >104 * Zero general purpose buffer ($DC00-$DDFF) + >105 +00E39E: A2 00 >106 ZeroGBuf LDX #$00 +00E3A0: 9E 00 DC >107 ClrGBuf STZ genBuf,X ;Zero out genBuf +00E3A3: 9E 00 DD >108 STZ genBuf+$100,X +00E3A6: E8 >109 INX +00E3A7: D0 F7 =E3A0 >110 BNE ClrGBuf ;loop until zipped! + >111 +00E3A9: A0 0B >112 LDY #c_time+1 ;Move user specified date/time +00E3AB: B1 40 >113 :loop1 LDA (parm),Y ; to directory entry +00E3AD: 99 81 FE >114 STA d_file+d_creDate-c_date,y +00E3B0: 8A >115 TXA ;If all four bytes of date/time are zero +00E3B1: 11 40 >116 ORA (parm),Y ; then use built in date/time +00E3B3: AA >117 TAX +00E3B4: 88 >118 DEY ;Have all four bytes been moved and tested? +00E3B5: C0 07 >119 CPY #c_fileKind +00E3B7: D0 F2 =E3AB >120 BNE :loop1 ;Branch if not +00E3B9: 8A >121 TXA ;Does user want default time? +00E3BA: D0 0B =E3C7 >122 BNE :1 ;Branch if not + >123 +00E3BC: A2 03 >124 LDX #$03 +00E3BE: BD 90 BF >125 :loop2 LDA DateLo,X ;Move current default date/time +00E3C1: 9D 89 FE >126 STA d_file+d_creDate,X +00E3C4: CA >127 DEX +00E3C5: 10 F7 =E3BE >128 BPL :loop2 + >129 +00E3C7: B1 40 >130 :1 LDA (parm),Y ;(y is indexing fileKind) +00E3C9: C9 04 >131 CMP #tree+1 +00E3CB: A9 10 >132 LDA #seedling*16 ;Assume tree type +00E3CD: 90 02 =E3D1 >133 BCC :2 +00E3CF: A9 D0 >134 LDA #directoryFile*16 ;Its dir since file kind has already been verified +00E3D1: AE CA FE >135 :2 LDX namPtr ;Get index to 'local' name of pathname +00E3D4: 1D 00 D7 >136 ORA pathBuf,X ;Combine file kind with name length +00E3D7: 8D 71 FE >137 STA d_file+d_stor ;(sos calls this 'storage type') +00E3DA: 29 0F >138 AND #$0F ;Strip back to name length +00E3DC: A8 >139 TAY ; & use as count-down for move +00E3DD: 18 >140 CLC +00E3DE: 6D CA FE >141 ADC namPtr ;Calculate end of name +00E3E1: AA >142 TAX + >143 +00E3E2: BD 00 D7 >144 CrName LDA pathBuf,X ;Now move local name as filename +00E3E5: 99 71 FE >145 STA d_file+d_stor,Y +00E3E8: CA >146 DEX +00E3E9: 88 >147 DEY ;All characters transfered? +00E3EA: D0 F6 =E3E2 >148 BNE CrName ;Branch if not + >149 +00E3EC: A0 03 >150 LDY #c_attr ;Index to 'access' parameter +00E3EE: B1 40 >151 LDA (parm),Y +00E3F0: 8D 8F FE >152 STA d_file+d_attr +00E3F3: C8 >153 INY ;Also move 'file identification' +00E3F4: B1 40 >154 LDA (parm),Y +00E3F6: 8D 81 FE >155 STA d_file+d_fileID + >156 +00E3F9: C8 >157 :loop1 INY ; & finally, the auxillary +00E3FA: B1 40 >158 LDA (parm),Y ; identifcation bytes +00E3FC: 99 8B FE >159 STA d_file+d_auxID-c_auxID,Y +00E3FF: C0 06 >160 CPY #c_auxID+1 +00E401: D0 F6 =E3F9 >161 BNE :loop1 + >162 +00E403: AD 16 FE >163 LDA XDOSver ;Save current xdos version number +00E406: 8D 8D FE >164 STA d_file+d_sosVer +00E409: AD 17 FE >165 LDA compat ; & backward compatiblity number +00E40C: 8D 8E FE >166 STA d_file+d_comp + >167 +00E40F: A9 01 >168 LDA #$01 ;Usage is always 1 block +00E411: 8D 84 FE >169 STA d_file+d_usage +00E414: AD 6C FE >170 LDA d_head ;Place back pointer to header block +00E417: 8D 96 FE >171 STA d_file+d_dHdr +00E41A: AD 6D FE >172 LDA d_head+1 +00E41D: 8D 97 FE >173 STA d_file+d_dHdr+1 + >174 +00E420: AD 71 FE >175 LDA d_file+d_stor ;Get storage type again +00E423: 29 E0 >176 AND #$E0 ;Is it a directory? +00E425: F0 35 =E45C >177 BEQ CrAlocBlk ;Branch if seed file + >178 +00E427: A2 1E >179 LDX #30 ;Move header to data block +00E429: BD 71 FE >180 :loop2 LDA d_file+d_stor,X +00E42C: 9D 04 DC >181 STA genBuf+4,X +00E42F: CA >182 DEX +00E430: 10 F7 =E429 >183 BPL :loop2 + >184 +00E432: 49 30 >185 EOR #$30 ;($Dn->$En) last byte is fileKind/namlen +00E434: 8D 04 DC >186 STA genBuf+4 ;Make it a directory header mark + >187 +00E437: A2 07 >188 LDX #$07 ;Now overwrite password area +00E439: BD 15 FE >189 :loop3 LDA Pass,X ; and other header info +00E43C: 9D 14 DC >190 STA genBuf+4+hPassEnable,X +00E43F: BD 16 FE >191 LDA XDOSver,X +00E442: 9D 20 DC >192 STA genBuf+4+hVer,X +00E445: CA >193 DEX +00E446: 10 F1 =E439 >194 BPL :loop3 + >195 +00E448: A2 02 >196 LDX #$02 ; & include info about 'parent directory +00E44A: 8E 87 FE >197 STX d_file+d_eof+1 +00E44D: BD 6E FE >198 :loop4 LDA d_entBlk,X +00E450: 9D 27 DC >199 STA genBuf+4+hOwnerBlk,X +00E453: CA >200 DEX +00E454: 10 F7 =E44D >201 BPL :loop4 + >202 +00E456: AD 63 FE >203 LDA h_entLen ;Lastly the length of parent's dir entries +00E459: 8D 2A DC >204 STA genBuf+4+hOwnerLen + >205 +00E45C: 20 90 EA >206 CrAlocBlk JSR Alloc1Blk ;Get address of file's data block +00E45F: B0 37 =E498 >207 BCS CrErr3 ;Branch if error encountered +00E461: 8D 82 FE >208 STA d_file+d_first +00E464: 8C 83 FE >209 STY d_file+d_first+1 +00E467: 85 46 >210 STA blockNum +00E469: 84 47 >211 STY blockNum+1 +00E46B: 20 C3 EB >212 JSR WrtGBuf ;Go write data block of file +00E46E: B0 28 =E498 >213 BCS CrErr3 +00E470: EE 65 FE >214 INC h_fileCnt ;Add 1 to total # of files in this directory +00E473: D0 03 =E478 >215 BNE :1 +00E475: EE 66 FE >216 INC h_fileCnt+1 +00E478: 20 99 E4 >217 :1 JSR ReviseDir ;Go revise directories with new file +00E47B: B0 1B =E498 >218 BCS CrErr3 +00E47D: 4C 64 EB >219 JMP UpdateBitMap ;Lastly, update volume bitmap + >220 + >221 *------------------------------------------------- + >222 * Point dirBufPtr ($48/$49) at directory entry + >223 +00E480: A9 DC >224 EntCalc LDA #genBuf/256 ;Set high address of directory +00E482: 85 49 >225 STA dirBufPtr+1 ; entry index pointer +00E484: A9 04 >226 LDA #$04 ;Calculate address of entry based +00E486: AE 70 FE >227 LDX d_entNum ; on the entry number +00E489: 18 >228 :loop1 CLC +00E48A: CA >229 :loop2 DEX ;addr=genBuf+((entnum-1)*entlen) +00E48B: F0 09 =E496 >230 BEQ :exitLoop +00E48D: 6D 63 FE >231 ADC h_entLen +00E490: 90 F8 =E48A >232 BCC :loop2 +00E492: E6 49 >233 INC dirBufPtr+1 ;Bump hi address +00E494: B0 F3 =E489 >234 BCS :loop1 ;Branch always +00E496: 85 48 >235 :exitLoop STA dirBufPtr ;Save newly calculated low address + =E498 >236 CrErr3 EQU * +00E498: 60 >237 DError2 RTS ;Return errors + >238 + >239 *------------------------------------------------- + >240 * Update directory(s) + >241 +00E499: AD 90 BF >242 ReviseDir LDA DateLo ;If no clock, +00E49C: F0 0B =E4A9 >243 BEQ ReviseDirZ ; then don't touch mod time/date + >244 +00E49E: A2 03 >245 LDX #$03 +00E4A0: BD 90 BF >246 :loop LDA DateLo,X ;Move last modification date/time +00E4A3: 9D 92 FE >247 STA d_file+d_modDate,X ; to entry being updated +00E4A6: CA >248 DEX +00E4A7: 10 F7 =E4A0 >249 BPL :loop + >250 +00E4A9: AD 8F FE >251 ReviseDirZ LDA d_file+d_attr ;Mark entry as backupable +00E4AC: 0D C5 FE >252 ORA bkBitFlg ; bit 5 = backup needed bit +00E4AF: 8D 8F FE >253 STA d_file+d_attr +00E4B2: AD 6B FE >254 LDA d_dev ;Get device number of directory +00E4B5: 8D 30 BF >255 STA DevNum ; to be revised +00E4B8: AD 6E FE >256 LDA d_entBlk ; & address of directory block +00E4BB: AE 6F FE >257 LDX d_entBlk+1 +00E4BE: 20 B7 EB >258 JSR RdBlkAX ;Read block into general purpose buffer +00E4C1: B0 D5 =E498 >259 BCS DError2 + >260 +00E4C3: 20 80 E4 >261 JSR EntCalc ;Fix up pointer to entry location within gbuf +00E4C6: AC 63 FE >262 LDY h_entLen ;Now move 'd_' stuff to directory +00E4C9: 88 >263 DEY +00E4CA: B9 71 FE >264 :loop1 LDA d_file+d_stor,Y +00E4CD: 91 48 >265 STA (dirBufPtr),Y +00E4CF: 88 >266 DEY +00E4D0: 10 F8 =E4CA >267 BPL :loop1 + >268 +00E4D2: AD 6C FE >269 LDA d_head ;Is the entry block the same as the +00E4D5: C5 46 >270 CMP blockNum ; entry's header block? +00E4D7: D0 07 =E4E0 >271 BNE SavEntDir ;No, save entry block +00E4D9: AD 6D FE >272 LDA d_head+1 ;Maybe, test high addresses +00E4DC: C5 47 >273 CMP blockNum+1 +00E4DE: F0 10 =E4F0 >274 BEQ UpHead ;Branch if they are the same block + >275 +00E4E0: 20 C3 EB >276 SavEntDir JSR WrtGBuf ;Write updated directory block +00E4E3: B0 B3 =E498 >277 BCS DError2 ;Return any error +00E4E5: AD 6C FE >278 LDA d_head ;Get address of header block +00E4E8: AE 6D FE >279 LDX d_head+1 +00E4EB: 20 B7 EB >280 JSR RdBlkAX ;Read in header block for modification +00E4EE: B0 A8 =E498 >281 BCS DError2 + >282 +00E4F0: A0 01 >283 UpHead LDY #$01 ;Update current # of files in this directory +00E4F2: B9 65 FE >284 :loop2 LDA h_fileCnt,Y +00E4F5: 99 25 DC >285 STA genBuf+hFileCnt+4,Y ;(current entry count) +00E4F8: 88 >286 DEY +00E4F9: 10 F7 =E4F2 >287 BPL :loop2 + >288 +00E4FB: AD 62 FE >289 LDA h_attr ;Also update header's attributes +00E4FE: 8D 22 DC >290 STA genBuf+hAttr+4 +00E501: 20 C3 EB >291 JSR WrtGBuf ;Go write updated header +00E504: B0 54 =E55A >292 BCS DError1 + >293 +00E506: AD 04 DC >294 Ripple LDA genBuf+4 ;Test for 'root' directory +00E509: 29 F0 >295 AND #$F0 ;If it is root, then dir revision is complete +00E50B: 49 F0 >296 EOR #$F0 ;(leaves carry clear) +00E50D: F0 61 =E570 >297 BEQ DirRevDone ;Branch if ripple done + >298 +00E50F: AD 29 DC >299 LDA genBuf+hOwnerEnt+4 ;Get entry number & +00E512: 8D 70 FE >300 STA d_entNum +00E515: AD 2A DC >301 LDA genBuf+hOwnerEnt+5 ; the length of entries in that dir +00E518: 8D 63 FE >302 STA h_entLen + >303 +00E51B: AD 27 DC >304 LDA genBuf+hOwnerBlk+4 ;Get addr of parent entry's dir block +00E51E: AE 28 DC >305 LDX genBuf+hOwnerBlk+5 +00E521: 20 B7 EB >306 JSR RdBlkAX ;Read that sucker in +00E524: B0 34 =E55A >307 BCS DError1 + >308 +00E526: 20 80 E4 >309 JSR EntCalc ;Get indirect ptr to parent entry in genBuf +00E529: AD 90 BF >310 LDA DateLo ;Don't touch mod +00E52C: F0 0D =E53B >311 BEQ RUpdate ; if no clock... + >312 +00E52E: A2 03 >313 LDX #$03 ;Now update the modification date +00E530: A0 24 >314 LDY #d_modDate+3 ; & time for this entry too +00E532: BD 90 BF >315 RipTime LDA DateLo,X +00E535: 91 48 >316 STA (dirBufPtr),Y +00E537: 88 >317 DEY +00E538: CA >318 DEX +00E539: 10 F7 =E532 >319 BPL RipTime ;Move all for bytes... + >320 + >321 * Write updated entry back to disk. (Assumes blockNum undisturbed) + >322 +00E53B: 20 C3 EB >323 RUpdate JSR WrtGBuf +00E53E: B0 1A =E55A >324 BCS DError1 ;Give up on any error + >325 +00E540: A0 25 >326 LDY #d_dHdr ;Now compare current block number to +00E542: B1 48 >327 LDA (dirBufPtr),Y ; this entry's header block +00E544: C8 >328 INY +00E545: C5 46 >329 CMP blockNum ;Are low addresses the same? +00E547: 85 46 >330 STA blockNum ;(save it in case it's not) +00E549: D0 06 =E551 >331 BNE :1 ;Branch if entry does not reside in same block as header +00E54B: B1 48 >332 LDA (dirBufPtr),Y ;Check high address just to be sure +00E54D: C5 47 >333 CMP blockNum+1 +00E54F: F0 B5 =E506 >334 BEQ Ripple ;They are the same, continue ripple to root directory + >335 +00E551: B1 48 >336 :1 LDA (dirBufPtr),Y ;They aren't the same, +00E553: 85 47 >337 STA blockNum+1 ; read in this directory's header +00E555: 20 C7 EB >338 JSR RdGBuf +00E558: 90 AC =E506 >339 BCC Ripple ;Continue if read was good +00E55A: 60 >340 DError1 RTS + >341 +00E55B: A9 52 >342 TestErr LDA #unknownVol ;Not tree or dir - not a recognized type! +00E55D: 38 >343 SEC +00E55E: 60 >344 RTS + >345 + >346 *------------------------------------------------- + >347 * Is this a ProDOS vol? + >348 +00E55F: AD 00 DC >349 TestSOS LDA genBuf ;Test SOS stamp +00E562: 0D 01 DC >350 ORA genBuf+1 +00E565: D0 F4 =E55B >351 BNE TestErr +00E567: AD 04 DC >352 LDA genBuf+4 ;Test for header +00E56A: 29 E0 >353 AND #$E0 +00E56C: C9 E0 >354 CMP #$E0 +00E56E: D0 EB =E55B >355 BNE TestErr ;Branch if not SOS header (no error number) +00E570: 18 >356 DirRevDone CLC ;Indicate no error +00E571: 60 >357 RTS + 31 PUT mli.src/FndFil + >1 ************************************************** + >2 * Get File entry + >3 +00E572: 20 85 E5 >4 FindFile JSR LookFile ;See if file exists +00E575: B0 0D =E584 >5 BCS NoFind ;Branch if an error was encountered +00E577: AC 63 FE >6 MovEntry LDY h_entLen ;Move entire entry info +00E57A: B1 48 >7 :loop LDA (dirBufPtr),Y +00E57C: 99 71 FE >8 STA d_file+d_stor,Y ; to a safe area +00E57F: 88 >9 DEY +00E580: 10 F8 =E57A >10 BPL :loop +00E582: A9 00 >11 LDA #$00 ;To indicate all is well +00E584: 60 >12 NoFind RTS ;Return condition codes + >13 + >14 *------------------------------------------------- + >15 * Follow path to a file + >16 +00E585: 20 0B E7 >17 LookFile JSR PrepRoot ;Find volume and set up other boring stuff +00E588: B0 5F =E5E9 >18 BCS FndErr ;Pass back any error encountered +00E58A: D0 39 =E5C5 >19 BNE LookFile0 ;Branch if more than root +00E58C: A9 DC >20 LDA #>genBuf ;Otherwise, report a badpath error +00E58E: 85 49 >21 STA dirBufPtr+1 ;(but first create a phantom entry for open) +00E590: A9 04 >22 LDA #23 STA dirBufPtr + >24 +00E594: A0 1F >25 LDY #d_auxID ;First move in id, and date stuff +00E596: B1 48 >26 :loop1 LDA (dirBufPtr),Y +00E598: 99 71 FE >27 STA d_file,Y +00E59B: 88 >28 DEY +00E59C: C0 17 >29 CPY #d_creDate-1 +00E59E: D0 F6 =E596 >30 BNE :loop1 + >31 +00E5A0: B9 0E FE >32 :loop2 LDA rootStuff-d_fileID,Y +00E5A3: 99 71 FE >33 STA d_file,Y +00E5A6: 88 >34 DEY +00E5A7: C0 0F >35 CPY #d_fileID-1 +00E5A9: D0 F5 =E5A0 >36 BNE :loop2 + >37 +00E5AB: A9 D0 >38 LDA #directoryFile*16 ;Fake directory file +00E5AD: 8D 71 FE >39 STA d_file+d_stor +00E5B0: AD 02 DC >40 LDA genBuf+2 ;A forward link? +00E5B3: 0D 03 DC >41 ORA genBuf+3 +00E5B6: D0 0A =E5C2 >42 BNE :1 ;Yes + >43 +00E5B8: A9 02 >44 LDA #$02 +00E5BA: 8D 87 FE >45 STA d_file+d_eof+1 +00E5BD: A9 01 >46 LDA #$01 ;Allocate 1 blk +00E5BF: 8D 84 FE >47 STA d_file+d_usage +00E5C2: A9 40 >48 :1 LDA #badPathSyntax +00E5C4: 60 >49 RTS + >50 + >51 * Scan subdir for file + >52 +00E5C5: 9C AD FE >53 LookFile0 STZ noFree ;Reset free entry indicator +00E5C8: 38 >54 SEC ;Indicate that dir to be searched has header in this blk +00E5C9: 9C A9 FE >55 ScanDirLoop STZ totEnt ;reset entry counter +00E5CC: 20 B5 E6 >56 JSR LookName ;Look for name pointed to by pnPtr +00E5CF: 90 60 =E631 >57 BCC NameFound ;Branch if name was found +00E5D1: AD AA FE >58 LDA entCnt ;Have we looked at all of the +00E5D4: ED A9 FE >59 SBC totEnt ; entries in this directory? +00E5D7: 90 09 =E5E2 >60 BCC :11 ;Maybe, check hi count +00E5D9: D0 10 =E5EB >61 BNE LookFile2 ;No, read next directory block +00E5DB: CD AB FE >62 CMP entCnt+1 ;Has the last entry been looked at (A=0) +00E5DE: F0 25 =E605 >63 BEQ ErrFNF ;Yes, give 'file not found' error +00E5E0: D0 09 =E5EB >64 BNE LookFile2 ;Branch always + >65 +00E5E2: CE AB FE >66 :11 DEC entCnt+1 ;Should be at least 1 +00E5E5: 10 04 =E5EB >67 BPL LookFile2 ;(this should be branch always...) +00E5E7: A9 51 >68 ErrDir LDA #dirError ;Report directory messed up +00E5E9: 38 >69 FndErr SEC +00E5EA: 60 >70 RTS + >71 +00E5EB: 8D AA FE >72 LookFile2 STA entCnt ;Keep running count +00E5EE: A9 DC >73 LDA #>genBuf ;Reset indirect pointer +00E5F0: 85 49 >74 STA dirBufPtr+1 +00E5F2: AD 02 DC >75 LDA genBuf+2 ;Get link to next directory block +00E5F5: D0 05 =E5FC >76 BNE NxtDir0 ;(if there is one) +00E5F7: CD 03 DC >77 CMP genBuf+3 ;Are both zero, i.e. no link? +00E5FA: F0 EB =E5E7 >78 BEQ ErrDir ;If so, then not all entries were accounted for +00E5FC: AE 03 DC >79 NxtDir0 LDX genBuf+3 ;A has value for block # (low) +00E5FF: 20 B7 EB >80 JSR RdBlkAX ;Go read the next linked directory in +00E602: 90 C5 =E5C9 >81 BCC ScanDirLoop ;Branch if no error +00E604: 60 >82 RTS ;Return error (in A) + >83 + >84 * No more file entries + >85 +00E605: AD AD FE >86 ErrFNF LDA noFree ;Was any free entry found? +00E608: D0 1B =E625 >87 BNE FNF0 + >88 +00E60A: AD 02 DC >89 LDA genBuf+2 ;Test link +00E60D: D0 05 =E614 >90 BNE TellFree +00E60F: CD 03 DC >91 CMP genBuf+3 ;If both are zero, then give up +00E612: F0 11 =E625 >92 BEQ FNF0 ; simply report 'not found' + >93 +00E614: 8D 6E FE >94 TellFree STA d_entBlk +00E617: AD 03 DC >95 LDA genBuf+3 +00E61A: 8D 6F FE >96 STA d_entBlk+1 ;Assume first entry of next block +00E61D: A9 01 >97 LDA #$01 ; is free for use +00E61F: 8D 70 FE >98 STA d_entNum +00E622: 8D AD FE >99 STA noFree ;Mark d_entNum as valid (for create) +00E625: 20 4C E7 >100 FNF0 JSR NxtPNameZ ;Test for 'file not found' versus 'path not found' + >101 +00E628: 38 >102 ErrPath1 SEC ;If non-zero then 'path not found' +00E629: F0 03 =E62E >103 BEQ :21 +00E62B: A9 44 >104 LDA #pathNotFound ;Report no such path +00E62D: 60 >105 RTS + >106 +00E62E: A9 46 >107 :21 LDA #fileNotFound ;Report file not found +00E630: 60 >108 RTS + >109 + >110 * File entry found + >111 +00E631: 20 45 E7 >112 NameFound JSR NxtPName ;Adjust index to next name in path +00E634: F0 67 =E69D >113 BEQ FileFound ;Branch if that was last name +00E636: A0 00 >114 LDY #d_stor ;Be sure this is a directory entry +00E638: B1 48 >115 LDA (dirBufPtr),Y ;High nibble will tell +00E63A: 29 F0 >116 AND #$F0 +00E63C: C9 D0 >117 CMP #directoryFile*16 ;Is it a sub-directory? +00E63E: D0 E8 =E628 >118 BNE ErrPath1 ;Report the user's mistake + >119 +00E640: A0 11 >120 LDY #d_first ;Get address of first sub-directory block +00E642: B1 48 >121 LDA (dirBufPtr),Y +00E644: 85 46 >122 STA blockNum ;(no checking is done here for a valid +00E646: C8 >123 INY ; block number... ) +00E647: 8D 6C FE >124 STA d_head ;Save as file's header block too +00E64A: B1 48 >125 LDA (dirBufPtr),Y +00E64C: 85 47 >126 STA blockNum+1 +00E64E: 8D 6D FE >127 STA d_head+1 +00E651: 20 C7 EB >128 JSR RdGBuf ;Read sub-directory into gbuf +00E654: B0 1F =E675 >129 BCS FndErr1 ;Return immediately any error encountered + >130 +00E656: AD 25 DC >131 LDA genBuf+4+hFileCnt ;Get the number of files +00E659: 8D AA FE >132 STA entCnt ; contained in this directory +00E65C: AD 26 DC >133 LDA genBuf+4+hFileCnt+1 +00E65F: 8D AB FE >134 STA entCnt+1 +00E662: AD 14 DC >135 LDA genBuf+4+hPassEnable ;Make sure password disabled +00E665: A2 00 >136 LDX #$00 +00E667: 38 >137 SEC +00E668: 2A >138 ROL +00E669: 90 01 =E66C >139 TestPass0 BCC :1 +00E66B: E8 >140 INX +00E66C: 0A >141 :1 ASL +00E66D: D0 FA =E669 >142 BNE TestPass0 +00E66F: E0 05 >143 CPX #$05 ;Is password disabled? +00E671: F0 04 =E677 >144 BEQ MovHead +00E673: A9 4A >145 LDA #badFileFormat ;Tell them this directory is not compatible +00E675: 38 >146 FndErr1 SEC +00E676: 60 >147 RTS + >148 +00E677: 20 7D E6 >149 MovHead JSR MoveHeadZ ;Move info about this directory +00E67A: 4C C5 E5 >150 JMP LookFile0 ;Do next local pathname + >151 + >152 *------------------------------------------------- + >153 * Copy directory (vol/sub) header + >154 +00E67D: A2 0A >155 MoveHeadZ LDX #$0A ;move info about this directory +00E67F: BD 1C DC >156 :loop1 LDA genBuf+4+hCreDate,X +00E682: 9D 5C FE >157 STA h_creDate,X +00E685: CA >158 DEX +00E686: 10 F7 =E67F >159 BPL :loop1 + >160 +00E688: AD 04 DC >161 LDA genBuf+4 ;If this is root, then nothing to do +00E68B: 29 F0 >162 AND #$F0 +00E68D: 49 F0 >163 EOR #$F0 ;Test header type +00E68F: F0 0B =E69C >164 BEQ :11 ;Branch if root + >165 +00E691: A2 03 >166 LDX #$03 ;Otherwise, save owner info about this header +00E693: BD 27 DC >167 :loop2 LDA genBuf+4+hOwnerBlk,X +00E696: 9D 58 FE >168 STA ownersBlock,X +00E699: CA >169 DEX +00E69A: 10 F7 =E693 >170 BPL :loop2 +00E69C: 60 >171 :11 RTS + >172 + >173 *------------------------------------------------- + >174 * Save dir entry # & block + >175 + =E69D >176 FileFound EQU * +00E69D: AD 64 FE >177 EntAdr LDA h_maxEnt ;Figure out which is entry number this is +00E6A0: 38 >178 SEC +00E6A1: ED AC FE >179 SBC cntEnt ;max entries - count entries + 1 = entry number +00E6A4: 69 00 >180 ADC #$00 ;(carry is/was set) +00E6A6: 8D 70 FE >181 STA d_entNum + >182 +00E6A9: A5 46 >183 LDA blockNum +00E6AB: 8D 6E FE >184 STA d_entBlk +00E6AE: A5 47 >185 LDA blockNum+1 ; & indicate blk # of this dir +00E6B0: 8D 6F FE >186 STA d_entBlk+1 +00E6B3: 18 >187 CLC +00E6B4: 60 >188 RTS + >189 + >190 *------------------------------------------------- + >191 * Search one dir block for file + >192 +00E6B5: AD 64 FE >193 LookName LDA h_maxEnt ;reset count of files per block +00E6B8: 8D AC FE >194 STA cntEnt +00E6BB: A9 DC >195 LDA #>genBuf +00E6BD: 85 49 >196 STA dirBufPtr+1 +00E6BF: A9 04 >197 LDA #$04 +00E6C1: 85 48 >198 LookName1 STA dirBufPtr ;Reset indirect pointer to genBuf +00E6C3: B0 33 =E6F8 >199 BCS LookName2 ;Branch if this block contains a header +00E6C5: A0 00 >200 LDY #$00 +00E6C7: B1 48 >201 LDA (dirBufPtr),Y ;Get length of name in dir +00E6C9: D0 0D =E6D8 >202 BNE IsName ;Branch if there is a name + >203 +00E6CB: AD AD FE >204 LDA noFree ;Test to see if a free entry has been declared +00E6CE: D0 28 =E6F8 >205 BNE LookName2 ;Yes bump to next entry +00E6D0: 20 9D E6 >206 JSR EntAdr ;Set address for current entry +00E6D3: EE AD FE >207 INC noFree ;Indicate a free spot has been found +00E6D6: D0 20 =E6F8 >208 BNE LookName2 ;Branch always + >209 +00E6D8: 29 0F >210 IsName AND #$0F ;Strip type (this is checked by 'FileFound') +00E6DA: EE A9 FE >211 INC totEnt ;(bump count of valid files found) +00E6DD: 8D C8 FE >212 STA namCnt ;Save name length as counter +00E6E0: AE CA FE >213 LDX pnPtr ;Get index to current path +00E6E3: DD 00 D7 >214 CMP pathBuf,X ;Are both names of the same length? +00E6E6: D0 10 =E6F8 >215 BNE LookName2 ;No, bump to next entry + >216 +00E6E8: E8 >217 CmpNames INX ;(first) next letter index +00E6E9: C8 >218 INY +00E6EA: B1 48 >219 LDA (dirBufPtr),Y ;Compare names letter by letter +00E6EC: DD 00 D7 >220 CMP pathBuf,X +00E6EF: D0 07 =E6F8 >221 BNE LookName2 +00E6F1: CE C8 FE >222 DEC namCnt ;Have all letters been compared? +00E6F4: D0 F2 =E6E8 >223 BNE CmpNames ;No, continue.. +00E6F6: 18 >224 CLC ;By golly, we got us a match! +00E6F7: 60 >225 NoName RTS + >226 +00E6F8: CE AC FE >227 LookName2 DEC cntEnt ;Have we checked all possible entries in this blk? +00E6FB: 38 >228 SEC +00E6FC: F0 F9 =E6F7 >229 BEQ NoName ;Yes, give up + >230 +00E6FE: AD 63 FE >231 LDA h_entLen ;Add entry length to current pointer +00E701: 18 >232 CLC +00E702: 65 48 >233 ADC dirBufPtr +00E704: 90 BB =E6C1 >234 BCC LookName1 ;Branch if we're still in the first page +00E706: E6 49 >235 INC dirBufPtr+1 ;Look on second page +00E708: 18 >236 CLC ;Carry should always be clear before looking at next +00E709: 90 B6 =E6C1 >237 BCC LookName1 ;Branch always... + 32 PUT mli.src/NewFndVol + >1 ************************************************** + >2 * Get directory data + >3 +00E70B: 20 64 E7 >4 PrepRoot JSR FindVol ;Search VCB's and devices for specified volume +00E70E: B0 53 =E763 >5 BCS NoVolume ;Branch if not found + >6 +00E710: A9 00 >7 LDA #$00 ;Zero out directory temps +00E712: A0 42 >8 LDY #$42 +00E714: 99 58 FE >9 ClrDsp STA ownersBlock,Y ; & owner info +00E717: 88 >10 DEY +00E718: 10 FA =E714 >11 BPL ClrDsp + >12 +00E71A: AD 30 BF >13 LDA DevNum ;Set up device number for this directory +00E71D: 8D 6B FE >14 STA d_dev +00E720: 20 7D E6 >15 JSR MoveHeadZ ;Set up other header info from directory + >16 +00E723: A0 01 >17 LDY #$01 ; in genBuf & clean up misc +00E725: AE A3 FE >18 LDX vcbPtr +00E728: E8 >19 INX +00E729: BD 12 D9 >20 RootMisc LDA vcb+vcbTotBlks,X ;Misc info includes +00E72C: 99 69 FE >21 STA h_totBlk,Y ; total # of blocks, +00E72F: BD 1A D9 >22 LDA vcb+vcbBitMap,X ; the disk addr of the first bitmap, +00E732: 99 67 FE >23 STA h_bitMap,Y +00E735: B9 46 00 >24 LDA |blockNum,Y ; directory's disk address, +00E738: 99 6C FE >25 STA d_head,Y +00E73B: B9 65 FE >26 LDA h_fileCnt,Y ; & lastly, setting up a counter for +00E73E: 99 AA FE >27 STA entCnt,Y ; the # of files in this directory +00E741: CA >28 DEX ;Move low order bytes too +00E742: 88 >29 DEY +00E743: 10 E4 =E729 >30 BPL RootMisc + >31 +00E745: 20 4C E7 >32 NxtPName JSR NxtPNameZ ;Get new pnPtr in Y & next namlen in A +00E748: 8C CA FE >33 STY pnPtr ;Save new pathname pointer +00E74B: 60 >34 RTS ;(status reg according to ACC) + >35 + >36 *------------------------------------------------- + >37 * Advance to next dir name + >38 +00E74C: AC CA FE >39 NxtPNameZ LDY pnPtr ;Bump pathname pointer to +00E74F: B9 00 D7 >40 LDA pathBuf,Y ; next name in the path... +00E752: 38 >41 SEC +00E753: 6D CA FE >42 ADC pnPtr ;If this addition results in zero +00E756: A8 >43 TAY ; then prefixed directory has been moved +00E757: D0 06 =E75F >44 BNE :1 ; to another device. Branch if not + >45 +00E759: AD 30 BF >46 LDA DevNum ;Revise devnum for prefixed directory +00E75C: 8D B1 FE >47 STA pathDev +00E75F: B9 00 D7 >48 :1 LDA pathBuf,Y ;Test for end of name (Z=1) +00E762: 18 >49 CLC ;Indicate no errors +00E763: 60 >50 NoVolume RTS + >51 + >52 *------------------------------------------------- + >53 * Find base dir + >54 +00E764: A9 00 >55 FindVol LDA #$00 +00E766: AC 9A BF >56 LDY PfixPtr ;Use prefix volume name to look up VCB +00E769: 2C CC FE >57 BIT prfxFlg ;Is this a prefixed path? +00E76C: 10 01 =E76F >58 BPL :1 ;Branch if it is +00E76E: A8 >59 TAY ;Set ptr to volume name + >60 +00E76F: 8C CB FE >61 :1 STY vnPtr ;Save pointer +00E772: 8D 30 BF >62 STA DevNum ;Zero out device number until VCB located + >63 +00E775: 48 >64 Adv2NxtVCB PHA ;Acc now used as VCB lookup index +00E776: AA >65 TAX ;Move pointer to X-reg for index +00E777: BD 00 D9 >66 LDA vcb+vcbNamLen,X ;Get volume name length +00E77A: D0 0B =E787 >67 BNE MatchVol ;Branch if claimed VCB to be tested +00E77C: AC CB FE >68 NxtVCB LDY vnPtr ;Restore ptr to requested volume name +00E77F: 68 >69 PLA ;Now adjust VCB index to next vcb entry +00E780: 18 >70 CLC +00E781: 69 20 >71 ADC #vcbSize +00E783: 90 F0 =E775 >72 BCC Adv2NxtVCB ;Branch if more VCB's to check +00E785: B0 4D =E7D4 >73 BCS LookVol ;Otherwise go look for unlogged volumes + >74 +00E787: 8D C8 FE >75 MatchVol STA namCnt ;Save length of vol name to be compared +00E78A: D9 00 D7 >76 :loop1 CMP pathBuf,Y ;Is it the same as requested vol name? +00E78D: D0 ED =E77C >77 BNE NxtVCB ;branch if not +00E78F: E8 >78 INX +00E790: C8 >79 INY +00E791: BD 00 D9 >80 LDA vcb+vcbName-1,X ;Bump to next character +00E794: CE C8 FE >81 DEC namCnt ;Was that the last character? +00E797: 10 F1 =E78A >82 BPL :loop1 ;Branch if not + >83 +00E799: FA >84 PLX ;Restore pointer to VCB that matches +00E79A: 8E A3 FE >85 STX vcbPtr ;Save it for future reference +00E79D: BD 10 D9 >86 LDA vcb+vcbDevice,X ;Get its device number +00E7A0: 8D 30 BF >87 STA DevNum ;Save it +00E7A3: 64 47 >88 STZ blockNum+1 ;Assume prefix is not used and +00E7A5: A9 02 >89 LDA #$02 ; that root directory is to be used +00E7A7: 85 46 >90 STA blockNum + >91 +00E7A9: AD CB FE >92 LDA vnPtr ;= 0 if no prefix +00E7AC: A8 >93 PfxDir TAY ;If prefix, then find ptr to prefixed dir name +00E7AD: 8D CA FE >94 STA pnPtr ;Save path ptr +00E7B0: F0 10 =E7C2 >95 BEQ ChkVolName ;Branch if no prefix +00E7B2: 38 >96 SEC ;Bump to next dir in prefix path +00E7B3: 79 00 D7 >97 ADC pathBuf,Y +00E7B6: 90 F4 =E7AC >98 BCC PfxDir ;Branch if there is another dir in prefix + >99 +00E7B8: AD B2 FE >100 LDA pathBlok ;Volume verification will occur +00E7BB: 85 46 >101 STA blockNum ; at sub directory level +00E7BD: AD B3 FE >102 LDA pathBlok+1 +00E7C0: 85 47 >103 STA blockNum+1 + >104 + >105 *------------------------------------------------- + >106 ******verify volume name****** + >107 +00E7C2: 20 C7 EB >108 ChkVolName JSR RdGBuf ;Read in directory (or prefix directory) +00E7C5: B0 05 =E7CC >109 BCS WrgVol ;If error then look on other devices +00E7C7: 20 7D E8 >110 JSR CmpPName ;Compare directory name with pathname +00E7CA: 90 24 =E7F0 >111 BCC WrgVolErr ;If they match, don't look elsewhere + >112 +00E7CC: AE A3 FE >113 WrgVol LDX vcbPtr ;Find out if current (matched) vcb is active +00E7CF: BD 11 D9 >114 LDA vcb+vcbStatus,X ; i.e. does it have open files? +00E7D2: 30 19 =E7ED >115 BMI LookVolErr ;Report not found if active + >116 +00E7D4: AD CB FE >117 LookVol LDA vnPtr ;Make path pointer same as volume ptr +00E7D7: 8D CA FE >118 STA pnPtr +00E7DA: 20 2A E8 >119 JSR MovDevNums ;Copy all device numbers to be examined +00E7DD: AD 30 BF >120 LDA DevNum ;Log current device first, before searching others +00E7E0: D0 0F =E7F1 >121 BNE WrgVol3 + >122 +00E7E2: AE 31 BF >123 TryNxtUnit LDX DevCnt ;Scan look list for devices we need +00E7E5: BD D9 FE >124 :loop LDA lookList,X ; to search for the requested volume +00E7E8: D0 0A =E7F4 >125 BNE WrgVol4 ;Branch if we've a device to look at +00E7EA: CA >126 DEX +00E7EB: 10 F8 =E7E5 >127 BPL :loop ;Look at next guy + >128 +00E7ED: A9 45 >129 LookVolErr LDA #volNotFound ;Report that no mounted volume +00E7EF: 38 >130 SEC ; matches the requested +00E7F0: 60 >131 WrgVolErr RTS + >132 +00E7F1: AE 31 BF >133 WrgVol3 LDX DevCnt ;Now remove the device from the list +00E7F4: DD D9 FE >134 WrgVol4 CMP lookList,X ; of prospective devices (so we don't look twice) +00E7F7: F0 05 =E7FE >135 BEQ :1 ;Branch if match +00E7F9: CA >136 DEX ;Look until found +00E7FA: 10 F8 =E7F4 >137 BPL WrgVol4 ;Branch always taken! (usually!) * * * +00E7FC: 30 EF =E7ED >138 BMI LookVolErr ;Never unless device was manually removed from devlst (/ram) + >139 +00E7FE: 8D 30 BF >140 :1 STA DevNum ;Preserve device we're about to investigate +00E801: 9E D9 FE >141 STZ lookList,X ;Mark this one as tested +00E804: 20 3C E8 >142 JSR ScanVCB ;Find VCB that claims this device, if any +00E807: B0 20 =E829 >143 BCS FndVolErr ;Branch if VCB full +00E809: AE A3 FE >144 LDX vcbPtr ;Did 'fnddvcb' find it or did it return free vcb? +00E80C: BD 00 D9 >145 LDA vcb,X +00E80F: F0 05 =E816 >146 BEQ :2 ;Branch if free VCB +00E811: BD 11 D9 >147 LDA vcb+vcbStatus,X ;Is this volume active? +00E814: 30 CC =E7E2 >148 BMI TryNxtUnit ;If so, no need to re-log + >149 +00E816: A9 02 >150 :2 LDA #$02 ;Go read root directory into genBuf +00E818: A2 00 >151 LDX #$00 +00E81A: 20 B7 EB >152 JSR RdBlkAX +00E81D: B0 C3 =E7E2 >153 BCS TryNxtUnit ;Ignore if unable to read +00E81F: 20 A3 E8 >154 JSR LogVCB ;Go log in this volume's proper name +00E822: B0 BE =E7E2 >155 BCS TryNxtUnit ;Look at next if non xdos disk was mounted +00E824: 20 7D E8 >156 JSR CmpPName ;Is this the volume we're looking for? +00E827: B0 B9 =E7E2 >157 BCS TryNxtUnit ;Branch if not +00E829: 60 >158 FndVolErr RTS ;return to caller + >159 +00E82A: AE 31 BF >160 MovDevNums LDX DevCnt ;Copy all device numbers to be examined +00E82D: BD 32 BF >161 :loop LDA DevLst,X +00E830: 29 F0 >162 AND #$F0 ;Strip device type info +00E832: 9D D9 FE >163 STA lookList,X ;Copy them to a temporary workspace +00E835: CA >164 DEX +00E836: 10 F5 =E82D >165 BPL :loop +00E838: AE 31 BF >166 LDX DevCnt +00E83B: 60 >167 RTS + >168 + >169 ************************************************** + >170 * Scan VCBs' for device # + >171 * Input + >172 * (DevNum) - Look for vcb with this device number + >173 * Output + >174 * C = - Got a match/Got a free slot + >175 +00E83C: A9 00 >176 ScanVCB LDA #$00 +00E83E: A0 FF >177 LDY #$FF +00E840: AA >178 ScanNxtVCB TAX ;New index to next VCB +00E841: BD 10 D9 >179 LDA vcb+vcbDevice,X ;Check all devnums +00E844: CD 30 BF >180 CMP DevNum ;Is this the VCB were looking for? +00E847: D0 05 =E84E >181 BNE NotThisVCB ;Branch if not +00E849: 8E A3 FE >182 STX vcbPtr +00E84C: 18 >183 CLC ;Indicate found +00E84D: 60 >184 RTS + >185 +00E84E: BD 00 D9 >186 NotThisVCB LDA vcb,X ;Is this a free VCB? +00E851: D0 04 =E857 >187 BNE :1 ;Branch if not +00E853: C8 >188 INY +00E854: 8E A3 FE >189 STX vcbPtr +00E857: 8A >190 :1 TXA ;now... +00E858: 18 >191 CLC ; bump index to next VCB +00E859: 69 20 >192 ADC #vcbSize +00E85B: D0 E3 =E840 >193 BNE ScanNxtVCB +00E85D: 98 >194 TYA ;Were any free VCB's available? +00E85E: 10 19 =E879 >195 BPL :3 ;Yes + >196 +00E860: A9 00 >197 LDA #$00 +00E862: AA >198 :loop TAX ;Save index +00E863: BD 11 D9 >199 LDA vcb+vcbStatus,X ;Any files opened? +00E866: 10 08 =E870 >200 BPL :2 ;No +00E868: 8A >201 TXA +00E869: 18 >202 CLC +00E86A: 69 20 >203 ADC #vcbSize +00E86C: D0 F4 =E862 >204 BNE :loop +00E86E: F0 0A =E87A >205 BEQ :ErrExit ;Always + >206 +00E870: 8E A3 FE >207 :2 STX vcbPtr ;This slot can be used +00E873: 9E 00 D9 >208 STZ vcb,X ;Prepare it for use +00E876: 9E 10 D9 >209 STZ vcb+vcbDevice,X +00E879: 18 >210 :3 CLC ;Indicate no errors +00E87A: A9 55 >211 :ErrExit LDA #vcbFullErr +00E87C: 60 >212 RTS + >213 + >214 *------------------------------------------------- + >215 * Compare dir name with path level + >216 +00E87D: A2 00 >217 CmpPName LDX #$00 ;Index to directory name +00E87F: AC CA FE >218 LDY pnPtr ;Index to pathname +00E882: AD 04 DC >219 LDA genBuf+4+hNamLen ;Get directory name length (and type) +00E885: C9 E0 >220 CMP #$E0 ;Also make sure it's a directory +00E887: 90 07 =E890 >221 BCC :1 ;Branch if not a directory +00E889: 29 0F >222 AND #$0F ;Isolate name length +00E88B: 8D C8 FE >223 STA namCnt ;Save as counter +00E88E: D0 05 =E895 >224 BNE :2 ;Branch if valid length +00E890: 38 >225 :1 SEC ;Indicate not what were looking for +00E891: 60 >226 RTS + >227 +00E892: BD 04 DC >228 :loop LDA genBuf+4+hName-1,X ;Get next char +00E895: D9 00 D7 >229 :2 CMP pathBuf,Y +00E898: D0 F6 =E890 >230 BNE :1 ;Branch if not the same +00E89A: E8 >231 INX ;Check nxt char +00E89B: C8 >232 INY +00E89C: CE C8 FE >233 DEC namCnt +00E89F: 10 F1 =E892 >234 BPL :loop ;Branch if more to compare +00E8A1: 18 >235 CLC ;Otherwise we got a match!!! +00E8A2: 60 >236 RTS + >237 + >238 *------------------------------------------------- + >239 * Mount new volume + >240 +00E8A3: AE A3 FE >241 LogVCB LDX vcbPtr ;Is this a previously logged in volume +00E8A6: BD 00 D9 >242 LDA vcb,X ;(A=0?) +00E8A9: F0 05 =E8B0 >243 BEQ LogVCBZ ;No, go ahead and prepare vcb +00E8AB: 20 06 E9 >244 JSR CmpVCB ;Does VCB match volume read? +00E8AE: 90 55 =E905 >245 BCC VCBLogged ;Yes, don't disturb it + >246 +00E8B0: A0 1F >247 LogVCBZ LDY #vcbSize-1 +00E8B2: 9E 00 D9 >248 ZeroVCB STZ vcb,X ;Zero out VCB entry +00E8B5: E8 >249 INX +00E8B6: 88 >250 DEY +00E8B7: 10 F9 =E8B2 >251 BPL ZeroVCB + >252 +00E8B9: 20 5F E5 >253 JSR TestSOS ;Make sure it's an xdos diskette +00E8BC: B0 47 =E905 >254 BCS VCBLogged ;If not, return carry set + >255 +00E8BE: 20 2A E9 >256 JSR TestDupVol ;find out if a duplicate with open files already exists +00E8C1: B0 41 =E904 >257 BCS NotLog0 +00E8C3: AD 04 DC >258 LDA genBuf+4+hNamLen ;Move volume name to VCB +00E8C6: 29 0F >259 AND #$0F ;Strip root marker +00E8C8: A8 >260 TAY ;len byte to Y-reg +00E8C9: 48 >261 PHA +00E8CA: 0D A3 FE >262 ORA vcbPtr ;Add in offset to VCB record +00E8CD: AA >263 TAX +00E8CE: B9 04 DC >264 MovVolNam LDA genBuf+4+hNamLen,Y +00E8D1: 9D 00 D9 >265 STA vcb+hNamLen,X +00E8D4: CA >266 DEX +00E8D5: 88 >267 DEY +00E8D6: D0 F6 =E8CE >268 BNE MovVolNam + >269 +00E8D8: 68 >270 PLA ;Get length again +00E8D9: 9D 00 D9 >271 STA vcb+hNamLen,X ;Save that too. +00E8DC: AD 30 BF >272 LDA DevNum +00E8DF: 9D 10 D9 >273 STA vcb+vcbDevice,X ;Save device number also +00E8E2: AD 29 DC >274 LDA genBuf+4+vTotBlk ; & totol # of blocks on this unit, +00E8E5: 9D 12 D9 >275 STA vcb+vcbTotBlks,X +00E8E8: AD 2A DC >276 LDA genBuf+4+vTotBlk+1 +00E8EB: 9D 13 D9 >277 STA vcb+vcbTotBlks+1,X +00E8EE: A5 46 >278 LDA blockNum ; & address of root directory +00E8F0: 9D 16 D9 >279 STA vcb+vcbRoot,X +00E8F3: A5 47 >280 LDA blockNum+1 +00E8F5: 9D 17 D9 >281 STA vcb+vcbRoot+1,X + >282 +00E8F8: AD 27 DC >283 LDA genBuf+4+vBitMap ; & lastly, the address +00E8FB: 9D 1A D9 >284 STA vcb+vcbBitMap,X ; of the first bitmap +00E8FE: AD 28 DC >285 LDA genBuf+4+vBitMap+1 +00E901: 9D 1B D9 >286 STA vcb+vcbBitMap+1,X +00E904: 18 >287 NotLog0 CLC ;Indicate that it was logged if possible +00E905: 60 >288 VCBLogged RTS + >289 + >290 *------------------------------------------------- + >291 * Compare vol names to make sure they match + >292 +00E906: AD 04 DC >293 CmpVCB LDA genBuf+4+hNamLen ;Compare volume name in VCB +00E909: 29 0F >294 AND #$0F ; with name in directory +00E90B: DD 00 D9 >295 CMP vcb+hNamLen,X ;Are they same length? +00E90E: 8E A2 FE >296 STX xvcbPtr +00E911: D0 0B =E91E >297 BNE :1 + >298 +00E913: A8 >299 TAY +00E914: 0D A2 FE >300 ORA xvcbPtr +00E917: AA >301 TAX +00E918: B9 04 DC >302 :CmpLoop LDA genBuf+4+hNamLen,Y +00E91B: DD 00 D9 >303 CMP vcb+hNamLen,X +00E91E: 38 >304 :1 SEC ;Anticipate different names +00E91F: D0 05 =E926 >305 BNE NotSame +00E921: CA >306 DEX +00E922: 88 >307 DEY +00E923: D0 F3 =E918 >308 BNE :CmpLoop + >309 +00E925: 18 >310 CLC ;Indicate match +00E926: AE A2 FE >311 NotSame LDX xvcbPtr ;Get back offset to start of vcb +00E929: 60 >312 RTS + >313 + >314 *------------------------------------------------- + >315 * Look for duplicate vol + >316 +00E92A: A9 00 >317 TestDupVol LDA #$00 ;Look for other logged in volumes with same name +00E92C: AA >318 :loop TAX +00E92D: 20 06 E9 >319 JSR CmpVCB +00E930: B0 0F =E941 >320 BCS :1 ;Branch if no match + >321 +00E932: BD 11 D9 >322 LDA vcb+vcbStatus,X ;Test for any open files +00E935: 30 14 =E94B >323 BMI FoundDupVol ;Tell the sucker he can't look at this volume! + >324 +00E937: A9 00 >325 LDA #$00 ;Take duplicate off line if no open file +00E939: 9D 00 D9 >326 STA vcb,X +00E93C: 9D 10 D9 >327 STA vcb+vcbDevice,X +00E93F: F0 08 =E949 >328 BEQ NoDupVol ;Return that all is ok to log in new + >329 +00E941: 8A >330 :1 TXA ;Index to next VCB +00E942: 18 >331 CLC +00E943: 29 E0 >332 AND #$E0 ;Strip odd stuff +00E945: 69 20 >333 ADC #vcbSize ;Bump to next entry +00E947: 90 E3 =E92C >334 BCC :loop ;Branch if more to look at + >335 +00E949: 18 >336 NoDupVol CLC +00E94A: 60 >337 RTS + >338 +00E94B: 8D C6 FE >339 FoundDupVol STA duplFlag ;A duplicate has been detected +00E94E: 8E C7 FE >340 STX vcbEntry ;Save pointer to conflicting vcb +00E951: 38 >341 SEC ;Indicate error +00E952: 60 >342 RTS + >343 *------------------------------------------------- + >344 * See if a quantity of free blks is available on volume + >345 * Input + >346 * (reqL,H) = # of blks required + >347 +00E953: AE A3 FE >348 TestFreeBlk LDX vcbPtr ;Find out if enough free blocks +00E956: BD 15 D9 >349 LDA vcb+vcbFreeBlks+1,X ; available to accomodate the request +00E959: 1D 14 D9 >350 ORA vcb+vcbFreeBlks,X ; but first find out if we got a proper cnt for this vol +00E95C: D0 4F =E9AD >351 BNE CmpFreeBlk ;Branch if count is non-zero + >352 + >353 * Compute VCB free blk count + >354 +00E95E: 20 FF E9 >355 TakeFreeCnt JSR CntBMs ;Get # of bitmaps +00E961: 8D AE FE >356 STA bmCnt ;Save it +00E964: 9C 98 FE >357 STZ scrtch ;Start count at zero +00E967: 9C 99 FE >358 STZ scrtch+1 +00E96A: A9 FF >359 LDA #$FF ;Mark 'first free' temp as unknown +00E96C: 8D AD FE >360 STA noFree +00E96F: 20 64 EB >361 JSR UpdateBitMap ;(nothing happens if it don't hafta.) +00E972: B0 4D =E9C1 >362 BCS TFBErr ;Branch if we got trouble + >363 +00E974: AE A3 FE >364 LDX vcbPtr ;Get address of first bit map +00E977: BD 1A D9 >365 LDA vcb+vcbBitMap,X +00E97A: 85 46 >366 STA blockNum +00E97C: BD 1B D9 >367 LDA vcb+vcbBitMap+1,X +00E97F: 85 47 >368 STA blockNum+1 + >369 +00E981: 20 C7 EB >370 BitMapRd JSR RdGBuf ;Use g(eneral)buff(er) for temporary +00E984: B0 3B =E9C1 >371 BCS TFBErr ; space to count free blocks (bits) +00E986: 20 C2 E9 >372 JSR FreeCount ;Go count 'em +00E989: CE AE FE >373 DEC bmCnt ;Was that the last bit map? +00E98C: 30 08 =E996 >374 BMI ChgVCB ;If so, go change VCB to avoid doing this again! +00E98E: E6 46 >375 INC blockNum ;Note: the organization of the bit maps +00E990: D0 EF =E981 >376 BNE BitMapRd ; are contiguous for sos version 0 +00E992: E6 47 >377 INC blockNum+1 ;If some other organization is implemented, +00E994: 80 EB =E981 >378 BRA BitMapRd ; this code must be changed! + >379 +00E996: AE A3 FE >380 ChgVCB LDX vcbPtr ;Mark which block had first free space +00E999: AD AD FE >381 LDA noFree +00E99C: 30 20 =E9BE >382 BMI DskFull ;Branch if no free space was found +00E99E: 9D 1C D9 >383 STA vcb+vcbCurrBitMap,X ;Update the free count +00E9A1: AD 99 FE >384 LDA scrtch+1 ;Get high count byte +00E9A4: 9D 15 D9 >385 STA vcb+vcbFreeBlks+1,X ;Update volume control block +00E9A7: AD 98 FE >386 LDA scrtch +00E9AA: 9D 14 D9 >387 STA vcb+vcbFreeBlks,X ; & low byte too... + >388 +00E9AD: BD 14 D9 >389 CmpFreeBlk LDA vcb+vcbFreeBlks,X ;Compare total available +00E9B0: 38 >390 SEC +00E9B1: ED A6 FE >391 SBC reqL ; free blocks on this volume +00E9B4: BD 15 D9 >392 LDA vcb+vcbFreeBlks+1,X +00E9B7: ED A7 FE >393 SBC reqH +00E9BA: 90 02 =E9BE >394 BCC DskFull +00E9BC: 18 >395 CLC +00E9BD: 60 >396 RTS + >397 +00E9BE: A9 48 >398 DskFull LDA #volumeFull +00E9C0: 38 >399 SEC +00E9C1: 60 >400 TFBErr RTS + >401 + >402 *------------------------------------------------- + >403 * Scan and count bitMap blks + >404 +00E9C2: A0 00 >405 FreeCount LDY #$00 ;Begin at the beginning +00E9C4: B9 00 DC >406 :loop LDA genBuf,Y ;Get bit pattern +00E9C7: F0 03 =E9CC >407 BEQ :1 ;Don't bother counting nothin' +00E9C9: 20 EF E9 >408 JSR CntFree +00E9CC: B9 00 DD >409 :1 LDA genBuf+$100,Y ;Do both pages with same loop +00E9CF: F0 03 =E9D4 >410 BEQ :2 +00E9D1: 20 EF E9 >411 JSR CntFree +00E9D4: C8 >412 :2 INY +00E9D5: D0 ED =E9C4 >413 BNE :loop ;Loop till all 512 bytes counted +00E9D7: 2C AD FE >414 BIT noFree ;Has first block with free space been found yet? +00E9DA: 10 12 =E9EE >415 BPL :3 ;Branch if it has + >416 +00E9DC: AD 98 FE >417 LDA scrtch ;Test to see if any blocks were counted +00E9DF: 0D 99 FE >418 ORA scrtch+1 +00E9E2: F0 0A =E9EE >419 BEQ :3 ;Branch if none counted + >420 +00E9E4: 20 FF E9 >421 JSR CntBMs ;Get total # of maps +00E9E7: 38 >422 SEC ;Subtract countdown from total bit maps +00E9E8: ED AE FE >423 SBC bmCnt +00E9EB: 8D AD FE >424 STA noFree +00E9EE: 60 >425 :3 RTS + >426 + >427 *------------------------------------------------- + >428 * Count # of 1 bits in a byte + >429 +00E9EF: 0A >430 CntFree ASL +00E9F0: 90 08 =E9FA >431 BCC :1 ;Not a 1-bit +00E9F2: EE 98 FE >432 INC scrtch +00E9F5: D0 03 =E9FA >433 BNE :1 +00E9F7: EE 99 FE >434 INC scrtch+1 +00E9FA: 09 00 >435 :1 ORA #$00 ;Loop until all bits counted +00E9FC: D0 F1 =E9EF >436 BNE CntFree +00E9FE: 60 >437 RTS + >438 + >439 *------------------------------------------------- + >440 * Compute # of bit map blks-1 + >441 +00E9FF: AE A3 FE >442 CntBMs LDX vcbPtr +00EA02: BC 13 D9 >443 LDY vcb+vcbTotBlks+1,X ;Return the # of bit maps +00EA05: BD 12 D9 >444 LDA vcb+vcbTotBlks,X ; posible with the total count +00EA08: D0 01 =EA0B >445 BNE :1 ; found in the vcb... +00EA0A: 88 >446 DEY ;Adjust for bitmap block boundary + >447 +00EA0B: 98 >448 :1 TYA +00EA0C: 4A >449 LSR ;Divide by 16. The result is +00EA0D: 4A >450 LSR ; the number of bit maps +00EA0E: 4A >451 LSR +00EA0F: 4A >452 LSR +00EA10: 60 >453 RTS + 33 PUT mli.src/Alloc + >1 ************************************************** + >2 * Free a blk on disk + >3 +00EA11: 8E AE FE >4 Dealloc STX bmCnt ;Save high order address of block to be freed +00EA14: 48 >5 PHA ;Save it +00EA15: AE A3 FE >6 LDX vcbPtr ; while the bitmap +00EA18: BD 13 D9 >7 LDA vcb+vcbTotBlks+1,X ; disk address is checked +00EA1B: CD AE FE >8 CMP bmCnt ; to see if it makes sense +00EA1E: 68 >9 PLA ;Restore +00EA1F: 90 6B =EA8C >10 BCC DeAllocErr1 ;Branch if impossible + >11 +00EA21: AA >12 TAX +00EA22: 29 07 >13 AND #$07 ;Get the bit to be OR-ed in +00EA24: A8 >14 TAY +00EA25: B9 26 FE >15 LDA WhichBit,Y ;(shifting takes 7 bytes, but is slower) +00EA28: 8D AD FE >16 STA noFree ;Save bit pattern +00EA2B: 8A >17 TXA ;Get low block address again +00EA2C: 4E AE FE >18 LSR bmCnt +00EA2F: 6A >19 ROR ;Get pointer to byte in bitmap that +00EA30: 4E AE FE >20 LSR bmCnt ; represents the block address +00EA33: 6A >21 ROR +00EA34: 4E AE FE >22 LSR bmCnt +00EA37: 6A >23 ROR +00EA38: 8D B4 FE >24 STA bmPtr ;Save pointer +00EA3B: 4E AE FE >25 LSR bmCnt ;Now transfer bit which specifies which page of bitmap +00EA3E: 2E B6 FE >26 ROL half + >27 +00EA41: 20 31 EB >28 JSR FindBitMap ;Make absolutely sure we've got the right device +00EA44: B0 45 =EA8B >29 BCS DeAllocErr ;Return any errors + >30 +00EA46: AD BB FE >31 LDA bmaCurrMap ;What is the current map? +00EA49: CD AE FE >32 CMP bmCnt ;Is in-core bit map the one we want? +00EA4C: F0 16 =EA64 >33 BEQ :1 ;Branch if in-core is correct + >34 +00EA4E: 20 64 EB >35 JSR UpdateBitMap ;Put current map away +00EA51: B0 38 =EA8B >36 BCS DeAllocErr ;Pass back any error + >37 +00EA53: AD AE FE >38 LDA bmCnt ;Get desired map number +00EA56: AE A3 FE >39 LDX vcbPtr +00EA59: 9D 1C D9 >40 STA vcb+vcbCurrBitMap,X +00EA5C: AD B8 FE >41 LDA bmaDev +00EA5F: 20 75 EB >42 JSR GetBitMap ;Read it into the buffer +00EA62: B0 27 =EA8B >43 BCS DeAllocErr + >44 +00EA64: AC B4 FE >45 :1 LDY bmPtr ;Index to byte +00EA67: 4E B6 FE >46 LSR half +00EA6A: AD AD FE >47 LDA noFree ;(get individual bit) +00EA6D: 90 08 =EA77 >48 BCC bmBufHi ;Branch if on page one of bitmap +00EA6F: 19 00 DB >49 ORA bmBuf+$100,Y +00EA72: 99 00 DB >50 STA bmBuf+$100,Y +00EA75: B0 06 =EA7D >51 BCS DeAloc3 ;Branch always taken + >52 +00EA77: 19 00 DA >53 bmBufHi ORA bmBuf,Y +00EA7A: 99 00 DA >54 STA bmBuf,Y + >55 +00EA7D: A9 80 >56 DeAloc3 LDA #$80 ;mark bitmap as modified +00EA7F: 0C B7 FE >57 TSB bmaStat +00EA82: EE D1 FE >58 INC deBlock ;Bump count of blocks deallocated +00EA85: D0 03 =EA8A >59 BNE :11 +00EA87: EE D2 FE >60 INC deBlock+1 +00EA8A: 18 >61 :11 CLC +00EA8B: 60 >62 DeAllocErr RTS + >63 +00EA8C: A9 5A >64 DeAllocErr1 LDA #damagedBitMap ;bit map block # impossible +00EA8E: 38 >65 SEC ;Say bit map disk address wrong +00EA8F: 60 >66 RTS ;(probably data masquerading as index block) + >67 + >68 ************************************************** + >69 * Find a free disk block & allocate it + >70 * Exit + >71 * (Y,A)=disk addr + >72 * (scrtch)=disk addr + >73 +00EA90: 20 31 EB >74 Alloc1Blk JSR FindBitMap ;Get address of bit map in 'bmAdr' +00EA93: B0 23 =EAB8 >75 BCS ErrAloc1 ;Branch if error encountered +00EA95: A0 00 >76 SrchFree LDY #$00 ;Start search at beginning of bit map block +00EA97: 8C B6 FE >77 STY half ;Indicate which half (page) we're searching +00EA9A: B9 00 DA >78 GetBits1 LDA bmBuf,Y ;Free blocks are indicated by 'on' bits +00EA9D: D0 1A =EAB9 >79 BNE BitFound +00EA9F: C8 >80 INY +00EAA0: D0 F8 =EA9A >81 BNE GetBits1 ;Check all of 'em in first page + >82 +00EAA2: EE B6 FE >83 INC half ;Indicate search has progressed to page 2 +00EAA5: EE B5 FE >84 INC basVal ;base value=base address/2048 +00EAA8: B9 00 DB >85 :loop LDA bmBuf+$100,Y ;Search second half for free block +00EAAB: D0 0C =EAB9 >86 BNE BitFound +00EAAD: C8 >87 INY +00EAAE: D0 F8 =EAA8 >88 BNE :loop + >89 +00EAB0: EE B5 FE >90 INC basVal ;Add 2048 offset for next page +00EAB3: 20 18 EB >91 JSR NxtBitMap ;Get next bitmap (if it exists) and update VCB +00EAB6: 90 DD =EA95 >92 BCC SrchFree ;Branch if no error encountered +00EAB8: 60 >93 ErrAloc1 RTS ;Return error + >94 + >95 * Calculate blk # represented by first set VBM bit + >96 +00EAB9: 8C B4 FE >97 BitFound STY bmPtr ;Save index pointer to valid bit group +00EABC: AD B5 FE >98 LDA basVal ;Set up for block address calculation +00EABF: 8D 99 FE >99 STA scrtch+1 +00EAC2: 98 >100 TYA ;Get address of bit pattern +00EAC3: 0A >101 ASL ;Multiply this and basVal by 8 +00EAC4: 2E 99 FE >102 ROL scrtch+1 +00EAC7: 0A >103 ASL +00EAC8: 2E 99 FE >104 ROL scrtch+1 +00EACB: 0A >105 ASL +00EACC: 2E 99 FE >106 ROL scrtch+1 +00EACF: AA >107 TAX ;Now X=low address within 7 of actual address +00EAD0: 38 >108 SEC +00EAD1: AD B6 FE >109 LDA half +00EAD4: F0 05 =EADB >110 BEQ Page1Alloc ;Branch if allocating from 1st half +00EAD6: B9 00 DB >111 LDA bmBuf+$100,Y ;Get pattern from second page +00EAD9: B0 03 =EADE >112 BCS adcAloc ;Branch always +00EADB: B9 00 DA >113 Page1Alloc LDA bmBuf,Y ;Get bit pattern from first page + >114 +00EADE: 2A >115 adcAloc ROL ;Find left most 'on' bit +00EADF: B0 03 =EAE4 >116 BCS Bounce ;Branch if found +00EAE1: E8 >117 INX ;Adjust low address +00EAE2: D0 FA =EADE >118 BNE adcAloc ;Branch always + >119 +00EAE4: 4A >120 Bounce LSR ;Restore all but left most bit to original position +00EAE5: 90 FD =EAE4 >121 BCC Bounce ;Loop until mark (set above) moves into Carry +00EAE7: 8E 98 FE >122 STX scrtch ;Save low address +00EAEA: AE B6 FE >123 LDX half ;Which half of bit map? +00EAED: D0 05 =EAF4 >124 BNE Page2Alloc +00EAEF: 99 00 DA >125 STA bmBuf,Y +00EAF2: F0 03 =EAF7 >126 BEQ DirtyBitMap ;Branch always +00EAF4: 99 00 DB >127 Page2Alloc STA bmBuf+$100,Y ;Update bitmap to show allocated block in use + >128 +00EAF7: A9 80 >129 DirtyBitMap LDA #$80 ;Indicate map has been +00EAF9: 0C B7 FE >130 TSB bmaStat ; modified by setting dirty bit +00EAFC: AC A3 FE >131 LDY vcbPtr ;Subtract 1 from total free +00EAFF: B9 14 D9 >132 LDA vcb+vcbFreeBlks,Y ; blocks in VCB to account for newly +00EB02: E9 01 >133 SBC #$01 ; allocated block (carry is set from 'bounce') +00EB04: 99 14 D9 >134 STA vcb+vcbFreeBlks,Y +00EB07: B0 07 =EB10 >135 BCS Ret1Blk ;Branch if hi free count doesn't need adjustment + >136 +00EB09: B9 15 D9 >137 LDA vcb+vcbFreeBlks+1,Y ;Adjust high count +00EB0C: 3A >138 DEC +00EB0D: 99 15 D9 >139 STA vcb+vcbFreeBlks+1,Y +00EB10: 18 >140 Ret1Blk CLC ;Indicate no error encountered +00EB11: AD 98 FE >141 LDA scrtch ;Get address low in A-Reg +00EB14: AC 99 FE >142 LDY scrtch+1 ; & high address in Y-Reg +00EB17: 60 >143 RTS ;Return address of newly allocated block + >144 + >145 *------------------------------------------------- + >146 * Get next volume bit map block + >147 +00EB18: AC A3 FE >148 NxtBitMap LDY vcbPtr ;Before bumping to next map, +00EB1B: B9 13 D9 >149 LDA vcb+vcbTotBlks+1,Y ; check to be sure there is +00EB1E: 4A >150 LSR ; indeed a next map! +00EB1F: 4A >151 LSR +00EB20: 4A >152 LSR +00EB21: 4A >153 LSR +00EB22: D9 1C D9 >154 CMP vcb+vcbCurrBitMap,Y ;Are there more maps? +00EB25: F0 39 =EB60 >155 BEQ NoMorBM ;Branch if no more to look at +00EB27: B9 1C D9 >156 LDA vcb+vcbCurrBitMap,Y +00EB2A: 1A >157 INC ;Add 1 to current map +00EB2B: 99 1C D9 >158 STA vcb+vcbCurrBitMap,Y +00EB2E: 20 64 EB >159 JSR UpdateBitMap + >160 + >161 *------------------------------------------------- + >162 * Read volume bit map block + >163 +00EB31: AC A3 FE >164 FindBitMap LDY vcbPtr ;Get device number +00EB34: B9 10 D9 >165 LDA vcb+vcbDevice,Y +00EB37: CD B8 FE >166 CMP bmaDev +00EB3A: F0 0E =EB4A >167 BEQ FreshMap +00EB3C: 20 64 EB >168 JSR UpdateBitMap ;Save out other volumes' bitmap, and +00EB3F: B0 1E =EB5F >169 BCS NoGo + >170 +00EB41: AC A3 FE >171 LDY vcbPtr +00EB44: B9 10 D9 >172 LDA vcb+vcbDevice,Y +00EB47: 8D B8 FE >173 STA bmaDev ; read in fresh bitmap for this device +00EB4A: AC B7 FE >174 FreshMap LDY bmaStat ;Is this one already modified? +00EB4D: 30 05 =EB54 >175 BMI BMFound ;Yes, return pointer in 'bmAdr' +00EB4F: 20 75 EB >176 JSR GetBitMap ;Otherwise read in fresh bit map +00EB52: B0 0B =EB5F >177 BCS NoGo ;Branch if unsuccessful + >178 +00EB54: AC A3 FE >179 BMFound LDY vcbPtr +00EB57: B9 1C D9 >180 LDA vcb+vcbCurrBitMap,Y ;Get offset into VBM +00EB5A: 0A >181 ASL +00EB5B: 8D B5 FE >182 STA basVal ;Save page offset into VBM +00EB5E: 18 >183 CLC ;Indicate all is valid and good! +00EB5F: 60 >184 NoGo RTS + >185 +00EB60: A9 48 >186 NoMorBM LDA #volumeFull ;Indicate request can't be filled +00EB62: 38 >187 SEC ;Indicate error +00EB63: 60 >188 RTS + >189 + >190 *------------------------------------------------- + >191 * Check point vol bitMap for disk writing + >192 +00EB64: 18 >193 UpdateBitMap CLC ;Anticipate nothing to do +00EB65: AD B7 FE >194 LDA bmaStat ;Is current map dirty? +00EB68: 10 F5 =EB5F >195 BPL NoGo ;No need to do anything +00EB6A: 20 BF EB >196 JSR WrtBitMap ;It is dirty, update device! +00EB6D: B0 F0 =EB5F >197 BCS NoGo ;Error encountered on writing +00EB6F: A9 00 >198 LDA #$00 +00EB71: 8D B7 FE >199 STA bmaStat ;Mark bm buffer as free +00EB74: 60 >200 RTS ;All done! + >201 + >202 *------------------------------------------------- + >203 * Prepare to read Vol BitMap block + >204 +00EB75: 8D B8 FE >205 GetBitMap STA bmaDev ;Read bitmap specified by dev & vcb +00EB78: AC A3 FE >206 LDY vcbPtr ;Get lowest map number with free blocks in it +00EB7B: B9 1C D9 >207 LDA vcb+vcbCurrBitMap,Y +00EB7E: 8D BB FE >208 STA bmaCurrMap ;Associate the offset with the bitmap control block + >209 +00EB81: 18 >210 CLC ;Add this number to the base +00EB82: 79 1A D9 >211 ADC vcb+vcbBitMap,Y ; address of first bit map +00EB85: 8D B9 FE >212 STA bmaDskAdr ;Save low address of bit map to be used +00EB88: B9 1B D9 >213 LDA vcb+vcbBitMap+1,Y ;Now get high disk address of map +00EB8B: 69 00 >214 ADC #$00 ;Add to this the state of the carry +00EB8D: 8D BA FE >215 STA bmaDskAdr+1 ;Save high disk address too +00EB90: A9 01 >216 LDA #rdCmd + >217 + >218 * Read/write Volume BitMap block + >219 +00EB92: 85 42 >220 DoBMap STA dhpCmd ;Save device command +00EB94: AD 30 BF >221 LDA DevNum ;Preserve current devnum. +00EB97: 48 >222 PHA +00EB98: AD B8 FE >223 LDA bmaDev ;Get bitmap's device number +00EB9B: 8D 30 BF >224 STA DevNum + >225 +00EB9E: AD B9 FE >226 LDA bmaDskAdr ; & map's disk address +00EBA1: 85 46 >227 STA blockNum +00EBA3: AD BA FE >228 LDA bmaDskAdr+1 +00EBA6: 85 47 >229 STA blockNum+1 + >230 +00EBA8: AD 79 EA >231 LDA bmBufHi+2 +00EBAB: 20 CD EB >232 JSR DoBitMap ;(note: low address is fixed to zero as this is a buffer) +00EBAE: AA >233 TAX ;Preserve error code, if any +00EBAF: 68 >234 PLA ;Restore the +00EBB0: 8D 30 BF >235 STA DevNum ; dev # we came in with! +00EBB3: 90 01 =EBB6 >236 BCC :Ret ;Return devnum if no error +00EBB5: 8A >237 TXA ;Return any errors +00EBB6: 60 >238 :Ret RTS + >239 + >240 *------------------------------------------------- + >241 * Read blk # in A,X regs + >242 +00EBB7: 85 46 >243 RdBlkAX STA blockNum +00EBB9: 86 47 >244 STX blockNum+1 +00EBBB: 20 C7 EB >245 JSR RdGBuf +00EBBE: 60 >246 RTS + >247 + >248 *------------------------------------------------- + >249 * Write Vol BitMap block + >250 +00EBBF: A9 02 >251 WrtBitMap LDA #wrtCmd ;write bit map +00EBC1: D0 CF =EB92 >252 BNE DoBMap ;Branch always + >253 + >254 * Write primary buffer blk + >255 +00EBC3: A9 02 >256 WrtGBuf LDA #wrtCmd ;Set call for write +00EBC5: D0 02 =EBC9 >257 BNE SavGCmd ;Branch always + >258 + >259 * Read primary buffer blk + >260 +00EBC7: A9 01 >261 RdGBuf LDA #rdCmd ;Set call for read + >262 + >263 * Read/Write primary buffer blk + >264 +00EBC9: 85 42 >265 SavGCmd STA dhpCmd ;Passed to device handler +00EBCB: A9 DC >266 LDA #>genBuf ;Get high address of general buffer + >267 + >268 *------------------------------------------------- + >269 * Read/Write block + >270 +00EBCD: 08 >271 DoBitMap PHP ;No interupts allowed +00EBCE: 78 >272 SEI +00EBCF: 85 45 >273 STA bufPtr+1 ;General purpose buffers always +00EBD1: 64 44 >274 STZ bufPtr ; start on a page boundary +00EBD3: 9C 0F BF >275 STZ SErr ;Clear global error value + >276 +00EBD6: A9 FF >277 LDA #$FF ;Also, set to indicate +00EBD8: 8D C3 FE >278 STA ioAccess ; reg call made to dev handler +00EBDB: AD 30 BF >279 LDA DevNum ;transfer the device number for +00EBDE: 85 43 >280 STA unitNum ; dispatcher to convert to unit number. +00EBE0: 20 DD DE >281 JSR DMgr ;Call the driver +00EBE3: B0 03 =EBE8 >282 BCS :1 ;Branch if error +00EBE5: 28 >283 PLP ;Restore interupts +00EBE6: 18 >284 CLC +00EBE7: 60 >285 RTS + >286 +00EBE8: 28 >287 :1 PLP ;Restore interupts +00EBE9: 38 >288 SEC +00EBEA: 60 >289 RTS + 34 PUT mli.src/PosnOpen + >1 ************************************************** + >2 * GETMARK Call + >3 +00EBEB: AE A4 FE >4 GetMark LDX fcbPtr ;Get index to open file control block +00EBEE: A0 02 >5 LDY #c_mark ; & index to user's mark parameter +00EBF0: BD 12 D8 >6 :loop LDA fcb+fcbMark,X +00EBF3: 91 40 >7 STA (parm),Y ;Transfer current position +00EBF5: E8 >8 INX ; to user's parameter list +00EBF6: C8 >9 INY +00EBF7: C0 05 >10 CPY #c_mark+3 ;Have all three bytes been transferred? +00EBF9: D0 F5 =EBF0 >11 BNE :loop ;Branch if not... +00EBFB: 18 >12 CLC ;No errors +00EBFC: 60 >13 RTS + >14 +00EBFD: A9 4D >15 ErrMrkEOF LDA #outOfRange ;Report invalid position. +00EBFF: 38 >16 SEC +00EC00: 60 >17 RTS + >18 + >19 ************************************************** + >20 * SETMARK Call + >21 +00EC01: A0 04 >22 SetMark LDY #c_mark+2 ;Get index to user's desired position +00EC03: AE A4 FE >23 LDX fcbPtr ; & file's control block index +00EC06: E8 >24 INX ;(bump by 2 for index to hi EOF) +00EC07: E8 >25 INX +00EC08: 38 >26 SEC ;Indicate comparisons are necessary +00EC09: B1 40 >27 :loop LDA (parm),Y ;Move it to 'tPos' +00EC0B: 99 BA FE >28 STA tPosll-c_mark,Y +00EC0E: 90 08 =EC18 >29 BCC :1 ;Branch if we already know mark30 CMP fcb+fcbEOF,X ;Carry or Z flag must be clear to qualify +00EC13: 90 03 =EC18 >31 BCC :1 ;Branch if mark qualifies for sure +00EC15: D0 E6 =EBFD >32 BNE ErrMrkEOF ;Branch if mark>EOF +00EC17: CA >33 DEX + >34 +00EC18: 88 >35 :1 DEY dey ;Prepare to move/compare next lower byte of mark +00EC19: 98 >36 TYA ;Test for all bytes moved/tested +00EC1A: 49 01 >37 EOR #c_mark-1 ;To preserve carry status +00EC1C: D0 EB =EC09 >38 BNE :loop ;Branch if more + >39 + >40 * Still in same data block + >41 +00EC1E: AC A4 FE >42 RdPosn LDY fcbPtr ;First test to see if new position is +00EC21: B9 13 D8 >43 LDA fcb+fcbMark+1,Y ; within the same (current) data block +00EC24: 29 FE >44 AND #%11111110 +00EC26: 8D 98 FE >45 STA scrtch ;(At a block boundary) +00EC29: AD BD FE >46 LDA tPoslh ;Get middle byte of new position +00EC2C: 38 >47 SEC +00EC2D: ED 98 FE >48 SBC scrtch +00EC30: 8D 98 FE >49 STA scrtch +00EC33: 90 0F =EC44 >50 BCC TypMark ;Branch if possibly l.t. current position +00EC35: C9 02 >51 CMP #$02 ;Must be within 512 bytes of beginning of current +00EC37: B0 0B =EC44 >52 BCS TypMark ;No +00EC39: AD BE FE >53 LDA tPosHi ;Now make sure we're talking +00EC3C: D9 14 D8 >54 CMP fcb+fcbMark+2,Y ; about the same 64K chunk! +00EC3F: D0 03 =EC44 >55 BNE TypMark ;Branch if we aren't +00EC41: 4C 61 ED >56 JMP SavMark ;If we are, adjust FCB, posPtr and return + >57 + =EC44 >58 TypMark EQU * ;Now find out which type +00EC44: B9 07 D8 >59 LDA fcb+fcbStorTyp,Y ; of file we're positioning on +00EC47: F0 07 =EC50 >60 BEQ :11 ;There is no such type as zero, branch never! +00EC49: C9 04 >61 CMP #tree+1 ;Is it a tree class file? +00EC4B: 90 0C =EC59 >62 BCC TreePos ;Yes, go position +00EC4D: 4C 93 ED >63 JMP DirMark ;No, test for directory type + >64 +00EC50: A0 A4 >65 :11 LDY #fcbPtr ;Clear illegally typed FCB entry +00EC52: 99 00 D8 >66 STA fcb+fcbRefNum,Y +00EC55: A9 43 >67 LDA #invalidRefNum ;Tell 'em there is no such file +00EC57: 38 >68 SEC +00EC58: 60 >69 RTS + >70 + >71 * Need different data blk + >72 + =EC59 >73 TreePos EQU * ;Use storage type as number of index levels +00EC59: B9 07 D8 >74 LDA fcb+fcbStorTyp,Y ; (since 1=seed, 2=sapling, and 3=tree) +00EC5C: 8D A8 FE >75 STA levels +00EC5F: B9 08 D8 >76 LDA fcb+fcbStatus,Y ;Must not forget previous data +00EC62: 29 40 >77 AND #dataMod ;Therefore, see if previous data was modified +00EC64: F0 05 =EC6B >78 BEQ :21 ; then disk must be updated +00EC66: 20 66 EE >79 JSR WrFCBData ;Yes, so go write current data block +00EC69: B0 69 =ECD4 >80 BCS PosErr ;Return any error encountered + >81 +00EC6B: AC A4 FE >82 :21 LDY fcbPtr ;Test to see if current +00EC6E: B9 14 D8 >83 LDA fcb+fcbMark+2,Y ; index block is going to be usable... +00EC71: 29 FE >84 AND #%11111110 ; or in other words - is new position +00EC73: 8D 98 FE >85 STA scrtch ; within 128K of the beginning +00EC76: AD BE FE >86 LDA tPosHi ; of current sapling level chunk? +00EC79: 38 >87 SEC +00EC7A: ED 98 FE >88 SBC scrtch +00EC7D: 90 1E =EC9D >89 BCC PosNew2 ;Branch if a new index block is also needed +00EC7F: C9 02 >90 CMP #$02 ;New position is > begining of old. Is it within 128K? +00EC81: B0 1A =EC9D >91 BCS PosNew2 ;Branch if not +00EC83: AE A8 FE >92 LDX levels ;Is the file we're dealing with a seed? +00EC86: CA >93 DEX +00EC87: D0 77 =ED00 >94 BNE DataLevel ;No, use current indexes + >95 +00EC89: AD BD FE >96 TestTiny LDA tPoslh ;Is new position under 512? +00EC8C: 4A >97 LSR +00EC8D: 0D BE FE >98 ORA tPosHi +00EC90: D0 5D =ECEF >99 BNE NoIdxData ;No, mark both data and index block as un-allocated +00EC92: B9 0C D8 >100 LDA fcb+fcbFirst,Y ;First block is only block and it's data! +00EC95: 85 46 >101 STA blockNum +00EC97: B9 0D D8 >102 LDA fcb+fcbFirst+1,Y ;(high block address) +00EC9A: 4C 57 ED >103 JMP RdNewPos + >104 + =EC9D >105 PosNew2 EQU * ;Gota check to see if previous +00EC9D: B9 08 D8 >106 LDA fcb+fcbStatus,Y ; index block was modified +00ECA0: 29 80 >107 AND #idxMod +00ECA2: F0 05 =ECA9 >108 BEQ PosnIdx ;Read in over it if current is up to date +00ECA4: 20 79 EE >109 JSR WrFCBIdx ;Go update index on disk (block addr in fcb) +00ECA7: B0 2B =ECD4 >110 BCS PosErr + >111 +00ECA9: AE A8 FE >112 PosnIdx LDX levels ;Before reading in top index, check +00ECAC: E0 03 >113 CPX #tree ; to be sure that there is a top index... +00ECAE: F0 25 =ECD5 >114 BEQ PosIndex ;Branch if file is full blown tree + >115 +00ECB0: AD BE FE >116 LDA tPosHi ;Is new position within range +00ECB3: 4A >117 LSR ; of a sapling file (l.t. 128k)? +00ECB4: 08 >118 PHP ;Anticipate no good +00ECB5: A9 07 >119 LDA #topAloc+idxAloc+dataAloc ;(to indicate no level is allocated for new posn) +00ECB7: 28 >120 PLP ;Z flag tells all... +00ECB8: D0 5E =ED18 >121 BNE NoData ;Go mark 'em all dummy + >122 +00ECBA: 20 87 ED >123 JSR ClrStats ;Go clear status bits 0,1,2 (index/data alloc status) +00ECBD: CA >124 DEX ;(unaffected since loaded above) Check for seed +00ECBE: F0 C9 =EC89 >125 BEQ TestTiny ;If seed, check for position l.t. 512... + >126 +00ECC0: 20 10 EE >127 JSR RdFCBFst ;Go get only index block +00ECC3: B0 0F =ECD4 >128 BCS PosErr ;Branch if error + >129 +00ECC5: AC A4 FE >130 LDY fcbPtr ;Save newly loaded index block's address +00ECC8: A5 46 >131 LDA blockNum +00ECCA: 99 0E D8 >132 STA fcb+fcbIdxBlk,Y +00ECCD: A5 47 >133 LDA blockNum+1 +00ECCF: 99 0F D8 >134 STA fcb+fcbIdxBlk+1,Y +00ECD2: 90 2C =ED00 >135 BCC DataLevel ;Branch always... +00ECD4: 60 >136 PosErr RTS ;Carry always set when branched to + >137 +00ECD5: 20 87 ED >138 PosIndex JSR ClrStats ;Clear all allocation requirements for prev posn +00ECD8: 20 10 EE >139 JSR RdFCBFst ;Get highest level index block +00ECDB: B0 F7 =ECD4 >140 BCS PosErr + >141 +00ECDD: AD BE FE >142 LDA tPosHi ;Then test for a sap level index block +00ECE0: 4A >143 LSR +00ECE1: A8 >144 TAY +00ECE2: B1 48 >145 LDA (tIndex),Y +00ECE4: E6 49 >146 INC tIndex+1 +00ECE6: D1 48 >147 CMP (tIndex),Y ;(both hi and lo will be zero if no index exists) +00ECE8: D0 09 =ECF3 >148 BNE SapLevel +00ECEA: AA >149 TAX ;Are both bytes zero? +00ECEB: D0 06 =ECF3 >150 BNE SapLevel ;No +00ECED: C6 49 >151 DEC tIndex+1 ;Don't leave wrong pointers laying around! +00ECEF: A9 03 >152 NoIdxData LDA #idxAloc+dataAloc +00ECF1: 80 25 =ED18 >153 BRA NoData + >154 +00ECF3: 85 46 >155 SapLevel STA blockNum ;Read in next lower index block +00ECF5: B1 48 >156 LDA (tIndex),Y ;(hi address) +00ECF7: 85 47 >157 STA blockNum+1 +00ECF9: C6 49 >158 DEC tIndex+1 +00ECFB: 20 F3 ED >159 JSR RdFCBIdx ;Read in sapling level +00ECFE: B0 D4 =ECD4 >160 BCS PosErr + >161 +00ED00: AD BE FE >162 DataLevel LDA tPosHi ;Now get block address of data block +00ED03: 4A >163 LSR +00ED04: AD BD FE >164 LDA tPoslh ;( if there is one ) +00ED07: 6A >165 ROR +00ED08: A8 >166 TAY +00ED09: B1 48 >167 LDA (tIndex),Y ;Data block address low +00ED0B: E6 49 >168 INC tIndex+1 +00ED0D: D1 48 >169 CMP (tIndex),Y +00ED0F: D0 40 =ED51 >170 BNE PosNew3 +00ED11: AA >171 TAX ;Are both bytes zero? +00ED12: D0 3D =ED51 >172 BNE PosNew3 ;No +00ED14: A9 01 >173 LDA #dataAloc ;Show data block has never been allocated +00ED16: C6 49 >174 DEC tIndex+1 + >175 +00ED18: AC A4 FE >176 NoData LDY fcbPtr ;Set status to show what's missing +00ED1B: 19 08 D8 >177 ORA fcb+fcbStatus,Y +00ED1E: 99 08 D8 >178 STA fcb+fcbStatus,Y +00ED21: 4A >179 LSR ;Throw away bit that says data block un-allocated +00ED22: 4A >180 LSR ; cuz we know that. Carry now indicates if index block +00ED23: 20 3F ED >181 JSR ZipData ; also is invalid and needs to be zeroed (Carry undisturbed) +00ED26: 90 39 =ED61 >182 BCC SavMark ;Branch if index block doesn't need zipping + >183 +00ED28: 20 2D ED >184 JSR ZeroIndex ;Go zero index block in user's i/o buffer +00ED2B: 80 34 =ED61 >185 BRA SavMark + >186 +00ED2D: A9 00 >187 ZeroIndex LDA #$00 +00ED2F: A8 >188 TAY +00ED30: 91 48 >189 :loop1 STA (tIndex),Y ;Zero out the index half +00ED32: C8 >190 INY +00ED33: D0 FB =ED30 >191 BNE :loop1 ; of the user's i/o buffer +00ED35: E6 49 >192 INC tIndex+1 +00ED37: 91 48 >193 :loop2 STA (tIndex),Y +00ED39: C8 >194 INY +00ED3A: D0 FB =ED37 >195 BNE :loop2 ;Restore proper address +00ED3C: C6 49 >196 DEC tIndex+1 +00ED3E: 60 >197 RTS ;That's all + >198 +00ED3F: A9 00 >199 ZipData LDA #$00 ;Also is invalid and needs to be zeroed +00ED41: A8 >200 TAY +00ED42: 91 4A >201 :loop1 STA (dataPtr),Y ;Zero out data area +00ED44: C8 >202 INY +00ED45: D0 FB =ED42 >203 BNE :loop1 +00ED47: E6 4B >204 INC dataPtr+1 +00ED49: 91 4A >205 :loop2 STA (dataPtr),Y +00ED4B: C8 >206 INY +00ED4C: D0 FB =ED49 >207 BNE :loop2 +00ED4E: C6 4B >208 DEC dataPtr+1 +00ED50: 60 >209 RTS + >210 + >211 * Read file data blk + >212 +00ED51: 85 46 >213 PosNew3 STA blockNum ;Get data block of new position +00ED53: B1 48 >214 LDA (tIndex),Y ;(hi address) +00ED55: C6 49 >215 DEC tIndex+1 +00ED57: 85 47 >216 RdNewPos STA blockNum+1 +00ED59: 20 DA ED >217 JSR RdFCBData +00ED5C: B0 28 =ED86 >218 BCS pritz ;Return any error +00ED5E: 20 87 ED >219 JSR ClrStats ;Show whole chain is allocated + >220 + >221 * Got data blk wanted + >222 +00ED61: AC A4 FE >223 SavMark LDY fcbPtr ;Update position in file control block +00ED64: C8 >224 INY +00ED65: C8 >225 INY +00ED66: A2 02 >226 LDX #$02 +00ED68: B9 12 D8 >227 :loop LDA fcb+fcbMark,Y ;Remember oldmark in case +00ED6B: 9D 9F FE >228 STA oldMark,X ; calling routine fails later +00ED6E: BD BC FE >229 LDA tPosll,X ;Set new mark +00ED71: 99 12 D8 >230 STA fcb+fcbMark,Y ; in FCB +00ED74: 88 >231 DEY +00ED75: CA >232 DEX ;Move 3-byte position marker +00ED76: 10 F0 =ED68 >233 BPL :loop + >234 +00ED78: 18 >235 CLC ;Last, but not least, set up +00ED79: A5 4A >236 LDA dataPtr ; indirect address to buffer page pointed +00ED7B: 85 4C >237 STA posPtr ; to by the current position marker +00ED7D: AD BD FE >238 LDA tPoslh +00ED80: 29 01 >239 AND #$01 ;(A)=0/1 +00ED82: 65 4B >240 ADC dataPtr+1 ;(posPtr) = start of pg in +00ED84: 85 4D >241 STA posPtr+1 ; data blk which contains the mark +00ED86: 60 >242 pritz RTS ;Carry set indicates error! + >243 + >244 *------------------------------------------------- + >245 * Reset block allocate flags + >246 +00ED87: AC A4 FE >247 ClrStats LDY fcbPtr ;Clear allocation states for data block +00ED8A: B9 08 D8 >248 LDA fcb+fcbStatus,Y ; and both levels of indexes +00ED8D: 29 F8 >249 AND #$FF-topAloc-idxAloc-dataAloc +00ED8F: 99 08 D8 >250 STA fcb+fcbStatus,Y ;This says that either they exist currently +00ED92: 60 >251 RTS ; or that they're unnecessary for current position. + >252 + >253 *------------------------------------------------- + >254 * Set dir file position + >255 +00ED93: C9 0D >256 DirMark CMP #directoryFile ;Is it a directory? +00ED95: F0 05 =ED9C >257 BEQ DirPos ;Yes... +00ED97: A9 4A >258 LDA #badFileFormat ;No, there is a compatiblity problem - +00ED99: 20 09 BF >259 JSR SysErr ; the damn thing should never been opened! + >260 +00ED9C: AD 98 FE >261 DirPos LDA scrtch ;Recover results of previous subtraction +00ED9F: 4A >262 LSR ;Use difference as counter as to how many +00EDA0: 8D AC FE >263 STA cntEnt ; blocks must be read to get to new position +00EDA3: B9 13 D8 >264 LDA fcb+fcbMark+1,Y ;Test for position direction +00EDA6: CD BD FE >265 CMP tPoslh ;Carry indicates direction... +00EDA9: 90 0E =EDB9 >266 BCC DirFwrd ;If set, position forward + >267 +00EDAB: A0 00 >268 DirReverse LDY #$00 ;Otherwise, read directory file in reverse order +00EDAD: 20 C7 ED >269 JSR DirPos1 ;Read previous block +00EDB0: B0 24 =EDD6 >270 BCS DirPosErr ;Branch if anything goes wrong +00EDB2: EE AC FE >271 INC cntEnt ;Count up to 128 +00EDB5: 10 F4 =EDAB >272 BPL DirReverse ;Loop if there is more blocks to pass over +00EDB7: 30 A8 =ED61 >273 BMI SavMark ;Branch always + >274 +00EDB9: A0 02 >275 DirFwrd LDY #$02 ;Position is forward from current position +00EDBB: 20 C7 ED >276 JSR DirPos1 ;Read next directory block +00EDBE: B0 16 =EDD6 >277 BCS DirPosErr +00EDC0: CE AC FE >278 DEC cntEnt +00EDC3: D0 F4 =EDB9 >279 BNE DirFwrd ;Loop if position not found in this bloc +00EDC5: F0 9A =ED61 >280 BEQ SavMark ;Branch always + >281 +00EDC7: B1 4A >282 DirPos1 LDA (dataPtr),Y ;Get link address of previous +00EDC9: 85 46 >283 STA blockNum ; or next directory block +00EDCB: C9 01 >284 CMP #$01 ; but first be sure there is a link +00EDCD: C8 >285 INY +00EDCE: B1 4A >286 LDA (dataPtr),Y +00EDD0: D0 06 =EDD8 >287 BNE DirPos2 +00EDD2: B0 04 =EDD8 >288 BCS DirPos2 ;Branch if certain link exists +00EDD4: A9 4C >289 LDA #eofEncountered ;Something is wrong with this directory file! +00EDD6: 38 >290 DirPosErr SEC ;Indicate error +00EDD7: 60 >291 RTS + >292 +00EDD8: 85 47 >293 DirPos2 STA blockNum+1 ;(high order block address) + >294 * + >295 * Drop into rfcbdat (Read file's data block) + >296 * + >297 * + >298 * Note: for directory positioning, no optimization has been done since + >299 * since directory files will almost always be less than 6 blocks. + >300 * If more speed is required or directory type files are to be used + >301 * for other purposes requiring more blocks, then the recommended + >302 * method is to call RdFCBData for the first block and go directly to + >303 * device (via jmp (iounitl)) handler for subsequent accesses. + >304 * Also note that no checking is done for read/write enable since a + >305 * directory file can only be opened for read access. + >306 * +00EDDA: A9 01 >307 RdFCBData LDA #rdCmd ;Set read command +00EDDC: 85 42 >308 STA dhpCmd +00EDDE: A2 4A >309 LDX #dataPtr ;Use X to point at address of data buffer +00EDE0: 20 36 EE >310 JSR FileIOZ ;Go do file input +00EDE3: B0 0D =EDF2 >311 BCS :Ret ;Return any error + >312 +00EDE5: AC A4 FE >313 LDY fcbPtr +00EDE8: A5 46 >314 LDA blockNum +00EDEA: 99 10 D8 >315 STA fcb+fcbDataBlk,Y ;Save block number just read in FCB +00EDED: A5 47 >316 LDA blockNum+1 +00EDEF: 99 11 D8 >317 STA fcb+fcbDataBlk+1,Y +00EDF2: 60 >318 :Ret RTS ;Carry set indicates error + >319 + >320 *------------------------------------------------- + >321 * Read sub index blk + >322 +00EDF3: A9 01 >323 RdFCBIdx LDA #rdCmd ;Prepare to read in index bloc +00EDF5: 85 42 >324 STA dhpCmd +00EDF7: A2 48 >325 LDX #tIndex ;Point at address of current index buffer +00EDF9: 20 36 EE >326 JSR FileIOZ ;Go read index block +00EDFC: B0 0E =EE0C >327 BCS :Ret ;Report error +00EDFE: AC A4 FE >328 LDY fcbPtr +00EE01: A5 46 >329 LDA blockNum +00EE03: 99 0E D8 >330 STA fcb+fcbIdxBlk,Y ;Save block address of this index in fcb +00EE06: A5 47 >331 LDA blockNum+1 +00EE08: 99 0F D8 >332 STA fcb+fcbIdxBlk+1,Y +00EE0B: 18 >333 CLC +00EE0C: 60 >334 :Ret RTS + >335 + >336 *------------------------------------------------- + >337 * Write key index blk + >338 +00EE0D: A9 02 >339 WrFCBFst1 LDA #wrtCmd ;Set write mode for device +00EE0F: 2C >340 DB $2C ;Skip next 2 bytes for pseudo-branch always to RWFst + >341 + >342 * Read key index blk + >343 +00EE10: A9 01 >344 RdFCBFst LDA #rdCmd ;Set read mode for device +00EE12: 48 >345 RWFst PHA ;Save command +00EE13: A9 0C >346 LDA #fcbFirst +00EE15: 0D A4 FE >347 ORA fcbPtr ;Add offset to fcbPtr +00EE18: A8 >348 TAY +00EE19: 68 >349 PLA +00EE1A: A2 48 >350 LDX #tIndex ;Read block into index portion of file buffer + >351 * + >352 * Drop into DoFileIO + >353 * +00EE1C: 85 42 >354 DoFileIO STA dhpCmd ;Save command +00EE1E: B9 00 D8 >355 LDA fcb,Y ;Get disk block address from FCB +00EE21: 85 46 >356 STA blockNum ;Block zero not legal +00EE23: D9 01 D8 >357 CMP fcb+1,Y +00EE26: D0 09 =EE31 >358 BNE FileIO +00EE28: C9 00 >359 CMP #$00 ;Are both bytes zero? +00EE2A: D0 05 =EE31 >360 BNE FileIO ;No, continue with request +00EE2C: A9 0C >361 LDA #badBlockErr ;Otherwise report allocation error +00EE2E: 20 0C BF >362 JSR SysDeath ;Never returns... + >363 +00EE31: B9 01 D8 >364 FileIO LDA fcb+1,Y ;Get high address of disk block +00EE34: 85 47 >365 STA blockNum+1 + >366 + >367 *------------------------------------------------- + >368 * Set up and do file block I/O + >369 * Entry + >370 * (X) = buf ptr in page zero + >371 +00EE36: 08 >372 FileIOZ PHP ;No interupts from here on out +00EE37: 78 >373 SEI +00EE38: B5 00 >374 LDA $00,X ;Get memory address of buffer from +00EE3A: 85 44 >375 STA bufPtr ; zero page pointed to by +00EE3C: B5 01 >376 LDA $01,X ; the X-register +00EE3E: 85 45 >377 STA bufPtr+1 ; & pass address to device handler + >378 +00EE40: AC A4 FE >379 LDY fcbPtr +00EE43: B9 01 D8 >380 LDA fcb+fcbDevNum,Y ;Of course having the device number +00EE46: 8D 30 BF >381 STA DevNum ; would make the whole operation more meaningful... +00EE49: A9 FF >382 LDA #$FF ;Also, set to +00EE4B: 8D C3 FE >383 STA ioAccess ; indicate reg call made to dev handler +00EE4E: AD 30 BF >384 LDA DevNum ;xfer the device # for dispatcher to convert to unit # +00EE51: 85 43 >385 STA unitNum +00EE53: 9C 0F BF >386 STZ SErr ;Clear global error value +00EE56: 20 DD DE >387 JSR DMgr ;Call the driver +00EE59: B0 03 =EE5E >388 BCS :1 ;Branch if error +00EE5B: 28 >389 PLP ;Restore interupts +00EE5C: 18 >390 CLC +00EE5D: 60 >391 RTS + >392 +00EE5E: 28 >393 :1 PLP ;Restore interupts +00EE5F: 38 >394 SEC +00EE60: 60 >395 RTS + >396 + >397 *------------------------------------------------- + >398 * Check point bit map & write key blk + >399 +00EE61: 20 64 EB >400 WrFCBFirst JSR UpdateBitMap ;First update the bitmap +00EE64: 80 A7 =EE0D >401 BRA WrFCBFst1 ; and go write file's first block! + >402 + >403 *------------------------------------------------- + >404 * Check point data blk buffer + >405 +00EE66: A2 4A >406 WrFCBData LDX #dataPtr +00EE68: A9 10 >407 LDA #fcbDataBlk ;Point at mem addr with X and disk addr with Y +00EE6A: 0D A4 FE >408 ORA fcbPtr ;Add offset to fcbptr +00EE6D: A8 >409 TAY ; and put it in Y-reg +00EE6E: A9 02 >410 LDA #wrtCmd ;Write data block +00EE70: 20 1C EE >411 JSR DoFileIO +00EE73: B0 21 =EE96 >412 BCS FileIOerr ;Report any errors +00EE75: A9 BF >413 LDA #$FF-dataMod ;Mark data status as current +00EE77: 80 14 =EE8D >414 BRA FCBUpdate + >415 + >416 *------------------------------------------------- + >417 * Check point index blk buffer + >418 +00EE79: 20 64 EB >419 WrFCBIdx JSR UpdateBitMap ;Go update bitmap +00EE7C: A2 48 >420 LDX #tIndex ;Point at address of index buffer +00EE7E: A9 0E >421 LDA #fcbIdxBlk ; & block address of that index block +00EE80: 0D A4 FE >422 ORA fcbPtr +00EE83: A8 >423 TAY +00EE84: A9 02 >424 LDA #wrtCmd +00EE86: 20 1C EE >425 JSR DoFileIO ;Go write out index block +00EE89: B0 0B =EE96 >426 BCS FileIOerr ;Report any errors +00EE8B: A9 7F >427 LDA #$FF-idxMod ;Mark index status as current +00EE8D: AC A4 FE >428 FCBUpdate LDY fcbPtr ;Change status byte to +00EE90: 39 08 D8 >429 AND fcb+fcbStatus,Y ; reflect successful disk file update +00EE93: 99 08 D8 >430 STA fcb+fcbStatus,Y ;(carry is unaffected) +00EE96: 60 >431 FileIOerr RTS + >432 + >433 ************************************************** + >434 * ProDOS8 OPEN Call + >435 +00EE97: 20 72 E5 >436 Open JSR FindFile ;First of all look up the file... +00EE9A: 90 04 =EEA0 >437 BCC :1 +00EE9C: C9 40 >438 CMP #badPathSyntax ;Is an attempt to open a root directory? +00EE9E: D0 07 =EEA7 >439 BNE ErrOpen ;No, pass back error +00EEA0: 20 7D EF >440 :1 JSR TestOpen ;Find out if any other files are writing +00EEA3: 90 08 =EEAD >441 BCC Open1 ; to this same file. (branch if not) +00EEA5: A9 50 >442 ErrBusy LDA #fileBusy +00EEA7: 38 >443 ErrOpen SEC +00EEA8: 60 >444 RTS + >445 +00EEA9: A9 4B >446 WrgStorTyp LDA #badStoreType ;Report file is of wrong storage type! +00EEAB: 38 >447 SEC +00EEAC: 60 >448 RTS + >449 +00EEAD: AC A4 FE >450 Open1 LDY fcbPtr ;Get address of first free FCB found +00EEB0: AD A5 FE >451 LDA fcbFlg ;This byte indicates that a free FCB found +00EEB3: D0 04 =EEB9 >452 BNE AssignFCB ; if non-zero is available for use +00EEB5: A9 42 >453 LDA #fcbFullErr ;Report FCB full error +00EEB7: 38 >454 SEC +00EEB8: 60 >455 RTS + >456 +00EEB9: A2 1F >457 AssignFCB LDX #fcbSize-1 ;Assign fcb, but first +00EEBB: A9 00 >458 LDA #$00 ; clean out any old +00EEBD: 99 00 D8 >459 ClrFCB STA fcb,Y ; rubbish left around... +00EEC0: C8 >460 INY +00EEC1: CA >461 DEX +00EEC2: 10 F9 =EEBD >462 BPL ClrFCB + >463 +00EEC4: A9 06 >464 LDA #fcbEntNum ;Now begin claim by moving in file info +00EEC6: AA >465 TAX ;Use X as source index +00EEC7: 0D A4 FE >466 ORA fcbPtr +00EECA: A8 >467 TAY ; and Y as destination (FCB) +00EECB: BD 6A FE >468 FCBOwner LDA d_dev-1,X ;Move ownership information +00EECE: 99 00 D8 >469 STA fcb,Y ;Note: this code depends upon the defined +00EED1: 88 >470 DEY ; order of both the FCB and directory entry +00EED2: CA >471 DEX +00EED3: D0 F6 =EECB >472 BNE FCBOwner ; buffer (d.). beware of changes!!! ************* + >473 +00EED5: AD 71 FE >474 LDA d_file+d_stor ;Get storage type +00EED8: 4A >475 LSR ;Strip off file name length +00EED9: 4A >476 LSR +00EEDA: 4A >477 LSR +00EEDB: 4A >478 LSR ;(by dividing by 16) +00EEDC: AA >479 TAX ;Save in X for later type comparison +00EEDD: 99 07 D8 >480 STA fcb+fcbStorTyp,Y ; and in FCB for future access + >481 +00EEE0: AD 8F FE >482 LDA d_file+d_attr ;Get files attributes & use +00EEE3: 29 03 >483 AND #readEnable+writeEnable ; it as a default access request +00EEE5: E0 0D >484 CPX #directoryFile ;If directory, don't allow write enable +00EEE7: D0 02 =EEEB >485 BNE SavAttr1 +00EEE9: 29 01 >486 AND #readEnable ;(Read-only) +00EEEB: 99 09 D8 >487 SavAttr1 STA fcb+fcbAttr,Y +00EEEE: 29 02 >488 AND #writeEnable ;Check for write enabled requested +00EEF0: F0 05 =EEF7 >489 BEQ :1 ;Branch if read only open +00EEF2: AD A9 FE >490 LDA totEnt ;Otherwise, be sure no one else is reading +00EEF5: D0 AE =EEA5 >491 BNE ErrBusy ; same file (set up by TestOpen) + >492 +00EEF7: E0 04 >493 :1 CPX #tree+1 ;Is it a tree type file? +00EEF9: 90 04 =EEFF >494 BCC :2 ;Test for further compatiblity. It must +00EEFB: E0 0D >495 CPX #directoryFile ; be either a tree or a directory +00EEFD: D0 AA =EEA9 >496 BNE WrgStorTyp ;Report file is of wrong storage type + >497 +00EEFF: A2 06 >498 :2 LDX #$06 ;Move address of first block of file, +00EF01: 85 47 >499 :loop1 STA blockNum+1 ; end of file, and current usage count +00EF03: AD A4 FE >500 LDA fcbPtr +00EF06: 1D 2E FE >501 ORA oFCBTbl,X ;This is done via a translation +00EF09: A8 >502 TAY ; table between directory info and FCB +00EF0A: BD 82 FE >503 LDA d_file+d_first,X +00EF0D: 99 00 D8 >504 STA fcb,Y +00EF10: CA >505 DEX ;Has all info been moved? +00EF11: 10 EE =EF01 >506 BPL :loop1 + >507 +00EF13: 85 46 >508 STA blockNum ;Last loop stored hi addr of first block +00EF15: AC A4 FE >509 LDY fcbPtr +00EF18: AD AC FE >510 LDA cntEnt ;This was set up by 'TestOpen'... +00EF1B: 99 00 D8 >511 STA fcb+fcbRefNum,Y ;Claim fcb for this file +00EF1E: 20 D3 FB >512 JSR AllocBuf ;Go allocate buffer in memtables +00EF21: B0 24 =EF47 >513 BCS ErrOpen2 ;Give up if any errors occurred + >514 +00EF23: 20 D7 E1 >515 JSR FndFCBuf ;Returns addrs of bufs in data & index pointers +00EF26: AD 94 BF >516 LDA Level ;Mark level at which +00EF29: 99 1B D8 >517 STA fcb+fcbLevel,Y ; file was opened +00EF2C: B9 07 D8 >518 LDA fcb+fcbStorTyp,Y ;File must be positioned to beginning +00EF2F: C9 04 >519 CMP #tree+1 ;Is it a tree file? +00EF31: B0 2B =EF5E >520 BCS OpenDir ;No, assume it's a directory +00EF33: A9 FF >521 LDA #$FF ;Fool the position routine into giving a +00EF35: 99 14 D8 >522 STA fcb+fcbMark+2,Y ; valid position with preloaded data, etc +00EF38: A0 02 >523 LDY #$02 ;Set desired position to zero +00EF3A: A9 00 >524 LDA #$00 +00EF3C: 99 BC FE >525 :loop2 STA tPosll,Y +00EF3F: 88 >526 DEY +00EF40: 10 FA =EF3C >527 BPL :loop2 + >528 +00EF42: 20 1E EC >529 JSR RdPosn ;Let tree position routine do the rest +00EF45: 90 1C =EF63 >530 BCC OpenDone ;Branch if successful + >531 +00EF47: 48 >532 ErrOpen2 PHA ;Save error code +00EF48: AC A4 FE >533 LDY fcbPtr ;Return buffer to free space +00EF4B: B9 0B D8 >534 LDA fcb+fcbFileBuf,Y +00EF4E: F0 06 =EF56 >535 BEQ :1 ;Branch if no buf # + >536 +00EF50: 20 30 FC >537 JSR ReleaseBuf ;Doesn't matter if it was never allocated +00EF53: AC A4 FE >538 LDY fcbPtr ; since error was encountered before file +00EF56: A9 00 >539 :1 LDA #$00 ; was successfully opened, then +00EF58: 99 00 D8 >540 STA fcb+fcbRefNum,Y ; it's necessary to release FCB +00EF5B: 68 >541 PLA +00EF5C: 38 >542 SEC +00EF5D: 60 >543 RTS + >544 +00EF5E: 20 DA ED >545 OpenDir JSR RdFCBData ;Read in first block of directory file +00EF61: B0 E4 =EF47 >546 BCS ErrOpen2 ;Return any error after freeing buffer & FCB +00EF63: AE A3 FE >547 OpenDone LDX vcbPtr ;Index to volume control block +00EF66: FE 1E D9 >548 INC vcb+vcbOpenCnt,X ;Add 1 to the number of files currently open +00EF69: BD 11 D9 >549 LDA vcb+vcbStatus,X ; & indicate that this volume has +00EF6C: 09 80 >550 ORA #$80 ; at least 1 file active +00EF6E: 9D 11 D9 >551 STA vcb+vcbStatus,X + >552 +00EF71: AC A4 FE >553 LDY fcbPtr ;Index to file control block +00EF74: B9 00 D8 >554 LDA fcb+fcbRefNum,Y ;Return reference number to user +00EF77: A0 05 >555 LDY #c_outRef +00EF79: 91 40 >556 STA (parm),Y +00EF7B: 18 >557 CLC ;Indicate successful open! +00EF7C: 60 >558 RTS ;All done... + >559 + >560 *------------------------------------------------- + >561 * Test if file can be opened + >562 * C=1 + >563 * Already opened with write access + >564 * NB. Multiple write access is not allowed + >565 * C=0 + >566 * File may be opened/already opened + >567 * If fcbFlag <> 0, got a free FCB & + >568 * (fcbPtr) = index into FCB table + >569 * NB. Multiple read access is allowed + >570 +00EF7D: A9 00 >571 TestOpen LDA #$00 +00EF7F: 8D AC FE >572 STA cntEnt ;This temp returns the refnum of a free FCB +00EF82: 8D A9 FE >573 STA totEnt ;This is used as a flag to indicate file is already open +00EF85: 8D A5 FE >574 STA fcbFlg ;This is a flag to indicate a free FCB is available + >575 +00EF88: A8 >576 TestOpen1 TAY ;Index to next FCB +00EF89: AE A5 FE >577 LDX fcbFlg ;Test for free FCB found +00EF8C: D0 03 =EF91 >578 BNE :1 ;Branch if already found +00EF8E: EE AC FE >579 INC cntEnt +00EF91: B9 00 D8 >580 :1 LDA fcb+fcbRefNum,Y ;Is this FCB in use? +00EF94: D0 0D =EFA3 >581 BNE ChkActive ;Branch if it is +00EF96: 8A >582 TXA ;If not, should we claim it? +00EF97: D0 28 =EFC1 >583 BNE TestNxtFCB ;Branch if free FCB already found +00EF99: 8C A4 FE >584 STY fcbPtr ;Save index to free FCB +00EF9C: A9 FF >585 LDA #-1 ;Set fcb flag to indicate free FCB found +00EF9E: 8D A5 FE >586 STA fcbFlg +00EFA1: D0 1E =EFC1 >587 BNE TestNxtFCB ;Branch always to test next FCB + >588 +00EFA3: 98 >589 ChkActive TYA ;Add offset to index to ownership info +00EFA4: 09 06 >590 ORA #fcbEntNum +00EFA6: A8 >591 TAY ;Put it back in Y-reg +00EFA7: A2 06 >592 LDX #fcbEntNum ;Index to directory entry owner info +00EFA9: B9 00 D8 >593 WhoOwns LDA fcb,Y +00EFAC: DD 6A FE >594 CMP d_dev-1,X ;All bytes must match to say that its +00EFAF: D0 10 =EFC1 >595 BNE TestNxtFCB ; the same file again +00EFB1: 88 >596 DEY ;Index to next lower bytes +00EFB2: CA >597 DEX +00EFB3: D0 F4 =EFA9 >598 BNE WhoOwns ;Loop to check all owner info + >599 +00EFB5: EE A9 FE >600 INC totEnt ;File is already open, +00EFB8: B9 09 D8 >601 LDA fcb+fcbAttr,Y ;Now see if it's already opened for write +00EFBB: 29 02 >602 AND #writeEnable +00EFBD: F0 02 =EFC1 >603 BEQ TestNxtFCB ;Branch if this file is read access only +00EFBF: 38 >604 SEC ;Multiple write access not allowed +00EFC0: 60 >605 RTS + >606 +00EFC1: 98 >607 TestNxtFCB TYA ;Calc position of next FCB +00EFC2: 29 E0 >608 AND #%11100000 ;First strip any possible index offsets +00EFC4: 18 >609 CLC +00EFC5: 69 20 >610 ADC #fcbSize ;Bump to next FCB +00EFC7: D0 BF =EF88 >611 BNE TestOpen1 ;Branch if more to compare +00EFC9: 18 >612 CLC ;Report no conflicts +00EFCA: 60 >613 RTS + 35 PUT mli.src/ReadWrite + >1 ************************************************** + >2 * READ Call + >3 +00EFCB: 20 D6 F1 >4 Read JSR MovDBuf ;First transfer buffer adr & request count to a +00EFCE: 20 BB F1 >5 JSR MovCBytes ; more accessible location, also get fcbAttr, CLC +00EFD1: 48 >6 PHA ;Save attributes for now +00EFD2: 20 E8 F1 >7 JSR CalcMark ;Calc mark after read, test mark>eof +00EFD5: 68 >8 PLA ;Carry Set indicates end mark>eof +00EFD6: 29 01 >9 AND #readEnable ;Test for read enabled first +00EFD8: D0 04 =EFDE >10 BNE :1 ;Branch if ok to read +00EFDA: A9 4E >11 LDA #invalidAccess ;Report illegal access +00EFDC: D0 24 =F002 >12 BNE GoFix1 ;Branch always taken + >13 +00EFDE: 90 25 =F005 >14 :1 BCC Read2 ;Branch if result mark15 ; Adjust request to read up to (but not including) end of file. +00EFE0: AC A4 FE >16 LDY fcbPtr +00EFE3: B9 15 D8 >17 LDA fcb+fcbEOF,Y ;Result= (eof-1)-position +00EFE6: ED BC FE >18 SBC tPosll +00EFE9: 8D E9 FE >19 STA cBytes +00EFEC: 8D BF FE >20 STA rwReqL +00EFEF: B9 16 D8 >21 LDA fcb+fcbEOF+1,Y +00EFF2: ED BD FE >22 SBC tPoslh +00EFF5: 8D EA FE >23 STA cBytes+1 +00EFF8: 8D C0 FE >24 STA rwReqH +00EFFB: 0D E9 FE >25 ORA cBytes ;If both bytes are zero, report EOF error +00EFFE: D0 10 =F010 >26 BNE NotEOF +00F000: A9 4C >27 LDA #eofEncountered +00F002: 4C BC F0 >28 GoFix1 JMP ErrFixZ + >29 +00F005: AD E9 FE >30 Read2 LDA cBytes +00F008: 0D EA FE >31 ORA cBytes+1 +00F00B: D0 03 =F010 >32 BNE NotEOF ;Branch if read request definitely non-zero +00F00D: 4C C3 F0 >33 GoRdDone JMP RWDone ;Do nothing + >34 +00F010: 20 65 FC >35 NotEOF JSR ValDBuf ;Validate user's data buffer range +00F013: B0 ED =F002 >36 BCS GoFix1 ;Branch if memory conflict +00F015: 20 E1 F1 >37 JSR GfcbStorTyp ;Get storage type +00F018: C9 04 >38 CMP #tree+1 ;Now find if it's a tree or other +00F01A: 90 03 =F01F >39 BCC TreeRead ;Branch if a tree file +00F01C: 4C 84 F1 >40 JMP DirRead ;Othewise assume it's a directory + >41 +00F01F: 20 1E EC >42 TreeRead JSR RdPosn ;Get data pointer set up +00F022: B0 DE =F002 >43 BCS GoFix1 ;Report any errors +00F024: 20 DA F0 >44 JSR PrepRW ;Test for newline, sets up for partial read +00F027: 20 04 F1 >45 JSR ReadPart ;Move current data buffer contents to user area +00F02A: 70 E1 =F00D >46 BVS GoRdDone ;Branch if request is satisfied +00F02C: B0 F1 =F01F >47 BCS TreeRead ;Carry set indicates newline is set + >48 +00F02E: AD C0 FE >49 LDA rwReqH ;Find out how many blocks are to be read +00F031: 4A >50 LSR ;If less than two, +00F032: F0 EB =F01F >51 BEQ TreeRead ; then do it the slow way + >52 +00F034: 8D C4 FE >53 STA bulkCnt ;Save bulk block count +00F037: 20 C3 F5 >54 JSR GetFCBStat ;Make sure current data area doesn't need writing before +00F03A: 29 40 >55 AND #dataMod ; resetting pointer to read directly into user's area. +00F03C: D0 E1 =F01F >56 BNE TreeRead ;Branch if data need to be written + >57 + >58 * Setup for fast Direct Read rtn + >59 +00F03E: 8D C3 FE >60 STA ioAccess ; to force first call thru all device handler checking +00F041: A5 4E >61 LDA userBuf ;Make the data buffer the user's space +00F043: 85 4A >62 STA dataPtr +00F045: A5 4F >63 LDA userBuf+1 +00F047: 85 4B >64 STA dataPtr+1 + >65 +00F049: 20 1E EC >66 RdFast JSR RdPosn ;Get next block directly into user space +00F04C: B0 69 =F0B7 >67 BCS ErrFix ;Branch on any error +00F04E: E6 4B >68 RdFastLoop INC dataPtr+1 +00F050: E6 4B >69 INC dataPtr+1 ;Bump all pointers by 512 (one block) +00F052: CE C0 FE >70 DEC rwReqH +00F055: CE C0 FE >71 DEC rwReqH +00F058: EE BD FE >72 INC tPoslh +00F05B: EE BD FE >73 INC tPoslh +00F05E: D0 09 =F069 >74 BNE :11 ;Branch if position does not get to a 64K boundary +00F060: EE BE FE >75 INC tPosHi ;Otherwise, must check for a 128K boundary +00F063: AD BE FE >76 LDA tPosHi ;If mod 128K has been +00F066: 49 01 >77 EOR #$01 +00F068: 4A >78 LSR ; reached, set Carry +00F069: CE C4 FE >79 :11 DEC bulkCnt ;Have we read all we can fast? +00F06C: D0 0D =F07B >80 BNE :12 ;Branch if more to read + >81 +00F06E: 20 76 F1 >82 JSR FixDataPtr ;Go fix up data pointer to xdos buffer +00F071: AD BF FE >83 LDA rwReqL ;Test for end of read +00F074: 0D C0 FE >84 ORA rwReqH ;Are both zero? +00F077: F0 4A =F0C3 >85 BEQ RWDone +00F079: D0 A4 =F01F >86 BNE TreeRead ;No + >87 +00F07B: B0 CC =F049 >88 :12 BCS RdFast +00F07D: AD BE FE >89 LDA tPosHi ;Get index to next block address +00F080: 4A >90 LSR +00F081: AD BD FE >91 LDA tPoslh +00F084: 6A >92 ROR +00F085: A8 >93 TAY ;Index to address is int(pos/512) +00F086: B1 48 >94 LDA (tIndex),Y ;Get low address +00F088: 85 46 >95 STA blockNum +00F08A: E6 49 >96 INC tIndex+1 +00F08C: D1 48 >97 CMP (tIndex),Y ;Are both hi and low addresses the same? +00F08E: D0 09 =F099 >98 BNE RealRd ;No, it's a real block address +00F090: C9 00 >99 CMP #$00 ;Are both bytes zero? +00F092: D0 05 =F099 >100 BNE RealRd ;Nope -- must be real data +00F094: 8D C3 FE >101 STA ioAccess ;Don't do repeatio just after sparse +00F097: F0 03 =F09C >102 BEQ NoStuff ;Branch always (carry set) + >103 +00F099: B1 48 >104 RealRd LDA (tIndex),Y ;Get high address byte +00F09B: 18 >105 CLC +00F09C: C6 49 >106 NoStuff DEC tIndex+1 +00F09E: B0 A9 =F049 >107 BCS RdFast ;Branch if no block to read +00F0A0: 85 47 >108 STA blockNum+1 +00F0A2: AD C3 FE >109 LDA ioAccess ;Has first call gone to device yet? +00F0A5: F0 A2 =F049 >110 BEQ RdFast ;Nope, go thru normal route... +00F0A7: 18 >111 CLC +00F0A8: 08 >112 PHP ;Interupts cannot occur while calling dmgr +00F0A9: 78 >113 SEI +00F0AA: A5 4B >114 LDA dataPtr+1 ;Reset hi buffer address for device handler +00F0AC: 85 45 >115 STA bufPtr+1 +00F0AE: 20 DD DE >116 JSR DMgr +00F0B1: B0 03 =F0B6 >117 BCS :31 ;Branch if error +00F0B3: 28 >118 PLP +00F0B4: 90 98 =F04E >119 BCC RdFastLoop ;No errors, branch always + >120 +00F0B6: 28 >121 :31 PLP ;Restore interupts +00F0B7: 48 >122 ErrFix PHA ;Save error code +00F0B8: 20 76 F1 >123 JSR FixDataPtr ;Go restore data pointers, etc... +00F0BB: 68 >124 PLA +00F0BC: 48 >125 ErrFixZ PHA ;Save error code +00F0BD: 20 C3 F0 >126 JSR RWDone ;Pass back number of bytes actually read +00F0C0: 68 >127 PLA +00F0C1: 38 >128 SEC ;Report error +00F0C2: 60 >129 RTS + >130 + >131 *------------------------------------------------- + >132 * I/O finish up + >133 +00F0C3: A0 06 >134 RWDone LDY #c_xferCnt ;Return total # of bytes actually read +00F0C5: 38 >135 SEC ;This is derived from cbytes-rwreq +00F0C6: AD E9 FE >136 LDA cBytes +00F0C9: ED BF FE >137 SBC rwReqL +00F0CC: 91 40 >138 STA (parm),Y +00F0CE: C8 >139 INY +00F0CF: AD EA FE >140 LDA cBytes+1 +00F0D2: ED C0 FE >141 SBC rwReqH +00F0D5: 91 40 >142 STA (parm),Y +00F0D7: 4C 1E EC >143 JMP RdPosn ;Leave with valid position in FCB + >144 + >145 *------------------------------------------------- + >146 * Set up buffer indexing + >147 * Exit + >148 * C=1 newline enabled + >149 * (Y) = index to first data byte to be xferred + >150 * (X) = LOB of request count + >151 +00F0DA: AC A4 FE >152 PrepRW LDY fcbPtr ;Adjust pointer to user's buffer +00F0DD: 38 >153 SEC ; to make the transfer +00F0DE: A5 4E >154 LDA userBuf +00F0E0: ED BC FE >155 SBC tPosll +00F0E3: 85 4E >156 STA userBuf +00F0E5: B0 02 =F0E9 >157 BCS :1 ;Branch if no adjustment to hi addr needed +00F0E7: C6 4F >158 DEC userBuf+1 +00F0E9: B9 1F D8 >159 :1 LDA fcb+fcbNLMask,Y ;Test for new line enabled +00F0EC: 18 >160 CLC +00F0ED: F0 0A =F0F9 >161 BEQ NoNewLine ;Branch if newline is not enabled + >162 +00F0EF: 38 >163 SEC ;Carry set indicates newline enabled +00F0F0: 8D C2 FE >164 STA nlMask +00F0F3: B9 0A D8 >165 LDA fcb+fcbNewLin,Y ;Move newline character +00F0F6: 8D C1 FE >166 STA nlChar ; to more accessible spot + >167 +00F0F9: AC BC FE >168 NoNewLine LDY tPosll ;Get index to first data byte +00F0FC: A5 4A >169 LDA dataPtr ;Reset low order of posPtr to beginning of page +00F0FE: 85 4C >170 STA posPtr +00F100: AE BF FE >171 LDX rwReqL ; & lastly get low order count of requested bytes +00F103: 60 >172 RTS ;Return statuses... + >173 + >174 *------------------------------------------------- + >175 * Copy from I/O blk buffer to data buffer + >176 * Exit if : 1. len goes to zero + >177 * 2. next block is needed + >178 * 3. newLine char is found + >179 * Exit + >180 * V = 1 - done + >181 * V = 0 - next blk needed + >182 +00F104: 8A >183 ReadPart TXA ;(X)=low count of bytes to move +00F105: D0 08 =F10F >184 BNE :1 ;Branch if request is not an even page +00F107: AD C0 FE >185 LDA rwReqH ;A call of zero bytes should never get here! +00F10A: F0 51 =F15D >186 BEQ SetRdDone ;Branch if nothin' to do +00F10C: CE C0 FE >187 DEC rwReqH +00F10F: CA >188 :1 DEX + >189 + >190 * NB. In order for the same Y-reg to be used below, + >191 * the ptr to user's buffer had been adjusted (see + >192 * code in PrepRW rtn) + >193 +00F110: B1 4C >194 RdPart LDA (posPtr),Y ;Move data to user's buffer +00F112: 91 4E >195 STA (userBuf),Y ; one byte at a time +00F114: B0 30 =F146 >196 BCS TestNewLine ;Let's test for newline first! +00F116: 8A >197 RdPart2 TXA ;Note: (X) must be unchanged from TestNewLine! +00F117: F0 19 =F132 >198 BEQ EndReqChk ;See if read request is satisfied... +00F119: CA >199 RdPart1 DEX ;Decr # of bytes left to move +00F11A: C8 >200 INY ;Page crossed? +00F11B: D0 F3 =F110 >201 BNE RdPart ;No, move next byte +00F11D: A5 4D >202 LDA posPtr+1 ;Test for end of buffer +00F11F: E6 4F >203 INC userBuf+1 ; but first adjust user buffer +00F121: EE BD FE >204 INC tPoslh ; pointer and position +00F124: D0 03 =F129 >205 BNE :11 +00F126: EE BE FE >206 INC tPosHi +00F129: E6 4D >207 :11 INC posPtr+1 ;& sos buffer high address +00F12B: 45 4B >208 EOR dataPtr+1 ;(Carry has been cleverly undisturbed.) +00F12D: F0 E1 =F110 >209 BEQ RdPart ;Branch if more to read in buffer +00F12F: B8 >210 CLV ;Indicate not finished +00F130: 50 2E =F160 >211 BVC RdPartDone ;Branch always + >212 +00F132: AD C0 FE >213 EndReqChk LDA rwReqH ;NB. (X)=0 +00F135: F0 19 =F150 >214 BEQ RdReqDone ;Branch if request satisfied +00F137: C8 >215 INY ;Done with this block of data? +00F138: D0 06 =F140 >216 BNE :31 ;No, adjust high byte of request + >217 +00F13A: A5 4D >218 LDA posPtr+1 ;Maybe-check for end of block buffer +00F13C: 45 4B >219 EOR dataPtr+1 ;(don't disturb carry) +00F13E: D0 03 =F143 >220 BNE :32 ;Branch if hi count can be dealt with next time +00F140: CE C0 FE >221 :31 DEC rwReqH ;Decr count by 1 page +00F143: 88 >222 :32 DEY ;Restore proper value to Y-reg +00F144: 80 D3 =F119 >223 BRA RdPart1 + >224 +00F146: B1 4C >225 TestNewLine LDA (posPtr),Y ;Get last byte transfered again +00F148: 2D C2 FE >226 AND nlMask ;Only bits on in mask are significant +00F14B: 4D C1 FE >227 EOR nlChar ;Have we matched newline character? +00F14E: D0 C6 =F116 >228 BNE RdPart2 ;No, read next + >229 +00F150: C8 >230 RdReqDone INY ;Adjust position +00F151: D0 0A =F15D >231 BNE SetRdDone +00F153: E6 4F >232 INC userBuf+1 ;Bump pointers +00F155: EE BD FE >233 INC tPoslh +00F158: D0 03 =F15D >234 BNE SetRdDone +00F15A: EE BE FE >235 INC tPosHi +00F15D: 2C 75 F1 >236 SetRdDone BIT SetVFlag ;(set V flag) + >237 +00F160: 8C BC FE >238 RdPartDone STY tPosll ;Save low position +00F163: 70 01 =F166 >239 BVS :41 +00F165: E8 >240 INX ;Leave request as +1 for next call +00F166: 8E BF FE >241 :41 STX rwReqL ; & remainder of request count. +00F169: 08 >242 PHP ;Save statuses +00F16A: 18 >243 CLC ;Adjust user's low buffer address +00F16B: 98 >244 TYA +00F16C: 65 4E >245 ADC userBuf +00F16E: 85 4E >246 STA userBuf +00F170: 90 02 =F174 >247 BCC :42 +00F172: E6 4F >248 INC userBuf+1 ;Adjust hi address as needed +00F174: 28 >249 :42 PLP ;Restore return statuses +00F175: 60 >250 SetVFlag RTS ;(this byte <$60> is used to set V flag) + >251 + >252 *------------------------------------------------- + >253 * Cleanup after direct I/O + >254 +00F176: A5 4A >255 FixDataPtr LDA dataPtr ;Put current user buffer +00F178: 85 4E >256 STA userBuf ; address back to normal +00F17A: A5 4B >257 LDA dataPtr+1 +00F17C: 85 4F >258 STA userBuf+1 ;Bank pair byte should be moved also +00F17E: AC A4 FE >259 LDY fcbPtr ;Restore buffer address +00F181: 4C D7 E1 >260 JMP FndFCBuf + >261 + >262 *------------------------------------------------- + >263 * Read directory file... + >264 +00F184: 20 1E EC >265 DirRead JSR RdPosn +00F187: B0 2F =F1B8 >266 BCS ErrDirRd ;Pass back any errors +00F189: 20 DA F0 >267 JSR PrepRW ;Prepare for transfer +00F18C: 20 04 F1 >268 JSR ReadPart ;Move data to user's buffer +00F18F: 50 F3 =F184 >269 BVC DirRead ;Repeat until request is satisfied +00F191: 20 C3 F0 >270 JSR RWDone ;Update FCB as to new position +00F194: 90 20 =F1B6 >271 BCC :1 ;Branch if all is well +00F196: C9 4C >272 CMP #eofEncountered ;Was last read to end of file? +00F198: 38 >273 SEC ;Anticipate some other problem +00F199: D0 1C =F1B7 >274 BNE :Ret ;Branch if not EOF error + >275 +00F19B: 20 61 ED >276 JSR SavMark +00F19E: 20 3F ED >277 JSR ZipData ;Clear out data block +00F1A1: A0 00 >278 LDY #$00 ;Provide dummy back pointer for future re-position +00F1A3: AE A4 FE >279 LDX fcbPtr ;Get hi byte of last block +00F1A6: BD 10 D8 >280 :loop LDA fcb+fcbDataBlk,X +00F1A9: 91 4A >281 STA (dataPtr),Y +00F1AB: A9 00 >282 LDA #$00 ;Mark current block as imposible +00F1AD: 9D 10 D8 >283 STA fcb+fcbDataBlk,X +00F1B0: E8 >284 INX +00F1B1: C8 >285 INY ;Bump indexes to do both hi & low bytes +00F1B2: C0 02 >286 CPY #$02 +00F1B4: D0 F0 =F1A6 >287 BNE :loop +00F1B6: 18 >288 :1 CLC ;Indicate no error +00F1B7: 60 >289 :Ret RTS + >290 +00F1B8: 4C BC F0 >291 ErrDirRd JMP ErrFixZ + >292 + >293 *------------------------------------------------- + >294 * Copy caller's I/O len + >295 * Exit + >296 * (A)=attributes + >297 * (Y)=(fcbptr) + >298 +00F1BB: A0 04 >299 MovCBytes LDY #c_reqCnt ;Move request count +00F1BD: B1 40 >300 LDA (parm),Y ; to a more accessible location +00F1BF: 8D E9 FE >301 STA cBytes +00F1C2: 8D BF FE >302 STA rwReqL +00F1C5: C8 >303 INY +00F1C6: B1 40 >304 LDA (parm),Y +00F1C8: 8D EA FE >305 STA cBytes+1 +00F1CB: 8D C0 FE >306 STA rwReqH +00F1CE: AC A4 FE >307 LDY fcbPtr ;Also return (Y)=val(fcbptr) +00F1D1: B9 09 D8 >308 LDA fcb+fcbAttr,Y ; & (A)=attributes +00F1D4: 18 >309 CLC ; & carry clear... +00F1D5: 60 >310 RTS + >311 + >312 *------------------------------------------------- + >313 * Point userBuf ($4E,$4F) to caller's data buffer + >314 * Exit + >315 * (A) = file's storage type + >316 +00F1D6: A0 02 >317 MovDBuf LDY #c_dataBuf ;Move pointer to user's buffer to bfm +00F1D8: B1 40 >318 LDA (parm),Y +00F1DA: 85 4E >319 STA userBuf +00F1DC: C8 >320 INY +00F1DD: B1 40 >321 LDA (parm),Y +00F1DF: 85 4F >322 STA userBuf+1 + >323 +00F1E1: AC A4 FE >324 GfcbStorTyp LDY fcbPtr ;Also return storage type +00F1E4: B9 07 D8 >325 LDA fcb+fcbStorTyp,Y ;(on fall thru) +00F1E7: 60 >326 RTS + >327 + >328 *------------------------------------------------- + >329 * Copy file mark, compute and compare end mark + >330 +00F1E8: A2 00 >331 CalcMark LDX #$00 ;This subroutine adds the requested byte +00F1EA: AC A4 FE >332 LDY fcbPtr +00F1ED: 18 >333 CLC +00F1EE: B9 12 D8 >334 :loop LDA fcb+fcbMark,Y ;Count to mark, and returns sum +00F1F1: 9D BC FE >335 STA tPosll,X ; in scrtch and also returns mark in tPos +00F1F4: 9D 9F FE >336 STA oldMark,X ; and oldMark +00F1F7: 7D E9 FE >337 ADC cBytes,X +00F1FA: 9D 98 FE >338 STA scrtch,X ;On exit: Y, X, A=unknown +00F1FD: 8A >339 TXA ;Carry set indicates scrtch>eof +00F1FE: 49 02 >340 EOR #$02 ;(cBytes+2 always = 0) +00F200: F0 04 =F206 >341 BEQ EOFtest +00F202: C8 >342 INY +00F203: E8 >343 INX +00F204: D0 E8 =F1EE >344 BNE :loop ;Branch always + >345 +00F206: BD 98 FE >346 EOFtest LDA scrtch,X ;New mark in scrtch! +00F209: D9 15 D8 >347 CMP fcb+fcbEOF,Y ;Is new position > eof? +00F20C: 90 06 =F214 >348 BCC :Ret ;No, proceed +00F20E: D0 04 =F214 >349 BNE :Ret ;Yes, adjust 'cBytes' request +00F210: 88 >350 DEY +00F211: CA >351 DEX ;Have we compared all three bytes? +00F212: 10 F2 =F206 >352 BPL EOFtest +00F214: 60 >353 :Ret RTS + >354 + >355 *------------------------------------------------- + >356 * Set new mark & eof + >357 +00F215: 20 47 F2 >358 WrErrEOF JSR Plus2FCB ;Reset EOF to pre-error position +00F218: BD 9C FE >359 :loop LDA oldEOF,X ;Place oldEOF back into fcb +00F21B: 99 15 D8 >360 STA fcb+fcbEOF,Y +00F21E: BD 9F FE >361 LDA oldMark,X ;Also reset mark to last best write position +00F221: 99 12 D8 >362 STA fcb+fcbMark,Y +00F224: 9D 98 FE >363 STA scrtch,X ; & copy mark to scrtch for +00F227: 88 >364 DEY ; test of EOF less than mark +00F228: CA >365 DEX +00F229: 10 ED =F218 >366 BPL :loop +00F22B: 20 47 F2 >367 JSR Plus2FCB ;Get pointers to test EOF368 JSR EOFtest ;Carry set means mark>EOF!! + >369 + >370 * Drop into WrAdjEOF to adjust EOF to mark if necessary. + >371 +00F231: 20 47 F2 >372 WrAdjEOF JSR Plus2FCB ;Get (Y)=fcbPtr+2, (X)=2,(A)=(Y) +00F234: B9 15 D8 >373 :loop1 LDA fcb+fcbEOF,Y ;Copy EOF to oldEOF +00F237: 9D 9C FE >374 STA oldEOF,X +00F23A: 90 06 =F242 >375 BCC :1 ; & if carry set... +00F23C: BD 98 FE >376 LDA scrtch,X ; copy scrtch to fcb's EOF +00F23F: 99 15 D8 >377 STA fcb+fcbEOF,Y +00F242: 88 >378 :1 DEY +00F243: CA >379 DEX ;Copy all three bytes +00F244: 10 EE =F234 >380 BPL :loop1 +00F246: 60 >381 RTS + >382 + >383 *------------------------------------------------- + >384 * Set 3-byte indices + >385 * Exit + >386 * (A)=(Y)=(fcbPtr)+2 + >387 * (X)=2 + >388 +00F247: A9 02 >389 Plus2FCB LDA #$02 +00F249: AA >390 TAX +00F24A: 0D A4 FE >391 ORA fcbPtr +00F24D: A8 >392 TAY +00F24E: 60 >393 RTS + >394 + >395 ************************************************** + >396 * WRITE Call + >397 + =F24F >398 Write EQU * ;First determine if requested +00F24F: 20 BB F1 >399 JSR MovCBytes ; write is legal +00F252: 48 >400 PHA ;Save attributes temporarily +00F253: 20 E8 F1 >401 JSR CalcMark ;Save a copy of EOF to oldEOF, set/clr Carry +00F256: 20 31 F2 >402 JSR WrAdjEOF ; to determine if new mark > EOF +00F259: 68 >403 PLA ;Get attributes again +00F25A: 29 02 >404 AND #writeEnable +00F25C: D0 04 =F262 >405 BNE Write1 ;It's write enabled + >406 +00F25E: A9 4E >407 ErrAccess LDA #invalidAccess ;Report illegal access +00F260: D0 40 =F2A2 >408 BNE WrtError ;Always + >409 +00F262: 20 17 F4 >410 Write1 JSR TestWrProt ;Otherwise, ensure device is not write protected +00F265: B0 3B =F2A2 >411 BCS WrtError ;Report write potected and abort operation +00F267: AD E9 FE >412 LDA cBytes +00F26A: 0D EA FE >413 ORA cBytes+1 ;Anything to write? +00F26D: D0 03 =F272 >414 BNE :1 ;branch if write request definitely non-zero +00F26F: 4C C3 F0 >415 JMP RWDone ;Do nothing + >416 +00F272: 20 D6 F1 >417 :1 JSR MovDBuf ;Move pointer to user's buffer to bfm +00F275: C9 04 >418 CMP #tree+1 ; zpage area, also get storage type +00F277: B0 E5 =F25E >419 BCS ErrAccess ;If not tree, return an access error! + >420 +00F279: 20 1E EC >421 TreeWrite JSR RdPosn ;Read block we're in +00F27C: B0 24 =F2A2 >422 BCS WrtError +00F27E: 20 C3 F5 >423 JSR GetFCBStat ;Get file's status +00F281: 29 07 >424 AND #dataAloc+idxAloc+topAloc ;Need to allocate? +00F283: F0 64 =F2E9 >425 BEQ TreeWrt1 ;No + >426 +00F285: A0 00 >427 LDY #$00 ;Find out if enough disk space is available +00F287: C8 >428 :loop INY ; for indexes and data block +00F288: 4A >429 LSR ;Count # of blks needed +00F289: D0 FC =F287 >430 BNE :loop + >431 +00F28B: 8C A6 FE >432 STY reqL ;Store # of blks needed +00F28E: 8D A7 FE >433 STA reqH ;(A)=0 +00F291: 20 53 E9 >434 JSR TestFreeBlk +00F294: B0 0C =F2A2 >435 BCS WrtError ;Pass back any errors + >436 +00F296: 20 C3 F5 >437 JSR GetFCBStat ;Now get more specific +00F299: 29 04 >438 AND #topAloc ;Are we lacking a tree top? +00F29B: F0 0F =F2AC >439 BEQ TestSapWr ;No, test for lack of sapling level index +00F29D: 20 69 F3 >440 JSR MakeTree ;Go allocate tree top and adjust file type +00F2A0: 90 16 =F2B8 >441 BCC AllocDataBlk ;Continue with allocation of data block + >442 +00F2A2: 48 >443 WrtError PHA ;Save error +00F2A3: 20 BC F0 >444 JSR ErrFixZ +00F2A6: 20 15 F2 >445 JSR WrErrEOF ;Adjust EOF and mark to pre-error state +00F2A9: 68 >446 PLA ;Restore error code +00F2AA: 38 >447 SEC ;Flag error +00F2AB: 60 >448 RTS + >449 +00F2AC: 20 C3 F5 >450 TestSapWr JSR GetFCBStat ;Get status byte again +00F2AF: 29 02 >451 AND #idxAloc ;Do we need a sapling level index block? +00F2B1: F0 05 =F2B8 >452 BEQ AllocDataBlk ;No, assume it's just a data block needed + >453 +00F2B3: 20 A5 F3 >454 JSR AddNewIdxBlk ;Go allocate an index block and update tree top +00F2B6: B0 EA =F2A2 >455 BCS WrtError ;Return any errors + >456 +00F2B8: 20 F7 F3 >457 AllocDataBlk JSR AllocWrBlk ;Go allocate for data block +00F2BB: B0 E5 =F2A2 >458 BCS WrtError + >459 +00F2BD: 20 C3 F5 >460 JSR GetFCBStat ;Clear allocation required bits in status +00F2C0: 09 80 >461 ORA #idxMod ; but first tell 'em index block is dirty +00F2C2: 29 F8 >462 AND #$FF-dataAloc-idxAloc-topAloc ;Flag these have been allocated +00F2C4: 99 08 D8 >463 STA fcb+fcbStatus,Y +00F2C7: AD BE FE >464 LDA tPosHi ;Calculate position within index block +00F2CA: 4A >465 LSR +00F2CB: AD BD FE >466 LDA tPoslh +00F2CE: 6A >467 ROR +00F2CF: A8 >468 TAY ;Now put block address into index block +00F2D0: E6 49 >469 INC tIndex+1 ;High byte first +00F2D2: AD 99 FE >470 LDA scrtch+1 +00F2D5: AA >471 TAX +00F2D6: 91 48 >472 STA (tIndex),Y +00F2D8: C6 49 >473 DEC tIndex+1 ;(Restore pointer to lower page of index block) +00F2DA: AD 98 FE >474 LDA scrtch ;Get low block address +00F2DD: 91 48 >475 STA (tIndex),Y ;Now store low address + >476 +00F2DF: AC A4 FE >477 LDY fcbPtr ;Also update file control block to indicate +00F2E2: 99 10 D8 >478 STA fcb+fcbDataBlk,Y ; that this block is allocated +00F2E5: 8A >479 TXA ;Get high address again +00F2E6: 99 11 D8 >480 STA fcb+fcbDataBlk+1,Y + >481 +00F2E9: 20 DA F0 >482 TreeWrt1 JSR PrepRW ;Write on +00F2EC: 20 F4 F2 >483 JSR WrtPart +00F2EF: 50 88 =F279 >484 BVC TreeWrite +00F2F1: 4C C3 F0 >485 JMP RWDone ;Update FCB with new position + >486 + >487 *------------------------------------------------- + >488 * Copy write data to I/O blk + >489 * Logic is similar to ReadPart rtn + >490 * Exit + >491 * V = 1 - done + >492 * V = 0 - More to write + >493 +00F2F4: 8A >494 WrtPart TXA +00F2F5: D0 08 =F2FF >495 BNE WrtPart1 ;Branch if request is not an even page +00F2F7: AD C0 FE >496 LDA rwReqH ;A call of zero bytes should never get here! +00F2FA: F0 4A =F346 >497 BEQ SetWrDone ;Do nothing! + >498 +00F2FC: CE C0 FE >499 DEC rwReqH +00F2FF: CA >500 WrtPart1 DEX +00F300: B1 4E >501 LDA (userBuf),Y ;Move data from user's buffer +00F302: 91 4C >502 STA (posPtr),Y ; one byte at a time +00F304: 8A >503 TXA +00F305: F0 1E =F325 >504 BEQ EndWReqChk +00F307: C8 >505 WrtPart2 INY ;Page crossed? +00F308: D0 F5 =F2FF >506 BNE WrtPart1 ;No, move next byte + >507 +00F30A: A5 4D >508 LDA posPtr+1 ;Test for end of buffer +00F30C: E6 4F >509 INC userBuf+1 ; but first adjust user buffer +00F30E: EE BD FE >510 INC tPoslh ; pointer and position +00F311: D0 09 =F31C >511 BNE :1 +00F313: EE BE FE >512 INC tPosHi + >513 + >514 * Don't wrap around on file! + >515 +00F316: D0 04 =F31C >516 BNE :1 +00F318: A9 4D >517 LDA #outOfRange ; Say out of range if >32 meg +00F31A: D0 86 =F2A2 >518 BNE WrtError ;Always +00F31C: E6 4D >519 :1 INC posPtr+1 ; and sos buffer high address +00F31E: 45 4B >520 EOR dataPtr+1 ;(carry has been cleverly undisturbed.) +00F320: F0 DD =F2FF >521 BEQ WrtPart1 ;Crunch if more to write to buffer + >522 +00F322: B8 >523 CLV ;Indicate not finished +00F323: 50 24 =F349 >524 BVC WrPartDone ;Branch always + >525 +00F325: AD C0 FE >526 EndWReqChk LDA rwReqH +00F328: F0 0F =F339 >527 BEQ WrtReqDone ;Branch if request satisfied +00F32A: C8 >528 INY ;Are we done with this block of data? +00F32B: D0 06 =F333 >529 BNE :11 ;Branch if not +00F32D: A5 4D >530 LDA posPtr+1 +00F32F: 45 4B >531 EOR dataPtr+1 ;While this is redundant, it's necessary for +00F331: D0 03 =F336 >532 BNE :12 ; proper adjustment of request count +00F333: CE C0 FE >533 :11 DEC rwReqH ;(not finished- ok to adjust hi byte.) +00F336: 88 >534 :12 DEY ;Reset modified Y-reg +00F337: 80 CE =F307 >535 BRA WrtPart2 + >536 +00F339: C8 >537 WrtReqDone INY ; and position +00F33A: D0 0A =F346 >538 BNE SetWrDone +00F33C: E6 4F >539 INC userBuf+1 ;bump pointers +00F33E: EE BD FE >540 INC tPoslh +00F341: D0 03 =F346 >541 BNE SetWrDone +00F343: EE BE FE >542 INC tPosHi +00F346: 2C 75 F1 >543 SetWrDone BIT SetVFlag ;(set V flag) + >544 +00F349: 8C BC FE >545 WrPartDone STY tPosll ;Save low position +00F34C: 8E BF FE >546 STX rwReqL ; and remainder of request count +00F34F: 08 >547 PHP ;Save statuses +00F350: 20 C3 F5 >548 JSR GetFCBStat +00F353: 09 50 >549 ORA #dataMod+useMod +00F355: 99 08 D8 >550 STA fcb+fcbStatus,Y +00F358: 18 >551 CLC ;Adjust user's low buffer address +00F359: AD BC FE >552 LDA tPosll +00F35C: 65 4E >553 ADC userBuf +00F35E: 85 4E >554 STA userBuf +00F360: 90 02 =F364 >555 BCC :21 +00F362: E6 4F >556 INC userBuf+1 ;Adjust hi address as needed +00F364: 20 20 FA >557 :21 JSR FCBUsed ; Set directory flush bit +00F367: 28 >558 PLP ;Restore return statuses +00F368: 60 >559 RTS + >560 + >561 *------------------------------------------------- + >562 * Make a tree file by adding a new master index blk + >563 +00F369: 20 B2 F3 >564 MakeTree JSR SwapDown ;First make curr 1st blk an entry in new top +00F36C: B0 43 =F3B1 >565 BCS ErrMakeTree ;Return any errors + >566 +00F36E: 20 E1 F1 >567 JSR GfcbStorTyp ;Find out if storage type has been changed to 'tree' + >568 ;(if not, assume it was originally a seed and +00F371: C9 03 >569 CMP #tree ; both levels need to be built +00F373: F0 05 =F37A >570 BEQ MakeTree1 ; Otherwise, only an index need be allocated) +00F375: 20 B2 F3 >571 JSR SwapDown ;Make previous swap a sap level index block +00F378: B0 37 =F3B1 >572 BCS ErrMakeTree + >573 +00F37A: 20 F7 F3 >574 MakeTree1 JSR AllocWrBlk ;Get another block address for the sap level index +00F37D: B0 32 =F3B1 >575 BCS ErrMakeTree +00F37F: AD BE FE >576 LDA tPosHi ;Calculate position of new index block +00F382: 4A >577 LSR ; in the top of the tree +00F383: A8 >578 TAY +00F384: AD 98 FE >579 LDA scrtch ;Get address of newly allocated index block again +00F387: AA >580 TAX +00F388: 91 48 >581 STA (tIndex),Y +00F38A: E6 49 >582 INC tIndex+1 +00F38C: AD 99 FE >583 LDA scrtch+1 +00F38F: 91 48 >584 STA (tIndex),Y ;Save hi address +00F391: C6 49 >585 DEC tIndex+1 + >586 +00F393: AC A4 FE >587 LDY fcbPtr ;Make newly allocated block the current index block +00F396: 99 0F D8 >588 STA fcb+fcbIdxBlk+1,Y +00F399: 8A >589 TXA +00F39A: 99 0E D8 >590 STA fcb+fcbIdxBlk,Y +00F39D: 20 61 EE >591 JSR WrFCBFirst ;Save new top of tree +00F3A0: B0 0F =F3B1 >592 BCS ErrMakeTree +00F3A2: 4C 2D ED >593 JMP ZeroIndex ;Zero index block in user's i/o buffer + >594 + >595 *------------------------------------------------- + >596 * Add new index blk + >597 +00F3A5: 20 E1 F1 >598 AddNewIdxBlk JSR GfcbStorTyp ;Find out if we're dealing with a tree +00F3A8: C9 01 >599 CMP #seedling ;If seed then an adjustment to file type is necessary +00F3AA: F0 06 =F3B2 >600 BEQ SwapDown ;Branch if seed +00F3AC: 20 10 EE >601 JSR RdFCBFst ;Otherwise read in top of tree. +00F3AF: 90 C9 =F37A >602 BCC MakeTree1 ;Branch if no error +00F3B1: 60 >603 ErrMakeTree RTS ;Return errors + >604 + >605 * Add a higher index level to file + >606 + =F3B2 >607 SwapDown EQU * ;Make current seed into a sapling +00F3B2: 20 F7 F3 >608 JSR AllocWrBlk ;Allocate a block before swap +00F3B5: B0 3F =F3F6 >609 BCS SwapErr ;Return errors immediately +00F3B7: AC A4 FE >610 LDY fcbPtr ;Get previous first block +00F3BA: B9 0C D8 >611 LDA fcb+fcbFirst,Y ; address into index block +00F3BD: 48 >612 PHA ;Save temporarly while swapping in new top index +00F3BE: AD 98 FE >613 LDA scrtch ;Get new block address (low) +00F3C1: AA >614 TAX +00F3C2: 99 0C D8 >615 STA fcb+fcbFirst,Y +00F3C5: B9 0D D8 >616 LDA fcb+fcbFirst+1,Y +00F3C8: 48 >617 PHA +00F3C9: AD 99 FE >618 LDA scrtch+1 ; and high address too +00F3CC: 99 0D D8 >619 STA fcb+fcbFirst+1,Y +00F3CF: 99 0F D8 >620 STA fcb+fcbIdxBlk+1,Y ;Make new top also the current index in memory +00F3D2: 8A >621 TXA ;Get low address again +00F3D3: 99 0E D8 >622 STA fcb+fcbIdxBlk,Y +00F3D6: E6 49 >623 INC tIndex+1 ;Make previous the first entry in sub index +00F3D8: 68 >624 PLA +00F3D9: 92 48 >625 STA (tIndex) +00F3DB: C6 49 >626 DEC tIndex+1 +00F3DD: 68 >627 PLA +00F3DE: 92 48 >628 STA (tIndex) +00F3E0: 20 61 EE >629 JSR WrFCBFirst ;Save new file top +00F3E3: B0 11 =F3F6 >630 BCS SwapErr +00F3E5: 20 E1 F1 >631 JSR GfcbStorTyp ;Now adjust storage type by adding 1 +00F3E8: 69 01 >632 ADC #$01 ; (thus seed becomes sapling becomes tree) +00F3EA: 99 07 D8 >633 STA fcb+fcbStorTyp,Y +00F3ED: B9 08 D8 >634 LDA fcb+fcbStatus,Y ;Mark storage type modified +00F3F0: 09 08 >635 ORA #storTypMod +00F3F2: 99 08 D8 >636 STA fcb+fcbStatus,Y +00F3F5: 18 >637 CLC ;Return 'no error' status +00F3F6: 60 >638 SwapErr RTS + >639 + >640 *------------------------------------------------- + >641 +00F3F7: 20 90 EA >642 AllocWrBlk JSR Alloc1Blk ;Allocate 1 block +00F3FA: B0 1A =F416 >643 BCS AlocErr +00F3FC: 20 C3 F5 >644 JSR GetFCBStat ;Mark usage as modified +00F3FF: 09 10 >645 ORA #useMod +00F401: 99 08 D8 >646 STA fcb+fcbStatus,Y +00F404: B9 18 D8 >647 LDA fcb+fcbBlksUsed,Y ;Bump current usage count by 1 +00F407: 18 >648 CLC +00F408: 69 01 >649 ADC #$01 +00F40A: 99 18 D8 >650 STA fcb+fcbBlksUsed,Y +00F40D: B9 19 D8 >651 LDA fcb+fcbBlksUsed+1,Y +00F410: 69 00 >652 ADC #$00 +00F412: 99 19 D8 >653 STA fcb+fcbBlksUsed+1,Y +00F415: 18 >654 WrOK CLC ;Indicate no error +00F416: 60 >655 AlocErr RTS ;All done + >656 + >657 *------------------------------------------------- + >658 * Do Status if not I/O yet + >659 +00F417: 20 C3 F5 >660 TestWrProt JSR GetFCBStat ;Check for a 'never been modified' condition +00F41A: 29 F0 >661 AND #useMod+dataMod+idxMod+eofMod +00F41C: D0 F7 =F415 >662 BNE WrOK ;Ordinary RTS if known write ok + >663 +00F41E: B9 01 D8 >664 LDA fcb+fcbDevNum,Y ;Get file's device number +00F421: 8D 30 BF >665 STA DevNum ;Get current status of block device + >666 + >667 * Status call + >668 +00F424: 85 43 >669 TestWrProtZ STA unitNum ;Make the device status call +00F426: A5 47 >670 LDA blockNum+1 +00F428: 48 >671 PHA +00F429: A5 46 >672 LDA blockNum ;Save the current block values +00F42B: 48 >673 PHA +00F42C: 64 42 >674 STZ dhpCmd ;=statCmd +00F42E: 64 46 >675 STZ blockNum ;Zero the block # +00F430: 64 47 >676 STZ blockNum+1 +00F432: 08 >677 PHP +00F433: 78 >678 SEI +00F434: 20 DD DE >679 JSR DMgr ;Branch if write protect error +00F437: B0 02 =F43B >680 BCS :1 +00F439: A9 00 >681 LDA #$00 ; Otherwise, assume no errors +00F43B: 28 >682 :1 PLP ;Restore interrupt status +00F43C: 18 >683 CLC +00F43D: AA >684 TAX ;Save error +00F43E: F0 01 =F441 >685 BEQ :2 ;Branch if no error +00F440: 38 >686 SEC ; else, set carry to show error +00F441: 68 >687 :2 PLA +00F442: 85 46 >688 STA blockNum ;Restore the block # +00F444: 68 >689 PLA +00F445: 85 47 >690 STA blockNum+1 +00F447: 8A >691 TXA +00F448: 60 >692 RTS ;Carry is indeterminate + 36 PUT mli.src/CloseEOF + >1 *********************************************************** + >2 * Close Call + >3 +00F449: A0 01 >4 Close LDY #c_refNum ;Close all? +00F44B: B1 40 >5 LDA (parm),Y +00F44D: D0 34 =F483 >6 BNE Close1 ;No, just one of 'em +00F44F: 8D CD FE >7 STA clsFlshErr ;Clear global close error +00F452: A9 00 >8 LDA #$00 ;Begin at the beginning +00F454: 8D A4 FE >9 ClsAll STA fcbPtr ;Save current low byte of pointer +00F457: A8 >10 TAY ;Fetch the level at which +00F458: B9 1B D8 >11 LDA fcb+fcbLevel,Y ; file was opened +00F45B: CD 94 BF >12 CMP Level ;Test against current global level +00F45E: 90 15 =F475 >13 BCC NxtClose ;Don't close if files level is < global level +00F460: B9 00 D8 >14 LDA fcb+fcbRefNum,Y ;Is this reference file open? +00F463: F0 10 =F475 >15 BEQ NxtClose ;No, try next +00F465: 20 E1 F4 >16 JSR FlushZ ;Clean it out... +00F468: B0 4C =F4B6 >17 BCS ClosErr ;Return flush errors + >18 +00F46A: 20 88 F4 >19 JSR CloseZ ;Update FCB & VCB +00F46D: A0 01 >20 LDY #c_refNum +00F46F: B1 40 >21 LDA (parm),Y +00F471: F0 02 =F475 >22 BEQ NxtClose ;No err if close all +00F473: B0 41 =F4B6 >23 BCS ClosErr +00F475: AD A4 FE >24 NxtClose LDA fcbPtr +00F478: 18 >25 CLC +00F479: 69 20 >26 ADC #fcbSize +00F47B: 90 D7 =F454 >27 BCC ClsAll ;Branch if within same page + >28 +00F47D: AD CD FE >29 LDA clsFlshErr ;On final close of close all report logged errors +00F480: F0 32 =F4B4 >30 BEQ ClosEnd ;Branch if errors +00F482: 60 >31 RTS ;Carry already set (see BCC) + >32 +00F483: 20 E9 F4 >33 Close1 JSR Flush1 ;Flush file first (including updating bit map) +00F486: B0 2E =F4B6 >34 BCS ClosErr ;Report errors immediately!! + >35 +00F488: AC A4 FE >36 CloseZ LDY fcbPtr +00F48B: B9 0B D8 >37 LDA fcb+fcbFileBuf,Y ;Release file buffer +00F48E: 20 30 FC >38 JSR ReleaseBuf +00F491: B0 23 =F4B6 >39 BCS ClosErr +00F493: A9 00 >40 LDA #$00 +00F495: AC A4 FE >41 LDY fcbPtr +00F498: 99 00 D8 >42 STA fcb+fcbRefNum,Y ;Free file control block too +00F49B: B9 01 D8 >43 LDA fcb+fcbDevNum,Y +00F49E: 8D 30 BF >44 STA DevNum +00F4A1: 20 3C E8 >45 JSR ScanVCB ;Go look for associated VCB +00F4A4: AE A3 FE >46 LDX vcbPtr ;Get vcbptr +00F4A7: DE 1E D9 >47 DEC vcb+vcbOpenCnt,X ;Indicate one less file open +00F4AA: D0 08 =F4B4 >48 BNE ClosEnd ;Branch if that wasn't the last... +00F4AC: BD 11 D9 >49 LDA vcb+vcbStatus,X +00F4AF: 29 7F >50 AND #$7F ;Strip 'files open' bit +00F4B1: 9D 11 D9 >51 STA vcb+vcbStatus,X +00F4B4: 18 >52 ClosEnd CLC +00F4B5: 60 >53 RTS + >54 +00F4B6: B0 2E =F4E6 >55 ClosErr BCS FlushErr ;Don't report close all err now + >56 +00F4B8: A0 01 >57 Flush LDY #c_refNum ;Flush all? +00F4BA: B1 40 >58 LDA (parm),Y +00F4BC: D0 2B =F4E9 >59 BNE Flush1 ;No, just one of 'em + >60 +00F4BE: 8D CD FE >61 STA clsFlshErr ;Clear global flush error +00F4C1: A9 00 >62 LDA #$00 ;Begin at the beginning +00F4C3: 8D A4 FE >63 :loop STA fcbPtr ;Save current low byte of pointer +00F4C6: A8 >64 TAY ;Index to reference number +00F4C7: B9 00 D8 >65 LDA fcb+fcbRefNum,Y ;Is this reference file open? +00F4CA: F0 05 =F4D1 >66 BEQ :1 ;No, try next +00F4CC: 20 E1 F4 >67 JSR FlushZ ;Clean it out.. +00F4CF: B0 15 =F4E6 >68 BCS FlushErr ;Return any errors +00F4D1: AD A4 FE >69 :1 LDA fcbPtr ;Bump pointer to next file control block +00F4D4: 18 >70 CLC +00F4D5: 69 20 >71 ADC #fcbSize +00F4D7: 90 EA =F4C3 >72 BCC :loop ;Branch if within same page + >73 +00F4D9: 18 >74 FlushEnd CLC +00F4DA: AD CD FE >75 LDA clsFlshErr ;On last flush of a flush(0) +00F4DD: F0 01 =F4E0 >76 BEQ :Ret ;Branch if no logged errors +00F4DF: 38 >77 SEC ;Report error now +00F4E0: 60 >78 :Ret RTS + >79 +00F4E1: 20 D7 E1 >80 FlushZ JSR FndFCBuf ;Must set up assoc vcb & buffer locations first +00F4E4: 90 0B =F4F1 >81 BCC Flush2a ;Branch if no error encountered +00F4E6: 4C B4 F5 >82 FlushErr JMP GlbErr ;Check for close or flush all + >83 +00F4E9: 9C CD FE >84 Flush1 STZ clsFlshErr ;Clear gbl flush error for normal refnum flush +00F4EC: 20 BD E1 >85 JSR FindFCB ;set up pointer to fcb user references +00F4EF: B0 F5 =F4E6 >86 BCS FlushErr ;return any errors + >87 + =F4F1 >88 Flush2a EQU * ;Test to see if file is modified +00F4F1: B9 09 D8 >89 LDA fcb+fcbAttr,Y ;First test write enabled +00F4F4: 29 02 >90 AND #writeEnable +00F4F6: F0 E1 =F4D9 >91 BEQ FlushEnd ;Branch if 'read only' +00F4F8: B9 1C D8 >92 LDA fcb+fcbDirty,Y ;See if eof has been modified +00F4FB: 30 07 =F504 >93 BMI :11 ;Branch if it has + >94 +00F4FD: 20 C3 F5 >95 JSR GetFCBStat ;now test for data modified +00F500: 29 70 >96 AND #useMod+eofMod+dataMod ; was written to while it's been open? +00F502: F0 D5 =F4D9 >97 BEQ FlushEnd ;Branch if file not modified + >98 +00F504: 20 C3 F5 >99 :11 JSR GetFCBStat ;Now test for data modified +00F507: 29 40 >100 AND #dataMod ;Does current data buffer need +00F509: F0 05 =F510 >101 BEQ :12 ; to be written? Branch if not +00F50B: 20 66 EE >102 JSR WrFCBData ;If so, go write it stupid! +00F50E: B0 D6 =F4E6 >103 BCS FlushErr + >104 +00F510: 20 C3 F5 >105 :12 JSR GetFCBStat ;Check to see if the index block +00F513: 29 80 >106 AND #idxMod ; (tree files only) needs to be written +00F515: F0 05 =F51C >107 BEQ :13 ;Branch if not... +00F517: 20 79 EE >108 JSR WrFCBIdx +00F51A: B0 CA =F4E6 >109 BCS FlushErr ;Return any errors + >110 +00F51C: A9 06 >111 :13 LDA #fcbEntNum ;Now prepare to update directory +00F51E: AA >112 TAX +00F51F: 0D A4 FE >113 ORA fcbPtr ;(This should preserved Carry-bit) +00F522: A8 >114 TAY +00F523: B9 00 D8 >115 OwnerMov LDA fcb,Y ;Note: this code depends on the +00F526: 9D 6A FE >116 STA d_dev-1,X ; defined order of the file control +00F529: 88 >117 DEY ; block and the temporary directory +00F52A: CA >118 DEX ; area in 'workspc'! ************* +00F52B: D0 F6 =F523 >119 BNE OwnerMov + >120 +00F52D: 8D 30 BF >121 STA DevNum +00F530: AD 6C FE >122 LDA d_head ;Read the directory header for this file +00F533: AE 6D FE >123 LDX d_head+1 +00F536: 20 B7 EB >124 JSR RdBlkAX ;Read it into the general purpose buffer +00F539: B0 AB =F4E6 >125 BCS FlushErr ;Branch if error +00F53B: 20 7D E6 >126 JSR MoveHeadZ ;Move header info +00F53E: AD 6E FE >127 LDA d_entBlk ;Get address of directory block +00F541: AC 6F FE >128 LDY d_entBlk+1 ; that contains the file entry +00F544: CD 6C FE >129 CMP d_head ;Test to see if it's the same block that +00F547: D0 05 =F54E >130 BNE FlsHdrBlk ; the header is in. Branch if not +00F549: CC 6D FE >131 CPY d_head+1 +00F54C: F0 07 =F555 >132 BEQ Flush5 ;Branch if header block = entry block + >133 +00F54E: 85 46 >134 FlsHdrBlk STA blockNum +00F550: 84 47 >135 STY blockNum+1 +00F552: 20 C7 EB >136 JSR RdGBuf ;Get block with file entry in general buffer + >137 +00F555: 20 80 E4 >138 Flush5 JSR EntCalc ;Set up pointer to entry +00F558: 20 77 E5 >139 JSR MovEntry ;Move entry to temp entry buffer in 'workspc' + >140 +00F55B: AC A4 FE >141 LDY fcbPtr ;Update 'blocks used' count +00F55E: B9 18 D8 >142 LDA fcb+fcbBlksUsed,Y +00F561: 8D 84 FE >143 STA d_file+d_usage +00F564: B9 19 D8 >144 LDA fcb+fcbBlksUsed+1,Y +00F567: 8D 85 FE >145 STA d_file+d_usage+1 ;hi byte too... + >146 +00F56A: A2 00 >147 LDX #$00 ;and move in end of file mark +00F56C: B9 15 D8 >148 EOFupdate LDA fcb+fcbEOF,Y ; whether we need to or not +00F56F: 9D 86 FE >149 STA d_file+d_eof,X +00F572: E8 >150 INX ;Move all three bytes +00F573: E0 03 >151 CPX #$03 +00F575: F0 09 =F580 >152 BEQ :21 +00F577: B9 0C D8 >153 LDA fcb+fcbFirst,Y ;Also move in the address of +00F57A: 9D 81 FE >154 STA d_file+d_first-1,X ; the file's first block since +00F57D: C8 >155 INY ; it might have changed since the file +00F57E: D0 EC =F56C >156 BNE EOFupdate ; first opened. Branch always taken + >157 +00F580: B9 05 D8 >158 :21 LDA fcb+fcbStorTyp-2,Y ;the last thing to update +00F583: 0A >159 ASL ; is storage type (y=fcbPtr+2) +00F584: 0A >160 ASL ;(shift it into the hi nibble) +00F585: 0A >161 ASL +00F586: 0A >162 ASL +00F587: 8D 98 FE >163 STA scrtch +00F58A: AD 71 FE >164 LDA d_file+d_stor ;Get old type byte (it might be the same) +00F58D: 29 0F >165 AND #$0F ;Strip off old type +00F58F: 0D 98 FE >166 ORA scrtch ;Add in the new type, +00F592: 8D 71 FE >167 STA d_file+d_stor ; & put it away +00F595: 20 99 E4 >168 JSR ReviseDir ;Go update directory! +00F598: B0 1A =F5B4 >169 BCS GlbErr + >170 +00F59A: AC A4 FE >171 LDY fcbPtr ;Mark +00F59D: B9 1C D8 >172 LDA fcb+fcbDirty,Y ; FCB/directory +00F5A0: 29 7F >173 AND #$FF-fcbMod ; as not +00F5A2: 99 1C D8 >174 STA fcb+fcbDirty,Y ; dirty +00F5A5: AD 6B FE >175 LDA d_dev ;See if bitmap should be written +00F5A8: CD B8 FE >176 CMP bmaDev ;Is it in same as current file? +00F5AB: D0 05 =F5B2 >177 BNE :22 ;Yes, put it on the disk if necessary +00F5AD: 20 64 EB >178 JSR UpdateBitMap ;Go put it away +00F5B0: B0 02 =F5B4 >179 BCS GlbErr +00F5B2: 18 >180 :22 CLC +00F5B3: 60 >181 RTS + >182 +00F5B4: A0 01 >183 GlbErr LDY #c_refNum ;Report error immediately +00F5B6: 48 >184 PHA ; only if not a close all or flush all +00F5B7: B1 40 >185 LDA (parm),Y +00F5B9: D0 06 =F5C1 >186 BNE :31 ;Not an 'all' so report now +00F5BB: 18 >187 CLC +00F5BC: 68 >188 PLA +00F5BD: 8D CD FE >189 STA clsFlshErr ;Save for later +00F5C0: 60 >190 RTS +00F5C1: 68 >191 :31 PLA +00F5C2: 60 >192 RTS + >193 + >194 * Get status of FCB + >195 +00F5C3: AC A4 FE >196 GetFCBStat LDY fcbPtr ;Index to fcb +00F5C6: B9 08 D8 >197 LDA fcb+fcbStatus,Y ;Return status byte +00F5C9: 60 >198 RTS ;That is all... + >199 +00F5CA: A9 4E >200 SetErr LDA #invalidAccess +00F5CC: 38 >201 SEC +00F5CD: 60 >202 EOFret RTS + >203 + >204 *********************************************************** + >205 * SETEOF Call + >206 +00F5CE: 20 E1 F1 >207 SetEOF JSR GfcbStorTyp ;Only know how to move eof of tree, sapling, or seed +00F5D1: C9 04 >208 CMP #tree+1 +00F5D3: B0 F5 =F5CA >209 BCS SetErr +00F5D5: 0A >210 ASL +00F5D6: 0A >211 ASL +00F5D7: 0A >212 ASL +00F5D8: 0A >213 ASL ;=$10,$20,$30 +00F5D9: 8D D0 FE >214 STA storType ;May be used later for trimming the tree... +00F5DC: B9 09 D8 >215 LDA fcb+fcbAttr,Y ;Now check to insure write is enabled +00F5DF: 29 02 >216 AND #writeEnable ;Can we set new eof? +00F5E1: F0 E7 =F5CA >217 BEQ SetErr ;Nope, access error + >218 +00F5E3: 20 17 F4 >219 JSR TestWrProt ;Find out if mod is posible (H/W write protect) +00F5E6: B0 E2 =F5CA >220 BCS SetErr + >221 +00F5E8: AC A4 FE >222 LDY fcbPtr ;Save old EOF +00F5EB: C8 >223 INY +00F5EC: C8 >224 INY +00F5ED: A2 02 >225 LDX #$02 ; so it can be seen +00F5EF: B9 15 D8 >226 SetSave LDA fcb+fcbEOF,Y ; whether blocks need +00F5F2: 9D 9C FE >227 STA oldEOF,X ; to be released +00F5F5: 88 >228 DEY ; upon +00F5F6: CA >229 DEX ; contraction +00F5F7: 10 F6 =F5EF >230 BPL SetSave ;All three bytes of the eof + >231 +00F5F9: A0 04 >232 LDY #c_eof+2 +00F5FB: A2 02 >233 LDX #$02 +00F5FD: B1 40 >234 NewEOFPos LDA (parm),Y ;Position mark to new EOF +00F5FF: 9D BC FE >235 STA tPosll,X +00F602: 88 >236 DEY +00F603: CA >237 DEX +00F604: 10 F7 =F5FD >238 BPL NewEOFPos + >239 +00F606: A2 02 >240 LDX #$02 ;Point to third byte +00F608: BD 9C FE >241 PurgeTest LDA oldEOF,X ;See if EOF moved backwards +00F60B: DD BC FE >242 CMP tPosll,X ; so blocks can +00F60E: 90 05 =F615 >243 BCC EOFset ; be released (branch if not) +00F610: D0 18 =F62A >244 BNE Purge ;Branch if blocks to be released +00F612: CA >245 DEX +00F613: 10 F3 =F608 >246 BPL PurgeTest ;All three bytes + >247 +00F615: A0 04 >248 EOFset LDY #c_eof+2 +00F617: AE A4 FE >249 LDX fcbPtr ;Place new end of file into FCB +00F61A: E8 >250 INX +00F61B: E8 >251 INX +00F61C: B1 40 >252 :loop LDA (parm),Y +00F61E: 9D 15 D8 >253 STA fcb+fcbEOF,X +00F621: CA >254 DEX +00F622: 88 >255 DEY +00F623: C0 02 >256 CPY #c_eof ;All three bytes moved? +00F625: B0 F5 =F61C >257 BCS :loop ;Branch if not... +00F627: 4C 20 FA >258 JMP FCBUsed ;Mark fcb as dirty... all done + >259 +00F62A: 20 E9 F4 >260 Purge JSR Flush1 ;Make sure file is current +00F62D: B0 9E =F5CD >261 BCS EOFret +00F62F: A6 4B >262 LDX dataPtr+1 ;Restore pointer to index block +00F631: E8 >263 INX +00F632: E8 >264 INX ;(zero page conflict with dirPtr) +00F633: 86 49 >265 STX tIndex+1 +00F635: A6 4A >266 LDX dataPtr +00F637: 86 48 >267 STX tIndex +00F639: AC A4 FE >268 LDY fcbPtr ;Find out if eof < mark +00F63C: C8 >269 INY +00F63D: C8 >270 INY +00F63E: A2 02 >271 LDX #$02 +00F640: B9 12 D8 >272 NewEOFtest LDA fcb+fcbMark,Y +00F643: DD BC FE >273 CMP tPosll,X ;Compare until not equal or carry clear +00F646: 90 17 =F65F >274 BCC SetEOF1 ;branch if eof>mark (mark is b4 new EOF) +00F648: D0 04 =F64E >275 BNE SetEOF0 ;branch if eof276 DEY +00F64B: CA >277 DEX +00F64C: 10 F2 =F640 >278 BPL NewEOFtest ;Loop on all three bytes + >279 +00F64E: AC A4 FE >280 SetEOF0 LDY fcbPtr +00F651: A2 00 >281 LDX #$00 +00F653: BD BC FE >282 FakeEOF LDA tPosll,X ;Fake position, correct position +00F656: 99 12 D8 >283 STA fcb+fcbMark,Y +00F659: C8 >284 INY ; will be made below... +00F65A: E8 >285 INX ;Move all three bytes +00F65B: E0 03 >286 CPX #$03 +00F65D: D0 F4 =F653 >287 BNE FakeEOF + >288 +00F65F: 20 5E E9 >289 SetEOF1 JSR TakeFreeCnt ;Force proper free blk cnt before releasing blocks +00F662: AD BC FE >290 LDA tPosll ;Now prepare for purge of excess blocks... +00F665: 8D D5 FE >291 STA dSeed ;All blocks and bytes beyond new +00F668: AD BD FE >292 LDA tPoslh ; EOF must be zeroed! +00F66B: 8D D4 FE >293 STA dSap +00F66E: 29 01 >294 AND #$01 +00F670: 8D D6 FE >295 STA dSeed+1 ;(=0/1) +00F673: AD BE FE >296 LDA tPosHi +00F676: 4A >297 LSR +00F677: 8D D3 FE >298 STA dTree +00F67A: 6E D4 FE >299 ROR dSap ;Pass position in terms of block & bytes +00F67D: AD D5 FE >300 LDA dSeed ;Now adjust for boundaries of $200 +00F680: 0D D6 FE >301 ORA dSeed+1 ;(block boundaries) +00F683: D0 1D =F6A2 >302 BNE SetEOF3 ;Branch if no adjustment necessary + >303 +00F685: AD D4 FE >304 LDA dSap ;Get correct block positions +00F688: 38 >305 SEC ; for sap & tree levels +00F689: E9 01 >306 SBC #$01 +00F68B: 8D D4 FE >307 STA dSap ;Deallocate for last (phantom) block +00F68E: A9 02 >308 LDA #$02 ; & don't modify last data block +00F690: B0 0D =F69F >309 BCS SetEOF2 ;branch if tree level unaffected +00F692: CE D3 FE >310 DEC dTree ;But if it is affected, make sure new eof # 0 +00F695: 10 08 =F69F >311 BPL SetEOF2 ;Branch if new eof not zero + >312 +00F697: A9 00 >313 LDA #$00 ;Otherwise, just make a null seed out of it +00F699: 8D D3 FE >314 STA dTree +00F69C: 8D D4 FE >315 STA dSap +00F69F: 8D D6 FE >316 SetEOF2 STA dSeed+1 ;(On fall thru, =0 else = 2) +00F6A2: AC A4 FE >317 SetEOF3 LDY fcbPtr ;Also must pass file's first block addr +00F6A5: B9 0C D8 >318 LDA fcb+fcbFirst,Y ; which is its keyblk +00F6A8: 8D CE FE >319 STA firstBlkL +00F6AB: B9 0D D8 >320 LDA fcb+fcbFirst+1,Y +00F6AE: 8D CF FE >321 STA firstBlkH + >322 +00F6B1: 9C D1 FE >323 STZ deBlock ;Lastly, number of blocks to be +00F6B4: 9C D2 FE >324 STZ deBlock+1 ; freed should be initialized +00F6B7: 20 32 FA >325 JSR DeTree ;Go defoliate... +00F6BA: 08 >326 PHP ;Save any error status until +00F6BB: 48 >327 PHA ; FCB is cleaned up! + >328 +00F6BC: 38 >329 SEC +00F6BD: AC A4 FE >330 LDY fcbPtr +00F6C0: A2 00 >331 LDX #$00 +00F6C2: BD CE FE >332 AdjFCB LDA firstBlkL,X +00F6C5: 99 0C D8 >333 STA fcb+fcbFirst,Y ;Move in posible new first file block addr +00F6C8: B9 18 D8 >334 LDA fcb+fcbBlksUsed,Y ;Adjust usage count also +00F6CB: FD D1 FE >335 SBC deBlock,X +00F6CE: 99 18 D8 >336 STA fcb+fcbBlksUsed,Y +00F6D1: C8 >337 INY +00F6D2: E8 >338 INX +00F6D3: 8A >339 TXA +00F6D4: 29 01 >340 AND #$01 ;Test for both bytes adjusted +00F6D6: D0 EA =F6C2 >341 BNE AdjFCB ; without disturbing carry + >342 +00F6D8: AD D0 FE >343 LDA storType ;get possibly modified storage type +00F6DB: 4A >344 LSR +00F6DC: 4A >345 LSR +00F6DD: 4A >346 LSR +00F6DE: 4A >347 LSR +00F6DF: AC A4 FE >348 LDY fcbPtr ;save it in fcb +00F6E2: 99 07 D8 >349 STA fcb+fcbStorTyp,Y +00F6E5: 20 87 ED >350 JSR ClrStats ;Make it look as though position has +00F6E8: 20 B2 F9 >351 JSR DvcbRev ; nothing allocated, update total blocks in VCB + >352 +00F6EB: AC A4 FE >353 LDY fcbPtr ;Now correct position stuff +00F6EE: C8 >354 INY +00F6EF: C8 >355 INY +00F6F0: A2 02 >356 LDX #$02 +00F6F2: B9 12 D8 >357 CorrectPos LDA fcb+fcbMark,Y ;Tell RdPosn to go to correct +00F6F5: 9D BC FE >358 STA tPosll,X +00F6F8: 49 80 >359 EOR #$80 ; position from incorrect place +00F6FA: 99 12 D8 >360 STA fcb+fcbMark,Y +00F6FD: 88 >361 DEY +00F6FE: CA >362 DEX +00F6FF: 10 F1 =F6F2 >363 BPL CorrectPos + >364 +00F701: 20 1E EC >365 JSR RdPosn ;Go do it!!! +00F704: 90 07 =F70D >366 BCC Purge1 ;Branch if no error +00F706: AA >367 TAX ;Otherwise report latest error +00F707: 68 >368 PLA +00F708: 28 >369 PLP +00F709: 8A >370 TXA ;Restore latest error code to stack +00F70A: 38 >371 SEC +00F70B: 08 >372 PHP +00F70C: 48 >373 PHA ;Save new error + =F70D >374 Purge1 EQU * ;Mark file as in need of a flush and +00F70D: 20 15 F6 >375 JSR EOFset ; update FCB with new end of file +00F710: 20 E9 F4 >376 JSR Flush1 ;Now go do flush +00F713: 90 07 =F71C >377 BCC :1 ;Branch if no error + >378 +00F715: AA >379 TAX ;Save latest error +00F716: 68 >380 PLA ;Clean previous error off stack +00F717: 28 >381 PLP +00F718: 8A >382 TXA ;Restore latest error code to stack +00F719: 38 >383 SEC ;Set the carry to show error condition +00F71A: 08 >384 PHP ;Restore error status to stack +00F71B: 48 >385 PHA ; & the error code +00F71C: 68 >386 :1 PLA ;Report any errors that may have cropped up +00F71D: 28 >387 PLP +00F71E: 60 >388 RTS + >389 +00F71F: AE A4 FE >390 GetEOF LDX fcbPtr ;Index to end of file mark +00F722: A0 02 >391 LDY #c_eof ; & index to user's call parameters +00F724: BD 15 D8 >392 OutEOF LDA fcb+fcbEOF,X +00F727: 91 40 >393 STA (parm),Y +00F729: E8 >394 INX +00F72A: C8 >395 INY +00F72B: C0 05 >396 CPY #c_eof+3 +00F72D: D0 F5 =F724 >397 BNE OutEOF ;Loop until all three bytes are moved +00F72F: 18 >398 CLC ;No errors +00F730: 60 >399 RTS + 37 PUT mli.src/Destroy + >1 *********************************************************** + >2 * Newline Call + >3 +00F731: A0 02 >4 NewLine LDY #c_isNewln ;Adjust newline status for open file +00F733: B1 40 >5 LDA (parm),Y ;on or off? +00F735: AE A4 FE >6 LDX fcbPtr ;It will be zero if off +00F738: 9D 1F D8 >7 STA fcb+fcbNLMask,X ;Set new line mask +00F73B: C8 >8 INY +00F73C: B1 40 >9 LDA (parm),Y ; & move in new 'new-line' byte +00F73E: 9D 0A D8 >10 STA fcb+fcbNewLin,X +00F741: 18 >11 CLC +00F742: 60 >12 RTS ;No error possible + >13 +00F743: 20 72 E5 >14 GetInfo JSR FindFile ;Look for file they want to know about +00F746: 90 40 =F788 >15 BCC :1 ;Branch if no errors +00F748: C9 40 >16 CMP #badPathSyntax ;Was it a root directory file? +00F74A: 38 >17 SEC ;(in case of no match) +00F74B: D0 57 =F7A4 >18 BNE :Ret +00F74D: A9 F0 >19 LDA #$F0 +00F74F: 8D 71 FE >20 STA d_file+d_stor ;For get info, report proper storage type +00F752: 9C A6 FE >21 STZ reqL ;Force a count of free blocks +00F755: 9C A7 FE >22 STZ reqH + >23 +00F758: AE A3 FE >24 LDX vcbPtr +00F75B: 20 5E E9 >25 JSR TakeFreeCnt ;Take a fresh count of free blocks on this volume +00F75E: AE A3 FE >26 LDX vcbPtr +00F761: BD 15 D9 >27 LDA vcb+vcbFreeBlks+1,X ;Return total blocks and total in use +00F764: 8D A7 FE >28 STA reqH ;First transfer 'free' blocks to zpage for later subtract +00F767: BD 14 D9 >29 LDA vcb+vcbFreeBlks,X ; to determine the 'used' count +00F76A: 8D A6 FE >30 STA reqL + >31 +00F76D: BD 13 D9 >32 LDA vcb+vcbTotBlks+1,X ;Transfer to 'd_' table as auxID +00F770: 8D 91 FE >33 STA d_file+d_auxID+1 ;(total block count is considered auxID for the volume) +00F773: 48 >34 PHA +00F774: BD 12 D9 >35 LDA vcb+vcbTotBlks,X +00F777: 8D 90 FE >36 STA d_file+d_auxID + >37 +00F77A: 38 >38 SEC ;Now subtract and report the number of blocks 'in use' +00F77B: ED A6 FE >39 SBC reqL +00F77E: 8D 84 FE >40 STA d_file+d_usage +00F781: 68 >41 PLA +00F782: ED A7 FE >42 SBC reqH +00F785: 8D 85 FE >43 STA d_file+d_usage+1 + >44 +00F788: AD 71 FE >45 :1 LDA d_file+d_stor ;Transfer bytes from there internal order +00F78B: 4A >46 LSR ; to call spec via 'infoTabl' translation table +00F78C: 4A >47 LSR +00F78D: 4A >48 LSR ; but first change storage type to +00F78E: 4A >49 LSR ; external (low nibble) format +00F78F: 8D 71 FE >50 STA d_file+d_stor + >51 +00F792: A0 11 >52 LDY #c_creTime+1 ;Index to last of user's spec table +00F794: B9 32 FE >53 :CpyLoop LDA InfoTabl-3,Y +00F797: 29 7F >54 AND #$7F ;Strip bit used by setinfo +00F799: AA >55 TAX +00F79A: BD 71 FE >56 LDA d_file,X ;Move directory info to call spec. table +00F79D: 91 40 >57 STA (parm),Y +00F79F: 88 >58 DEY +00F7A0: C0 03 >59 CPY #c_attr ;have all info bytes been sent? +00F7A2: B0 F0 =F794 >60 BCS :CpyLoop +00F7A4: 60 >61 :Ret RTS + >62 +00F7A5: 20 72 E5 >63 SetInfo JSR FindFile ;Find what user wants... +00F7A8: B0 25 =F7CF >64 BCS SInfoErr ;Return any failure + >65 +00F7AA: AD 95 BF >66 LDA BUBit ;Discover if backup bit can be cleared +00F7AD: 49 20 >67 EOR #backupNeeded +00F7AF: 2D 8F FE >68 AND d_file+d_attr +00F7B2: 29 20 >69 AND #backupNeeded +00F7B4: 8D C5 FE >70 STA bkBitFlg ; or preserve current... + >71 +00F7B7: A0 0D >72 LDY #c_modTime+1 ;Init pointer to user supplied list +00F7B9: BE 32 FE >73 :loop1 LDX InfoTabl-3,Y ;Get index into coresponding 'd_' table +00F7BC: 30 05 =F7C3 >74 BMI :11 ;Branch if we've got a non-setable parameter +00F7BE: B1 40 >75 LDA (parm),Y +00F7C0: 9D 71 FE >76 STA d_file,X +00F7C3: 88 >77 :11 DEY ;Has user's request been satisfied? +00F7C4: C0 03 >78 CPY #c_attr +00F7C6: B0 F1 =F7B9 >79 BCS :loop1 ;No, move next byte + >80 + >81 * Make sure no illegal access bits were set! + >82 +00F7C8: 29 18 >83 AND #$FF-destroyEnable-renameEnable-backupNeeded-fileInvisible-writeEnable-readEnable +00F7CA: F0 04 =F7D0 >84 BEQ SetInfo3 ;Branch if legal access +00F7CC: A9 4E >85 LDA #invalidAccess ;Otherwise, refuse to do it +00F7CE: 38 >86 SEC ;Indicate error +00F7CF: 60 >87 SInfoErr RTS + >88 +00F7D0: A0 0B >89 SetInfo3 LDY #c_modDate+1 +00F7D2: B1 40 >90 LDA (parm),Y ;Was clock null input? +00F7D4: F0 03 =F7D9 >91 BEQ :Jump +00F7D6: 4C A9 E4 >92 JMP ReviseDirZ ;End by updating directory +00F7D9: 4C 99 E4 >93 :Jump JMP ReviseDir ;Update with clock also... + >94 + >95 *------------------------------------------------- + >96 * RENAME call + >97 * Only the final name in the path specification + >98 * may be renamed. In other words, the new name + >99 * must be in the same DIRectory as the old name. + >100 +00F7DC: 20 85 E5 >101 Rename JSR LookFile ;Look for source (original) file +00F7DF: 90 3D =F81E >102 BCC Rename0 ;Branch if found +00F7E1: C9 40 >103 CMP #badPathSyntax ;Trying to rename a volume? +00F7E3: D0 18 =F7FD >104 BNE :1 ;No, return other error +00F7E5: 20 02 F9 >105 JSR RenamePath ;Syntax new name +00F7E8: B0 13 =F7FD >106 BCS :1 + >107 +00F7EA: AC 00 D7 >108 LDY pathBuf ;Find out if only rootname for new name +00F7ED: C8 >109 INY +00F7EE: B9 00 D7 >110 LDA pathBuf,Y ;Must be $ff if v-name only +00F7F1: D0 7F =F872 >111 BNE RenBadPath ;Branch if not single name + >112 +00F7F3: AE A3 FE >113 LDX vcbPtr ;Test for open files before changing +00F7F6: BD 11 D9 >114 LDA vcb+vcbStatus,X +00F7F9: 10 04 =F7FF >115 BPL RenameVol ;Branch if volume not busy +00F7FB: A9 50 >116 LDA #fileBusy +00F7FD: 38 >117 :1 SEC +00F7FE: 60 >118 RTS + >119 +00F7FF: A0 00 >120 RenameVol LDY #$00 ;Get newname's length +00F801: B9 00 D7 >121 LDA pathBuf,Y +00F804: 09 F0 >122 ORA #$F0 ;(root file storage type) +00F806: 20 F3 F8 >123 JSR MovRootName ;Update root directory +00F809: B0 69 =F874 >124 BCS RenErr + >125 +00F80B: A0 00 >126 LDY #$00 +00F80D: AE A3 FE >127 LDX vcbPtr ;Update VCB also +00F810: B9 00 D7 >128 :loop LDA pathBuf,Y ;Move new name to VCB +00F813: F0 07 =F81C >129 BEQ :ExitLoop +00F815: 9D 00 D9 >130 STA vcb,X +00F818: C8 >131 INY ;Bump to next character +00F819: E8 >132 INX +00F81A: D0 F4 =F810 >133 BNE :loop ;Branch always taken +00F81C: 18 >134 :ExitLoop CLC ;No errors +00F81D: 60 >135 RTS + >136 +00F81E: 20 10 F9 >137 Rename0 JSR GetNamePtr ;Set Y-reg to first char of path, X=0 +00F821: B9 00 D7 >138 :loop1 LDA pathBuf,Y ;Move original name to genBuf +00F824: 9D 00 DC >139 STA genBuf,X ; for later comparison with new name +00F827: 30 04 =F82D >140 BMI :11 ;Branch if last character has been moved +00F829: C8 >141 INY ;Otherwise, get the next one +00F82A: E8 >142 INX +00F82B: D0 F4 =F821 >143 BNE :loop1 ;Branch always taken + >144 +00F82D: 20 02 F9 >145 :11 JSR RenamePath ;Get new name syntaxed +00F830: B0 42 =F874 >146 BCS RenErr +00F832: 20 10 F9 >147 JSR GetNamePtr ;Set Y to path, X to 0 +00F835: B9 00 D7 >148 LDA pathBuf,Y ;Now compare new name with old name +00F838: DD 00 DC >149 :loop2 CMP genBuf,X ; to make sure that they are in the same dir +00F83B: 08 >150 PHP ;Save result of compare for now +00F83C: 29 F0 >151 AND #$F0 ;Was last char really a count? +00F83E: D0 06 =F846 >152 BNE :12 ;Branch if not +00F840: 8C C9 FE >153 STY rnPtr ;Save pointer to next name, it might be the last +00F843: 8E CA FE >154 STX pnPtr +00F846: 28 >155 :12 PLP ;What was the result of the compare? +00F847: D0 09 =F852 >156 BNE NoMatch ;Branch if different character or count +00F849: E8 >157 INX ;Bump pointers +00F84A: C8 >158 INY +00F84B: B9 00 D7 >159 LDA pathBuf,Y ;Was that the last character? +00F84E: D0 E8 =F838 >160 BNE :loop2 ;Branch if not +00F850: 18 >161 CLC ;No-operation, names were the same +00F851: 60 >162 RTS + >163 +00F852: AC C9 FE >164 NoMatch LDY rnPtr ;Index to last name in the chains +00F855: B9 00 D7 >165 LDA pathBuf,Y ;Get last name length +00F858: 38 >166 SEC +00F859: 6D C9 FE >167 ADC rnPtr +00F85C: A8 >168 TAY +00F85D: B9 00 D7 >169 LDA pathBuf,Y ;This byte should be $00! +00F860: D0 10 =F872 >170 BNE RenBadPath ;Branch if not + >171 +00F862: AE CA FE >172 LDX pnPtr ;Index to last of original name +00F865: BD 00 DC >173 LDA genBuf,X +00F868: 38 >174 SEC +00F869: 6D CA FE >175 ADC pnPtr +00F86C: AA >176 TAX +00F86D: BD 00 DC >177 LDA genBuf,X ;This byte should also be $00 +00F870: F0 04 =F876 >178 BEQ GoodNames ;Continue processing if it is + >179 +00F872: A9 40 >180 RenBadPath LDA #badPathSyntax +00F874: 38 >181 RenErr SEC +00F875: 60 >182 RTS ;Report error + >183 +00F876: 20 85 E5 >184 GoodNames JSR LookFile ;Test for duplicate file name +00F879: B0 04 =F87F >185 BCS :21 ;Branch if file not found, which is what we want! +00F87B: A9 47 >186 LDA #dupPathname ;New name already exists +00F87D: 38 >187 SEC ;Report duplicate +00F87E: 60 >188 RTS + >189 +00F87F: C9 46 >190 :21 CMP #fileNotFound ;Was it a valid "file not found"? +00F881: D0 F1 =F874 >191 BNE RenErr ;No, return other error code +00F883: 20 7D E0 >192 JSR SetPath ;Now syntax the pathname of the file to be changed +00F886: 20 72 E5 >193 JSR FindFile ;Get all the info on this one +00F889: B0 E9 =F874 >194 BCS RenErr + >195 +00F88B: 20 7D EF >196 JSR TestOpen ;Don't allow rename to occur if file is in use +00F88E: A9 50 >197 LDA #fileBusy ;Anticipate error +00F890: B0 E2 =F874 >198 BCS RenErr +00F892: AD 8F FE >199 LDA d_file+d_attr ;Test bit that says it's ok to rename +00F895: 29 40 >200 AND #renameEnable +00F897: D0 04 =F89D >201 BNE Rename8 ;Branch if it's alright to rename +00F899: A9 4E >202 LDA #invalidAccess ;Otherwise report illegal access +00F89B: 38 >203 RenErr1 SEC +00F89C: 60 >204 RTS + >205 +00F89D: AD 71 FE >206 Rename8 LDA d_file+d_stor ;Find out which storage type +00F8A0: 29 F0 >207 AND #$F0 ;Strip off name length +00F8A2: C9 D0 >208 CMP #directoryFile*16 ;Is it a directory? +00F8A4: F0 08 =F8AE >209 BEQ :31 +00F8A6: C9 40 >210 CMP #{tree+1}*16 ;Is it a seed, sapling, or tree? +00F8A8: 90 04 =F8AE >211 BCC :31 +00F8AA: A9 4A >212 LDA #badFileFormat +00F8AC: D0 ED =F89B >213 BNE RenErr1 + >214 +00F8AE: 20 02 F9 >215 :31 JSR RenamePath ;Well... since both names would go into the dir, +00F8B1: B0 C1 =F874 >216 BCS RenErr ; re-syntax the new name to get local name address + >217 +00F8B3: AC C9 FE >218 LDY rnPtr ;(Y contains index to local name length) +00F8B6: BE 00 D7 >219 LDX pathBuf,Y ;Adjust Y to last char of new name +00F8B9: 98 >220 TYA +00F8BA: 79 00 D7 >221 ADC pathBuf,Y +00F8BD: A8 >222 TAY +00F8BE: B9 00 D7 >223 :loop LDA pathBuf,Y ;Move local name to dir entry workspace +00F8C1: 9D 71 FE >224 STA d_file+d_stor,X +00F8C4: 88 >225 DEY +00F8C5: CA >226 DEX +00F8C6: D0 F6 =F8BE >227 BNE :loop + >228 +00F8C8: AD 71 FE >229 LDA d_file+d_stor ;Preserve file storage type +00F8CB: 29 F0 >230 AND #$F0 ;Strip off old name length +00F8CD: AA >231 TAX +00F8CE: 19 00 D7 >232 ORA pathBuf,Y ;Add in new name's length +00F8D1: 8D 71 FE >233 STA d_file+d_stor +00F8D4: E0 D0 >234 CPX #directoryFile*16 ; that file must be changed also +00F8D6: D0 18 =F8F0 >235 BNE RenameDone ;Branch if not directory type + >236 + >237 * Renaming a DIR file + >238 +00F8D8: AD 82 FE >239 LDA d_file+d_first ;Read in 1st (header) block of sub-dir +00F8DB: AE 83 FE >240 LDX d_file+d_first+1 +00F8DE: 20 B7 EB >241 JSR RdBlkAX +00F8E1: B0 91 =F874 >242 BCS RenErr ;Report errors + >243 +00F8E3: AC C9 FE >244 LDY rnPtr ;Change the header's name to match the owner's new name +00F8E6: B9 00 D7 >245 LDA pathBuf,Y ;Get local name length again +00F8E9: 09 E0 >246 ORA #$E0 ;Assume it's a vol/subdir header +00F8EB: 20 F3 F8 >247 JSR MovRootName +00F8EE: B0 84 =F874 >248 BCS RenErr +00F8F0: 4C A9 E4 >249 RenameDone JMP ReviseDirZ ;End by updating all path directories + >250 +00F8F3: A2 00 >251 MovRootName LDX #$00 +00F8F5: 9D 04 DC >252 :loop STA genBuf+4,X +00F8F8: E8 >253 INX +00F8F9: C8 >254 INY +00F8FA: B9 00 D7 >255 LDA pathBuf,Y +00F8FD: D0 F6 =F8F5 >256 BNE :loop +00F8FF: 4C C3 EB >257 JMP WrtGBuf ;Write changed header block + >258 + >259 *------------------------------------------------- + >260 +00F902: A0 03 >261 RenamePath LDY #c_newPath ;Get address to new pathname +00F904: B1 40 >262 LDA (parm),Y +00F906: C8 >263 INY +00F907: 85 48 >264 STA tPath +00F909: B1 40 >265 LDA (parm),Y ;Set up for syntaxing routine (SynPath) +00F90B: 85 49 >266 STA tPath+1 +00F90D: 4C 88 E0 >267 JMP SynPath ;Go syntax it. (Ret last local name length in Y) + >268 +00F910: A0 00 >269 GetNamePtr LDY #$00 ;Return pointer to first name of path +00F912: 2C CC FE >270 BIT prfxFlg ;Is this a prefixed name? +00F915: 30 03 =F91A >271 BMI :1 ;Branch if not +00F917: AC 97 BF >272 LDY NewPfxPtr +00F91A: A2 00 >273 :1 LDX #$00 +00F91C: 60 >274 RTS + >275 + >276 *********************************************************** + >277 * Destroy Call + >278 +00F91D: 20 72 E5 >279 Destroy JSR FindFile ;Look for file to be wiped out +00F920: B0 44 =F966 >280 BCS DstryErr ;Pass back any error +00F922: 20 7D EF >281 JSR TestOpen ;Is this file open? +00F925: AD A9 FE >282 LDA totEnt +00F928: D0 3A =F964 >283 BNE :3 ;Branch if file open + >284 +00F92A: 9C A6 FE >285 STZ reqL ;Force proper free count in volume +00F92D: 9C A7 FE >286 STZ reqH ;(no disk access occurs if already proper) +00F930: 20 53 E9 >287 JSR TestFreeBlk +00F933: 90 04 =F939 >288 BCC :1 +00F935: C9 48 >289 CMP #volumeFull ;Was it just a full disk? +00F937: D0 2D =F966 >290 BNE DstryErr ;Nope, report error + >291 +00F939: AD 8F FE >292 :1 LDA d_file+d_attr ;Make sure it's ok to destroy this file +00F93C: 29 80 >293 AND #destroyEnable +00F93E: D0 05 =F945 >294 BNE :2 ;Branch if ok +00F940: A9 4E >295 LDA #invalidAccess ;Tell user it's not kosher +00F942: 20 09 BF >296 JSR SysErr ;(returns to caller of destroy) + >297 +00F945: AD 30 BF >298 :2 LDA DevNum ;Before going thru deallocation, +00F948: 20 24 F4 >299 JSR TestWrProtZ ; test for write protected hardware +00F94B: B0 19 =F966 >300 BCS DstryErr +00F94D: AD 82 FE >301 LDA d_file+d_first ;"DeTree" needs first block addr +00F950: 8D CE FE >302 STA firstBlkL ; which is file's keyblk +00F953: AD 83 FE >303 LDA d_file+d_first+1 +00F956: 8D CF FE >304 STA firstBlkH +00F959: AD 71 FE >305 LDA d_file+d_stor ;Find out which storage type +00F95C: 29 F0 >306 AND #$F0 ;Strip off name length +00F95E: C9 40 >307 CMP #{tree+1}*16 ;Is it a seed, sapling, or tree? +00F960: 90 06 =F968 >308 BCC DstryTree ;Branch if it is +00F962: 80 6B =F9CF >309 BRA DestroyDir ;Otherwise test for directory destroy + >310 +00F964: A9 50 >311 :3 LDA #fileBusy +00F966: 38 >312 DstryErr SEC ;Inform user that file can't +00F967: 60 >313 RTS ; be destroyed at this time + >314 + =F968 >315 DstryTree EQU * ;Destroy a tree file +00F968: 8D D0 FE >316 STA storType ;Save storage type +00F96B: A2 05 >317 LDX #$05 +00F96D: A9 00 >318 LDA #$00 ;Set "DeTree" input variables +00F96F: 9D D0 FE >319 :loop STA storType,X ;Variables must be +00F972: CA >320 DEX ; in order:deBlock, dTree, dSap, dSeed +00F973: D0 FA =F96F >321 BNE :loop ;Loop until all set to zero +00F975: A9 02 >322 LDA #$02 +00F977: 8D D6 FE >323 STA dSeed+1 ;This avoids an extra file i/o + >324 + >325 ********************** see rev note #73 ********************** + >326 ********************* see rev note #49 ********************** + >327 ********************** see rev note #41 ********************* + >328 +00F97A: EE F0 FE >329 INC delFlag ;Don't allow DeTree to zero index blocks +00F97D: 20 32 FA >330 JSR DeTree ;Make trees and saplings into seeds +00F980: CE F0 FE >331 DEC delFlag ;Reset flag +00F983: B0 0E =F993 >332 BCS DstryErr1 ;(de-evolution) + >333 +00F985: AE CF FE >334 DstryLast LDX firstBlkH +00F988: AD CE FE >335 LDA firstBlkL ;Now deallocate seed +00F98B: 20 11 EA >336 JSR Dealloc +00F98E: B0 03 =F993 >337 BCS DstryErr1 +00F990: 20 64 EB >338 JSR UpdateBitMap + >339 +00F993: 48 >340 DstryErr1 PHA ;Save error code (if any) +00F994: A9 00 >341 LDA #$00 ;Update directory to free entry space +00F996: 8D 71 FE >342 STA d_file+d_stor +00F999: CD 65 FE >343 CMP h_fileCnt ;File entry wrap? +00F99C: D0 03 =F9A1 >344 BNE :2 ;Branch if no carry adjustment +00F99E: CE 66 FE >345 DEC h_fileCnt+1 ;Take carry from high byte of file entries +00F9A1: CE 65 FE >346 :2 DEC h_fileCnt ;Mark header with one less file +00F9A4: 20 B2 F9 >347 JSR DvcbRev ;Go update block count in VCB +00F9A7: 20 99 E4 >348 JSR ReviseDir ;Update directory last... +00F9AA: AA >349 TAX +00F9AB: 68 >350 PLA +00F9AC: 90 01 =F9AF >351 BCC :3 +00F9AE: 8A >352 TXA +00F9AF: C9 01 >353 :3 CMP #badSystemCall +00F9B1: 60 >354 RTS + >355 + >356 *------------------------------------------------- + >357 * Update free block count in VCB + >358 +00F9B2: AC A3 FE >359 DvcbRev LDY vcbPtr +00F9B5: AD D1 FE >360 LDA deBlock ;Add blks freed to +00F9B8: 79 14 D9 >361 ADC vcb+vcbFreeBlks,Y ; total free blks +00F9BB: 99 14 D9 >362 STA vcb+vcbFreeBlks,Y ;Update current free block count +00F9BE: AD D2 FE >363 LDA deBlock+1 +00F9C1: 79 15 D9 >364 ADC vcb+vcbFreeBlks+1,Y +00F9C4: 99 15 D9 >365 STA vcb+vcbFreeBlks+1,Y +00F9C7: A9 00 >366 LDA #$00 ;Force rescan for free blks +00F9C9: 99 1C D9 >367 STA vcb+vcbCurrBitMap,Y ; from first bitmap +00F9CC: 60 >368 RTS + >369 +00F9CD: 90 B6 =F985 >370 ToDstLast BCC DstryLast ;Always + >371 +00F9CF: C9 D0 >372 DestroyDir CMP #directoryFile*16 ;Is this a directory file? +00F9D1: D0 48 =FA1B >373 BNE DirCompErr ;No, report file incompatible +00F9D3: 20 31 EB >374 JSR FindBitMap ;Make sure a buffer is available for the bitmap +00F9D6: B0 42 =FA1A >375 BCS DstryDirErr + >376 +00F9D8: AD 82 FE >377 LDA d_file+d_first ;Read in first block +00F9DB: 85 46 >378 STA blockNum ; of directory into genBuf +00F9DD: AD 83 FE >379 LDA d_file+d_first+1 +00F9E0: 85 47 >380 STA blockNum+1 +00F9E2: 20 C7 EB >381 JSR RdGBuf +00F9E5: B0 33 =FA1A >382 BCS DstryDirErr + >383 +00F9E7: AD 25 DC >384 LDA genBuf+4+hFileCnt ;Find out if any files exist on this directory +00F9EA: D0 05 =F9F1 >385 BNE DstryDirAccs ;Branch if any exist +00F9EC: AD 26 DC >386 LDA genBuf+4+hFileCnt+1 +00F9EF: F0 05 =F9F6 >387 BEQ DstryDir1 +00F9F1: A9 4E >388 DstryDirAccs LDA #invalidAccess +00F9F3: 20 09 BF >389 JSR SysErr + >390 +00F9F6: 8D 04 DC >391 DstryDir1 STA genBuf+4 ;Make it an invalid subdir +00F9F9: 20 C3 EB >392 JSR WrtGBuf +00F9FC: B0 1C =FA1A >393 BCS DstryDirErr +00F9FE: AD 02 DC >394 :loop LDA genBuf+2 ;Get forward link +00FA01: C9 01 >395 CMP #$01 ;Test for no link +00FA03: AE 03 DC >396 LDX genBuf+3 +00FA06: D0 02 =FA0A >397 BNE :1 +00FA08: 90 C3 =F9CD >398 BCC ToDstLast ;If no link, then finished + >399 +00FA0A: 20 11 EA >400 :1 JSR Dealloc ;Free this block +00FA0D: B0 0B =FA1A >401 BCS DstryDirErr +00FA0F: AD 02 DC >402 LDA genBuf+2 +00FA12: AE 03 DC >403 LDX genBuf+3 +00FA15: 20 B7 EB >404 JSR RdBlkAX +00FA18: 90 E4 =F9FE >405 BCC :loop ;Loop until all are freed +00FA1A: 60 >406 DstryDirErr RTS + >407 +00FA1B: A9 4A >408 DirCompErr LDA #badFileFormat ;File is not compatible +00FA1D: 20 09 BF >409 JSR SysErr + >410 + >411 * Mark as FCB as dirty so the directory will be flushed on 'flush' + >412 +00FA20: 48 >413 FCBUsed PHA ;Save regs +00FA21: 98 >414 TYA +00FA22: 48 >415 PHA +00FA23: AC A4 FE >416 LDY fcbPtr +00FA26: B9 1C D8 >417 LDA fcb+fcbDirty,Y ;Fetch current fcbDirty byte +00FA29: 09 80 >418 ORA #fcbMod ;Mark FCB as dirty +00FA2B: 99 1C D8 >419 STA fcb+fcbDirty,Y ;Save it back +00FA2E: 68 >420 PLA +00FA2F: A8 >421 TAY ; & restore regs +00FA30: 68 >422 PLA +00FA31: 60 >423 RTS + 38 PUT mli.src/DeTree + >1 ************************************************** + >2 * "DeTree" deallocates blocks from tree files. + >3 * + >4 * It is assumed that the device preselected and the 'genBuf' may be used. + >5 * + >6 * On entry the following values must be set: + >7 * storType = storage type in upper nibble, lower nibble is undisturbed. + >8 * firstBlkL & firstBlkH = first block of file (index or data) + >9 * deBlock = 0 (see below) + >10 * dTree = ptr to 1st block with stuff to be deallocated at tree level. + >11 * dSap = ptr to 1st block at sapling level + >12 * dSeed = byte (0-511) position to be zeroed from (inclusive). + >13 * NB. There is 2 special cases when dSeed = 512 + >14 * Case 1) when EOF is set at a block boundary + >15 * Case 2) when file is destroyed + >16 * + >17 * On exit: + >18 * storType = modified result of storage type (if applicable) + >19 * firstBlkL & H = modified if storage type changed. + >20 * deBlock = total number of blocks freed at all levels. + >21 * dTree, dSap, dSeed unchanged. + >22 * + >23 * To trim a tree to a seed file, both dTree and dSap must be zero. + >24 * To go from tree to sapling, dTree alone must be zero. + >25 +00FA32: AD D0 FE >26 DeTree LDA storType ;Which flavor of tree? +00FA35: C9 20 >27 CMP #sapling*16 ;Is it a 'seed' (<=$1F) +00FA37: 90 0D =FA46 >28 BCC SeedDeAlloc ;Yes +00FA39: C9 30 >29 CMP #tree*16 ;Maybe a 'sapling'? +00FA3B: 90 14 =FA51 >30 BCC SapDeAlloc +00FA3D: C9 40 >31 CMP #{tree+1}*16 ;Well, at least be certain it's a 'tree' +00FA3F: 90 18 =FA59 >32 BCC TreeDeAlloc ;Branch if it is +00FA41: A9 0C >33 LDA #badBlockErr ;Block allocation error +00FA43: 20 0C BF >34 JSR SysDeath ;Should never have been called + >35 +00FA46: AD D4 FE >36 SeedDeAlloc LDA dSap +00FA49: 0D D3 FE >37 ORA dTree +00FA4C: D0 74 =FAC2 >38 BNE BummErr +00FA4E: 4C 29 FB >39 JMP SeedDeAlloc0 ;Trim to a seed + >40 +00FA51: AD D3 FE >41 SapDeAlloc LDA dTree +00FA54: D0 6C =FAC2 >42 BNE BummErr +00FA56: 4C F0 FA >43 JMP SapDeAlloc0 ;Trim to a sapling + >44 +00FA59: A9 80 >45 TreeDeAlloc LDA #128 +00FA5B: 8D D7 FE >46 STA topDest ;For tree top, start at end, work backwards +00FA5E: 20 53 FB >47 :loop1 JSR RdKeyBlk ;Read specified first block into genBuf +00FA61: B0 5F =FAC2 >48 BCS BummErr ;Return all errors +00FA63: AC D7 FE >49 LDY topDest ;Get current pointer to top indexes +00FA66: CC D3 FE >50 CPY dTree ;Have enough sapling indexes been deallocated? +00FA69: F0 58 =FAC3 >51 BEQ TreeDel17 ;Yes, now deallocate top guys! + >52 +00FA6B: A2 07 >53 LDX #$07 ;Buffer up to 8 sapling index block addrs +00FA6D: B9 00 DC >54 :loop2 LDA genBuf,Y ;Fetch low block address +00FA70: 9D D9 FE >55 STA deAlocBufL,X ; and save it +00FA73: 19 00 DD >56 ORA genBuf+$100,Y ;Is it a real block that is allocated? +00FA76: F0 09 =FA81 >57 BEQ :1 ;It's a phantom block +00FA78: B9 00 DD >58 LDA genBuf+$100,Y ;Fetch hi block addr +00FA7B: 9D E1 FE >59 STA deAlocBufH,X ; and save it +00FA7E: CA >60 DEX ;Decrement and test for dealoc buf filled +00FA7F: 30 12 =FA93 >61 BMI :2 ;Branch if we've fetched 8 addresses +00FA81: 88 >62 :1 DEY ;Look now for end of deallocation limit +00FA82: CC D3 FE >63 CPY dTree ;Is this the last position on tree level? +00FA85: D0 E6 =FA6D >64 BNE :loop2 ;No + >65 +00FA87: C8 >66 INY +00FA88: A9 00 >67 LDA #$00 ;Fill rest of deAloc buffer with NULL addresses +00FA8A: 9D D9 FE >68 :loop3 STA deAlocBufL,X +00FA8D: 9D E1 FE >69 STA deAlocBufH,X +00FA90: CA >70 DEX +00FA91: 10 F7 =FA8A >71 BPL :loop3 ;Loop until filled + >72 +00FA93: 88 >73 :2 DEY ;Decrement to prepare for next time +00FA94: 8C D7 FE >74 STY topDest ;save index + >75 +00FA97: A2 07 >76 LDX #$07 +00FA99: 8E D8 FE >77 :loop4 STX dTempX ;Save index to deAloc buf +00FA9C: BD D9 FE >78 LDA deAlocBufL,X +00FA9F: 85 46 >79 STA blockNum +00FAA1: 1D E1 FE >80 ORA deAlocBufH,X ;Are we finished? +00FAA4: F0 B8 =FA5E >81 BEQ :loop1 ;Branch if done with this level + >82 +00FAA6: BD E1 FE >83 LDA deAlocBufH,X ;Complete address with hi byte +00FAA9: 85 47 >84 STA blockNum+1 +00FAAB: 20 C7 EB >85 JSR RdGBuf ;Read sapling level into genBuf +00FAAE: B0 12 =FAC2 >86 BCS BummErr ;Return any errors +00FAB0: 20 8E FB >87 JSR DeAllocBlk ;Go free all data indexes in this block +00FAB3: B0 0D =FAC2 >88 BCS BummErr +00FAB5: 20 C3 EB >89 JSR WrtGBuf +00FAB8: B0 08 =FAC2 >90 BCS BummErr +00FABA: AE D8 FE >91 LDX dTempX ;Restore index to dealloc buff +00FABD: CA >92 DEX ;Are there more to free? +00FABE: 10 D9 =FA99 >93 BPL :loop4 ;Branch if there are +00FAC0: 30 9C =FA5E >94 BMI :loop1 ;Branch always to do next bunch + >95 + =FAC2 >96 deAlocTreeDone EQU * + =FAC2 >97 deAlocSapDone EQU * +00FAC2: 60 >98 BummErr RTS + >99 +00FAC3: AC D3 FE >100 TreeDel17 LDY dTree ;Now deallocate all tree level +00FAC6: C8 >101 INY ; blocks greater than specified block +00FAC7: 20 90 FB >102 JSR DeAlocBlkZ ;(tree top in genBuf) +00FACA: B0 F6 =FAC2 >103 BCS BummErr ;Report any errors +00FACC: 20 C3 EB >104 JSR WrtGBuf ;Write updated top back to disk +00FACF: B0 F1 =FAC2 >105 BCS BummErr +00FAD1: AC D3 FE >106 LDY dTree ;Now figure out if tree can become sapling +00FAD4: F0 15 =FAEB >107 BEQ :11 ;Branch if it can! + >108 +00FAD6: B9 00 DC >109 LDA genBuf,Y ;Otherwise, continue with partial +00FAD9: 85 46 >110 STA blockNum ; deallocation of last sapling index +00FADB: 19 00 DD >111 ORA genBuf+$100,Y ;Is there such a sapling index block? +00FADE: F0 E2 =FAC2 >112 BEQ deAlocTreeDone ;All done if not! +00FAE0: B9 00 DD >113 LDA genBuf+$100,Y ;Read in sapling level to be modified +00FAE3: 85 47 >114 STA blockNum+1 +00FAE5: 20 C7 EB >115 JSR RdGBuf ;Read 'highest' sapling index into genBuf +00FAE8: 90 0B =FAF5 >116 BCC SapDeAllocZ +00FAEA: 60 >117 RTS + >118 +00FAEB: 20 5C FB >119 :11 JSR Shrink ;Shrink tree to sapling +00FAEE: B0 D2 =FAC2 >120 BCS BummErr + >121 + >122 * Deallocate a sapling file + >123 +00FAF0: 20 53 FB >124 SapDeAlloc0 JSR RdKeyBlk ;Read specified only sapling level index into gbuf +00FAF3: B0 CD =FAC2 >125 BCS BummErr +00FAF5: AC D4 FE >126 SapDeAllocZ LDY dSap ;fetch pointer to last of desirable indexes +00FAF8: C8 >127 INY ;Bump to the first undesirable +00FAF9: F0 0A =FB05 >128 BEQ :21 ;branch if all are desirable +00FAFB: 20 90 FB >129 JSR DeAlocBlkZ ;Deallocate all indexes above appointed +00FAFE: B0 C2 =FAC2 >130 BCS BummErr +00FB00: 20 C3 EB >131 JSR WrtGBuf ;Update disk with remaining indexes +00FB03: B0 BD =FAC2 >132 BCS BummErr + >133 +00FB05: AC D4 FE >134 :21 LDY dSap ;Now prepare to cleanup last data block +00FB08: F0 15 =FB1F >135 BEQ :22 ;Branch if there is a posiblity of making it a seed +00FB0A: B9 00 DC >136 :loop LDA genBuf,Y ;Fetch low order data block addr +00FB0D: 85 46 >137 STA blockNum +00FB0F: 19 00 DD >138 ORA genBuf+$100,Y ;Is it a real block? +00FB12: F0 AE =FAC2 >139 BEQ deAlocSapDone ;We're done if not +00FB14: B9 00 DD >140 LDA genBuf+$100,Y +00FB17: 85 47 >141 STA blockNum+1 +00FB19: 20 C7 EB >142 JSR RdGBuf ;Go read data block into gbuf +00FB1C: 90 10 =FB2E >143 BCC SeedDeAllocZ ;Branch if good read +00FB1E: 60 >144 RTS ;Otherwise return error + >145 +00FB1F: AD D3 FE >146 :22 LDA dTree ;Are both tree and sap levels zero? +00FB22: D0 E6 =FB0A >147 BNE :loop ;Branch if not. +00FB24: 20 5C FB >148 JSR Shrink ;Reduce this sap to a seed +00FB27: B0 29 =FB52 >149 BCS BumErr1 + >150 + >151 * If no error, drop into SeedDeAlloc0 + >152 +00FB29: 20 53 FB >153 SeedDeAlloc0 JSR RdKeyBlk ;Go read only data block +00FB2C: B0 24 =FB52 >154 BCS BumErr1 ;Report any errors +00FB2E: AC D6 FE >155 SeedDeAllocZ LDY dSeed+1 ;Check hi byte for no deletion +00FB31: F0 06 =FB39 >156 BEQ :31 ;Branch if all of second page is to be deleted +00FB33: 88 >157 DEY ;If dseed>$200 then were all done! +00FB34: D0 1C =FB52 >158 BNE BumErr1 ;Branch if that's the case + >159 +00FB36: AC D5 FE >160 LDY dSeed ;Clear only bytes >= dseed +00FB39: A9 00 >161 :31 LDA #$00 +00FB3B: 99 00 DD >162 :loop1 STA genBuf+$100,Y ;Zero out unwanted data +00FB3E: C8 >163 INY +00FB3F: D0 FA =FB3B >164 BNE :loop1 +00FB41: AC D6 FE >165 LDY dSeed+1 ;Was that all? +00FB44: D0 09 =FB4F >166 BNE :32 ;Branch if it was +00FB46: AC D5 FE >167 LDY dSeed +00FB49: 99 00 DC >168 :loop2 STA genBuf,Y +00FB4C: C8 >169 INY +00FB4D: D0 FA =FB49 >170 BNE :loop2 +00FB4F: 4C C3 EB >171 :32 JMP WrtGBuf ;Update data block to disk +00FB52: 60 >172 BumErr1 RTS + >173 +00FB53: AD CE FE >174 RdKeyBlk LDA firstBlkL ;Read specified first +00FB56: AE CF FE >175 LDX firstBlkH ; block into genBbuf +00FB59: 4C B7 EB >176 JMP RdBlkAX ;Go do it! + >177 + >178 ************************************************** + >179 * Beware that dealloc may bring in a new bitmap block + >180 * and may destroy locations 46 and 47 which use to + >181 * point to the current index block. + >182 ************************************************** +00FB5C: AE CF FE >183 Shrink LDX firstBlkH ;First deallocate top block +00FB5F: 8A >184 TXA +00FB60: 48 >185 PHA +00FB61: AD CE FE >186 LDA firstBlkL +00FB64: 48 >187 PHA ;Save block address of this index block +00FB65: 20 11 EA >188 JSR Dealloc ;Go do it +00FB68: 68 >189 PLA +00FB69: 85 46 >190 STA blockNum ;Set master of sapling index block address +00FB6B: 68 >191 PLA +00FB6C: 85 47 >192 STA blockNum+1 +00FB6E: B0 1D =FB8D >193 BCS :Ret ;report any errors + >194 +00FB70: AD 00 DC >195 LDA genBuf ;Get first block at lower level +00FB73: 8D CE FE >196 STA firstBlkL +00FB76: AD 00 DD >197 LDA genBuf+$100 +00FB79: 8D CF FE >198 STA firstBlkH +00FB7C: A0 00 >199 LDY #$00 +00FB7E: 20 BD FB >200 JSR SwapMe +00FB81: 38 >201 SEC ;Now change file type, from +00FB82: AD D0 FE >202 LDA storType ; tree to sapling, +00FB85: E9 10 >203 SBC #$10 ; or from sapling to seed! +00FB87: 8D D0 FE >204 STA storType +00FB8A: 20 C3 EB >205 JSR WrtGBuf +00FB8D: 60 >206 :Ret RTS + >207 + >208 *------------------------------------------------- + >209 * Free master index/index block entries + >210 * If DeAlockBlkZ is used, (Y) must be set correctly + >211 +00FB8E: A0 00 >212 DeAllocBlk LDY #$00 ;Start at the beginning +00FB90: A5 46 >213 DeAlocBlkZ LDA blockNum ;Save disk address +00FB92: 48 >214 PHA ; of genBuf's data +00FB93: A5 47 >215 LDA blockNum+1 +00FB95: 48 >216 PHA + >217 +00FB96: 8C AF FE >218 :loop STY sapPtr ;Save current index +00FB99: B9 00 DC >219 LDA genBuf,Y ;Get address (low) of block to be deallocated +00FB9C: C9 01 >220 CMP #$01 ;Test for NULL block +00FB9E: BE 00 DD >221 LDX genBuf+$100,Y ;Get the rest of the block address +00FBA1: D0 02 =FBA5 >222 BNE :1 ;Branch if not NULL +00FBA3: 90 0B =FBB0 >223 BCC :2 ;Skip it if NULL + >224 +00FBA5: 20 11 EA >225 :1 JSR Dealloc ;Free it up on volume bitMap +00FBA8: B0 0A =FBB4 >226 BCS :3 ;Return any error +00FBAA: AC AF FE >227 LDY sapPtr ;Get index to sapling level index block again +00FBAD: 20 BD FB >228 JSR SwapMe + >229 +00FBB0: C8 >230 :2 INY ;Point at next block address +00FBB1: D0 E3 =FB96 >231 BNE :loop ;Branch if more to deallocate (or test) + >232 +00FBB3: 18 >233 CLC ;Indicate no error +00FBB4: AA >234 :3 TAX ;Save error code, if any +00FBB5: 68 >235 PLA +00FBB6: 85 47 >236 STA blockNum+1 +00FBB8: 68 >237 PLA +00FBB9: 85 46 >238 STA blockNum +00FBBB: 8A >239 TXA ;Restore return code +00FBBC: 60 >240 RTS + >241 + >242 ************************************************** + >243 * delFlag = 0 - Not called by Destroy + >244 * delFlag = 1 - Called Destroy ie swapping + >245 * Swap the Lo & Hi indices making up a disk addr + >246 * so that disk recovery programs may be able + >247 * to undelete a destroyed file + >248 +00FBBD: AD F0 FE >249 SwapMe LDA delFlag ;Are we swapping or zeroing ? +00FBC0: D0 03 =FBC5 >250 BNE :1 ;Skip if swapping +00FBC2: AA >251 TAX ;Make X a 0 +00FBC3: F0 06 =FBCB >252 BEQ :2 ;0 the index (always taken) + >253 +00FBC5: BE 00 DD >254 :1 LDX genBuf+$100,Y ;Get index, hi +00FBC8: B9 00 DC >255 LDA genBuf,Y ;Get index, lo +00FBCB: 99 00 DD >256 :2 STA genBuf+$100,Y ;Save index, hi +00FBCE: 8A >257 TXA +00FBCF: 99 00 DC >258 STA genBuf,Y ;Save index, lo +00FBD2: 60 >259 RTS ;We're done + 39 PUT mli.src/MemMgr + >1 ************************************************** + >2 * Allocate I/O buf + >3 +00FBD3: A0 04 >4 AllocBuf LDY #c_bufPtr+1 ;Index to user specified buffer +00FBD5: B1 40 >5 AllocBufZ LDA (parm),Y ;This buffer must be on a page boundary +00FBD7: AA >6 TAX ;Save in X-reg for validation +00FBD8: C9 08 >7 CMP #$08 +00FBDA: 90 42 =FC1E >8 BCC BadBufr ;Cannot be lower than video! +00FBDC: C9 BC >9 CMP #$BC ;Nor greater than $BB00 +00FBDE: B0 3E =FC1E >10 BCS BadBufr ; since it would wipe out globals... +00FBE0: 85 4B >11 STA dataPtr+1 +00FBE2: 88 >12 DEY +00FBE3: B1 40 >13 LDA (parm),Y ;Low addr should be zero! +00FBE5: 85 4A >14 STA dataPtr +00FBE7: D0 35 =FC1E >15 BNE BadBufr ;Branch if it isn't +00FBE9: E8 >16 INX ;Add 4 pages for 1K buffer +00FBEA: E8 >17 INX +00FBEB: E8 >18 INX +00FBEC: E8 >19 INX +00FBED: CA >20 :loop1 DEX ;Test for conflicts +00FBEE: 20 56 FC >21 JSR CalcMemBit ;Test for free buffer space +00FBF1: 39 58 BF >22 AND memTabl,Y ;Report memory conflict +00FBF4: D0 28 =FC1E >23 BNE BadBufr ; if any... +00FBF6: E4 4B >24 CPX dataPtr+1 ;Test all four pages +00FBF8: D0 F3 =FBED >25 BNE :loop1 +00FBFA: E8 >26 INX ;Add 4 pages again for allocation +00FBFB: E8 >27 INX +00FBFC: E8 >28 INX +00FBFD: E8 >29 INX + >30 +00FBFE: CA >31 :loop2 DEX ;Set proper bits to 1 +00FBFF: 20 56 FC >32 JSR CalcMemBit +00FC02: 19 58 BF >33 ORA memTabl,Y ; to mark it's allocation +00FC05: 99 58 BF >34 STA memTabl,Y +00FC08: E4 4B >35 CPX dataPtr+1 ;Set all four pages +00FC0A: D0 F2 =FBFE >36 BNE :loop2 + >37 +00FC0C: AC A4 FE >38 LDY fcbPtr ;Now calculate buffer number +00FC0F: B9 00 D8 >39 LDA fcb+fcbRefNum,Y +00FC12: 0A >40 ASL ;buffer number=(entnum)*2 +00FC13: 99 0B D8 >41 STA fcb+fcbFileBuf,Y ;Save it in FCB +00FC16: AA >42 TAX ;Use entnum*2 as index to global buffer addr tables +00FC17: A5 4B >43 LDA dataPtr+1 ;Get addr already validated as good +00FC19: 9D 6F BF >44 STA GblBuf-1,X ;Store hi addr (entnums start at 1, not zero) +00FC1C: 18 >45 CLC +00FC1D: 60 >46 RTS ;All done allocating buffers + >47 +00FC1E: A9 56 >48 BadBufr LDA #badBufErr ;Tell user buf is in use or not legal otherwise +00FC20: 38 >49 SEC ;Indicate error +00FC21: 60 >50 RTS + >51 + >52 ************************************************** + >53 * Locate ptr to I/O buf in global page + >54 +00FC22: AA >55 GetBufAdr TAX ;Index into global buffer table +00FC23: BD 6E BF >56 LDA GblBuf-2,X ;Low buffer addr +00FC26: 8D EC FE >57 STA bufAddrL +00FC29: BD 6F BF >58 LDA GblBuf-1,X ;and high addr +00FC2C: 8D ED FE >59 STA bufAddrH +00FC2F: 60 >60 RTS + >61 + >62 ************************************************** + >63 * Free I/O buf + >64 +00FC30: 20 22 FC >65 ReleaseBuf JSR GetBufAdr ;Preserve buf adr in 'bufAddr' +00FC33: A8 >66 TAY ;Returns high buffer addr in A +00FC34: F0 1E =FC54 >67 BEQ RelBufX ;Branch if unallocated buffer space + >68 +00FC36: 9E 6F BF >69 STZ GblBuf-1,X ;Take address out of buffer list +00FC39: 9E 6E BF >70 STZ GblBuf-2,X ;(X was set up by GetBufAdr) + >71 +00FC3C: AE ED FE >72 FreeBuf LDX bufAddrH ;Get hi addr of buffer again +00FC3F: E8 >73 INX ;Add 4 pages to account for 1k space +00FC40: E8 >74 INX +00FC41: E8 >75 INX +00FC42: E8 >76 INX +00FC43: CA >77 :loop DEX ;Drop to next lower page +00FC44: 20 56 FC >78 JSR CalcMemBit ;Get bit and posn to memTabl of this page +00FC47: 49 FF >79 EOR #$FF ;Invert mask +00FC49: 39 58 BF >80 AND memTabl,Y ;Mark addr as free space now +00FC4C: 99 58 BF >81 STA memTabl,Y +00FC4F: EC ED FE >82 CPX bufAddrH ;All pages freed yet? +00FC52: D0 EF =FC43 >83 BNE :loop ;Branch if not +00FC54: 18 >84 RelBufX CLC ;Indicate no error +00FC55: 60 >85 RTS + >86 + >87 ************************************************** + >88 * Calculate memory allocation bit position + >89 * entry: (X)=hi addr of buffer, low addr assumed zero. + >90 * + >91 * exit: (A)=allocation bit mask, (X)=unchanged, + >92 * (Y)=pointer to memTabl byte + >93 +00FC56: 8A >94 CalcMemBit TXA ;Move page address to A +00FC57: 29 07 >95 AND #$07 ;Which page in any 2k set? +00FC59: A8 >96 TAY ;Use as index to determine +00FC5A: B9 26 FE >97 LDA WhichBit,Y ; bit position representation +00FC5D: 48 >98 PHA ;Save bit position mask for now +00FC5E: 8A >99 TXA ;Get page address again +00FC5F: 4A >100 LSR +00FC60: 4A >101 LSR ;Now determine 2K set +00FC61: 4A >102 LSR +00FC62: A8 >103 TAY ;Return it in Y +00FC63: 68 >104 PLA ;Restore bit mask +00FC64: 60 >105 RTS ;Return bit position in A&Y, ptr to memtabl in X + >106 + >107 ************************************************** + >108 * Check buffer validity + >109 +00FC65: A5 4F >110 ValDBuf LDA userBuf+1 ;Get high addr of user's buffer +00FC67: C9 02 >111 CMP #$02 ;Must be greater than page 2 +00FC69: 90 B3 =FC1E >112 BCC BadBufr ;Report bad buffer +00FC6B: AE EA FE >113 LDX cBytes+1 +00FC6E: AD E9 FE >114 LDA cBytes ;Get cbytes-1 value +00FC71: E9 01 >115 SBC #$01 ;(carry is set) +00FC73: B0 01 =FC76 >116 BCS :1 +00FC75: CA >117 DEX +00FC76: 18 >118 :1 CLC +00FC77: 65 4E >119 ADC userBuf ;Calculate end of request addr +00FC79: 8A >120 TXA ;Do hi addr +00FC7A: 65 4F >121 ADC userBuf+1 ;All we care about is final addr +00FC7C: AA >122 TAX ;Must be less than $BF (globals) +00FC7D: E0 BF >123 CPX #$BF +00FC7F: B0 9D =FC1E >124 BCS BadBufr +00FC81: E8 >125 INX ;Loop thru all affected pages + >126 +00FC82: CA >127 ValDBufZ DEX ;Check next lower page +00FC83: 20 56 FC >128 JSR CalcMemBit +00FC86: 39 58 BF >129 AND memTabl,Y ;If zero then no conflict +00FC89: D0 93 =FC1E >130 BNE BadBufr ;Branch if conflict... +00FC8B: E4 4F >131 CPX userBuf+1 ;Was that the last (lowest) page? +00FC8D: D0 F3 =FC82 >132 BNE ValDBufZ ;Branch if not +00FC8F: 18 >133 CLC ;Indicate all pages ok +00FC90: 60 >134 RTS ;All done here + >135 + >136 ************************************************** + >137 * GETBUF Call + >138 +00FC91: A0 02 >139 GetBuf LDY #c_bufAdr ;Give user address of file buffer +00FC93: AD EC FE >140 LDA bufAddrL ; referenced by refnum +00FC96: 91 40 >141 STA (parm),Y +00FC98: C8 >142 INY +00FC99: AD ED FE >143 LDA bufAddrH +00FC9C: 91 40 >144 STA (parm),Y ;No errors possible if this rtn is called +00FC9E: 18 >145 CLC +00FC9F: 60 >146 RTS + >147 + >148 ************************************************** + >149 * SETBUF Call + >150 +00FCA0: A0 03 >151 SetBuf LDY #c_bufAdr+1 +00FCA2: 20 D5 FB >152 JSR AllocBufZ ;Allocate new buffer address over old one +00FCA5: B0 20 =FCC7 >153 BCS SetBufErr ;Report any conflicts immediately + >154 +00FCA7: AD ED FE >155 LDA bufAddrH +00FCAA: 85 4F >156 STA userBuf+1 +00FCAC: AD EC FE >157 LDA bufAddrL +00FCAF: 85 4E >158 STA userBuf +00FCB1: 20 3C FC >159 JSR FreeBuf ;Now free address space of old buffer + >160 +00FCB4: A0 00 >161 LDY #$00 +00FCB6: A2 03 >162 LDX #$03 +00FCB8: B1 4E >163 :loop LDA (userBuf),Y ;Move all four pages of +00FCBA: 91 4A >164 STA (dataPtr),Y ; the buffer to new location +00FCBC: C8 >165 INY +00FCBD: D0 F9 =FCB8 >166 BNE :loop +00FCBF: E6 4B >167 INC dataPtr+1 +00FCC1: E6 4F >168 INC userBuf+1 +00FCC3: CA >169 DEX +00FCC4: 10 F2 =FCB8 >170 BPL :loop +00FCC6: 18 >171 CLC +00FCC7: 60 >172 SetBufErr RTS + >173 + >174 ************************************************** + >175 * + >176 * This is the routine that moves the 3 pages of dispatcher 1 + >177 * from $D100 of the alt 4k bank to its execution address ($1000). + >178 * Since it is in the MLI and must swap the $D000-$DFFF banks, + >179 * it must be resident at all times above $E000. + >180 * + >181 ************************************************** + >182 + >183 * NB. There is a vector @ $FEFD which points to this rtn + >184 +00FCC8: AD 83 C0 >185 CallDisp LDA LCBANK2 +00FCCB: AD 83 C0 >186 LDA LCBANK2 ;Bring in the other $D000 space +00FCCE: A9 10 >187 LDA #>DispAdr ;Destination address of user-code +00FCD0: 85 3F >188 STA A2+1 +00FCD2: A9 00 >189 LDA #190 STA A2 +00FCD6: A9 D1 >191 LDA #$D1 ;Dispatcher is stored at $D100-$D3FF +00FCD8: 85 3D >192 STA A1+1 +00FCDA: 64 3C >193 STZ A1 + >194 +00FCDC: A0 00 >195 LDY #$00 +00FCDE: A2 03 >196 LDX #$03 ;3 pages of code to move +00FCE0: 88 >197 MovPage DEY ;Nifty routine to move a page of code +00FCE1: B1 3C >198 LDA (A1),Y ;Move all 255 bytes on the page +00FCE3: 91 3E >199 STA (A2),Y +00FCE5: 98 >200 TYA +00FCE6: D0 F8 =FCE0 >201 BNE MovPage +00FCE8: E6 3D >202 INC A1+1 ;Move pointers to next page +00FCEA: E6 3F >203 INC A2+1 +00FCEC: CA >204 DEX +00FCED: D0 F1 =FCE0 >205 BNE MovPage + >206 +00FCEF: AD 8B C0 >207 LDA LCBANK1 +00FCF2: AD 8B C0 >208 LDA LCBANK1 ;Swap MLI's $D000 space back in + >209 +00FCF5: 9C 9B BF >210 STZ mliActv +00FCF8: 9C F2 03 >211 STZ SOFTEV ;Set up the reset vector +00FCFB: A9 10 >212 LDA #>DispAdr +00FCFD: 8D F3 03 >213 STA SOFTEV+1 ; to dispatch entry +00FD00: 49 A5 >214 EOR #$A5 ;Set up power up byte +00FD02: 8D F4 03 >215 STA PWREDUP +00FD05: 4C 00 10 >216 JMP DispAdr + >217 + >218 ************************************************** + >219 * Handles calls to mirror devices + >220 * ProDOS unit #s are of the form DSSS xxxx + >221 * where the bits of the low nibble are the + >222 * attributes of the device. + >223 * D=0/1 (drive 1/drive 2) + >224 * The handler only supports 14 mirror devices + >225 * A statusCmd ($00) call will return the # + >226 * of blocks in (Y,X) + >227 +00FD08: A2 03 >228 MirrorDevEntry LDX #$03 ;Default parm cnt +00FD0A: A5 42 >229 LDA dhpCmd ;Get cmd +00FD0C: 8D 4A FD >230 STA spCmdNum +00FD0F: D0 0A =FD1B >231 BNE :1 + >232 +00FD11: A0 EC >233 LDY #234 STY bufPtr +00FD15: A0 D6 >235 LDY #>spStatList +00FD17: 84 45 >236 STY bufPtr+1 +00FD19: 64 46 >237 STZ blockNum +00FD1B: C9 03 >238 :1 CMP #$03 ;FormatCmd? +00FD1D: D0 02 =FD21 >239 BNE :2 ;No + >240 +00FD1F: A2 01 >241 LDX #$01 ;parm cnt for a formatCmd +00FD21: 8E 8D FD >242 :2 STX spCmdList +00FD24: A5 43 >243 LDA unitNum ;(dsss 0000) +00FD26: 4A >244 LSR +00FD27: 4A >245 LSR +00FD28: 4A >246 LSR +00FD29: 4A >247 LSR +00FD2A: AA >248 TAX ;0000 dsss ($01-$0F; $00,$08,$0B-invalid) +00FD2B: BD EF D6 >249 LDA spUnits-1,X ;Get actual SP unit # which +00FD2E: 8D 8E FD >250 STA spUnitNum ; corr to this ProDOS unit # +00FD31: BD 6E FD >251 LDA spDrvAdrL-1,X +00FD34: 8D 48 FD >252 STA CallSPort+1 ;Get addr of SP dev driver +00FD37: BD 7D FD >253 LDA spDrvAdrH-1,X +00FD3A: 8D 49 FD >254 STA CallSPort+2 ; which handles this SP unit + >255 +00FD3D: A2 04 >256 LDX #$04 +00FD3F: B5 43 >257 :CpyLoop LDA bufPtr-1,X +00FD41: 9D 8E FD >258 STA blkIOParms-1,X +00FD44: CA >259 DEX +00FD45: D0 F8 =FD3F >260 BNE :CpyLoop + >261 +00FD47: 20 00 00 >262 CallSPort JSR $0000 ;Go do it! +00FD4A: 00 >263 spCmdNum DB $00 +00FD4B: 8D FD >264 DA spCmdList +00FD4D: B0 1F =FD6E >265 BCS :Rtn + >266 +00FD4F: AE 4A FD >267 LDX spCmdNum ;Was a SP STATUS call executed? +00FD52: D0 1A =FD6E >268 BNE :Rtn ;No +00FD54: AE ED D6 >269 LDX spDevTotBlks ;# of blocks +00FD57: AC EE D6 >270 LDY spDevTotBlks+1 +00FD5A: AD EC D6 >271 LDA genStatus +00FD5D: 89 10 >272 BIT #$10 ;Is dev online/disk in drive? +00FD5F: D0 04 =FD65 >273 BNE :1 ;Yes +00FD61: A9 2F >274 LDA #drvrOffLine +00FD63: 80 08 =FD6D >275 BRA :2 + >276 +00FD65: 29 44 >277 :1 AND #$44 ;Retain bits 6,2 +00FD67: 49 40 >278 EOR #$40 ;Is it write-protected? +00FD69: F0 03 =FD6E >279 BEQ :Rtn ;No +00FD6B: A9 2B >280 LDA #drvrWrtProt +00FD6D: 38 >281 :2 SEC +00FD6E: 60 >282 :Rtn RTS + >283 + >284 *------------------------------------------------- + >285 * This table was built during a P8 boot + >286 +00FD6F: 00 00 00 00 >287 spDrvAdrL DS $F,0 ;Actual entry points +00FD7E: 00 00 00 00 >288 spDrvAdrH DS $F,0 ; of a device's driver + >289 + >290 * Command List used for all 4 commands viz + >291 * 0-Status, 1-Read Block, 2-Write Block, 3-Format + >292 * The caller must pass the parms using the + >293 * usual zp locations $42-$47 + >294 +00FD8D: 03 >295 spCmdList DB $03 ;parm count +00FD8E: 00 >296 spUnitNum DB $00 ;unit # +00FD8F: 00 00 >297 blkIOParms DA $0000 ;Data I/O buf +00FD91: 00 00 00 >298 blokNum DB 0,0,0 ;blk # (only 2 bytes used) + 40 PUT mli.src/DataTbls + >1 *********************************************************** + >2 * ---- Added call $41 & its count - see rev note 20 -------- + >3 + =FD94 >4 scNums EQU * +00FD94: D3 00 00 00 >5 DFB $D3,0,0,0 ;(zeros are reserved for bfm) +00FD98: 40 41 00 00 >6 DFB $40,$41,$00,0 ;(zero is reserved for interrupt calls) +00FD9C: 80 81 82 65 >7 DFB $80,$81,$82,$65 +00FDA0: C0 C1 C2 C3 >8 DFB $C0,$C1,$C2,$C3 +00FDA4: C4 C5 C6 C7 >9 DFB $C4,$C5,$C6,$C7 +00FDA8: C8 C9 CA CB >10 DFB $C8,$C9,$CA,$CB +00FDAC: CC CD CE CF >11 DFB $CC,$CD,$CE,$CF +00FDB0: 00 D0 D1 D2 >12 DFB $00,$D0,$D1,$D2 ;zero is non-existent. + >13 + =FDB4 >14 pCntTbl EQU * ;parameter counts for the calls +00FDB4: 02 FF FF FF >15 HEX 02FFFFFF +00FDB8: 02 01 FF FF >16 HEX 0201FFFF +00FDBC: 03 03 00 04 >17 HEX 03030004 +00FDC0: 07 01 02 07 >18 HEX 07010207 +00FDC4: 0A 02 01 01 >19 HEX 0A020101 +00FDC8: 03 03 04 04 >20 HEX 03030404 +00FDCC: 01 01 02 02 >21 HEX 01010202 +00FDD0: FF 02 02 02 >22 HEX FF020202 + >23 + >24 *------------------------------------------------- + >25 * JMP table + >26 + =FDD4 >27 cmdTable EQU * +00FDD4: F1 E2 >28 DA Create +00FDD6: 1D F9 >29 DA Destroy +00FDD8: DC F7 >30 DA Rename +00FDDA: A5 F7 >31 DA SetInfo +00FDDC: 43 F7 >32 DA GetInfo +00FDDE: 21 E2 >33 DA Online +00FDE0: 24 E1 >34 DA SetPrefix +00FDE2: 7C E1 >35 DA GetPrefix +00FDE4: 97 EE >36 DA Open +00FDE6: 31 F7 >37 DA NewLine +00FDE8: CB EF >38 DA Read +00FDEA: 4F F2 >39 DA Write +00FDEC: 49 F4 >40 DA Close +00FDEE: B8 F4 >41 DA Flush +00FDF0: 01 EC >42 DA SetMark +00FDF2: EB EB >43 DA GetMark +00FDF4: CE F5 >44 DA SetEOF +00FDF6: 1F F7 >45 DA GetEOF +00FDF8: A0 FC >46 DA SetBuf +00FDFA: 91 FC >47 DA GetBuf + >48 + >49 *------------------------------------------------- + >50 * Function bits for MLI codes $C0-$D3 + >51 + =FDFC >52 Dispatch EQU * +00FDFC: A0 >53 DB prePath+preTime+0 ;create +00FDFD: A1 >54 DB prePath+preTime+1 ;destroy +00FDFE: A2 >55 DB prePath+preTime+2 ;rename +00FDFF: A3 >56 DB prePath+preTime+3 ;setinfo +00FE00: 84 >57 DB prePath+4 ;getinfo +00FE01: 05 >58 DB $05 ;volume +00FE02: 06 >59 DB $06 ;setprefix, pathname moved to prefix buffer +00FE03: 07 >60 DB $07 ;getprefix +00FE04: 88 >61 DB prePath+8 ;open +00FE05: 49 >62 DB preRef+$9 ;newline +00FE06: 4A >63 DB preRef+$a ;read +00FE07: 4B >64 DB preRef+$b ;write +00FE08: 2C >65 DB preTime+$c ;close +00FE09: 2D >66 DB preTime+$d ;flush, refnum may be zero to flush all +00FE0A: 4E >67 DB preRef+$e ;setmark +00FE0B: 4F >68 DB preRef+$f ;getmark +00FE0C: 50 >69 DB preRef+$10 ;set eof +00FE0D: 51 >70 DB preRef+$11 ;get eof +00FE0E: 52 >71 DB preRef+$12 ;set buffer address (move) +00FE0F: 53 >72 DB preRef+$13 ;get buffer address + >73 + >74 *------------------------------------------------- + >75 * Constants + >76 +00FE10: 01 00 00 02 >77 dIncTbl DB 1,0,0,2,0 ;Table to increment directory usage/EOF counts +00FE15: 75 >78 Pass DB $75 +00FE16: 00 00 C3 27 >79 XDOSver DB $0,0,$C3,$27,$0D,0,0,0 + =FE17 >80 compat EQU XDOSver+1 + >81 +00FE1E: 0F 02 00 04 >82 rootStuff DB $0F,2,0,4 +00FE22: 00 00 08 00 >83 DB 0,0,8,0 + >84 +00FE26: 80 40 20 10 >85 WhichBit HEX 8040201008040201 + >86 + >87 * The following table is used in the 'Open:loop1' (posn/open). + >88 * Offsets into file control blocks (FCBs) + >89 +00FE2E: 0C 0D 18 19 >90 oFCBTbl DFB fcbFirst,fcbFirst+1,fcbBlksUsed,fcbBlksUsed+1 +00FE32: 15 16 17 >91 DFB fcbEOF,fcbEOF+1,fcbEOF+2 + >92 + >93 * Set/Get file info offsets + >94 * The following with $80+ are ignored by SetInfo + >95 +00FE35: 1E 10 1F 20 >96 InfoTabl DFB d_attr,d_fileID,d_auxID,d_auxID+1 +00FE39: 80 93 94 21 >97 DFB $80+d_stor,$80+d_usage,$80+d_usage+1,d_modDate +00FE3D: 22 23 24 18 >98 DFB d_modDate+1,d_modTime,d_modTime+1,d_creDate +00FE41: 19 1A 1B >99 DFB d_creDate+1,d_creTime,d_creTime+1 + >100 +00FE44: 20 >101 Death ASC ' ' +00FE45: D2 C5 D3 D4 >102 ASC "RESTART SYSTEM-$01" +00FE57: 20 >103 ASC ' ' + 41 PUT mli.src/WrkSpace + >1 *********************************************************** + >2 * Global Data + >3 +00FE58: 00 00 >4 ownersBlock DW $0000 +00FE5A: 00 >5 ownersEnt DB $00 +00FE5B: 00 >6 ownersLen DB $00 + >7 + >8 *------------------------------------------------- + >9 * Part of volume dir header + >10 +00FE5C: 00 00 >11 h_creDate DW $0000 ;Directory creation date +00FE5E: 00 00 >12 DW $0000 ;Directory creation time +00FE60: 00 >13 DB $00 ;Version under which this directory was created +00FE61: 00 >14 DB $00 ;Earliest version that it's compatible with +00FE62: 00 >15 h_attr DB $00 ;Attributes (protect bit, etc.) +00FE63: 00 >16 h_entLen DB $00 ;Length of each entry in this dir +00FE64: 00 >17 h_maxEnt DB $00 ;Maximum # of entries per block +00FE65: 00 00 >18 h_fileCnt DW $0000 ;Current # of files in this dir +00FE67: 00 00 >19 h_bitMap DW $0000 ;Disk Addr of first allocation bit map +00FE69: 00 00 >20 h_totBlk DW $0000 ;Total number of blocks on this unit + >21 +00FE6B: 00 >22 d_dev DB $00 ;Device number of this directory entry +00FE6C: 00 00 >23 d_head DW $0000 ;Disk Addr of directory header +00FE6E: 00 00 >24 d_entBlk DW $0000 ;Disk Addr of block which contains this entry +00FE70: 00 >25 d_entNum DB $00 ;Entry number within block + >26 + >27 *------------------------------------------------- + >28 * Layout of file entry + >29 + =FE71 >30 d_file EQU * + =0000 >31 d_stor EQU *-d_file +00FE71: 00 >32 DB $00 ;storage type * 16 + file name length +00FE72: 00 00 00 00 >33 DS 15,0 ;file name + =0010 >34 d_fileID EQU *-d_file +00FE81: 00 >35 DB $00 ;User's identification byte + =0011 >36 d_first EQU *-d_file +00FE82: 00 00 >37 DW $0000 ;First block of file + =0013 >38 d_usage EQU *-d_file +00FE84: 00 00 >39 DW $0000 ;# of blks currently allocated to this file + =0015 >40 d_eof EQU *-d_file +00FE86: 00 00 00 >41 DB 0,0,0 ;Current end of file marker + =0018 >42 d_creDate EQU *-d_file +00FE89: 00 00 >43 DW $0000 ;date of file's creation + =001A >44 d_creTime EQU *-d_file +00FE8B: 00 00 >45 DW $0000 ;time of file's creation + =001C >46 d_sosVer EQU *-d_file +00FE8D: 00 >47 DB $00 ;SOS version that created this file + =001D >48 d_comp EQU *-d_file +00FE8E: 00 >49 DB $00 ;Backward version compatablity + =001E >50 d_attr EQU *-d_file +00FE8F: 00 >51 DB $00 ;'protect', read/write 'enable' etc. + =001F >52 d_auxID EQU *-d_file +00FE90: 00 00 >53 DW $0000 ;User auxillary identification + =0021 >54 d_modDate EQU *-d_file +00FE92: 00 00 >55 DW $0000 ;File's last modification date + =0023 >56 d_modTime EQU *-d_file +00FE94: 00 00 >57 DW $0000 ;File's last modification time + =0025 >58 d_dHdr EQU *-d_file +00FE96: 00 00 >59 DW $0000 ;Header block address of file's directory + >60 + >61 *------------------------------------------------- + >62 +00FE98: 00 00 00 00 >63 scrtch DS 4,0 ;Scratch area for allocation address conversion +00FE9C: 00 00 00 >64 oldEOF DS 3,0 ;Temp used in w/r +00FE9F: 00 00 00 >65 oldMark DS 3,0 ;Used by 'RdPosn' and 'Write' + >66 +00FEA2: 00 >67 xvcbPtr DB $00 ;Used in 'cmpvcb' as a temp +00FEA3: 00 >68 vcbPtr DB $00 ;Offset into VCB table +00FEA4: 00 >69 fcbPtr DB $00 ;Offset into FCB table +00FEA5: 00 >70 fcbFlg DB $00 ;This is a flag to indicate a free FCB is available + >71 +00FEA6: 00 >72 reqL DB $00 ;# of free blks required +00FEA7: 00 >73 reqH DB $00 +00FEA8: 00 >74 levels DB $00 ;Storage type (seedling,sapling etc) + >75 + >76 * # of entries examined or + >77 * used as a flag to indicate file is already open + >78 +00FEA9: 00 >79 totEnt DB $00 ;(0=open) +00FEAA: 00 00 >80 entCnt DW $0000 ;File count + >81 + >82 * entries/block loop count or + >83 * as a temp to return the refnum of a free FCB + >84 +00FEAC: 00 >85 cntEnt DB $00 + >86 + >87 * Free entry found flag (if > 0) + >88 * # of 1st bitMap block with free bit on + >89 * or bit for free + >90 +00FEAD: 00 >91 noFree DB $00 + >92 + >93 *------------------------------------------------- + >94 * Variable work area + >95 +00FEAE: 00 >96 bmCnt DB $00 ;# in bitMap left to search +00FEAF: 00 >97 sapPtr DB $00 +00FEB0: 00 >98 pathCnt DB $00 ;Pathname len +00FEB1: 00 >99 pathDev DB $00 ;Dev num for prefix dir header +00FEB2: 00 00 >100 pathBlok DW $0000 ;Block of prefix dir header +00FEB4: 00 >101 bmPtr DB $00 ;VBM byte offset in page +00FEB5: 00 >102 basVal DB $00 ;VBM page offset +00FEB6: 00 >103 half DB $00 ;VBM buf page (0 or 1) + >104 + >105 * bit map info tables (a & b) + >106 +00FEB7: 00 >107 bmaStat DB $00 ;VBM flag (If $80, needs writing) +00FEB8: 00 >108 bmaDev DB $00 ;VBM device +00FEB9: 00 00 >109 bmaDskAdr DW $00 ;VBM blk number +00FEBB: 00 >110 bmaCurrMap DB $00 ;bitMap blk offset for multiblk VBM + >111 + >112 * New mark to be positioned to for SetMark + >113 * or new moving mark (for Read) + >114 * or new EOF for SETEOF + >115 +00FEBC: 00 >116 tPosll DB $00 +00FEBD: 00 >117 tPoslh DB $00 +00FEBE: 00 >118 tPosHi DB $00 +00FEBF: 00 >119 rwReqL DB $00 ;Request count (R/W etc) +00FEC0: 00 >120 rwReqH DB $00 +00FEC1: 00 >121 nlChar DB $00 +00FEC2: 00 >122 nlMask DB $00 +00FEC3: 00 >123 ioAccess DB $00 ;Has a call been made to disk device handler? + =FEC4 >124 bulkCnt EQU * +00FEC4: 00 >125 cmdTmp DB $00 ;Test refnum, time, and dskswtch for (pre)processing + >126 +00FEC5: 00 >127 bkBitFlg DB $00 ;Used for ReviseDir to set or clear back up bit +00FEC6: 00 >128 duplFlag DB $00 ;Difference between volNotFound and dupVol by synPath +00FEC7: 00 >129 vcbEntry DB $00 ;Pointer to current VCB entry + >130 + >131 * xdos temporaries added.... + >132 +00FEC8: 00 >133 namCnt DB $00 ;ONLINE: vol len - loop index + >134 + >135 * Characters in current pathname index level or + >136 * New pathname : index to last name + >137 +00FEC9: 00 >138 rnPtr DB $00 + =FECA >139 pnPtr EQU * ; Old pathname: index to last name or +00FECA: 00 >140 namPtr DB $00 ;ONLINE: index to data buffer +00FECB: 00 >141 vnPtr DB $00 ;Old PfixPtr value +00FECC: 00 >142 prfxFlg DB $00 ;Pathname fully qualified flag (if $FF) + =FECD >143 clsFlshErr EQU * ;Close-all err code +00FECD: 00 >144 tempX DB $00 ;ONLINE: devcnt + >145 + >146 * The following are used for deallocation temps. + >147 +00FECE: 00 >148 firstBlkL DB $00 +00FECF: 00 >149 firstBlkH DB $00 +00FED0: 00 >150 storType DB $00 +00FED1: 00 00 >151 deBlock DW $0000 ;Count of freed blks +00FED3: 00 >152 dTree DB $00 ;EOFblk # (MSB) +00FED4: 00 >153 dSap DB $00 ;EOFblk # (LSB) +00FED5: 00 00 >154 dSeed DW $0000 ;EOF byte offset into blk +00FED7: 00 >155 topDest DB $00 ;EOF-master index counter +00FED8: 00 >156 dTempX DB $00 ;ONLINE: devcnt + >157 + >158 * Device table built by Online + >159 * Also used by SetEOF to keep track + >160 * of 8 blks to be freed at a time + >161 +00FED9: 00 00 00 00 >162 deAlocBufL DS 8,0 +00FEE1: 00 00 00 00 >163 deAlocBufH DS 8,0 + >164 + =FED9 >165 lookList EQU deAlocBufL + >166 +00FEE9: 00 00 >167 cBytes DW $0000 ;Len of path, etc +00FEEB: 00 >168 DB $00 ;cbytes+2 must always be zero. See "CalcMark" +00FEEC: 00 >169 bufAddrL DB $00 +00FEED: 00 >170 bufAddrH DB $00 ;Buffer allocation, getbuffr, and release buffer temps. +00FEEE: 00 00 >171 goAdr DA $0000 ;Jump vector used for indirect JMP +00FEF0: 00 >172 delFlag DB $00 ;Used by DeTree to know if called from delete +00FEF1: 00 00 00 00 >173 DS $FEFD-*,0 + =FEFD >174 dispVect EQU * +00FEFD: C8 FC >175 DA CallDisp ;Dispatcher/Selector + >176 + >177 * This flag is set in the loader indicating + >178 * whether the machine is a cortland + >179 +00FEFF: 00 >180 cortFlag DB 0 ;0=>non-cortland / 1=>cortland + 42 PUT mli.src/RAM0 + >1 ************************************************************ + >2 * * + >3 * PRODOS 8 KERNEL 59.5K RAMDISK (REV-E) * + >4 * * + >5 * COPYRIGHT APPLE COMPUTER, INC., 1983-86 * + >6 * * + >7 * ALL RIGHTS RESERVED * + >8 * * + >9 ************************************************************ + >10 + >11 * This module consist of 3 object files + >12 + >14 + >15 ORG EnterCard + >16 MX %11 + >17 * After the main routine has determined that the command + >18 * is ok, and the block to be read/written is within + >19 * range, it tranfers control to this routine. This routine + >20 * remaps the block requested as follows: + >21 * Request blocks 0,1 :invalid + >22 * 2 :returns VDIR (card block 3) + >23 * 3 :returns bitmap (synthesized) + >24 * 4 :returns card block 0 + >25 * $05-$5F :returns card blocks $05-$5F + >26 * $60-$67 :returns blocks $68-$7F in bank 1 of + >27 * card's language card + >28 * $68-$7F :returns blocks $68-$7F in bank 2 + >29 * of card's language card + >30 * +000200: AD 18 C0 >31 DoCmd LDA RD80COL ;Read 80STORE +000203: 48 >32 PHA ;Save for later +000204: 8D 00 C0 >33 STA CLR80COL ;Turn off 80STORE + >34 +000207: A2 04 >35 LDX #$04 ;Move the params for our use +000209: B5 42 >36 :loop LDA $42,X ;CMD,UNIT,BUFPTR,&BLOCK(lo) +00020B: 9D BD 03 >37 STA tCmd,X ;->tCmd,tUnit,R2L,R2,R1 +00020E: CA >38 DEX +00020F: 10 F8 =0209 >39 BPL :loop + >40 +000211: 2D BC 03 >41 AND FormatFlag ;Format the volume first time +000214: D0 39 =024F >42 BNE doCommand ; thru, or when requested + >43 +000216: A6 46 >44 doFormat LDX blockNum ;Save R1 during format +000218: A9 0E >45 LDA #>VBlock1 ;Block to be cleared +00021A: 20 33 03 >46 JSR ClrBuf1 ;ClrBuf clears all buffers +00021D: A0 03 >47 LDY #$03 ;Format volume in 2 chunks +00021F: B9 D2 03 >48 :loop1 LDA VDir,Y +000222: 99 04 0E >49 STA VBlock1+4,Y +000225: 88 >50 DEY +000226: 10 F7 =021F >51 BPL :loop1 + >52 +000228: A9 FE >53 LDA #$FE ;Set last block as unusable to protect vectors +00022A: 8D D1 03 >54 STA BitMap+$F +00022D: 98 >55 TYA ;Set bitmap bits to $FF +00022E: A0 0E >56 LDY #$0E ;15 bytes to set +000230: 99 C2 03 >57 :loop2 STA BitMap,Y +000233: 88 >58 DEY +000234: D0 FA =0230 >59 BNE :loop2 +000236: 8C C2 03 >60 STY BitMap ;First byte=0 + >61 +000239: A0 07 >62 LDY #$07 ;Do other chunk +00023B: B9 D6 03 >63 :loop3 LDA Access,Y +00023E: 99 22 0E >64 STA VBlock1+34,Y +000241: 88 >65 DEY +000242: 10 F7 =023B >66 BPL :loop3 + >67 +000244: AD BC 03 >68 LDA FormatFlag ;If 0, set to FF +000247: D0 61 =02AA >69 BNE DFX ;else exitcard + >70 +000249: 8C BC 03 >71 STY FormatFlag ;Y=FF, won't format next time +00024C: 8E C1 03 >72 STX R1 ;restore R1 + >73 + >74 * Now use the requested block number to determine + >75 * which routine performs the transfer + >76 +00024F: 0E C1 03 >77 doCommand ASL R1 ;Block requested->page requested +000252: AD C1 03 >78 LDA R1 ;Get page requested +000255: C9 BF >79 CMP #$BF ;In Language card? +000257: B0 0A =0263 >80 BCS XferLC1 ;Yes, do it +000259: C9 06 >81 CMP #$06 ;Bit map? +00025B: D0 03 =0260 >82 BNE :1 +00025D: 4C 8C 03 >83 JMP TBMap ;Yes, transfer bitmap +000260: 4C 42 03 >84 :1 JMP TReg ;else normal transfer + >85 + >86 * When a block between $60 and $7F is requested, it must + >87 * be spirited into/from the language card area of the + >88 * 64K card. This requires a two-stage move: into the temp + >89 * buffer and then to its real destination. + >90 +000263: AA >91 XferLC1 TAX ;Save R1 for later +000264: 20 E5 02 >92 JSR SetPtr ;Get direction +000267: 08 >93 PHP ;Save direction +000268: B0 4E =02B8 >94 BCS LCwrt ;It is a write +00026A: 8A >95 LCrd TXA ;Get R1 back +00026B: C9 CF >96 CMP #$CF ;Which bank is it in? +00026D: B0 04 =0273 >97 BCS XferLC2 ;In main bank +00026F: 09 10 >98 ORA #$10 ;In secondary bank +000271: D0 06 =0279 >99 BNE XferLC ;Branch always + >100 +000273: 8D 83 C0 >101 XferLC2 STA LCBANK2 ;Turn on main $D000 +000276: 8D 83 C0 >102 STA LCBANK2 + >103 +000279: 8D C1 03 >104 XferLC STA R1 ;Restore R1 +00027C: AD C0 03 >105 LDA R2H ;Save R2 for later +00027F: 48 >106 PHA +000280: AE BF 03 >107 LDX R2L +000283: 8D 09 C0 >108 STA SETALTZP ;Now switch to other ZP +000286: A9 0C >109 LDA #>ABuf ;Set R2 to Abuf +000288: 8D C0 03 >110 STA R2H +00028B: A9 00 >111 LDA #112 STA R2L +000290: 20 E5 02 >113 JSR SetPtr +000293: A8 >114 TAY +000294: B1 3C >115 :CpyLoop LDA (A1),Y ;Move A1,A2 to A4,A3 +000296: 91 42 >116 STA (A4),Y +000298: B1 3E >117 LDA (A2),Y +00029A: 91 40 >118 STA (A3),Y +00029C: 88 >119 DEY +00029D: D0 F5 =0294 >120 BNE :CpyLoop + >121 +00029F: 8D 08 C0 >122 STA SETSTDZP ;Restore normal ZP +0002A2: 8E BF 03 >123 STX R2L +0002A5: 68 >124 PLA ;Restore R2 +0002A6: 8D C0 03 >125 STA R2H +0002A9: 28 >126 PLP ;Get direction +0002AA: B0 09 =02B5 >127 DFX BCS XLCwrt ;Write, done with move + >128 +0002AC: 8D 8B C0 >129 STA LCBANK1 ;Now switch MLI part of LC in +0002AF: 8D 8B C0 >130 STA LCBANK1 +0002B2: 20 BE 02 >131 JSR BlockDo0 ;Read, transfer Abuf to main + >132 +0002B5: 4C DE 03 >133 XLCwrt JMP ExitCard + >134 +0002B8: 20 BE 02 >135 LCwrt JSR BlockDo0 ;Transfer main to Abuf +0002BB: 4C 6A 02 >136 JMP LCrd ;Transfer Abuf to Lang card + >137 + >138 *------------------------------------------------- + >139 * BLOCKDo transfers a block between main memory and the + >140 * 64K card. R1 contains the page address of the block + >141 * in the card; R2 contains the page address of the block + >142 * in main memory. The address in main memory is always + >143 * in the language card, so the language card is always + >144 * switched in. If CMD is 2, a write is done (R2->R1); + >145 * if CMD is 1, a read is done (R1->R2). + >146 +0002BE: A9 0C >147 BlockDo0 LDA #>ABuf ;Set up R1 = Abuf +0002C0: 8D C1 03 >148 BlockDo1 STA R1 +0002C3: 20 E5 02 >149 BlockDo JSR SetPtr ;set pointers +0002C6: B0 13 =02DB >150 BCS BlockWrite ;it's a write +0002C8: 8D 04 C0 >151 STA WRMAINRAM ;transfer buffer directly to main ram +0002CB: A8 >152 TAY ;0 left from SETPTR +0002CC: B1 3C >153 :CpyLoop LDA (A1),Y ;Transfer A1,A2 to A4,A3 +0002CE: 91 42 >154 STA (A4),Y +0002D0: B1 3E >155 LDA (A2),Y +0002D2: 91 40 >156 STA (A3),Y +0002D4: 88 >157 DEY +0002D5: D0 F5 =02CC >158 BNE :CpyLoop +0002D7: 8D 05 C0 >159 STA WRCARDRAM ;Back the way it was +0002DA: 60 >160 DoneWrt RTS ;MainWrt returns here + >161 +0002DB: A9 65 >162 BlockWrite LDA #163 STA PassIt ;Pass control to main ram +0002E0: A9 FF >164 LDA #>MainWrt +0002E2: 4C F6 03 >165 JMP Ex1 ;Set PassIt+1 and transfer + >166 + >167 *------------------------------------------------- + >168 * SETPTR is used by other routines to set up + >169 * pointers and to detect read or write. + >170 +0002E5: AD BD 03 >171 SetPtr LDA tCmd ;The rest depends on read +0002E8: 4A >172 LSR ;or write. Which is it? +0002E9: B0 1D =0308 >173 BCS CmdWrt ;It's write + >174 +0002EB: AD C0 03 >175 CmdRd LDA R2H ;Get dest page +0002EE: 85 43 >176 STA A4+1 ;1st dest page (MOVE) +0002F0: 85 41 >177 STA A3+1 ;2nd dest page +0002F2: AD BF 03 >178 LDA R2L ;Low byte dest page +0002F5: 85 42 >179 STA A4 ;1st dest page low +0002F7: 85 40 >180 STA A3 ;2nd dest page low +0002F9: AD C1 03 >181 LDA R1 ;Get source page +0002FC: 85 3D >182 STA A1+1 ;1st source page +0002FE: 85 3F >183 STA A2+1 ;2nd source page +000300: A9 00 >184 LDA #$00 ;Source page aligned +000302: 85 3C >185 STA A1 ;1st source page +000304: 85 3E >186 STA A2 ;2nd source page +000306: F0 1B =0323 >187 BEQ CmdBoth ;Update second pages + >188 +000308: AD C0 03 >189 CmdWrt LDA R2H ;Get source page +00030B: 85 3D >190 STA A1+1 ;1st source page +00030D: 85 3F >191 STA A2+1 ;2nd source page +00030F: AD BF 03 >192 LDA R2L ;Get source page low +000312: 85 3C >193 STA A1 ;1st source page low +000314: 85 3E >194 STA A2 ;2nd source page low +000316: AD C1 03 >195 LDA R1 ;Get dest page +000319: 85 43 >196 STA A4+1 ;1st dest page +00031B: 85 41 >197 STA A3+1 ;2nd dest page +00031D: A9 00 >198 LDA #$00 ;Dest page aligned +00031F: 85 42 >199 STA A4 ;1st dest page +000321: 85 40 >200 STA A3 ;2nd dest page + >201 +000323: E6 3F >202 CmdBoth INC A2+1 ;Update 2nd source page +000325: E6 41 >203 INC A3+1 ;Update 2nd dest page +000327: 60 >204 RTS + >205 + >206 *------------------------------------------------- + >207 * TZIP is called if Blocks 0,1,4,5 are requested. + >208 * On write it does nothing, on read, it returns 0's + >209 +000328: 20 31 03 >210 TZip JSR ClrBuf0 ;Fill ABUF with 0's +00032B: 20 C3 02 >211 JSR BlockDo ;Transfer them 0's +00032E: 4C DE 03 >212 JMP ExitCard ; & return + >213 + >214 *------------------------------------------------- + >215 * ClrBuf fills the buffer indicated by R1 to 0's + >216 * Should only be called on a read or format. + >217 +000331: A9 0C >218 ClrBuf0 LDA #>ABuf ;ABUF is temp buffer +000333: 8D C1 03 >219 ClrBuf1 STA R1 ;Assign to BLOCK +000336: 20 E5 02 >220 ClrBuf2 JSR SetPtr ;Set pointers +000339: A8 >221 TAY ;A set to 0 by setptr +00033A: 91 3C >222 :CpyLoop STA (A1),Y +00033C: 91 3E >223 STA (A2),Y +00033E: 88 >224 DEY +00033F: D0 F9 =033A >225 BNE :CpyLoop +000341: 60 >226 RTS + >227 + >228 *------------------------------------------------- + >229 * TREG maps the requested block into the aux card + >230 * so that 8K data files will be contiguous (the index + >231 * blocks will not be placed within data). + >232 +000342: C9 04 >233 TReg CMP #$04 ;page 4 = vdir +000344: D0 04 =034A >234 BNE :1 ;Not vdir, continue +000346: A9 07 >235 LDA #$07 ;Else xfer block 7 +000348: D0 0E =0358 >236 BNE GoTimes2 + >237 + >238 ***************** See Rev Note #43 ******************** + >239 +00034A: C9 0F >240 :1 CMP #$0F ;If any page241 BCC TZip ; it is invalid + >242 +00034E: A2 00 >243 LDX #$00 ;X contains number of iterations +000350: A5 46 >244 LDA blockNum ;Use true block number +000352: C9 5D >245 CMP #$5D ;Beyond 8K blocks? +000354: 90 05 =035B >246 BCC TReg1 ;No, do normal +000356: E9 50 >247 SBC #$50 ;else subtract offset +000358: 4C 85 03 >248 GoTimes2 JMP Times2 ;and multiply by 2 + >249 + >250 * Determine which 8K chunk it is in, place in X; + >251 * block offset into chunk goes into Y. + >252 +00035B: 38 >253 TReg1 SEC +00035C: E9 08 >254 SBC #$08 ;block = block -6 +00035E: C9 11 >255 :loop CMP #$11 ;If <=17, done +000360: 90 06 =0368 >256 BCC :3 ;Yup, got iteration +000362: E9 11 >257 SBC #$11 ;else block =block -17 +000364: E8 >258 INX ;Count iteration +000365: 10 F7 =035E >259 BPL :loop ;Branch always +000367: 00 >260 DB $00 ;Just in case (CRASH!) + >261 + >262 * If remainder is 1, it's an index block: start index + >263 * blocks at $1000,$2000..$19FF) + >264 * If remainder is 0, it is first data block in 8K + >265 * chunk. Page is 32 + (16 * X). + >266 * Otherwise, it is some other data block. + >267 * Page is 32 + (16 * X) + (2 * Y) + >268 +000368: A8 >269 :3 TAY ;Remainder in Y +000369: C0 01 >270 CPY #$01 ;Is it index block? +00036B: D0 06 =0373 >271 BNE :4 ;No +00036D: 8A >272 TXA ;Index = 2*(8+X) +00036E: 18 >273 CLC +00036F: 69 08 >274 ADC #$08 +000371: D0 12 =0385 >275 BNE Times2 ;Multiply by 2 +000373: E8 >276 :4 INX ;Need iteration+1 +000374: 8A >277 TXA ;Page = 2 * (16 + 8X) +000375: 0A >278 ASL +000376: 0A >279 ASL +000377: 0A >280 ASL +000378: 0A >281 ASL +000379: 8D C1 03 >282 STA R1 +00037C: 98 >283 TYA ;Get offset into 8K chunk +00037D: F0 02 =0381 >284 BEQ :5 ;if 0, no offset +00037F: 88 >285 DEY ;else offset = 2 * Y +000380: 98 >286 TYA +000381: 18 >287 :5 CLC +000382: 6D C1 03 >288 ADC R1 +000385: 0A >289 Times2 ASL ;A=2*A +000386: 20 C0 02 >290 JSR BlockDo1 ;Store in R1 and xfer +000389: 4C DE 03 >291 JMP ExitCard ; & return + >292 + >293 *------------------------------------------------- + >294 * When Block 3 is requested, the bitmap is returned. The + >295 * Real bitmap is only 16 bytes long (BITMAP); the rest of + >296 * the block is synthesized. The temporary buffer at $800 + >297 * is used to build/read a full size bitmap block. + >298 +00038C: A9 0C >299 TBMap LDA #>ABuf ;Use temporary buffer as BLOCK +00038E: 8D C1 03 >300 STA R1 +000391: 20 E5 02 >301 JSR SetPtr ;Set pointers/test read-write +000394: B0 13 =03A9 >302 BCS BitWrt ;Its a write! + >303 +000396: 20 36 03 >304 BitRd JSR ClrBuf2 + >305 +000399: A0 0F >306 LDY #$0F ;Now put real bitmap there +00039B: B9 C2 03 >307 :CpyLoop LDA BitMap,Y +00039E: 91 3C >308 STA (A1),Y +0003A0: 88 >309 DEY +0003A1: 10 F8 =039B >310 BPL :CpyLoop +0003A3: 20 C3 02 >311 JSR BlockDo ;Move temp buf to user buf +0003A6: 4C DE 03 >312 JMP ExitCard + >313 +0003A9: 20 C3 02 >314 BitWrt JSR BlockDo ;move user buf to temp buf +0003AC: 20 E5 02 >315 JSR SetPtr ;Set pointers +0003AF: A0 0F >316 LDY #$0F ;move temp buf to bitmap +0003B1: B1 42 >317 :CpyLoop LDA (A4),Y ;(pointer set by SETPTR) +0003B3: 99 C2 03 >318 STA BitMap,Y +0003B6: 88 >319 DEY +0003B7: 10 F8 =03B1 >320 BPL :CpyLoop +0003B9: 4C DE 03 >321 JMP ExitCard + >322 + >323 *------------------------------------------------- +0003BC: 00 >324 FormatFlag DB $00 ;Not formatted yet + >325 +0003BD: 00 >326 tCmd DS 1,0 ;Command byte +0003BE: 00 >327 tUnit DS 1,0 ;Unit byte (Not used) +0003BF: 00 >328 R2L DS 1,0 ;Low byte of user buffer +0003C0: 00 >329 R2H DS 1,0 ;Hi byte of user buffer +0003C1: 00 >330 R1 DS 1,0 ;Page requested + >331 + =03C2 >332 BitMap EQU * +0003C2: 00 FF FF FF >333 HEX 00FFFFFF ;Blocks 0-7 used +0003C6: FF FF FF FF >334 HEX FFFFFFFF +0003CA: FF FF FF FF >335 HEX FFFFFFFF +0003CE: FF FF FF FE >336 HEX FFFFFFFE + >337 + =03D2 >338 VDir EQU * ;Start of virt dir +0003D2: F3 >339 TypeNameLen DB $F3 ;Storage type F, namelength 3 +0003D3: 52 41 4D >340 ASC 'RAM' +0003D6: C3 >341 Access DB $C3 ;Destroy, Rename, Read enabled +0003D7: 27 >342 DB $27 ;entry length +0003D8: 0D >343 DB $0D ;Entries/Blk +0003D9: 00 00 >344 DW $0000 ;File Count +0003DB: 03 00 >345 DW $0003 ;Map_Pointer=Block 3 +0003DD: 7F >346 DB $7F ;Total_Blocks=128 blocks + >347 + >348 *------------------------------------------------- + >349 +0003DE: AD 8B C0 >350 ExitCard LDA LCBANK1 ;Restore lang card +0003E1: AD 8B C0 >351 LDA LCBANK1 +0003E4: 68 >352 PLA ;Get 80STORE +0003E5: 10 03 =03EA >353 BPL Ex0 ;80STORE wasn't on +0003E7: 8D 01 C0 >354 STA SET80COL +0003EA: 4C EF 03 >355 Ex0 JMP $03EF ;Jump around PassIt (3ED,3EE) + >356 +0003ED: 00 00 >357 DS $3EF-*,0 ;Pad thru $3EE + >358 +0003EF: A9 44 >359 LDA #360 STA PassIt +0003F4: A9 FF >361 LDA #>NoErr + >362 +0003F6: 8D EE 03 >363 Ex1 STA PassIt+1 ;Also used by BlockWrite +0003F9: 18 >364 CLC ;Transfer card to main +0003FA: B8 >365 CLV ;Use standard zp/stk +0003FB: 4C 14 C3 >366 JMP Xfer ;There's no place like home... + >367 + >368 * NOTE: The previous section of code MUST NOT use $3FE & $3FF + >369 * since the Interrupt Vector must go there if AUX interrupts + >370 * are to be used. + >371 +0003FE: 00 00 >372 DS 2,0 ;Pad to end of mem page + 43 PUT mli.src/XRW1 + >2 **************************************************** + >3 * + >4 * PRODOS 8 DISK II DRIVER (RWTS) + >5 * + >6 * COPYRIGHT APPLE COMPUTER INC., 1980-1986 + >7 * + >8 * ALL RIGHTS RESERVED + >9 * + >10 * REVISED 11/8/82 BY J.R.H. + >11 * + >12 **************************************************** + >13 **************************** + >14 * * + >15 * critical timing * + >16 * requires page bound * + >17 * considerations for * + >18 * code and data * + >19 * code----- * + >20 * virtually the entire * + >21 * 'write' routine * + >22 * must not cross * + >23 * page boundaries. * + >24 * critical branches in * + >25 * the 'write', 'read', * + >26 * and 'read adr' subrs * + >27 * which must not cross * + >28 * page boundaries are * + >29 * noted in comments. * + >30 * * + >31 **************************** + >32 * * + >33 * Equates * + >34 * * + =0004 >35 maxCmd EQU 4 ;Commands 0-3 only + =00E8 >36 dvMot EQU $E8 + >37 DUM $3A +00003A: 00 >38 wTemp DS 1 +00003B: 00 >39 midNib1 DS 1 +00003C: 00 >40 midNib2 DS 1 +00003D: 00 >41 lstNib DS 1 +00003E: 00 >42 slotZ DS 1 +00003F: 00 >43 yEnd DS 1 + >44 DEND + >45 + >46 ************************ + >47 * * + >48 * device address * + >49 * assignments * + >50 * * + >51 ************************ + =C080 >52 phaseOff EQU $C080 ;stepper phase off. + >53 *phaseOn EQU $C081 ;stepper phase on. + =C08C >54 q6l EQU $C08C ;q7l,q6l=read + =C08D >55 q6h EQU $C08D ;q7l,q6h=sense wprot + =C08E >56 q7l EQU $C08E ;q7h,q6l=write + =C08F >57 q7h EQU $C08F ;q7h,q6h=write store + >58 **************************************** + >59 * + >60 * Equates for rwts and block + >61 * + >62 **************************************** + =C088 >63 motorOff EQU $C088 + =C089 >64 motorOn EQU $C089 + =C08A >65 drv0En EQU $C08A + >66 *drv1en EQU $C08B + >67 + >68 ORG $D000 + >69 ************************ + >70 * * + >71 * block i/o * + >72 * * + >73 ************************ +00D000: D8 >74 BlockIO CLD ;This must be first as it is an ID value +00D001: 20 BE D6 >75 JSR ResetPhase + >76 + >77 * this is patch 76 part 1. part 2 is in xrw2. + >78 * this is patch 77, use to be 'lda q7l+14,x'. + >79 +00D004: BD 8E C0 >80 LDA q7l,X ;Turn off write enable please!!! + >81 * (pad is just spare bytes but the number is critical for page +00D007: EA >82 NOP +00D008: EA >83 NOP +00D009: 20 D0 D6 >84 JSR doCheck +00D00C: B0 26 =D034 >85 BCS BadBlk ;Branch if block # is out of range +00D00E: A0 05 >86 LDY #$05 +00D010: 0A >87 :loop ASL +00D011: 2E 56 D3 >88 ROL ibTrk +00D014: 88 >89 DEY +00D015: D0 F9 =D010 >90 BNE :loop +00D017: 0A >91 ASL +00D018: 90 02 =D01C >92 BCC :1 +00D01A: 09 10 >93 ORA #$10 ;Adjust for upper 4 blks of trk +00D01C: 4A >94 :1 LSR +00D01D: 4A >95 LSR +00D01E: 4A >96 LSR +00D01F: 4A >97 LSR +00D020: 48 >98 PHA ;Save sector# +00D021: 20 38 D0 >99 JSR RegRWTS +00D024: 68 >100 PLA ;Restore sector # +00D025: B0 09 =D030 >101 BCS Quit ;Branch if error encountered +00D027: E6 45 >102 INC bufPtr+1 +00D029: 69 02 >103 ADC #$02 +00D02B: 20 38 D0 >104 JSR RegRWTS ;Get second half of block +00D02E: C6 45 >105 DEC bufPtr+1 +00D030: AD 58 D3 >106 Quit LDA ibStat +00D033: 60 >107 RTS + >108 +00D034: A9 27 >109 BadBlk LDA #drvrIOError +00D036: 38 >110 SEC +00D037: 60 >111 RTS + >112 ************************** + >113 * * + >114 * read/write a * + >115 * track and sector * + >116 * * + >117 ************************** +00D038: A0 01 >118 RegRWTS LDY #$01 ;Retry count +00D03A: 8C 6A D3 >119 STY seekCnt ;Only one recalibrate per call +00D03D: 8D 57 D3 >120 STA ibSect +00D040: A5 43 >121 LDA unitNum ;Get slot # for this operation +00D042: 29 70 >122 AND #$70 +00D044: 85 3E >123 STA slotZ +00D046: 20 9B D6 >124 JSR ChkPrev ;Make sure other drives in other slots are stopped + >125 * + >126 * Now check if the motor is on, then start it + >127 * +00D049: 20 DA D4 >128 JSR ChkDrv ;Set zero flag if motor stopped +00D04C: 08 >129 PHP ;Save test results +00D04D: A9 E8 >130 LDA #dvMot +00D04F: 8D 70 D3 >131 STA monTimeH +00D052: A5 43 >132 LDA unitNum ;Determine drive one or two +00D054: CD 59 D3 >133 CMP iobPrevDn ;Same drive used before? +00D057: 8D 59 D3 >134 STA iobPrevDn ;Save it for next time +00D05A: 08 >135 PHP ;Keep results of compare +00D05B: 0A >136 ASL ;Get drive number into carry +00D05C: BD 89 C0 >137 LDA motorOn,X ;Turn on the drive +00D05F: 90 01 =D062 >138 BCC DrvSel ;Branch if drive 1 selected +00D061: E8 >139 INX ;Select drive 2 +00D062: BD 8A C0 >140 DrvSel LDA drv0En,X +00D065: 28 >141 PLP ;Was it same drive? +00D066: F0 0A =D072 >142 BEQ :1 ;Yes +00D068: 28 >143 PLP ;Must indicate drive off by setting zero flag +00D069: A0 07 >144 LDY #$07 ;Delay 150 ms before stepping +00D06B: 20 85 D3 >145 :WaitLoop JSR msWait ;(on return A=0) +00D06E: 88 >146 DEY +00D06F: D0 FA =D06B >147 BNE :WaitLoop +00D071: 08 >148 PHP ;Now zero flag set +00D072: A5 42 >149 :1 LDA dhpCmd ;Make sure this command needs seeking +00D074: F0 06 =D07C >150 BEQ :2 ;Branch if status check +00D076: AD 56 D3 >151 LDA ibTrk ;Get destination track +00D079: 20 0C D1 >152 JSR MySeek ; & go to it + >153 + >154 * Now at the desired track. Was the motor + >155 * on to start with? + >156 +00D07C: 28 >157 :2 PLP ;Was motor on? +00D07D: D0 0F =D08E >158 BNE TryTrk ;If so, don't delay, get it today! + >159 + >160 * Motor was off, wait for it to speed up. + >161 +00D07F: A9 01 >162 MotOff LDA #$01 ;Wait exactly 100 us for each count in monTime +00D081: 20 85 D3 >163 JSR msWait +00D084: AD 70 D3 >164 LDA monTimeH +00D087: 30 F6 =D07F >165 BMI MotOff ;count up to 0000 + >166 **************************************** + >167 * + >168 * Motor should be up to speed. + >169 * If it still looks stopped then + >170 * the drive is not present. + >171 * + >172 **************************************** +00D089: 20 DA D4 >173 JSR ChkDrv ;Is drive present? +00D08C: F0 5C =D0EA >174 BEQ HndlErr ;Branch if no drive + >175 + >176 * Now check: if it is not the format disk command, + >177 * locate the correct sector for this operation. + >178 +00D08E: A5 42 >179 TryTrk LDA dhpCmd ;Get command code # +00D090: F0 6B =D0FD >180 BEQ StatCmd ;If $00, then status command +00D092: 4A >181 LSR ;Set carry=1 for read, 0 for write +00D093: B0 03 =D098 >182 BCS :1 ;Must prenibblize for write +00D095: 20 F0 D5 >183 JSR PreNibl16 +00D098: A0 40 >184 :1 LDY #$40 ;Only 64 retries of any kind +00D09A: 8C 69 D3 >185 STY retryCnt +00D09D: A6 3E >186 TryAdr LDX slotZ ;Get slot num into X-reg +00D09F: 20 98 D3 >187 JSR RdAdr16 ;Read next address field +00D0A2: 90 1A =D0BE >188 BCC RdRight ;If read it right, hurrah! +00D0A4: CE 69 D3 >189 TryAdr2 DEC retryCnt ;Another mistake!! +00D0A7: 10 F4 =D09D >190 BPL TryAdr ;Well, let it go this time... +00D0A9: A9 27 >191 LDA #drvrIOError ;Anticipate a bad drive error +00D0AB: CE 6A D3 >192 DEC seekCnt ;Only recalibrate once! +00D0AE: D0 3A =D0EA >193 BNE HndlErr ;Tried to recalibrate a second time, error! +00D0B0: AD 5A D3 >194 LDA curTrk ;Save track we really want +00D0B3: 48 >195 PHA +00D0B4: 0A >196 ASL +00D0B5: 69 10 >197 ADC #$10 ;Pretend track is 8>curtrk +00D0B7: A0 40 >198 LDY #$40 +00D0B9: 8C 69 D3 >199 STY retryCnt ;Reset retries to 64 max +00D0BC: D0 0E =D0CC >200 BNE ReCal1 ;Branch always + >201 + >202 * Have now read an address field correctly. + >203 * Make sure this is the desired track, sector, and volume. + >204 +00D0BE: AC 6F D3 >205 RdRight LDY track ;On the right track? +00D0C1: CC 5A D3 >206 CPY curTrk +00D0C4: F0 0F =D0D5 >207 BEQ RtTrk ;if so, good + >208 + >209 * Recalibrating from this track + >210 +00D0C6: AD 5A D3 >211 LDA curTrk ;Preserve destination track +00D0C9: 48 >212 PHA +00D0CA: 98 >213 TYA +00D0CB: 0A >214 ASL ;(washing machine fix!) +00D0CC: 20 D3 D4 >215 ReCal1 JSR SetTrk +00D0CF: 68 >216 PLA +00D0D0: 20 0C D1 >217 JSR MySeek +00D0D3: 90 C8 =D09D >218 BCC TryAdr ;Go ahead and recalibrate + >219 + >220 * Drive is on right track, check volume mismatch + >221 +00D0D5: AD 6E D3 >222 RtTrk LDA sector ;Check if this is the right sector +00D0D8: CD 57 D3 >223 CMP ibSect +00D0DB: D0 C7 =D0A4 >224 BNE TryAdr2 ;No, try another sector +00D0DD: A5 42 >225 LDA dhpCmd ;read or write? +00D0DF: 4A >226 LSR ;The carry will tell +00D0E0: 90 12 =D0F4 >227 BCC WriteIt ;Carry was set for read operation, +00D0E2: 20 FD D3 >228 JSR Read16 ; cleared for write +00D0E5: B0 BD =D0A4 >229 BCS TryAdr2 ;Carry set upon return if bad read + =D0E7 >230 AllDone EQU * ;Was CLC +00D0E7: A9 00 >231 LDA #$00 ;No error +00D0E9: D0 >232 DB $D0 ;Branch never (skip 1 byte) +00D0EA: 38 >233 HndlErr SEC ;Indicate an error +00D0EB: 8D 58 D3 >234 STA ibStat ;Give him error # +00D0EE: A6 3E >235 LDX slotZ ;Get the slot offset +00D0F0: BD 88 C0 >236 LDA motorOff,X ;Turn it off... +00D0F3: 60 >237 RTS ;All finished! + >238 +00D0F4: 20 00 D5 >239 WriteIt JSR Write16 ;Write nybbles now +00D0F7: 90 EE =D0E7 >240 StatDone BCC AllDone ;If no errors +00D0F9: A9 2B >241 LDA #drvrWrtProt ;Disk is write protected!! +00D0FB: D0 ED =D0EA >242 BNE HndlErr ;Branch always + >243 +00D0FD: A6 3E >244 StatCmd LDX slotZ +00D0FF: BD 8D C0 >245 LDA q6h,X ;Test for write protected +00D102: BD 8E C0 >246 LDA q7l,X +00D105: 2A >247 ROL ;Write protect-->carry-->bit-0=1 +00D106: BD 8C C0 >248 LDA q6l,X ;Keep in read mode... +00D109: 4C F7 D0 >249 JMP StatDone ;Branch always taken + >250 + >251 * This is the 'seek' routine + >252 * seeks track 'n' in slot #x/$10 + >253 * If drivno is negative, on drive 0 + >254 * If drivno is positive, on drive 1 + >255 +00D10C: 0A >256 MySeek ASL ;Assume two phase stepper +00D10D: 8D 6F D3 >257 STA track ;Save destination track(*2) +00D110: 20 25 D1 >258 JSR AllOff ;Turn all phases off to be sure +00D113: 20 F1 D4 >259 JSR DrvIndx ;Get index to previous track for current drive +00D116: BD 59 D3 >260 LDA drv0Trk,X +00D119: 8D 5A D3 >261 STA curTrk ;This is where i am +00D11C: AD 6F D3 >262 LDA track ; & where i'm going to +00D11F: 9D 59 D3 >263 STA drv0Trk,X +00D122: 20 33 D1 >264 JSR Seek ;Go there! +00D125: A0 03 >265 AllOff LDY #$03 ;Turn off all phases before returning +00D127: 98 >266 NxtOff TYA ;(send phase in Acc) +00D128: 20 8A D1 >267 JSR ClrPhase ;Carry is clear, phases should be turned off +00D12B: 88 >268 DEY +00D12C: 10 F9 =D127 >269 BPL NxtOff +00D12E: 4E 5A D3 >270 LSR curTrk ;Divide back down +00D131: 18 >271 CLC +00D132: 60 >272 RTS ;All off... now it's dark + >273 ************************** + >274 * * + >275 * fast seek subroutine * + >276 ************************** + >277 * * + >278 * on entry ---- * + >279 * * + >280 * x-reg holds slotnum * + >281 * times $10. * + >282 * * + >283 * a-reg holds desired * + >284 * halftrack. * + >285 * (single phase) * + >286 * * + >287 * curtrk holds current * + >288 * halftrack. * + >289 * * + >290 * on exit ----- * + >291 * * + >292 * a-reg uncertain. * + >293 * y-reg uncertain. * + >294 * x-reg undisturbed. * + >295 * * + >296 * curtrk and trkn hold * + >297 * final halftrack. * + >298 * * + >299 * prior holds prior * + >300 * halftrack if seek * + >301 * was required. * + >302 * * + >303 * montimel and montimeh * + >304 * are incremented by * + >305 * the number of * + >306 * 100 usec quantums * + >307 * required by seek * + >308 * for motor on time * + >309 * overlap. * + >310 * * + >311 * --- variables used --- * + >312 * * + >313 * curtrk, trkn, count, * + >314 * prior, slottemp * + >315 * montimel, montimeh * + >316 * * + >317 ************************** + >318 +00D133: 8D 72 D3 >319 Seek STA trkNbr ;Save target track +00D136: CD 5A D3 >320 CMP curTrk ;On desired track? +00D139: F0 4C =D187 >321 BEQ SetPhase ;Yes,energize phase and return +00D13B: A9 00 >322 LDA #$00 +00D13D: 8D 6B D3 >323 STA trkCnt ;Halftrack count +00D140: AD 5A D3 >324 SeekLoop LDA curTrk ;Save curTrk for +00D143: 8D 71 D3 >325 STA prior ; delayed turnoff +00D146: 38 >326 SEC +00D147: ED 72 D3 >327 SBC trkNbr ;delta-tracks +00D14A: F0 37 =D183 >328 BEQ SeekEnd ;branch if curTrk=destination +00D14C: B0 07 =D155 >329 BCS Out ;(move out, not in) +00D14E: 49 FF >330 EOR #$FF ;Calc trks to go +00D150: EE 5A D3 >331 INC curTrk ;Incr current track (in) +00D153: 90 05 =D15A >332 BCC MinTst ;(always taken) +00D155: 69 FE >333 Out ADC #$FE ;Calc trks to go +00D157: CE 5A D3 >334 DEC curTrk ;Decr current track (out) +00D15A: CD 6B D3 >335 MinTst CMP trkCnt +00D15D: 90 03 =D162 >336 BCC MaxTst ; & 'trks moved' +00D15F: AD 6B D3 >337 LDA trkCnt +00D162: C9 09 >338 MaxTst CMP #$09 +00D164: B0 02 =D168 >339 BCS Step2 ;If trkcnt>$8 leave y alone (y=$8) +00D166: A8 >340 TAY ;else set acceleration index in y +00D167: 38 >341 SEC +00D168: 20 87 D1 >342 Step2 JSR SetPhase +00D16B: B9 73 D3 >343 LDA OnTable,Y ;For 'ontime' +00D16E: 20 85 D3 >344 JSR msWait ;(100 usec intervals) +00D171: AD 71 D3 >345 LDA prior +00D174: 18 >346 CLC ;For phaseoff +00D175: 20 8A D1 >347 JSR ClrPhase ;Turn off prior phase +00D178: B9 7C D3 >348 LDA OffTable,Y +00D17B: 20 85 D3 >349 JSR msWait +00D17E: EE 6B D3 >350 INC trkCnt ;'tracks moved' count +00D181: D0 BD =D140 >351 BNE SeekLoop ;(always taken) +00D183: 20 85 D3 >352 SeekEnd JSR msWait ;Settle 25 msec +00D186: 18 >353 CLC ;Set for phase off +00D187: AD 5A D3 >354 SetPhase LDA curTrk ;Get current track +00D18A: 29 03 >355 ClrPhase AND #$03 ;Mask for 1 of 4 phases +00D18C: 2A >356 ROL ;Double for phaseon/off index +00D18D: 05 3E >357 ORA slotZ +00D18F: AA >358 TAX +00D190: BD 80 C0 >359 LDA phaseOff,X ;Turn on/off one phase +00D193: A6 3E >360 LDX slotZ ;Restore x-reg +00D195: 60 >361 RTS ; & return + >362 ************************** + >363 * * + >364 * 7-bit to 6-bit * + >365 * 'deniblize' tabl * + >366 * (16-sector format) * + >367 * * + >368 * valid codes * + >369 * $96 to $ff only. * + >370 * * + >371 * codes with more than * + >372 * one pair of adjacent * + >373 * zeroes or with no * + >374 * adjacent ones (except * + >375 * bit 7) are excluded. * + >376 * * + >377 * * + >378 * nibls in the ranges * + >379 * of $a0-$a3, $c0-$c7, * + >380 * $e0-$e3 are used for * + >381 * other tables since no * + >382 * valid nibls are in * + >383 * these ranges. * + >384 ************************** + >385 + =D100 >386 dNibble EQU *-$96 +00D196: 00 04 >387 HEX 0004 +00D198: FF FF 08 0C >388 HEX FFFF080C +00D19C: FF 10 14 18 >389 HEX FF101418 +00D1A0: 00 80 40 C0 >390 TwoBit3 HEX 008040C0 ;Used in fast prenib as +00D1A4: FF FF 1C 20 >391 HEX FFFF1C20 ; lookup for 2-bit quantities +00D1A8: FF FF FF 24 >392 HEX FFFFFF24 +00D1AC: 28 2C 30 34 >393 HEX 282C3034 +00D1B0: FF FF 38 3C >394 HEX FFFF383C +00D1B4: 40 44 48 4C >395 HEX 4044484C +00D1B8: FF 50 54 58 >396 HEX FF505458 +00D1BC: 5C 60 64 68 >397 HEX 5C606468 +00D1C0: 00 20 10 30 >398 TwoBit2 HEX 00201030 ;Used in fast prenib +00D1C4: DE AA EB FF >399 EndMarks HEX DEAAEBFF ;Table using 'unused' +00D1C8: FF FF FF 6C >400 HEX FFFFFF6C ; nibls ($c4,$c5,$c6,$c7) +00D1CC: FF 70 74 78 >401 HEX FF707478 +00D1D0: FF FF FF 7C >402 HEX FFFFFF7C +00D1D4: FF FF 80 84 >403 HEX FFFF8084 +00D1D8: FF 88 8C 90 >404 HEX FF888C90 +00D1DC: 94 98 9C A0 >405 HEX 94989CA0 +00D1E0: 00 08 04 0C >406 TwoBit1 HEX 0008040C ;Used in fast prenib +00D1E4: FF A4 A8 AC >407 HEX FFA4A8AC +00D1E8: FF B0 B4 B8 >408 HEX FFB0B4B8 +00D1EC: BC C0 C4 C8 >409 HEX BCC0C4C8 +00D1F0: FF FF CC D0 >410 HEX FFFFCCD0 +00D1F4: D4 D8 DC E0 >411 HEX D4D8DCE0 +00D1F8: FF E4 E8 EC >412 HEX FFE4E8EC +00D1FC: F0 F4 F8 FC >413 HEX F0F4F8FC + >414 * page align the following tables. + >415 *************************** + >416 * * + >417 * 6-bit to 2-bit * + >418 * conversion tables. * + >419 * * + >420 * dnibl2 abcdef-->0000fe * + >421 * dnibl3 abcdef-->0000dc * + >422 * dnibl4 abcdef-->0000ba * + >423 * * + >424 *************************** + >425 * * + >426 * 6-bit to 7-bit * + >427 * nibl conversion table * + >428 * * + >429 * codes with more than * + >430 * one pair of adjacent * + >431 * zeroes or with no * + >432 * adjacent ones (except * + >433 * b7) are excluded. * + >434 * * + >435 *************************** + >436 +00D200: 00 >437 dNibble2 DB $00 +00D201: 00 >438 dNibble3 DB $00 +00D202: 00 >439 dNibble4 DB $00 +00D203: 96 02 00 00 >440 Nibbles HEX 9602000097 +00D208: 01 00 00 9A >441 HEX 0100009A0300009B +00D210: 00 02 00 9D >442 HEX 0002009D0202009E +00D218: 01 02 00 9F >443 HEX 0102009F030200A6 +00D220: 00 01 00 A7 >444 HEX 000100A7020100AB +00D228: 01 01 00 AC >445 HEX 010100AC030100AD +00D230: 00 03 00 AE >446 HEX 000300AE020300AF +00D238: 01 03 00 B2 >447 HEX 010300B2030300B3 +00D240: 00 00 02 B4 >448 HEX 000002B4020002B5 +00D248: 01 00 02 B6 >449 HEX 010002B6030002B7 +00D250: 00 02 02 B9 >450 HEX 000202B9020202BA +00D258: 01 02 02 BB >451 HEX 010202BB030202BC +00D260: 00 01 02 BD >452 HEX 000102BD020102BE +00D268: 01 01 02 BF >453 HEX 010102BF030102CB +00D270: 00 03 02 CD >454 HEX 000302CD020302CE +00D278: 01 03 02 CF >455 HEX 010302CF030302D3 +00D280: 00 00 01 D6 >456 HEX 000001D6020001D7 +00D288: 01 00 01 D9 >457 HEX 010001D9030001DA +00D290: 00 02 01 DB >458 HEX 000201DB020201DC +00D298: 01 02 01 DD >459 HEX 010201DD030201DE +00D2A0: 00 01 01 DF >460 HEX 000101DF020101E5 +00D2A8: 01 01 01 E6 >461 HEX 010101E6030101E7 +00D2B0: 00 03 01 E9 >462 HEX 000301E9020301EA +00D2B8: 01 03 01 EB >463 HEX 010301EB030301EC +00D2C0: 00 00 03 ED >464 HEX 000003ED020003EE +00D2C8: 01 00 03 EF >465 HEX 010003EF030003F2 +00D2D0: 00 02 03 F3 >466 HEX 000203F3020203F4 +00D2D8: 01 02 03 F5 >467 HEX 010203F5030203F6 +00D2E0: 00 01 03 F7 >468 HEX 000103F7020103F9 +00D2E8: 01 01 03 FA >469 HEX 010103FA030103FB +00D2F0: 00 03 03 FC >470 HEX 000303FC020303FD +00D2F8: 01 03 03 FE >471 HEX 010303FE030303FF + >472 +00D300: 00 00 00 00 >473 nBuf2 DS $56,0 ;nibble buffer for R/W of low 2-bits of each byte + >474 +00D356: 00 >475 ibTrk DB $00 +00D357: 00 >476 ibSect DB $00 +00D358: 00 >477 ibStat DB $00 +00D359: 00 >478 iobPrevDn DB $00 +00D35A: 00 >479 curTrk DB $00 + =D359 >480 drv0Trk EQU *-2 +00D35B: 00 00 00 00 >481 HEX 00000000000000 ;for slots 1 thru 7 +00D362: 00 00 00 00 >482 HEX 00000000000000 ;drives 1 & 2 +00D369: 00 >483 retryCnt DS 1,0 +00D36A: 00 >484 seekCnt DS 1,0 + >485 ************************ + >486 * * + >487 * readadr---- * + >488 * * + >489 ************************ + =D36B >490 count EQU * ;'must find' count +00D36B: 00 >491 last DS 1,0 ;'odd bit' nibls +00D36C: 00 >492 chkSum DS 1,0 ;Used for address header cksum +00D36D: 00 00 00 00 >493 csSTV DS 4,0 + >494 * checksum, sector, track, and volume. + =D36E >495 sector EQU csSTV+1 + =D36F >496 track EQU csSTV+2 + =D370 >497 volume EQU csSTV+3 + >498 + =D36B >499 trkCnt EQU count ;Halftracks moved count +00D371: 00 >500 prior DS 1,0 +00D372: 00 >501 trkNbr DS 1,0 + >502 ************************ + >503 * * + >504 * mswait ---- * + >505 * * + >506 ************************ + =D36F >507 monTimeL equ csSTV+2 ;Motor-on time + =D370 >508 monTimeH equ monTimeL+1 ;counters. + >509 ************************** + >510 * * + >511 * phase on-, off-time * + >512 * tables in 100-usec * + >513 * intervals. (seek) * + >514 * * + >515 ************************** +00D373: 01 30 28 >516 OnTable HEX 013028 +00D376: 24 20 1E >517 HEX 24201E +00D379: 1D 1C 1C >518 HEX 1D1C1C +00D37C: 70 2C 26 >519 OffTable HEX 702C26 +00D37F: 22 1F 1E >520 HEX 221F1E +00D382: 1D 1C 1C >521 HEX 1D1C1C + >522 + >523 ************************** + >524 * * + >525 * mswait subroutine * + >526 * * + >527 ************************** + >528 * * + >529 * delays a specified * + >530 * number of 100 usec * + >531 * intervals for motor * + >532 * on timing. * + >533 * * + >534 * on entry ---- * + >535 * * + >536 * a-reg: holds number * + >537 * of 100 usec * + >538 * intervals to * + >539 * delay. * + >540 * * + >541 * on exit ----- * + >542 * * + >543 * a-reg: holds $00. * + >544 * x-reg: holds $00. * + >545 * y-reg: unchanged. * + >546 * carry: set. * + >547 * * + >548 * montimel, montimeh * + >549 * are incremented once * + >550 * per 100 usec interval* + >551 * for moton on timing. * + >552 * * + >553 * assumes ---- * + >554 * * + >555 * 1 usec cycle time * + >556 * * + >557 ************************** +00D385: A2 11 >558 msWait LDX #$11 +00D387: CA >559 :loop DEX ;Delay 86 usec +00D388: D0 FD =D387 >560 BNE :loop +00D38A: EE 6F D3 >561 INC monTimeL +00D38D: D0 03 =D392 >562 BNE :1 ;double-byte +00D38F: EE 70 D3 >563 INC monTimeH ; increment +00D392: 38 >564 :1 SEC +00D393: E9 01 >565 SBC #$01 ;Done 'n' intervals? +00D395: D0 EE =D385 >566 BNE msWait ;(A-reg counts) +00D397: 60 >567 RTS + 44 PUT mli.src/XRW2 + >1 **************************** + >2 * * + >3 * read address field * + >4 * subroutine * + >5 * (16-sector format) * + >6 * * + >7 **************************** + >8 * * + >9 * reads volume, track * + >10 * and sector * + >11 * * + >12 * on entry ---- * + >13 * * + >14 * xreg: slotnum times $10 * + >15 * * + >16 * read mode (q6l, q7l) * + >17 * * + >18 * on exit ----- * + >19 * * + >20 * carry set if error. * + >21 * * + >22 * if no error: * + >23 * a-reg holds $aa. * + >24 * y-reg holds $00. * + >25 * x-reg unchanged. * + >26 * carry clear. * + >27 * * + >28 * csstv holds chksum, * + >29 * sector, track, and * + >30 * volume read. * + >31 * * + >32 * uses temps count, * + >33 * last, csum, and * + >34 * 4 bytes at csstv. * + >35 * * + >36 * expects ---- * + >37 * * + >38 * original 10-sector * + >39 * normal density nibls * + >40 * (4-bit), odd bits, * + >41 * then even. * + >42 * * + >43 * caution ---- * + >44 * * + >45 * observe * + >46 * 'no page cross' * + >47 * warnings on * + >48 * some branches!! * + >49 * * + >50 * assumes ---- * + >51 * * + >52 * 1 usec cycle time * + >53 * * + >54 **************************** + >55 +00D398: A0 FC >56 RdAdr16 LDY #$FC +00D39A: 8C 6B D3 >57 STY count ;'must find' count +00D39D: C8 >58 RdASyn INY +00D39E: D0 05 =D3A5 >59 BNE :loop1 ;Low order of count +00D3A0: EE 6B D3 >60 INC count ;(2k nibbles to find +00D3A3: F0 56 =D3FB >61 BEQ RdErr ; adr mark, else err) +00D3A5: BD 8C C0 >62 :loop1 LDA q6l,X ;Read nibble +00D3A8: 10 FB =D3A5 >63 BPL :loop1 ;*** no page cross! *** +00D3AA: C9 D5 >64 RdASyn1 CMP #$D5 ;Adr mark 1? +00D3AC: D0 EF =D39D >65 BNE RdASyn ;(loop if not) +00D3AE: EA >66 NOP ;Added nibble delay +00D3AF: BD 8C C0 >67 LDA q6l,X +00D3B2: 10 FB =D3AF >68 BPL *-3 ;*** no page cross! *** +00D3B4: C9 AA >69 CMP #$AA ;Adr mark 2? +00D3B6: D0 F2 =D3AA >70 BNE RdASyn1 ; (if not, is it am1?) + >71 * (added nibl delay) +00D3B8: A0 03 >72 LDY #$03 ;Index for 4-byte read +00D3BA: BD 8C C0 >73 LDA q6l,X +00D3BD: 10 FB =D3BA >74 BPL *-3 ;*** no page cross! *** +00D3BF: C9 96 >75 CMP #$96 ;Adr mark 3? +00D3C1: D0 E7 =D3AA >76 BNE RdASyn1 ; (if not, is it am1?) +00D3C3: 78 >77 SEI ;No interupts until address is tested.(carry is set) +00D3C4: A9 00 >78 LDA #$00 ;Init checksum +00D3C6: 8D 6C D3 >79 RdAddrFld STA chkSum +00D3C9: BD 8C C0 >80 LDA q6l,X ;Read 'odd bit' nibble +00D3CC: 10 FB =D3C9 >81 BPL *-3 ;*** no page cross! *** +00D3CE: 2A >82 ROL ;Align odd bits, '1' into lsb +00D3CF: 8D 6B D3 >83 STA last ; (save them) +00D3D2: BD 8C C0 >84 LDA q6l,X ;Read 'even bit' nibble +00D3D5: 10 FB =D3D2 >85 BPL *-3 ;*** no page cross! *** +00D3D7: 2D 6B D3 >86 AND last ;Merge odd and even bits +00D3DA: 99 6D D3 >87 STA csSTV,Y ;Store data byte +00D3DD: 4D 6C D3 >88 EOR chkSum +00D3E0: 88 >89 DEY +00D3E1: 10 E3 =D3C6 >90 BPL RdAddrFld ;Loop on 4 data bytes +00D3E3: A8 >91 TAY ;If final checksum +00D3E4: D0 15 =D3FB >92 BNE RdErr ; nonzero, then error +00D3E6: BD 8C C0 >93 LDA q6l,X ;First bit-slip nibble +00D3E9: 10 FB =D3E6 >94 BPL *-3 ;*** no page cross! *** +00D3EB: C9 DE >95 CMP #$DE +00D3ED: D0 0C =D3FB >96 BNE RdErr ;Error if nonmatch +00D3EF: EA >97 NOP ;delay +00D3F0: BD 8C C0 >98 LDA q6l,X ;Second bit-slip nibble +00D3F3: 10 FB =D3F0 >99 BPL *-3 ;*** no page cross! *** +00D3F5: C9 AA >100 CMP #$AA +00D3F7: D0 02 =D3FB >101 BNE RdErr ;Error if nonmatch +00D3F9: 18 >102 CLC ;Clear carry on +00D3FA: 60 >103 RTS ;Normal read exits + >104 +00D3FB: 38 >105 RdErr SEC +00D3FC: 60 >106 RTS + >107 ************************** + >108 * * + >109 * read subroutine * + >110 * (16-sector format) * + >111 * * + >112 ************************** + >113 * * + >114 * reads encoded bytes * + >115 * into nbuf1 and nbuf2 * + >116 * * + >117 * first reads nbuf2 * + >118 * high to low, * + >119 * then reads nbuf1 * + >120 * low to high. * + >121 * * + >122 * on entry ---- * + >123 * * + >124 * x-reg: slotnum * + >125 * times $10. * + >126 * * + >127 * read mode (q6l, q7l) * + >128 * * + >129 * on exit ----- * + >130 * * + >131 * carry set if error. * + >132 * * + >133 * if no error: * + >134 * a-reg holds $aa. * + >135 * x-reg unchanged. * + >136 * y-reg holds $00. * + >137 * carry clear. * + >138 * caution ----- * + >139 * * + >140 * observe * + >141 * 'no page cross' * + >142 * warnings on * + >143 * some branches!! * + >144 * * + >145 * assumes ---- * + >146 * * + >147 * 1 usec cycle time * + >148 * * + >149 ************************** + >150 +00D3FD: 8A >151 Read16 TXA ;Get slot # +00D3FE: 09 8C >152 ORA #$8C ;Prepare mods to read routine +00D400: 8D 5A D4 >153 STA Read4+1 ;Warning: the read routine is self modified!!! +00D403: 8D 73 D4 >154 STA Read5+1 +00D406: 8D 89 D4 >155 STA Read6+1 +00D409: 8D 9D D4 >156 STA Read7+1 +00D40C: 8D B2 D4 >157 STA Read8+1 +00D40F: A5 44 >158 LDA bufPtr ;Modify storage addresses also +00D411: A4 45 >159 LDY bufPtr+1 +00D413: 8D AF D4 >160 STA Ref3+1 +00D416: 8C B0 D4 >161 STY Ref3+2 +00D419: 38 >162 SEC +00D41A: E9 54 >163 SBC #$54 +00D41C: B0 01 =D41F >164 BCS :1 +00D41E: 88 >165 DEY +00D41F: 8D 97 D4 >166 :1 STA Ref2+1 +00D422: 8C 98 D4 >167 STY Ref2+2 +00D425: 38 >168 SEC +00D426: E9 57 >169 SBC #$57 +00D428: B0 01 =D42B >170 BCS :2 ;Branch if no borrow +00D42A: 88 >171 DEY +00D42B: 8D 70 D4 >172 :2 STA Ref1+1 +00D42E: 8C 71 D4 >173 STY Ref1+2 +00D431: A0 20 >174 LDY #$20 ;'must find count' +00D433: 88 >175 rSync DEY +00D434: F0 37 =D46D >176 BEQ RdErr2 ;Branch if can't find data header marks +00D436: BD 8C C0 >177 LDA q6l,X +00D439: 10 FB =D436 >178 BPL *-3 +00D43B: 49 D5 >179 rSync1 EOR #$D5 ;First data mark +00D43D: D0 F4 =D433 >180 BNE rSync +00D43F: EA >181 NOP ;Waste a little time... +00D440: BD 8C C0 >182 LDA q6l,X +00D443: 10 FB =D440 >183 BPL *-3 +00D445: C9 AA >184 CMP #$AA ;Data mark 2 +00D447: D0 F2 =D43B >185 BNE rSync1 ;If not, check for first again +00D449: EA >186 NOP +00D44A: BD 8C C0 >187 LDA q6l,X +00D44D: 10 FB =D44A >188 BPL *-3 +00D44F: C9 AD >189 CMP #$AD ;Data mark 3 +00D451: D0 E8 =D43B >190 BNE rSync1 ;If not, check for data mark 1 again +00D453: A0 AA >191 LDY #$AA +00D455: A9 00 >192 LDA #$00 +00D457: 85 3A >193 RdData1 STA wTemp ;Use zpage for checksum keepin +00D459: AE EC C0 >194 Read4 LDX $C0EC ;Warning: self modified +00D45C: 10 FB =D459 >195 BPL Read4 +00D45E: BD 00 D1 >196 LDA dNibble,X +00D461: 99 56 D2 >197 STA nBuf2-$AA,Y ;Save the two-bit groups in nbuf +00D464: 45 3A >198 EOR wTemp ;Update checksum +00D466: C8 >199 INY ;Bump to next nBuf2 position +00D467: D0 EE =D457 >200 BNE RdData1 ;Loop for all $56 two-bit groups +00D469: A0 AA >201 LDY #$AA ;Now read directly into user buffer +00D46B: D0 05 =D472 >202 BNE Read5 ;Branch always taken!!! +00D46D: 38 >203 RdErr2 SEC +00D46E: 60 >204 RTS + >205 +00D46F: 99 00 10 >206 Ref1 STA $1000,Y ;Warning: self modified! + >207 +00D472: AE EC C0 >208 Read5 LDX $C0EC +00D475: 10 FB =D472 >209 BPL Read5 +00D477: 5D 00 D1 >210 EOR dNibble,X ;Get actual 6-bit data from dNibble table +00D47A: BE 56 D2 >211 LDX nBuf2-$AA,Y ;Get associated two-bit pattern +00D47D: 5D 00 D2 >212 EOR dNibble2,X ; & combine to form whole byte +00D480: C8 >213 INY +00D481: D0 EC =D46F >214 BNE Ref1 ;Loop for $56 bytes +00D483: 48 >215 PHA ;Save this byte for now, no time to store... +00D484: 29 FC >216 AND #$FC ;Strip low 2 bits... +00D486: A0 AA >217 LDY #$AA ;Prepare for next $56 bytes +00D488: AE EC C0 >218 Read6 LDX $C0EC +00D48B: 10 FB =D488 >219 BPL Read6 +00D48D: 5D 00 D1 >220 EOR dNibble,X +00D490: BE 56 D2 >221 LDX nBuf2-$AA,Y +00D493: 5D 01 D2 >222 EOR dNibble3,X +00D496: 99 00 10 >223 Ref2 STA $1000,Y ;Warning: self modified +00D499: C8 >224 INY +00D49A: D0 EC =D488 >225 BNE Read6 ;Loop until this group of $56 read in + >226 * +00D49C: AE EC C0 >227 Read7 LDX $C0EC +00D49F: 10 FB =D49C >228 BPL Read7 +00D4A1: 29 FC >229 AND #$FC +00D4A3: A0 AC >230 LDY #$AC ;Last group is $54 long +00D4A5: 5D 00 D1 >231 RdData2 EOR dNibble,X +00D4A8: BE 54 D2 >232 LDX nBuf2-$AC,Y +00D4AB: 5D 02 D2 >233 EOR dNibble4,X ;Combine to form full byte +00D4AE: 99 00 10 >234 Ref3 STA $1000,Y +00D4B1: AE EC C0 >235 Read8 LDX $C0EC ;Warning: self modified +00D4B4: 10 FB =D4B1 >236 BPL Read8 +00D4B6: C8 >237 INY +00D4B7: D0 EC =D4A5 >238 BNE RdData2 +00D4B9: 29 FC >239 AND #$FC +00D4BB: 5D 00 D1 >240 EOR dNibble,X ;Check sum ok? +00D4BE: D0 0C =D4CC >241 BNE RdErr1 ;Branch if not +00D4C0: A6 3E >242 LDX slotZ ;Test end marks +00D4C2: BD 8C C0 >243 LDA q6l,X +00D4C5: 10 FB =D4C2 >244 BPL *-3 +00D4C7: C9 DE >245 CMP #$DE +00D4C9: 18 >246 CLC +00D4CA: F0 01 =D4CD >247 BEQ RdOK ;Branch if good trailer... +00D4CC: 38 >248 RdErr1 SEC +00D4CD: 68 >249 RdOK PLA +00D4CE: A0 55 >250 LDY #$55 ;Place last byte into user buffer +00D4D0: 91 44 >251 STA (bufPtr),Y +00D4D2: 60 >252 RTS + >253 + >254 * This subroutine sets the slot + >255 * dependent track location. + >256 +00D4D3: 20 F1 D4 >257 SetTrk JSR DrvIndx ;Get index to drive number +00D4D6: 9D 59 D3 >258 STA drv0Trk,X +00D4D9: 60 >259 RTS + >260 ***************************************** + >261 * + >262 * Subrtn to tell if motor is stopped + >263 * + >264 * If motor is stopped, controller's + >265 * shift reg will not be changing. + >266 * + >267 * return y=0 and zero flag set if it is stopped. + >268 * + >269 ***************************************** +00D4DA: A6 3E >270 ChkDrv LDX slotZ +00D4DC: A0 00 >271 ChkDrv0 LDY #$00 ;init loop counter +00D4DE: BD 8C C0 >272 :loop LDA q6l,X ;read the shift reg +00D4E1: 20 F0 D4 >273 JSR :ChkDrvRTS ;delay +00D4E4: 48 >274 PHA +00D4E5: 68 >275 PLA ;more delay +00D4E6: DD 8C C0 >276 CMP q6l,X +00D4E9: D0 05 =D4F0 >277 BNE :ChkDrvRTS +00D4EB: A9 28 >278 LDA #$28 +00D4ED: 88 >279 DEY +00D4EE: D0 EE =D4DE >280 BNE :loop +00D4F0: 60 >281 :ChkDrvRTS RTS + >282 +00D4F1: 48 >283 DrvIndx PHA ;Preserve Acc +00D4F2: A5 43 >284 LDA unitNum ;DSSS xxxx where D=0/1 & SSS=slot # +00D4F4: 4A >285 LSR +00D4F5: 4A >286 LSR +00D4F6: 4A >287 LSR +00D4F7: 4A >288 LSR ;0000 DSSS +00D4F8: C9 08 >289 CMP #$08 ;C=1 -> drive 2 +00D4FA: 29 07 >290 AND #$07 ;0000 0SSS +00D4FC: 2A >291 ROL ;0000 SSSD +00D4FD: AA >292 TAX ;Into X for index to table +00D4FE: 68 >293 PLA ;Restore A +00D4FF: 60 >294 RTS + >295 ************************ + >296 * * + >297 * write subr * + >298 * (16-sector format) * + >299 * * + >300 ************************ + >301 * * + >302 * writes data from * + >303 * nbuf1 and buf * + >304 * * + >305 * first nbuf2, * + >306 * high to low. * + >307 * then direct from * + >308 * (buf), low to high. * + >309 * self modified code!! * + >310 * on entry ---- * + >311 * * + >312 * x-reg: slotnum * + >313 * times $10. * + >314 * * + >315 * * + >316 * on exit ----- * + >317 * * + >318 * carry set if error. * + >319 * (w prot violation) * + >320 * * + >321 * if no error: * + >322 * * + >323 * a-reg uncertain. * + >324 * x-reg unchanged. * + >325 * y-reg holds $00. * + >326 * carry clear. * + >327 * * + >328 * assumes ---- * + >329 * * + >330 * 1 usec cycle time * + >331 * * + >332 ************************ + >333 +00D500: 38 >334 Write16 SEC ;Anticipate wprot err +00D501: BD 8D C0 >335 LDA q6h,X +00D504: BD 8E C0 >336 LDA q7l,X ;Sense wprot flag +00D507: 10 03 =D50C >337 BPL :1 +00D509: 4C DF D5 >338 JMP WExit ;Exit if write protected + >339 +00D50C: AD 00 D3 >340 :1 LDA nBuf2 +00D50F: 85 3A >341 STA wTemp +00D511: A9 FF >342 LDA #$FF ;Sync data +00D513: 9D 8F C0 >343 STA q7h,X ;(5) Goto write mode +00D516: 1D 8C C0 >344 ORA q6l,X ;(4) +00D519: A0 04 >345 LDY #$04 ;(2) For five nibbles +00D51B: EA >346 NOP ;(2) +00D51C: 48 >347 PHA ;(3) +00D51D: 68 >348 PLA ;(4) +00D51E: 48 >349 WSync PHA ;(3) exact timing +00D51F: 68 >350 PLA ;(4) exact timing +00D520: 20 E7 D5 >351 JSR WrNibl7 ;(13,9,6) write sync +00D523: 88 >352 DEY ;(2) +00D524: D0 F8 =D51E >353 BNE WSync ;(3-) must not cross page! +00D526: A9 D5 >354 LDA #$D5 ;(2) 1st data mark +00D528: 20 E6 D5 >355 JSR WrNibl9 ;(15,9,6) +00D52B: A9 AA >356 LDA #$AA ;(2) 2nd data mark +00D52D: 20 E6 D5 >357 JSR WrNibl9 ;(15,9,6) +00D530: A9 AD >358 LDA #$AD ;(2) 3rd data mark +00D532: 20 E6 D5 >359 JSR WrNibl9 ;(15,9,6) +00D535: 98 >360 TYA ;(2) zero checksum +00D536: A0 56 >361 LDY #$56 ;(2) nbuf2 index +00D538: D0 03 =D53D >362 BNE wData1 ;(3) branch always taken +00D53A: B9 00 D3 >363 wData0 LDA nBuf2,Y ;(4) prior 6-bit nibble +00D53D: 59 FF D2 >364 wData1 EOR nBuf2-1,Y ;(5) xor with current +00D540: AA >365 TAX ;(2) index to 7-bit nibl (nBuf2 must be on page bdry) +00D541: BD 03 D2 >366 LDA Nibbles,X ;(4) must not cross page boundary +00D544: A6 3E >367 LDX slotZ ;(3) restore slot index +00D546: 9D 8D C0 >368 STA q6h,X ;(5) store encoded byte +00D549: BD 8C C0 >369 LDA q6l,X ;(4) time must = 32 us per byte! +00D54C: 88 >370 DEY ;(2) +00D54D: D0 EB =D53A >371 BNE wData0 ;(3-) must not cross page boundary +00D54F: A5 3A >372 LDA wTemp ;(3) get prior nibble (from nBuf2) +00D551: A0 00 >373 WRefDr1 LDY #$00 ;(2) warning: load value modified by prenib! + =D553 >374 WData2 EQU * +00D553: 59 00 10 >375 WRefAdr1 EOR $1000,Y ;(4) warning: address modified by prenib! +00D556: 29 FC >376 AND #$FC ;(2) +00D558: AA >377 TAX ;(2) index to Nibbles table +00D559: BD 03 D2 >378 LDA Nibbles,X ;(4) +00D55C: A2 60 >379 WRefDr2 LDX #$60 ;(2) warning: load value modified by prenib +00D55E: 9D 8D C0 >380 STA q6h,X ;(5) write nibl +00D561: BD 8C C0 >381 LDA q6l,X ;(4) handshake +00D564: B9 00 10 >382 WRefAdr2 LDA $1000,Y ;(4) prior nibl. warning: address modified by prenib +00D567: C8 >383 INY ;(2) all done with this page? +00D568: D0 E9 =D553 >384 BNE WData2 ;(3-) loop until page end + >385 +00D56A: A5 3B >386 LDA midNib1 ;(3) get next (precalculated and translated) nibl +00D56C: F0 52 =D5C0 >387 BEQ WrtDone ;(2+) branch if code writen was page aligned +00D56E: A5 3F >388 LDA yEnd ;(3) get byte address of last byte to be written +00D570: F0 41 =D5B3 >389 BEQ WData4 ;(2+) branch if only 1 byte left to write +00D572: 4A >390 LSR ;(2) test for odd or even last byte (carry set or clear) +00D573: A5 3B >391 LDA midNib1 ;(3) restore nibl to a +00D575: 9D 8D C0 >392 STA q6h,X ;(5) +00D578: BD 8C C0 >393 LDA q6l,X ;(4) +00D57B: A5 3C >394 LDA midNib2 ;(3) =byte 0 of second page. xor'd with byte 1 if above test set carry +00D57D: EA >395 NOP ;(2) waste time +00D57E: C8 >396 INY ;(2) y=1 +00D57F: B0 18 =D599 >397 BCS WrtOdd ;(2+) branch if last byte to be odd + >398 + =D581 >399 WData3 EQU * +00D581: 59 00 11 >400 WRefAdr3 EOR $1100,Y ;(4) warning: address modified by prenib +00D584: 29 FC >401 AND #$FC ;(2) strip low 2 bits +00D586: AA >402 TAX ;(2) index to Nibbles table +00D587: BD 03 D2 >403 LDA Nibbles,X ;(4) get nibble +00D58A: A2 60 >404 WRefDr3 LDX #$60 ;(2) restore slot index. warning: modified by prenib +00D58C: 9D 8D C0 >405 STA q6h,X ;(5) +00D58F: BD 8C C0 >406 LDA q6l,X ;(4) +00D592: B9 00 11 >407 WRefAdr4 LDA $1100,Y ;(4) warning: modified by prenib +00D595: C8 >408 INY ;(2) got prior nibble, bump to next +00D596: 59 00 11 >409 WRefAdr5 EOR $1100,Y ;(4) warning: modified by prenib +00D599: C4 3F >410 WrtOdd CPY yEnd ;(3) set carry if this is last nibble +00D59B: 29 FC >411 AND #$FC ;(2) +00D59D: AA >412 TAX ;(2) +00D59E: BD 03 D2 >413 LDA Nibbles,X ;(4) +00D5A1: A2 60 >414 WRefDr4 LDX #$60 ;(2) restore slot. warning: modified by prenib +00D5A3: 9D 8D C0 >415 STA q6h,X ;(5) +00D5A6: BD 8C C0 >416 LDA q6l,X ;(4) +00D5A9: B9 00 11 >417 WRefAdr6 LDA $1100,Y ;(4) get prior. warning: these warnings are all the same +00D5AC: C8 >418 INY ;(2) +00D5AD: 90 D2 =D581 >419 BCC WData3 ;(3-) branch if that was not the las +00D5AF: B0 00 =D5B1 >420 BCS *+2 ;(3) waste 3 cycles, branch always +00D5B1: B0 0D =D5C0 >421 BCS WrtDone ;(3) branch always + >422 +00D5B3: AD 3B 00 >423 WData4 LDA |midNib1 ;(4) absolute reference to zero page +00D5B6: 9D 8D C0 >424 STA q6h,X ;(5) +00D5B9: BD 8C C0 >425 LDA q6l,X ;(4) +00D5BC: 48 >426 PHA ;(3) waste 14 us total +00D5BD: 68 >427 PLA ;(4) +00D5BE: 48 >428 PHA ;(3) +00D5BF: 68 >429 PLA ;(4) +00D5C0: A6 3D >430 WrtDone LDX lstNib ;(3) use last nibl (anded with $fc) for checksum +00D5C2: BD 03 D2 >431 LDA Nibbles,X ;(4) +00D5C5: A2 60 >432 WRefDr5 LDX #$60 ;(2) restore slot. warning: see above warnings... +00D5C7: 9D 8D C0 >433 STA q6h,X ;(5) +00D5CA: BD 8C C0 >434 LDA q6l,X ;(4) +00D5CD: A0 00 >435 LDY #$00 ;(2) set y to index end mark table +00D5CF: 48 >436 PHA ;(3) waste another 11 us +00D5D0: 68 >437 PLA ;(4) +00D5D1: EA >438 NOP ;(2) +00D5D2: EA >439 NOP ;(2) +00D5D3: B9 C4 D1 >440 WrEndMrk LDA EndMarks,Y ;(4) dm4, dm5, dm6, and turn off byte +00D5D6: 20 E9 D5 >441 JSR WrNibl ;(15,6) write it +00D5D9: C8 >442 INY ;(2) +00D5DA: C0 04 >443 CPY #$04 ;(2) have all end marks been written? +00D5DC: D0 F5 =D5D3 >444 BNE WrEndMrk ;(3) +00D5DE: 18 >445 CLC ;(2,9) +00D5DF: BD 8E C0 >446 WExit LDA q7l,X ;Out of write mode +00D5E2: BD 8C C0 >447 LDA q6l,X ;Into read mode +00D5E5: 60 >448 RTS ;Return from write + >449 **************************** + >450 * * + >451 * 7-bit nibl write subrs * + >452 * * + >453 * a-reg or'd prior exit * + >454 * carry cleared * + >455 * * + >456 **************************** + >457 +00D5E6: 18 >458 WrNibl9 CLC ;(2) 9 cycles, then write +00D5E7: 48 >459 WrNibl7 PHA ;(3) 7 cycles, then write +00D5E8: 68 >460 PLA ;(4) +00D5E9: 9D 8D C0 >461 WrNibl STA q6h,X ;(5) nibble write subrtn +00D5EC: 1D 8C C0 >462 ORA q6l,X ;(4) clobbers acc, not carry +00D5EF: 60 >463 RTS ;(6) + >464 **************************** + >465 * * + >466 * preniblize subr * + >467 * (16-sector format) * + >468 * * + >469 **************************** + >470 * * + >471 * converts 256 bytes of * + >472 * user data in (buf) into * + >473 * 6 bit nibls into nbuf2 * + >474 * high 6 bits are trans- * + >475 * lated directly by the * + >476 * write routines. * + >477 * * + >478 * on entry ---- * + >479 * * + >480 * buf is 2-byte pointer * + >481 * to 256 bytes of user * + >482 * data. * + >483 * * + >484 * on exit ----- * + >485 * * + >486 * a,x,y undefined. * + >487 * write routine modified * + >488 * to do direct conversion * + >489 * of high 6 bits of users * + >490 * buffer data. * + >491 **************************** + >492 +00D5F0: A5 44 >493 PreNibl16 LDA bufPtr ;First self modify addresses so we can be fast! +00D5F2: A4 45 >494 LDY bufPtr+1 ;Y contains high order address +00D5F4: 18 >495 CLC ;All offsets are -$AA... +00D5F5: 69 02 >496 ADC #$02 ;The highest set is bufPtr+$AC +00D5F7: 90 01 =D5FA >497 BCC :1 ;Branch if no carry +00D5F9: C8 >498 INY ;Otherwise add carry to high address +00D5FA: 8D 30 D6 >499 :1 STA PrN3+1 ;Self mod 3 +00D5FD: 8C 31 D6 >500 STY PrN3+2 +00D600: 38 >501 SEC +00D601: E9 56 >502 SBC #$56 ;middle set is buf+$56 +00D603: B0 01 =D606 >503 BCS :2 ;branch if no borrow +00D605: 88 >504 DEY ;otherwise deduct from high... +00D606: 8D 25 D6 >505 :2 STA PrN2+1 ;self mod 2 +00D609: 8C 26 D6 >506 STY PrN2+2 +00D60C: 38 >507 SEC +00D60D: E9 56 >508 SBC #$56 ;Low set is exactly bufPtr +00D60F: B0 01 =D612 >509 BCS :3 +00D611: 88 >510 DEY +00D612: 8D 1B D6 >511 :3 STA PrN1+1 ;self mod 1 +00D615: 8C 1C D6 >512 STY PrN1+2 + >513 +00D618: A0 AA >514 LDY #$AA ;Count up to 0 + =D61A >515 PreNib4 EQU * +00D61A: B9 00 10 >516 PrN1 LDA $1000,Y ;Fetch byte from lowest group. warning: self modified +00D61D: 29 03 >517 AND #%00000011 ;Strip high 6 bits +00D61F: AA >518 TAX ;Index to 2 bit equiv +00D620: BD E0 D1 >519 LDA TwoBit1,X +00D623: 48 >520 PHA ;save pattern +00D624: B9 56 10 >521 PrN2 LDA $1056,Y ;fetch from middle group +00D627: 29 03 >522 AND #%00000011 +00D629: AA >523 TAX +00D62A: 68 >524 PLA ;Restore pattern +00D62B: 1D C0 D1 >525 ORA TwoBit2,X ;Combine second group with first +00D62E: 48 >526 PHA ;Save new pattern +00D62F: B9 AC 10 >527 PrN3 LDA $10AC,Y ;Get highest group +00D632: 29 03 >528 AND #%00000011 +00D634: AA >529 TAX +00D635: 68 >530 PLA ;Restore new pattern +00D636: 1D A0 D1 >531 ORA TwoBit3,X ; & form final nibble +00D639: 48 >532 PHA +00D63A: 98 >533 TYA +00D63B: 49 FF >534 EOR #$FF +00D63D: AA >535 TAX +00D63E: 68 >536 PLA +00D63F: 9D 00 D3 >537 STA nBuf2,X ;Save in nibble buffer! +00D642: C8 >538 INY ;Bump to next set +00D643: D0 D5 =D61A >539 BNE PreNib4 ;Loop until all $56 nibbles formed +00D645: A4 44 >540 LDY bufPtr ;Now prepare data bytes for write16 routine +00D647: 88 >541 DEY ;Prepare end addr +00D648: 84 3F >542 STY yEnd +00D64A: A5 44 >543 LDA bufPtr +00D64C: 8D 52 D5 >544 STA WRefDr1+1 ;warning: the following storage addresses starting +00D64F: F0 0E =D65F >545 BEQ WrMod1 ; with 'wref' are referces into code space, +00D651: 49 FF >546 EOR #$FF ; changed by this routine +00D653: A8 >547 TAY ;Index to last byte of page pointed to by buf +00D654: B1 44 >548 LDA (bufPtr),Y ;Pre-niblize the last byte of the page with +00D656: C8 >549 INY ; the first byte of the next page +00D657: 51 44 >550 EOR (bufPtr),Y +00D659: 29 FC >551 AND #$FC +00D65B: AA >552 TAX +00D65C: BD 03 D2 >553 LDA Nibbles,X ;Get disk 7-bit nibble equivalent +00D65F: 85 3B >554 WrMod1 STA midNib1 +00D661: F0 0C =D66F >555 BEQ WrMod3 ;Branch if data to be written is page aligned +00D663: A5 3F >556 LDA yEnd ;Find out if last byte is even or odd address +00D665: 4A >557 LSR ;Shift even/oddness into carry +00D666: B1 44 >558 LDA (bufPtr),Y ;If even, then leave intact +00D668: 90 03 =D66D >559 BCC WrMod2 ;Branch if odd +00D66A: C8 >560 INY ;If even, then pre-xor with byte 1 +00D66B: 51 44 >561 EOR (bufPtr),Y +00D66D: 85 3C >562 WrMod2 STA midNib2 ;Save result for write routine +00D66F: A0 FF >563 WrMod3 LDY #$FF ;Index to last byte of data to be writen +00D671: B1 44 >564 LDA (bufPtr),Y ; to be used as checksum +00D673: 29 FC >565 AND #$FC ;Strip extra bits +00D675: 85 3D >566 STA lstNib ;Save it +00D677: A4 45 >567 LDY bufPtr+1 ;Now modify address reference to user data +00D679: 8C 55 D5 >568 STY WRefAdr1+2 +00D67C: 8C 66 D5 >569 STY WRefAdr2+2 +00D67F: C8 >570 INY +00D680: 8C 83 D5 >571 STY WRefAdr3+2 +00D683: 8C 94 D5 >572 STY WRefAdr4+2 +00D686: 8C 98 D5 >573 STY WRefAdr5+2 +00D689: 8C AB D5 >574 STY WRefAdr6+2 +00D68C: A6 3E >575 LDX slotZ ; & lastly index references to controller +00D68E: 8E 5D D5 >576 STX WRefDr2+1 +00D691: 8E 8B D5 >577 STX WRefDr3+1 +00D694: 8E A2 D5 >578 STX WRefDr4+1 +00D697: 8E C6 D5 >579 STX WRefDr5+1 +00D69A: 60 >580 RTS ;All done + >581 +00D69B: 4D 59 D3 >582 ChkPrev EOR iobPrevDn ;Same slot as last? +00D69E: 0A >583 ASL +00D69F: F0 1C =D6BD >584 BEQ :Rtn ;Yes +00D6A1: A9 01 >585 LDA #$01 +00D6A3: 8D 70 D3 >586 STA monTimeH +00D6A6: AD 59 D3 >587 :CkLoop LDA iobPrevDn ;=DSSS xxxx +00D6A9: 29 70 >588 AND #$70 ;=0SSS 0000 +00D6AB: AA >589 TAX +00D6AC: F0 0F =D6BD >590 BEQ :Rtn ;Branch if no previous ever (boot only) +00D6AE: 20 DC D4 >591 JSR ChkDrv0 ;Find out if previous drive running +00D6B1: F0 0A =D6BD >592 BEQ :Rtn ;Branch if stopped +00D6B3: A9 01 >593 LDA #$01 ;Waste some time +00D6B5: 20 85 D3 >594 JSR msWait +00D6B8: AD 70 D3 >595 LDA monTimeH +00D6BB: D0 E9 =D6A6 >596 BNE :CkLoop +00D6BD: 60 >597 :Rtn RTS + >598 + >599 * ----------------- see rev notes 14, 18 & 70 ------------- + >600 +00D6BE: A5 43 >601 ResetPhase LDA unitNum ;Get unit number +00D6C0: 29 7F >602 AND #$7F ;Map off hi bit (drive bit) +00D6C2: AA >603 TAX + >604 + >605 * clear all the phases and force read mode + >606 * patch 76 part 2. part 1 is in xrw1. + >607 +00D6C3: BD 80 C0 >608 LDA phaseOff,X ;make sure all motor +00D6C6: BD 82 C0 >609 LDA phaseOff+2,X ; phases are off +00D6C9: BD 84 C0 >610 LDA phaseOff+4,X +00D6CC: BD 86 C0 >611 LDA phaseOff+6,X +00D6CF: 60 >612 RTS + >613 + >614 * --------------------------------------------------------- +00D6D0: A5 42 >615 doCheck LDA dhpCmd ;Get the command number +00D6D2: C9 04 >616 CMP #maxCmd ;Is the command allowable? +00D6D4: B0 10 =D6E6 >617 BCS doChkBad ;Branch if not! +00D6D6: A5 46 >618 LDA blockNum +00D6D8: A6 47 >619 LDX blockNum+1 +00D6DA: 8E 56 D3 >620 STX ibTrk ;Calculate block's track & sector +00D6DD: F0 09 =D6E8 >621 BEQ doChkOK ;Branch if block # in range +00D6DF: CA >622 DEX ;else test further +00D6E0: D0 04 =D6E6 >623 BNE doChkBad ;Bad range +00D6E2: C9 18 >624 CMP #$18 ;Must be <$118 (280) +00D6E4: 90 02 =D6E8 >625 BCC doChkOK +00D6E6: 38 >626 doChkBad SEC ;Set carry for an error +00D6E7: 60 >627 RTS + >628 +00D6E8: 18 >629 doChkOK CLC +00D6E9: 60 >630 RTS + >631 +00D6EA: 00 00 >632 LD6EA DS 2,0 ;Not used + >633 + >634 * --------------------------------------------------------- + >635 * Variables for handling mirror devices + >636 * NB. Values of SmartPort unit #s: $00, $01-$7E + >637 * Status List - ref pg 122 IIGS Firmware + >638 + =D6EC >639 spStatList EQU * +00D6EC: 00 >640 genStatus DB 0 +00D6ED: 00 00 00 >641 spDevTotBlks DB 0,0,0 ;# of blocks + >642 +00D6F0: 00 00 00 00 >643 spUnits DS $F,0 ;table of SmartPort unit #s +00D6FF: 00 >644 DB 0 + 45 PUT mli.src/SEL0 + >1 *********************************************************** + >2 * * + >3 * PRODOS 8 LOBOTOMIZED DISPATCHER ROUTINE * + >4 * * + >5 * COPYRIGHT APPLE COMPUTER, INC., 1983-86 * + >6 * * + >7 * ALL RIGHTS RESERVED * + >8 * * + >9 *********************************************************** + >10 + >12 *********************************************************** + >13 * + >14 * DISPATCHER 1 - This code ORGs and operates at $1000 but + >15 * is resident in memory at $D100 in the Alt 4K bank of the + >16 * Language Card. The QUIT call vectors to a routine high + >17 * in the MLI that moves DISPATCHER 1 down and jumps to it. + >18 * The move routine MUST remain somewhere between $E000-$F7FF. + >19 * + >20 * NOTE: This entire routine MUST remain no larger than 3 pages. + >21 * + >22 *********************************************************** + >23 + >24 ORG $1000 + >25 MX %11 +001000: AD 82 C0 >26 HereIn LDA RDROM2 +001003: 8D 0C C0 >27 STA CLR80VID ;Disable 80 column hardware +001006: 8D 0E C0 >28 STA CLRALTCHAR ;Switch in primary char set +001009: 8D 00 C0 >29 STA CLR80COL ;Disable 80 column store +00100C: 20 84 FE >30 JSR SetNorm ;Normal white chars on black background +00100F: 20 2F FB >31 JSR Init ;Text pg1; text mode; set 40 col window +001012: 20 93 FE >32 JSR SetVid ;Does a PR#0 (puts COUT1 in CSW) +001015: 20 89 FE >33 JSR SetKBD ;Does an IN#0 to set Basic input to kbd + >34 **************************************************** + >35 * + >36 * Clear the memory Bit Map + >37 +001018: A2 17 >38 ClrMap LDX #$17 ;Do all the bytes +00101A: A9 01 >39 LDA #$01 +00101C: 9D 58 BF >40 STA memTabl,X ;Protect page $BF00 +00101F: CA >41 DEX +001020: A9 00 >42 LDA #$00 ;Clear the rest +001022: 9D 58 BF >43 :ClrLoop STA memTabl,X +001025: CA >44 DEX +001026: 10 FA =1022 >45 BPL :ClrLoop +001028: A9 CF >46 LDA #%11001111 +00102A: 8D 58 BF >47 STA memTabl ;Protect pages 0,1 & $400-$7FF (Screen) + =102D >48 Start EQU * + >49 + >50 ***************** See Rev Note #55 ********************* + >51 +00102D: 20 58 FC >52 JSR HOME ;Clear the screen +001030: 20 8E FD >53 JSR CROUT +001033: A2 00 >54 LDX #55 JSR PrntLoop +001038: A9 03 >56 LDA #3 ;Set CV to 3rd line +00103A: 85 25 >57 STA CV +00103C: 20 8E FD >58 JSR CROUT ; & col 1 +00103F: 20 00 BF >59 JSR GoPro ;Call the MLI (Remember, this code executes at $1000) +001042: C7 >60 DB $C7 +001043: C8 12 >61 DA Prefix +001045: AE 80 02 >62 LDX pnBuf ;Get PREFIX length +001048: A9 00 >63 LDA #$00 ;Put a 0 at end of Prefix +00104A: 9D 81 02 >64 STA pnBuf+1,X + >65 + >66 ******************* See Rev Note #69 ******************* + >67 +00104D: AE 80 02 >68 LDX pnBuf ;Get length byte back +001050: F0 0B =105D >69 BEQ NilPfx ;Branch if no prefix to display!!! +001052: BD 80 02 >70 :loop LDA pnBuf,X ;Display prefix directly +001055: 09 80 >71 ORA #$80 ;Set hi bit for NORMAL text +001057: 9D FF 05 >72 STA SLIN04-1,X ; to the screen +00105A: CA >73 DEX +00105B: D0 F5 =1052 >74 BNE :loop + >75 +00105D: A2 00 >76 NilPfx LDX #$00 +00105F: C6 25 >77 DEC CV +001061: 20 8E FD >78 JSR CROUT ;Put the cursor on the first char +001064: 20 0C FD >79 GetKey JSR RDKEY ;Wait for keyboard input +001067: C9 8D >80 CMP #$8D ;Is it CR? +001069: F0 52 =10BD >81 BEQ GotPfx ;Yes, and we accept what was entered +00106B: 48 >82 PHA ;No, save the char +00106C: 20 9C FC >83 JSR CLREOL ;Clear rest of line +00106F: 68 >84 PLA ;Get char back +001070: C9 9B >85 CMP #$9B ;Is it ESC? +001072: F0 B9 =102D >86 BEQ Start ;Yes, start over again +001074: C9 98 >87 CMP #$98 ;If it is CTRL-X, start over +001076: F0 B5 =102D >88 ReStrt BEQ Start ;(Used as an extended BEQ from PRMPT) +001078: C9 89 >89 CMP #$89 ;Is it TAB? +00107A: F0 17 =1093 >90 BEQ BadKey ;No good if it is! +00107C: C9 FF >91 CMP #$FF ;Delete? +00107E: F0 04 =1084 >92 BEQ :1 ;Branch if it is +001080: C9 88 >93 CMP #$88 ;Back Space? +001082: D0 0D =1091 >94 BNE NotBS +001084: E0 00 >95 :1 CPX #$00 ;If it is, are we at col 0? +001086: F0 03 =108B >96 BEQ *+5 ;If col 0, do nothing +001088: C6 24 >97 DEC CH ; else move left 1 char +00108A: CA >98 DEX ; decrement char count, +00108B: 20 9C FC >99 JSR CLREOL ; clear rest of line +00108E: 4C 64 10 >100 JMP GetKey ;Go get another char + >101 +001091: B0 06 =1099 >102 NotBS BCS Maybe +001093: 20 3A FF >103 BadKey JSR BELL ;Ring the speaker (bell) if it isn't +001096: 4C 64 10 >104 JMP GetKey + >105 +001099: C9 DB >106 Maybe CMP #$DB ;Ok, is it below 'Z'? +00109B: 90 02 =109F >107 BCC *+4 ;Branch if yes +00109D: 29 DF >108 AND #$DF ;If not, shift it up upper case +00109F: C9 AE >109 CMP #$AE ;Is it below "."? +0010A1: 90 F0 =1093 >110 BCC BadKey ;If yes, it ain't good! +0010A3: C9 DB >111 CMP #$DB ;Is it above "Z"? +0010A5: B0 EC =1093 >112 BCS BadKey ;If so, it also ain't good +0010A7: C9 BA >113 CMP #$BA ;Is it below ":"? ("." - "9" range) +0010A9: 90 04 =10AF >114 BCC GoodKey ;Yes, it's good! +0010AB: C9 C1 >115 CMP #$C1 ;If not, is it at or above "A"? ("A" - "Z") +0010AD: 90 E4 =1093 >116 BCC BadKey ;No, reject it +0010AF: E8 >117 GoodKey INX ;It's OK. Hallelulah! +0010B0: E0 27 >118 CPX #39 ;Were there more than 39 chars? +0010B2: B0 C2 =1076 >119 BCS ReStrt ;Yes, too many! Go restart +0010B4: 9D 80 02 >120 STA pnBuf,X ;No, save the lucky char +0010B7: 20 ED FD >121 JSR COUT ;Print it +0010BA: 4C 64 10 >122 JMP GetKey ; & go get another + >123 +0010BD: E0 00 >124 GotPfx CPX #$00 ;OK, is our Prefix length (chars entered)=0? +0010BF: F0 12 =10D3 >125 BEQ Prmpt ;If yes, don't bother re-setting it +0010C1: 8E 80 02 >126 STX pnBuf ;Set prefix length +0010C4: 20 00 BF >127 JSR GoPro ;Call the MLI +0010C7: C6 >128 DB $C6 +0010C8: C8 12 >129 DA Prefix +0010CA: 90 07 =10D3 >130 BCC Prmpt ;If ok, go get Filename +0010CC: 20 3A FF >131 JSR BELL ;If not, ring Bell +0010CF: A9 00 >132 LDA #$00 ; & try again +0010D1: F0 A3 =1076 >133 BadPfx BEQ ReStrt ;Z flag must be set for extended Branch + >134 +0010D3: 20 58 FC >135 Prmpt JSR HOME ;Clear the screen for application name +0010D6: 20 8E FD >136 JSR CROUT ;Output a CR + >137 ********************* Rev Note #55 ******************* +0010D9: A2 28 >138 LDX #139 JSR PrntLoop +0010DE: A9 03 >140 RetryRich LDA #$03 ;Set CV to 3rd line +0010E0: 85 25 >141 STA CV +0010E2: 20 8E FD >142 JSR CROUT ; & col 1 +0010E5: A2 00 >143 LDX #$00 + >144 + >145 ********************* Rev Note #69 ******************* + >146 +0010E7: 20 0C FD >147 Loop1 JSR RDKEY +0010EA: C9 9B >148 CMP #$9B ;ESC +0010EC: D0 06 =10F4 >149 BNE NotEsc +0010EE: A5 24 >150 LDA CH +0010F0: D0 E1 =10D3 >151 BNE Prmpt +0010F2: F0 DD =10D1 >152 BEQ BadPfx ;If ESC in col 0 go get PREFIX again +0010F4: C9 98 >153 NotEsc CMP #$98 ;CTRL-X +0010F6: F0 DB =10D3 >154 ExtndBr BEQ Prmpt ;(Used as a branch extender) +0010F8: C9 89 >155 CMP #$89 ;TAB +0010FA: F0 0D =1109 >156 BEQ NotGud +0010FC: C9 FF >157 CMP #$FF ;Delete? +0010FE: F0 04 =1104 >158 BEQ :1 +001100: C9 88 >159 CMP #$88 ;BACK SPACE +001102: D0 03 =1107 >160 BNE :2 +001104: 4C C0 11 >161 :1 JMP EatEm ;Eat the previous character + >162 +001107: B0 06 =110F >163 :2 BCS GetIn1 ;> $88 and the char may be acceptable +001109: 20 3A FF >164 NotGud JSR BELL ;Ring the bell (speaker) +00110C: 4C E7 10 >165 JMP Loop1 + >166 +00110F: C9 8D >167 GetIn1 CMP #$8D ;Is it a CR? +001111: F0 29 =113C >168 BEQ GetInpDone +001113: C9 DB >169 CMP #$DB ;> than "Z" +001115: 90 02 =1119 >170 BCC *+4 ;No +001117: 29 DF >171 AND #$DF ;Make sure its Upper case +001119: C9 AE >172 CMP #$AE ;Is it "."? +00111B: 90 EC =1109 >173 BCC NotGud ;Branch if less +00111D: C9 DB >174 CMP #$DB ;Must be less than "[" +00111F: B0 E8 =1109 >175 BCS NotGud +001121: C9 BA >176 CMP #$BA ;OK if less than or equal to "9" +001123: 90 04 =1129 >177 BCC ItsGud +001125: C9 C1 >178 CMP #$C1 ;Else must be > than "A" +001127: 90 E0 =1109 >179 BCC NotGud +001129: 48 >180 ItsGud PHA +00112A: 20 9C FC >181 JSR CLREOL +00112D: 68 >182 PLA +00112E: 20 ED FD >183 JSR COUT ;No, print it +001131: E8 >184 INX +001132: E0 27 >185 CPX #39 +001134: B0 C0 =10F6 >186 BCS ExtndBr +001136: 9D 80 02 >187 STA pnBuf,X +001139: 4C E7 10 >188 JMP Loop1 ;Go get the next one + >189 +00113C: A9 A0 >190 GetInpDone LDA #" " +00113E: 20 ED FD >191 JSR COUT ;After the CR, blank out the cursor +001141: 8E 80 02 >192 STX pnBuf ;Put the length in front of the name + >193 + >194 * At this point the specified Pathname is in pnBuf ($280) + >195 * and we can do a GET_FILE_INFO on it + >196 +001144: 20 00 BF >197 JSR GoPro +001147: C4 >198 DB $C4 +001148: A1 12 >199 DA Info +00114A: 90 03 =114F >200 BCC InfoOK +00114C: 4C E2 11 >201 JMP Error + >202 +00114F: AD A5 12 >203 InfoOK LDA Type +001152: C9 FF >204 CMP #$FF ;Is it a type SYS file? +001154: F0 05 =115B >205 BEQ DoIt +001156: A9 01 >206 LDA #$01 ;Not SYS File +001158: 4C E2 11 >207 JMP Error + >208 +00115B: A9 00 >209 DoIt LDA #$00 ;It's a type SYS all right! +00115D: 8D BA 12 >210 STA ClsNum +001160: 20 00 BF >211 JSR GoPro +001163: CC >212 DB $CC +001164: B9 12 >213 DA Cls ;CLOSE all open files first +001166: 90 03 =116B >214 BCC ChkAcs +001168: 4C E2 11 >215 JMP Error + >216 + >217 * Now check for the proper access + >218 +00116B: AD A4 12 >219 ChkAcs LDA Acess ;Get the allowed access +00116E: 29 01 >220 AND #readEnable ;Is READ disabled? +001170: D0 05 =1177 >221 BNE :1 ;No. Access ok +001172: A9 27 >222 LDA #drvrIOError ;I/O error +001174: 4C E2 11 >223 JMP Error ;Never returns! + >224 +001177: 20 00 BF >225 :1 JSR GoPro +00117A: C8 >226 DB $C8 +00117B: B3 12 >227 DA Opn ;OPEN it +00117D: 90 03 =1182 >228 BCC *+5 +00117F: 4C E2 11 >229 JMP Error + >230 +001182: AD B8 12 >231 LDA RefNum +001185: 8D BC 12 >232 STA ReedNum ;Spread REFNUM around +001188: 8D C4 12 >233 STA eofNum + >234 + >235 * Ok it's OPEN, let's get the EOF + >236 +00118B: 20 00 BF >237 JSR GoPro +00118E: D1 >238 DB $D1 +00118F: C3 12 >239 DA EOF +001191: B0 4F =11E2 >240 BCS Error +001193: AD C7 12 >241 LDA eofB+2 ;3rd of 3 bytes +001196: F0 04 =119C >242 BEQ EOFOK +001198: A9 27 >243 LDA #drvrIOError ;I/O ERROR even though the +00119A: D0 46 =11E2 >244 BNE Error ; file is simply too large +00119C: AD C5 12 >245 EOFOK LDA eofB ;Move EOF to Read # bytes +00119F: 8D BF 12 >246 STA RCount +0011A2: AD C6 12 >247 LDA eofB+1 +0011A5: 8D C0 12 >248 STA RCount+1 +0011A8: 20 00 BF >249 JSR GoPro +0011AB: CA >250 DB $CA ;Do the READ +0011AC: BB 12 >251 DA Reed +0011AE: 08 >252 PHP ;Push the processor status +0011AF: 20 00 BF >253 JSR GoPro +0011B2: CC >254 DB $CC ;Close it +0011B3: B9 12 >255 DA Cls +0011B5: 90 04 =11BB >256 BCC *+6 +0011B7: 28 >257 PLP ;Get status back (it is irrevalent now) +0011B8: D0 28 =11E2 >258 BNE Error ;(if CLOSE generated an error) +0011BA: 28 >259 PLP ;We're here if CLOSE was OK +0011BB: B0 FA =11B7 >260 BCS *-4 ;JMP ERROR +0011BD: 4C 00 20 >261 JMP $2000 + >262 +0011C0: A5 24 >263 EatEm LDA CH ;Is the cursor in col 0? +0011C2: F0 0F =11D3 >264 BEQ EatEmBak ;Yes, ignore it +0011C4: CA >265 DEX +0011C5: A9 A0 >266 LDA #" " +0011C7: 20 ED FD >267 JSR COUT ;Blank out the cursor +0011CA: C6 24 >268 DEC CH ;Point to last character +0011CC: C6 24 >269 DEC CH ; entered... +0011CE: 20 ED FD >270 JSR COUT ; and blank it too +0011D1: C6 24 >271 DEC CH ;Point to that location +0011D3: 4C E7 10 >272 EatEmBak JMP Loop1 ;Go back & get the next char + >273 + >274 ****************** See Rev Note #55 ***************** + >275 +0011D6: BD 11 12 >276 PrntLoop LDA Msg0,X ;Display string; offset is in X. +0011D9: F0 06 =11E1 >277 BEQ :Ret ;Branch if done. +0011DB: 20 ED FD >278 JSR COUT ;Output character... +0011DE: E8 >279 INX +0011DF: D0 F5 =11D6 >280 BNE PrntLoop ;Branch always. +0011E1: 60 >281 :Ret RTS + >282 +0011E2: 85 DE >283 Error STA ErrNum +0011E4: A9 0C >284 LDA #$0C ;Put error message on line 13 +0011E6: 85 25 >285 STA CV +0011E8: 20 8E FD >286 JSR CROUT +0011EB: A5 DE >287 LDA ErrNum +0011ED: C9 01 >288 CMP #badSystemCall +0011EF: D0 04 =11F5 >289 BNE NextErr + >290 *************** See Rev Note #55 ************** +0011F1: A2 4B >291 LDX #292 BNE DoError +0011F5: C9 40 >293 NextErr CMP #badPathSyntax +0011F7: F0 10 =1209 >294 BEQ Error3 +0011F9: C9 44 >295 CMP #pathNotFound +0011FB: F0 0C =1209 >296 BEQ Error3 +0011FD: C9 45 >297 CMP #volNotFound +0011FF: F0 08 =1209 >298 BEQ Error3 +001201: C9 46 >299 CMP #fileNotFound +001203: F0 04 =1209 >300 BEQ Error3 +001205: A2 62 >301 LDX #302 BNE DoError +001209: A2 79 >303 Error3 LDX #304 DoError JSR PrntLoop +00120E: 4C DE 10 >305 JMP RetryRich + >306 + >307 *------------------------------------------------- + >308 * Data + >309 + =1211 >310 MsgStart EQU * +001211: C5 CE D4 C5 >311 Msg0 ASC "ENTER PREFIX (PRESS "A2"RETURN"A2" TO ACCEPT)" +001238: 00 >312 DB $00 +001239: C5 CE D4 C5 >313 Msg ASC "ENTER PATHNAME OF NEXT APPLICATION" +00125B: 00 >314 DB $00 +00125C: 87 >315 Err1 DB $87 +00125D: CE CF D4 A0 >316 ASC "NOT A TYPE "A2"SYS"A2" FILE" +001272: 00 >317 DB $00 +001273: 87 >318 Err2 DB $87 +001274: C9 AF CF A0 >319 ASC "I/O ERROR " +001289: 00 >320 DB $00 +00128A: 87 >321 Err3 DB $87 +00128B: C6 C9 CC C5 >322 ASC "FILE/PATH NOT FOUND " +0012A0: 00 >323 DB $00 + >324 + >325 * + >326 +0012A1: 0A >327 Info DB $0A ;10 PARAMETERS ON GFI +0012A2: 80 02 >328 DA pnBuf ;Pathname buffer pointer +0012A4: 00 >329 Acess DB $00 ;ACCESS +0012A5: 00 >330 Type DB $00 ;File Type +0012A6: 00 00 00 00 >331 DS $D,0 ;All the rest are unimportant + >332 +0012B3: 03 >333 Opn DB $03 ;3 parameters on an OPEN +0012B4: 80 02 >334 DA pnBuf +0012B6: 00 18 >335 DA $1800 ;FCB Buffer +0012B8: 00 >336 RefNum DB $00 + >337 +0012B9: 01 >338 Cls DB $01 +0012BA: 00 >339 ClsNum DB $00 ;REFERENCE # + >340 +0012BB: 04 >341 Reed DB $04 ;4 Parameters for a READ +0012BC: 00 >342 ReedNum DB $00 +0012BD: 00 20 >343 DA $2000 ;SYS files always load at $2000 +0012BF: 00 00 >344 RCount DW $0000 +0012C1: 00 00 >345 DW $0000 + >346 +0012C3: 02 >347 EOF DB $02 +0012C4: 00 >348 eofNum DB $00 +0012C5: 00 00 00 >349 eofB DS 3,0 ;Three byte EOF + >350 +0012C8: 01 >351 Prefix DB $01 +0012C9: 80 02 >352 DA pnBuf + >353 + =02CB >354 ZZSiz EQU *-HereIn + =0034 >355 ZZFre EQU $2FF-ZZSiz +0012CB: 00 00 00 00 >356 DS $35,0 + 46 PUT mli.src/SEL1 + >1 ************************************************** + >2 * Zero page use + >3 + =0060 >4 SMrkPBlk EQU $60 ;SetMark parm blk + =0065 >5 numActvDev EQU $65 ;# of active devices-1 + =0067 >6 currEnt EQU $67 + =0068 >7 listTotal EQU $68 ;tot # of SYS/DIR entries in curr dir + =0069 >8 fnameLen EQU $69 + =006A >9 dispCnt EQU $6A ;# of entries displayed + =006B >10 depth EQU $6B ;0=unit, 1=root dir + =006C >11 fnamePtr EQU $6C + =006E >12 Entry_Len EQU $6E ;These are read fr dir file + =006F >13 EntPerBlk EQU $6F + =0070 >14 FileCount EQU $70 + =0072 >15 entryNum EQU $72 ;entry # within dir block + =0073 >16 scrolledNum EQU $73 ;# of entries that were scrolled up + >17 + =0074 >18 fTypeTbl EQU $74 ;$74-$F3 (128 entries) + =1400 >19 namesBuf EQU $1400 ;Store for file incl subdir names + =1C00 >20 P8IOBuf EQU $1C00 ;1024-byte buf for opened files + =2000 >21 entryBuf EQU $2000 ;Read buf for file entry & vol/sub dir header recs + >22 + >23 ************************************************** + >24 * Improved Dispatcher/Selector + >25 + >26 ORG DispAdr + >27 MX %11 + >28 +001000: D8 >29 BetterBye CLD ;Flag this is a SELECTOR +001001: AD 82 C0 >30 LDA RDROM2 ;Enable Motherboard ROM +001004: 9C F2 03 >31 STZ SOFTEV +001007: A9 10 >32 LDA #>BetterBye +001009: 8D F3 03 >33 STA SOFTEV+1 +00100C: 20 6F FB >34 JSR SETPWRC ;Set powerup byte +00100F: A9 A0 >35 LDA #$A0 ;Switch on $C3 video +001011: 20 00 C3 >36 JSR $C300 + >37 +001014: A2 17 >38 LDX #23 +001016: 9E 58 BF >39 :ClrLoop STZ memTabl,X +001019: CA >40 DEX +00101A: 10 FA =1016 >41 BPL :ClrLoop + >42 +00101C: EE 6F BF >43 INC memTabl+23 ;Protect $BF page +00101F: A9 CF >44 LDA #%11001111 ;Flag $00,$01 & $04-$07 mem +001021: 8D 58 BF >45 STA memTabl ; pages as being used +001024: A9 02 >46 LDA #$02 +001026: 85 60 >47 STA SMrkPBlk ;Set pCount +001028: AE 31 BF >48 LDX DevCnt ;Get # of devices-1 +00102B: 86 65 >49 STX numActvDev +00102D: AD 30 BF >50 LDA DevNum ;Is there a last accessed dev? +001030: D0 10 =1042 >51 BNE IsDevOL ;Yes, start with that one + >52 + >53 *------------------------------------------------- + >54 +001032: A6 65 >55 NxtActvDev LDX numActvDev ;Start search fr this +001034: BD 32 BF >56 LDA DevLst,X ;=DSSS IIII +001037: E0 01 >57 CPX #$01 ;Last on the list? +001039: B0 04 =103F >58 BCS :1 ;No +00103B: AE 31 BF >59 LDX DevCnt ;Start all over again +00103E: E8 >60 INX +00103F: CA >61 :1 DEX +001040: 86 65 >62 STX numActvDev + >63 +001042: 8D F5 12 >64 IsDevOL STA OLUnit ;Chk if vol is online +001045: 20 00 BF >65 JSR GoPro +001048: C5 >66 DB $C5 +001049: F4 12 >67 DA OLinPBlk +00104B: B0 E5 =1032 >68 BCS NxtActvDev ;No, try next device + >69 +00104D: 64 6B >70 STZ depth +00104F: AD 81 02 >71 LDA pnBuf+1 ;=DSSS LLLL +001052: 29 0F >72 AND #$0F ;Isolate name len of vol +001054: F0 DC =1032 >73 BEQ NxtActvDev ;Not online +001056: 69 02 >74 ADC #$02 ;For the 2 added slashes +001058: AA >75 TAX + >76 +001059: 8E 80 02 >77 OpenFolder STX pnBuf ;len of PN +00105C: A9 2F >78 LDA #'/' ;Add a slash to the +00105E: 8D 81 02 >79 STA pnBuf+1 +001061: 9D 80 02 >80 STA pnBuf,X ; beginning & end of PN +001064: 9E 81 02 >81 STZ pnBuf+1,X +001067: 20 00 BF >82 JSR GoPro ;Open the vol/sub dir +00106A: C8 >83 DB $C8 +00106B: EC 12 >84 DA OpenPBlk +00106D: 90 10 =107F >85 BCC FolderOpened + >86 +00106F: A5 6B >87 LDA depth +001071: F0 BF =1032 >88 BEQ NxtActvDev +001073: 20 DD FB >89 JSR BELL1 +001076: 20 DA 11 >90 JSR ChopName +001079: 8E 80 02 >91 STX pnBuf +00107C: 4C B0 11 >92 JMP GetKeyPress ;Pause + >93 + >94 *------------------------------------------------- + >95 +00107F: E6 6B >96 FolderOpened INC depth +001081: 64 68 >97 STZ listTotal ;# of SYS/DIR entries +001083: AD F1 12 >98 LDA OpenRef +001086: 8D FC 12 >99 STA ReadRef +001089: 85 61 >100 STA SMrkPBlk+c_refNum ;Set ref # +00108B: A9 2B >101 LDA #$27+4 ;Read in the link blk ptrs +00108D: 8D FF 12 >102 STA RdReqLen ; & vol/subdir header rec +001090: 9C 00 13 >103 STZ RdReqLen+1 +001093: 20 B4 12 >104 JSR ReadEntry +001096: B0 1B =10B3 >105 BCS ScanDirDone + >106 +001098: A2 03 >107 LDX #$03 ;Copy the file count, +00109A: BD 23 20 >108 :CpyLoop LDA entryBuf+hEntLen+4,X ; entries/blk +00109D: 95 6E >109 STA Entry_Len,X ; & entry len +00109F: CA >110 DEX +0010A0: 10 F8 =109A >111 BPL :CpyLoop + >112 +0010A2: 8D FF 12 >113 STA RdReqLen ;=entry_len ($27) +0010A5: A9 01 >114 LDA #$01 ;Start w/first file entry +0010A7: 85 72 >115 STA entryNum ; skipping the header entry +0010A9: 64 63 >116 STZ SMrkPBlk+c_mark+1 +0010AB: 64 64 >117 STZ SMrkPBlk+c_mark+2 +0010AD: A5 70 >118 LDA FileCount ;Is vol/sub dir empty? +0010AF: 05 71 >119 ORA FileCount+1 +0010B1: D0 02 =10B5 >120 BNE NxtFilEnt ;No +0010B3: 80 74 =1129 >121 ScanDirDone BRA ClsDirFile ;Done with reading dir + >122 +0010B5: 24 71 >123 NxtFilEnt BIT FileCount+1 ;Any more file entries? +0010B7: 30 FA =10B3 >124 BMI ScanDirDone ;Done + >125 +0010B9: A5 63 >126 SkipEnt LDA SMrkPBlk+c_mark+1 +0010BB: 29 FE >127 AND #%11111110 ;Do a MOD 512 to force +0010BD: 85 63 >128 STA SMrkPBlk+c_mark+1 ; a block alignment +0010BF: A4 72 >129 LDY entryNum +0010C1: A9 00 >130 LDA #$00 +0010C3: C4 6F >131 CPY EntPerBlk +0010C5: 90 07 =10CE >132 BCC CalcOffset + >133 +0010C7: A8 >134 TAY ;Y=0 +0010C8: 84 72 >135 STY entryNum +0010CA: E6 63 >136 INC SMrkPBlk+c_mark+1 ;On fall thru next block +0010CC: E6 63 >137 NxtPage INC SMrkPBlk+c_mark+1 ;2nd page of block + >138 +0010CE: 88 >139 CalcOffset DEY ;Compute offset to file entry +0010CF: 18 >140 CLC +0010D0: 30 06 =10D8 >141 BMI SetFilePos +0010D2: 65 6E >142 ADC Entry_Len +0010D4: 90 F8 =10CE >143 BCC CalcOffset +0010D6: B0 F4 =10CC >144 BCS NxtPage ;Always + >145 +0010D8: 69 04 >146 SetFilePos ADC #$04 ;Skip 4-byte header +0010DA: 85 62 >147 STA SMrkPBlk+c_mark +0010DC: 20 00 BF >148 JSR GoPro +0010DF: CE >149 DB $CE +0010E0: 60 00 >150 DA SMrkPBlk +0010E2: B0 CF =10B3 >151 BCS ScanDirDone + >152 +0010E4: 20 B4 12 >153 JSR ReadEntry +0010E7: B0 CA =10B3 >154 BCS ScanDirDone +0010E9: E6 72 >155 INC entryNum +0010EB: AD 00 20 >156 LDA entryBuf+d_stor ;Get storType/namelen +0010EE: 29 F0 >157 AND #$F0 ;Isolate storage type +0010F0: F0 C7 =10B9 >158 BEQ SkipEnt ;Deleted entry +0010F2: C6 70 >159 DEC FileCount +0010F4: D0 02 =10F8 >160 BNE GoodRead +0010F6: C6 71 >161 DEC FileCount+1 + >162 +0010F8: 6E 1E 20 >163 GoodRead ROR entryBuf+d_attr ;Check readEnable bit +0010FB: 90 B8 =10B5 >164 BCC NxtFilEnt ;File cannot be read +0010FD: AD 10 20 >165 LDA entryBuf+d_fileID ;Get file type +001100: C9 0F >166 CMP #$0F ;Is it a DIR file? +001102: F0 04 =1108 >167 BEQ :1 ;Yes +001104: C9 FF >168 CMP #$FF ;SYS file? +001106: D0 AD =10B5 >169 BNE NxtFilEnt ;No + >170 +001108: A6 68 >171 :1 LDX listTotal ;# of SYS/DIR entries +00110A: E0 80 >172 CPX #128 +00110C: B0 1B =1129 >173 BCS ClsDirFile +00110E: 95 74 >174 STA fTypeTbl,X ;Store filetype +001110: 20 58 12 >175 JSR GetNameSlot + >176 +001113: A0 0F >177 LDY #15 +001115: B9 00 20 >178 :CpyLoop LDA entryBuf+d_stor,Y ;Copy filename including +001118: 91 6C >179 STA (fnamePtr),Y ; the storType/namelen byte +00111A: 88 >180 DEY +00111B: 10 F8 =1115 >181 BPL :CpyLoop + >182 +00111D: C8 >183 INY ;Y=0 ;(A)=storType/namelen +00111E: 29 0F >184 AND #$0F ;Isolate len byte +001120: 91 6C >185 STA (fnamePtr),Y ;Save it +001122: E6 68 >186 INC listTotal ;# of SYS/DIR entries +001124: D0 8F =10B5 >187 BNE NxtFilEnt + >188 +001126: 4C 32 10 >189 CantCls JMP NxtActvDev ;Hitch a ride + >190 +001129: 20 00 BF >191 ClsDirFile JSR GoPro +00112C: CC >192 DB $CC +00112D: F2 12 >193 DA ClsPBlk +00112F: B0 F5 =1126 >194 BCS CantCls + >195 + >196 * Display list of files in vol/subdir + >197 +001131: 20 39 FB >198 JSR SETTXT +001134: 20 58 FC >199 JSR HOME ;Clear scrn & posn cursor @ top of scrn +001137: A9 17 >200 LDA #23 +001139: 20 5B FB >201 JSR TABV ;Posn cursor @ btm of scrn +00113C: A0 00 >202 LDY #helpStr-helpStr +00113E: A9 14 >203 LDA #20 ;Display Help Message +001140: 20 4A 12 >204 JSR ShowHelp ; starting @ scrn coords (23, 20) + >205 +001143: 20 AD 12 >206 JSR HomeCursor +001146: A2 00 >207 LDX #$00 +001148: BD 81 02 >208 :loop LDA pnBuf+1,X ;Display full PN +00114B: F0 06 =1153 >209 BEQ :1 ; at top of screen +00114D: 20 AF 12 >210 JSR PrtChar +001150: E8 >211 INX +001151: D0 F5 =1148 >212 BNE :loop + >213 +001153: 64 67 >214 :1 STZ currEnt +001155: 64 73 >215 STZ scrolledNum +001157: A5 68 >216 LDA listTotal ;# of SYS/DIR entries +001159: F0 55 =11B0 >217 BEQ GetKeyPress + >218 +00115B: C9 15 >219 CMP #21 +00115D: 90 02 =1161 >220 BCC :2 +00115F: A9 14 >221 LDA #20 ;Only 20 will be displayed +001161: 85 6A >222 :2 STA dispCnt +001163: A9 02 >223 LDA #2 ;Set the dimensions +001165: 85 22 >224 STA WNDTOP ; of our display window +001167: 85 20 >225 STA WNDLFT ; which is (2, 2) to (22, 24) +001169: A9 16 >226 LDA #22 +00116B: 85 21 >227 STA WNDWDTH +00116D: 85 23 >228 STA WNDBTM + >229 +00116F: 20 77 12 >230 :DspLoop JSR ShowEntry +001172: E6 67 >231 INC currEnt +001174: C6 6A >232 DEC dispCnt +001176: D0 F7 =116F >233 BNE :DspLoop + >234 +001178: 64 67 >235 STZ currEnt ;Highlight 1st entry +00117A: F0 2E =11AA >236 BEQ InvDsp ;Always + >237 +00117C: 20 77 12 >238 UpArwHit JSR ShowEntry +00117F: A6 67 >239 LDX currEnt ;Are we at the top of the list? +001181: F0 27 =11AA >240 BEQ InvDsp ;Yes -> No entries to scroll down +001183: C6 67 >241 DEC currEnt +001185: A5 25 >242 LDA CV ;Are we at the top of our window? +001187: C9 02 >243 CMP #$02 +001189: D0 1F =11AA >244 BNE InvDsp ;No, proceed to highlight entry +00118B: C6 73 >245 DEC scrolledNum ;Less 1 "scrolled up" entry +00118D: A9 16 >246 LDA #$16 ;Scroll down 1 line +00118F: D0 16 =11A7 >247 BNE Scroll ;always + >248 +001191: 20 77 12 >249 DwnArwHit JSR ShowEntry +001194: A6 67 >250 LDX currEnt ;Is this the last SYS/DIR +001196: E8 >251 INX +001197: E4 68 >252 CPX listTotal ; entry in the dir? +001199: B0 0F =11AA >253 BCS InvDsp ;Yes -> No entries to scroll up +00119B: 86 67 >254 STX currEnt +00119D: A5 25 >255 LDA CV ;Are we beyond the end of our window? +00119F: C9 15 >256 CMP #21 +0011A1: D0 07 =11AA >257 BNE InvDsp ;No +0011A3: E6 73 >258 INC scrolledNum ;We have scrolled up 1 entry +0011A5: A9 17 >259 LDA #$17 ;Scroll up 1 line +0011A7: 20 ED FD >260 Scroll JSR COUT +0011AA: 20 80 FE >261 InvDsp JSR SetInv ;Set 80-col card to inverse mode +0011AD: 20 77 12 >262 JSR ShowEntry + >263 +0011B0: AD 00 C0 >264 GetKeyPress LDA KBD +0011B3: 10 FB =11B0 >265 BPL GetKeyPress + >266 +0011B5: 8D 10 C0 >267 STA KBDSTROBE ;Clear keyboard strobe +0011B8: 20 84 FE >268 JSR SetNorm +0011BB: A6 68 >269 LDX listTotal ;Is vol/subdir empty? +0011BD: F0 0C =11CB >270 BEQ :1 ;Yes, no entries were displayed + >271 +0011BF: C9 8D >272 CMP #$8D ;CR? +0011C1: F0 31 =11F4 >273 BEQ AcceptEnt +0011C3: C9 8A >274 CMP #$8A ;Down arrow? +0011C5: F0 CA =1191 >275 BEQ DwnArwHit +0011C7: C9 8B >276 CMP #$8B ;Up arrow? +0011C9: F0 B1 =117C >277 BEQ UpArwHit +0011CB: C9 89 >278 :1 CMP #$89 ;TAB? +0011CD: F0 1E =11ED >279 BEQ NxtVol +0011CF: C9 9B >280 CMP #$9B ;ESC? +0011D1: D0 DD =11B0 >281 BNE GetKeyPress + >282 +0011D3: 20 DA 11 >283 JSR ChopName +0011D6: C6 6B >284 DEC depth +0011D8: 80 17 =11F1 >285 BRA ToOpenDir2 ;Go open parent dir + >286 + >287 * Scans the full pathname, and chops + >288 * off characters until it gets to a / + >289 +0011DA: AE 80 02 >290 ChopName LDX pnBuf ;Get len of PN +0011DD: CA >291 :loop DEX ;Bump to previous char +0011DE: BD 80 02 >292 LDA pnBuf,X +0011E1: C9 2F >293 CMP #'/' +0011E3: D0 F8 =11DD >294 BNE :loop +0011E5: E0 01 >295 CPX #$01 ;Have we reached the root? +0011E7: D0 03 =11EC >296 BNE :Rtn ;No +0011E9: AE 80 02 >297 LDX pnBuf ;Stay at root level +0011EC: 60 >298 :Rtn RTS + >299 +0011ED: 4C 32 10 >300 NxtVol JMP NxtActvDev ;Hitch a ride + >301 +0011F0: E8 >302 ToOpenDir1 INX ;1 more for the ending slash +0011F1: 4C 59 10 >303 ToOpenDir2 JMP OpenFolder + >304 +0011F4: 20 00 BF >305 AcceptEnt JSR GoPro +0011F7: C6 >306 DB $C6 +0011F8: F8 12 >307 DA SPfxPBlk +0011FA: B0 F1 =11ED >308 BCS NxtVol + >309 + >310 * Extend the pathname + >311 +0011FC: A6 67 >312 LDX currEnt +0011FE: 20 58 12 >313 JSR GetNameSlot +001201: AE 80 02 >314 LDX pnBuf ;Append filename +001204: C8 >315 :CpyLoop INY +001205: B1 6C >316 LDA (fnamePtr),Y ; to the PN +001207: E8 >317 INX +001208: 9D 80 02 >318 STA pnBuf,X +00120B: C4 69 >319 CPY fnameLen +00120D: 90 F5 =1204 >320 BCC :CpyLoop + >321 +00120F: 8E 80 02 >322 STX pnBuf +001212: A4 67 >323 LDY currEnt +001214: B9 74 00 >324 LDA |fTypeTbl,Y ;Get filetype +001217: 10 D7 =11F0 >325 BPL ToOpenDir1 ;Dir file + >326 +001219: 20 39 FB >327 JSR SETTXT +00121C: 20 58 FC >328 JSR HOME +00121F: A9 95 >329 LDA #$95 ;Deactivate 80-col, home cursor & clrsrcn +001221: 20 ED FD >330 JSR COUT +001224: 20 00 BF >331 JSR GoPro +001227: C8 >332 DB $C8 +001228: EC 12 >333 DA OpenPBlk +00122A: B0 C1 =11ED >334 BCS NxtVol + >335 +00122C: AD F1 12 >336 LDA OpenRef +00122F: 8D FC 12 >337 STA ReadRef +001232: A9 FF >338 LDA #$FF ;Prepare to read the +001234: 8D FF 12 >339 STA RdReqLen ; entire file whose +001237: 8D 00 13 >340 STA RdReqLen+1 ; len is unknown +00123A: 20 B4 12 >341 JSR ReadEntry +00123D: 08 >342 PHP ;Save err status +00123E: 20 00 BF >343 JSR GoPro +001241: CC >344 DB $CC +001242: F2 12 >345 DA ClsPBlk +001244: 28 >346 PLP +001245: B0 A6 =11ED >347 BCS NxtVol ;Read errs +001247: 4C 00 20 >348 JMP $2000 ;Transfer control to Applic + >349 + >350 *------------------------------------------------- + >351 +00124A: 85 24 >352 ShowHelp STA CH + =124C >353 ShowIcon EQU * +00124C: B9 BB 12 >354 :loop LDA helpStr,Y +00124F: F0 06 =1257 >355 BEQ :Rtn +001251: 20 ED FD >356 JSR COUT +001254: C8 >357 INY +001255: D0 F5 =124C >358 BNE :loop +001257: 60 >359 :Rtn RTS + >360 + >361 *------------------------------------------------- + >362 * Each file name 16 bytes/entry + >363 * Allow up to 128 SYS/DIR names to be + >364 * stored @ $1400-$1BFF + >365 * Entry + >366 * (X) = entry # + >367 * Exit + >368 * (Y) = 0 + >369 * (fnamePtr) = Ptr to name of entry + >370 +001258: 64 6D >371 GetNameSlot STZ fnamePtr+1 +00125A: 8A >372 TXA +00125B: 0A >373 ASL ;x16 +00125C: 26 6D >374 ROL fnamePtr+1 +00125E: 0A >375 ASL +00125F: 26 6D >376 ROL fnamePtr+1 +001261: 0A >377 ASL +001262: 26 6D >378 ROL fnamePtr+1 +001264: 0A >379 ASL +001265: 26 6D >380 ROL fnamePtr+1 +001267: 85 6C >381 STA fnamePtr + >382 +001269: A9 14 >383 LDA #>namesBuf +00126B: 18 >384 CLC +00126C: 65 6D >385 ADC fnamePtr+1 +00126E: 85 6D >386 STA fnamePtr+1 +001270: A0 00 >387 LDY #$00 +001272: B1 6C >388 LDA (fnamePtr),Y +001274: 85 69 >389 STA fnameLen +001276: 60 >390 RTS + >391 + >392 *------------------------------------------------- + >393 * Display name of an entry + >394 +001277: A9 02 >395 ShowEntry LDA #2 +001279: 8D 7B 05 >396 STA OURCH +00127C: A6 67 >397 LDX currEnt +00127E: 8A >398 TXA +00127F: 38 >399 SEC +001280: E5 73 >400 SBC scrolledNum +001282: 1A >401 INC +001283: 1A >402 INC +001284: 20 5B FB >403 JSR TABV +001287: B5 74 >404 LDA fTypeTbl,X +001289: 30 0E =1299 >405 BMI Its_Sys ;SYS file +00128B: 9C 7B 05 >406 STZ OURCH ;DIR file +00128E: A5 32 >407 LDA INVFLG +001290: 48 >408 PHA +001291: A0 2A >409 LDY #FolderIcon-helpStr +001293: 20 4C 12 >410 JSR ShowIcon +001296: 68 >411 PLA +001297: 85 32 >412 STA INVFLG + >413 +001299: 20 A9 12 >414 Its_Sys JSR PrtBlnk ;Print a space instead +00129C: 20 58 12 >415 JSR GetNameSlot ; followed the file/subdir name +00129F: C8 >416 :loop INY +0012A0: B1 6C >417 LDA (fnamePtr),Y +0012A2: 20 AF 12 >418 JSR PrtChar +0012A5: C4 69 >419 CPY fnameLen +0012A7: 90 F6 =129F >420 BCC :loop + >421 +0012A9: A9 A0 >422 PrtBlnk LDA #" " +0012AB: D0 04 =12B1 >423 BNE PrtAsIs ;Always + >424 +0012AD: A9 99 >425 HomeCursor LDA #$99 ;ctrl-Y +0012AF: 09 80 >426 PrtChar ORA #$80 +0012B1: 4C ED FD >427 PrtAsIs JMP COUT + >428 +0012B4: 20 00 BF >429 ReadEntry JSR GoPro +0012B7: CA >430 DB $CA +0012B8: FB 12 >431 DA RdPBlk +0012BA: 60 >432 RTS + >433 + >434 *------------------------------------------------- + >435 * Data area + >436 +0012BB: D2 C5 D4 D5 >437 helpStr ASC "RETURN: Select | TAB: Chg Vol | ESC: " +0012E0: C2 E1 E3 EB >438 ASC "Back" +0012E4: 00 >439 DB $00 + >440 +0012E5: 0F >441 FolderIcon DB $0F ;Set Inverse Display mode +0012E6: 1B >442 DB $1B ;Enable MouseText Mapping +0012E7: D8 >443 DB $D8 ;MouseText chars +0012E8: D9 >444 DB $D9 +0012E9: 18 >445 DB $18 ;Disable MouseText Mapping +0012EA: 0E >446 DB $0E ;Set Normal Display mode +0012EB: 00 >447 DB $00 ;end of string + >448 +0012EC: 03 >449 OpenPBlk DB $03 +0012ED: 80 02 >450 DA pnBuf +0012EF: 00 1C >451 DA P8IOBuf +0012F1: 00 >452 OpenRef DB $00 + >453 +0012F2: 01 >454 ClsPBlk DB $01 +0012F3: 00 >455 DB $00 + >456 +0012F4: 02 >457 OLinPBlk DB $02 +0012F5: 60 >458 OLUnit DB $60 +0012F6: 81 02 >459 DA pnBuf+1 + >460 +0012F8: 01 >461 SPfxPBlk DB $01 +0012F9: 80 02 >462 DA pnBuf + >463 +0012FB: 04 >464 RdPBlk DB $04 +0012FC: 01 >465 ReadRef DB $01 +0012FD: 00 20 >466 DA entryBuf + >467 ;RdReqLen DW 0 +0012FF: 00 >468 RdReqLen DB 0 ;Overflow + 47 PUT mli.src/SEL2 + >1 ************************************************** + >2 * New GS/OS Dispatcher for P8 + >3 + =E0D000 >4 GQuit8 EQU $E0D000 + >5 + >6 ORG DispAdr + >7 XC + >8 XC +001000: AD 8B C0 >9 GS_Disp LDA LCBANK1 ;Enable read +001003: 18 >10 CLC +001004: FB >11 XCE +001005: 5C 00 D0 E0 >12 JMPL GQuit8 + >13 +001009: 00 00 00 00 >14 DS 5,0 ;Pad with spaces + >15 +00100E: 47 51 >16 gqSign ASC 'GQ' ;Signature word + >17 + >18 *------------------------------------------------- + >19 * Control is passed back here by GQuit8 + >20 * after it has setup the required parameters + >21 + >22 MX %10 +001010: E2 20 >23 GS_DispZ SEP #$20 ;8-bit A, 16-bit index regs +001012: 48 >24 PHA +001013: A2 00 02 >25 LDX #inBuf ;Boot Volname +001016: 20 3F 11 >26 JSR GetVolName +001019: 68 >27 PLA +00101A: 38 >28 SEC ;Emulation mode +00101B: FB >29 XCE +00101C: 09 00 >30 ORA #$00 ;Nil prefix? +00101E: F0 0D =102D >31 BEQ :1 + >32 + >33 MX %11 +001020: 20 00 BF >34 :loop JSR GoPro +001023: C6 >35 DB $C6 +001024: 53 12 >36 DA SPfxParm +001026: 90 05 =102D >37 BCC :1 + >38 +001028: 20 9F 10 >39 JSR ShowAlrt +00102B: 80 F3 =1020 >40 BRA :loop + >41 +00102D: FB >42 :1 XCE + >43 MX %10 +00102E: C2 10 >44 REP #$10 ;16-bit index regs +001030: AD 81 02 >45 LDA pnBuf+1 ;Application's name is passed here +001033: C9 2F >46 CMP #'/' ;Does it begin with a slash? +001035: D0 06 =103D >47 BNE :2 ;No, so a partial PN is passed +001037: A2 80 02 >48 LDX #pnBuf ;Full PN is passed +00103A: 20 3F 11 >49 JSR GetVolName ;Application's vol name + >50 +00103D: 38 >51 :2 SEC ;Full emulation mode +00103E: FB >52 XCE + >53 +00103F: 20 00 BF >54 Try2Open JSR GoPro +001042: C8 >55 DB $C8 +001043: 56 12 >56 DA OpenParm +001045: 90 05 =104C >57 BCC Opened +001047: 20 9F 10 >58 JSR ShowAlrt +00104A: 80 F3 =103F >59 BRA Try2Open + >60 +00104C: AD 5B 12 >61 Opened LDA OpenRefNbr +00104F: 8D 5D 12 >62 STA eofRefNbr +001052: 8D 62 12 >63 STA ReadRefNbr +001055: 8D 6A 12 >64 STA ClsRefNbr + >65 +001058: 20 00 BF >66 GetFileLen JSR GoPro +00105B: D1 >67 DB $D1 +00105C: 5C 12 >68 DA eofParm +00105E: 90 05 =1065 >69 BCC GotFileLen +001060: 20 9F 10 >70 JSR ShowAlrt +001063: 80 F3 =1058 >71 BRA GetFileLen + >72 +001065: AD 5E 12 >73 GotFileLen LDA theEOF +001068: 8D 65 12 >74 STA ReadLen +00106B: AD 5F 12 >75 LDA theEOF+1 +00106E: 8D 66 12 >76 STA ReadLen+1 + >77 +001071: 20 00 BF >78 Try2Read JSR GoPro +001074: CA >79 DB $CA +001075: 61 12 >80 DA ReadParm +001077: 90 05 =107E >81 BCC Try2Cls +001079: 20 9F 10 >82 JSR ShowAlrt +00107C: 80 F3 =1071 >83 BRA Try2Read + >84 +00107E: 20 00 BF >85 Try2Cls JSR GoPro +001081: CC >86 DB $CC +001082: 69 12 >87 DA ClsParm +001084: 90 05 =108B >88 BCC ClsOK +001086: 20 9F 10 >89 JSR ShowAlrt +001089: 80 F3 =107E >90 BRA Try2Cls + >91 +00108B: 20 5C 11 >92 ClsOK JSR Chk4Intrp +00108E: D0 09 =1099 >93 BNE RunApp ;It's not an Interpreter eg BI +001090: 20 32 12 >94 JSR GetStartup ;Get the startup pgm +001093: 90 04 =1099 >95 BCC RunApp ;Transfer control to Interpreter +001095: A9 45 >96 LDA #volNotFound +001097: 80 12 =10AB >97 BRA ShwErrAlrt + >98 +001099: AD 82 C0 >99 RunApp LDA RDROM2 ;Enable motherboard ROM +00109C: 4C 00 20 >100 JMP $2000 ;Pass control to SYS application + >101 + >102 *------------------------------------------------- + >103 * (A)=Error Code + >104 * Report Err & Quit + >105 +00109F: 18 >106 ShowAlrt CLC +0010A0: FB >107 XCE +0010A1: C2 30 >108 REP #$30 ;Full 16-bit native mode +0010A3: 20 EC 10 >109 JSR Ask4Disk +0010A6: B0 03 =10AB >110 BCS ShwErrAlrt +0010A8: 38 >111 SEC ;Back to emulation mode +0010A9: FB >112 XCE +0010AA: 60 >113 RTS + >114 + >115 *------------------------------------------------- + >116 * Put up a text box showing an error code + >117 * (A)=err code. It calls P8's quit code + >118 +0010AB: 18 >119 ShwErrAlrt CLC +0010AC: FB >120 XCE +0010AD: C2 30 >121 REP #$30 ;Full 16-bit native mode +0010AF: 29 FF 00 >122 AND #$00FF +0010B2: 48 >123 PHA ;Convert err code +0010B3: >124 PushLong #ErrNumStr +0010B9: >125 PushWord #4 ; into 4-byte ASCIIs char +0010BC: >126 _Int2Hex + >127 +0010C3: 48 >128 PHA +0010C4: >129 PushLong #CantRunStr ;line1Ptr +0010CA: >130 PushLong #P8ErrStr ;line2Ptr +0010D0: >131 PushLong #acceptStr ;button1Ptr +0010D6: >132 PushLong #nullStr ;button2Ptr +0010DC: >133 _TLTextMountVol +0010E3: 68 >134 PLA ;Not used +0010E4: 38 >135 SEC ;Emulate 65C02 +0010E5: FB >136 XCE + >137 +0010E6: 20 00 BF >138 JSR GoPro +0010E9: 65 >139 DB $65 +0010EA: 6B 12 >140 DA QuitParms + >141 + >142 *------------------------------------------------- + >143 * On entry + >144 * (A)=Error Code + >145 + >146 MX %00 +0010EC: A0 00 00 >147 Ask4Disk LDY #$0000 ;ptr to volname +0010EF: A2 00 0F >148 LDX #VolNameStr +0010F2: 29 FF 00 >149 AND #$00FF ;Err # +0010F5: C9 45 00 >150 CMP #volNotFound +0010F8: F0 07 =1101 >151 BEQ :1 +0010FA: C9 2F 00 >152 CMP #drvrOffLine +0010FD: F0 02 =1101 >153 BEQ :1 +0010FF: 38 >154 SEC +001100: 60 >155 RTS + >156 + >157 * Prompt for correct vol + >158 +001101: 48 >159 :1 PHA ;Err code +001102: 5A >160 PHY +001103: DA >161 PHX +001104: 3B >162 TSC +001105: 0B >163 PHD +001106: 5B >164 TCD +001107: A7 01 >165 LDA [$01] ;Get len byte +001109: 3A >166 DEC +00110A: EB >167 XBA +00110B: 87 01 >168 STA [$01] +00110D: 48 >169 PHA ;word result +00110E: >170 PushLong #insDskStr ;line1Ptr +001114: 5A >171 PHY +001115: E8 >172 INX +001116: DA >173 PHX ;(Y,X) line2Ptr +001117: >174 PushLong #acceptStr ;button1Ptr +00111D: >175 PushLong #cancelStr ;button2Ptr +001123: >176 _TLTextMountVol +00112A: A7 01 >177 LDA [$01] +00112C: EB >178 XBA +00112D: 1A >179 INC +00112E: 87 01 >180 STA [$01] +001130: 68 >181 PLA ;button # chosen +001131: 2B >182 PLD +001132: FA >183 PLX +001133: FA >184 PLX +001134: C9 01 00 >185 CMP #$0001 ;Return? +001137: D0 03 =113C >186 BNE NotRet ;No, Esc +001139: 18 >187 CLC +00113A: 68 >188 PLA ;err # +00113B: 60 >189 RTS + >190 +00113C: 38 >191 NotRet SEC +00113D: 68 >192 PLA ;err # +00113E: 60 >193 RTS + >194 + >195 *------------------------------------------------- + >196 * Called with 8-bit Acc but 16-bit index regs + >197 * (X)=16-bit mem location to PN + >198 * Copies just the volname to our buf + >199 * On return, (A)=len of volname + >200 * This rtn will hang if there is no + >201 * trailing slash + >202 + >203 MX %10 +00113F: BD 01 00 >204 GetVolName LDA |$0001,X ;Get prefix char (if any) +001142: 8D 01 0F >205 STA VolNameStr+1 +001145: A0 02 00 >206 LDY #$0002 +001148: BD 02 00 >207 :loop LDA |$0002,X ;Get char +00114B: C9 2F >208 CMP #'/' ;Is it a trailing slash? +00114D: F0 07 =1156 >209 BEQ :Done ;Yes +00114F: 99 00 0F >210 STA VolNameStr,Y +001152: E8 >211 INX +001153: C8 >212 INY +001154: 80 F2 =1148 >213 BRA :loop + >214 +001156: 88 >215 :Done DEY ;backup 1 +001157: 98 >216 TYA +001158: 8D 00 0F >217 STA VolNameStr ;Set len byte +00115B: 60 >218 RTS + >219 + >220 *------------------------------------------------- + >221 * Application File was already loaded in mem @ $2000 + >222 * If it is an interpreter, the Tool Locator is check + >223 * for the name of the program which will be launched + >224 * by the interpreter. For example, click on a file + >225 * with type BAS with cause the BI to be loaded & + >226 * executed. BI will launch the BASIC program which + >227 * is passed via MessageCenter call of Tool Locator + >228 * + >229 * Z=0 Application is not an interpreter + >230 * Z=1 Success + >231 * Ref: pg 88 ProDOS 8 Technical Reference Manual + >232 +00115C: AD 00 20 >233 Chk4Intrp LDA $2000 ;Check if it's an interpreter +00115F: C9 4C >234 CMP #$4C ;JMP inst +001161: D0 0C =116F >235 BNE :Rtn +001163: A9 EE >236 LDA #$EE ;INC inst +001165: CD 03 20 >237 CMP $2003 +001168: D0 05 =116F >238 BNE :Rtn +00116A: CD 04 20 >239 CMP $2003+1 +00116D: F0 01 =1170 >240 BEQ :1 +00116F: 60 >241 :Rtn RTS + >242 +001170: A9 FF >243 :1 LDA #$FF ;Init ErrFlag & push +001172: 48 >244 PHA ; onto stack for later +001173: 18 >245 CLC +001174: FB >246 XCE +001175: C2 30 >247 REP #$30 ;Full native mode +001177: 48 >248 PHA +001178: >249 _MMStartUp +00117F: 68 >250 PLA ;user ID + >251 + >252 * Ref IIGS Toolbox Vol 2 pg 24-14 + >253 * IIGS Toolbox Vol 3 pg 52-4 + >254 * Any size for the message handle will do + >255 * since MessageCenter will resize it + >256 +001180: 48 >257 PHA ;Push back for later +001181: 48 >258 PHA ;long result +001182: 48 >259 PHA +001183: >260 PushLong #10 ;# of bytes to allocate +001189: 48 >261 PHA ;userID +00118A: >262 PushWord #$0000 ;attr +00118D: 48 >263 PHA +00118E: 48 >264 PHA +00118F: >265 _NewHandle +001196: 68 >266 PLA ;msg hndl +001197: FA >267 PLX +001198: B0 70 =120A >268 BCS ShutDnMM + >269 +00119A: DA >270 PHX +00119B: 48 >271 PHA +00119C: >272 PushWord #2 ;action=Get +00119F: >273 PushWord #1 ;msgID=file +0011A2: DA >274 PHX ;msg Hndl +0011A3: 48 >275 PHA +0011A4: >276 _MessageCenter +0011AB: B0 56 =1203 >277 BCS DumpMsgHndl + >278 +0011AD: 48 >279 PHA ;work space +0011AE: 48 >280 PHA ; for ptr +0011AF: 3B >281 TSC +0011B0: 0B >282 PHD +0011B1: 1A >283 INC +0011B2: 5B >284 TCD + >285 * + >286 * DP Space: + >287 * |--------------| + >288 * | ErrFlag | B + >289 * |--------------| + >290 * | userID | 9-A + >291 * |--------------| + >292 * | msgHndl | 4-7 + >293 * |--------------| + >294 * | 2 PHA's | 0-3 + >295 * |--------------| + >296 * + >297 +0011B3: A7 04 >298 LDA [$04] ;Deref the mem handle +0011B5: 85 00 >299 STA $00 +0011B7: A0 02 00 >300 LDY #$0002 +0011BA: B7 04 >301 LDA [$04],Y +0011BC: 85 02 >302 STA $00+2 + >303 + >304 ; Ref Vol 2 pg 24-15 + >305 +0011BE: A0 06 00 >306 LDY #$0006 +0011C1: B7 00 >307 LDA [$00],Y ;Get printFlag +0011C3: D0 2A =11EF >308 BNE DelMsg +0011C5: A5 00 >309 LDA $00 ;Open +0011C7: 18 >310 CLC +0011C8: 69 08 00 >311 ADC #$0008 +0011CB: 85 00 >312 STA $00 ;Point @ name (pString) +0011CD: 90 02 =11D1 >313 BCC :2 +0011CF: E6 02 >314 INC $00+2 + >315 +0011D1: A7 00 >316 :2 LDA [$00] +0011D3: 29 FF 00 >317 AND #$00FF ;Isolate len byte +0011D6: E2 20 >318 SEP #$20 ;NB. 8-bit Acc +0011D8: CD 05 20 >319 CMP $2003+2 ;Are the lens same? +0011DB: F0 02 =11DF >320 BEQ :3 ;Yes +0011DD: B0 10 =11EF >321 BCS DelMsg ;No + >322 +0011DF: A8 >323 :3 TAY +0011E0: B7 00 >324 :CpyLoop LDA [$00],Y ;Copy PN of +0011E2: 99 06 20 >325 STA $2000+6,Y ; pgm for Interpreter +0011E5: 99 00 02 >326 STA inBuf,Y ; to run +0011E8: 88 >327 DEY +0011E9: 10 F5 =11E0 >328 BPL :CpyLoop + >329 + >330 * + >331 * Stack contents: + >332 * | | + >333 * |--------------| + >334 * | ErrFlag | D + >335 * |--------------| + >336 * | userID | B-C + >337 * |--------------| + >338 * | msgHndl | 7-A + >339 * |--------------| + >340 * | 2 PHA's | 3-6 + >341 * |--------------| + >342 * | DP reg | 1-2 + >343 * |--------------| + >344 * | |<- SP + >345 * +0011EB: A9 00 >346 LDA #$00 ;Overwrite ErrFlag +0011ED: 83 0D >347 STA $0D,S ; which was $FF + >348 +0011EF: C2 20 >349 DelMsg REP #$20 ;16-bit Acc +0011F1: 2B >350 PLD +0011F2: 68 >351 PLA +0011F3: 68 >352 PLA +0011F4: >353 PushWord #3 ;action=delete +0011F7: >354 PushWord #1 ;type=file +0011FA: 48 >355 PHA +0011FB: 48 >356 PHA +0011FC: >357 _MessageCenter + >358 +001203: >359 DumpMsgHndl _DisposeHandle ;msgHndl +00120A: >360 ShutDnMM _MMShutDown ;userID still on stack + >361 + >362 MX %11 +001211: 38 >363 SEC ;Full emulation mode +001212: FB >364 XCE +001213: 68 >365 PLA ;Get ErrFlag +001214: D0 1B =1231 >366 BNE :Ret + >367 +001216: AE 00 02 >368 LDX inBuf ;Get len byte +001219: A9 2F >369 LDA #'/' +00121B: DD 00 02 >370 :CpyLoop CMP inBuf,X ;Look for a trailing slash +00121E: F0 05 =1225 >371 BEQ :1 ;Got one +001220: CA >372 DEX +001221: D0 F8 =121B >373 BNE :CpyLoop +001223: 80 0C =1231 >374 BRA :Ret + >375 +001225: CA >376 :1 DEX ;Backup 1 +001226: 8E 00 02 >377 STX inBuf ;len byte of vol name +001229: 20 00 BF >378 JSR GoPro +00122C: C6 >379 DB $C6 +00122D: 53 12 >380 DA SPfxParm +00122F: A9 00 >381 LDA #$00 ;Flag no errs +001231: 60 >382 :Ret RTS + >383 + >384 *------------------------------------------------- + >385 * Get the name of startup program that will be + >386 * launched by an interpreter. Verify it's there. + >387 * BI will look for a BASIC program called STARTUP + >388 * C=0 - Success + >389 +001232: 18 >390 GetStartup CLC ;Native mode +001233: FB >391 XCE +001234: C2 10 >392 REP #$10 +001236: A2 06 20 >393 LDX #$2000+6 ;Get full/partial PN +001239: 20 3F 11 >394 JSR GetVolName ; of startup program + >395 +00123C: 38 >396 :loop SEC ;Full emulation mode +00123D: FB >397 XCE +00123E: 20 00 BF >398 JSR GoPro +001241: C4 >399 DB $C4 +001242: 72 12 >400 DA GFIParm +001244: 90 0C =1252 >401 BCC :Rtn + >402 +001246: 18 >403 CLC +001247: FB >404 XCE +001248: C2 30 >405 REP #$30 ;Full 16-bit native mode +00124A: 20 EC 10 >406 JSR Ask4Disk ;Ask for disk w/startup pgm +00124D: 90 ED =123C >407 BCC :loop + >408 +00124F: 38 >409 SEC ;Back to emulation mode +001250: FB >410 XCE +001251: 38 >411 SEC ;Flag failure +001252: 60 >412 :Rtn RTS + >413 + >414 *------------------------------------------------- + >415 * ProDOS8 Parm tables + >416 +001253: 01 >417 SPfxParm DB $01 +001254: 00 02 >418 DA inBuf + >419 +001256: 03 >420 OpenParm DB $03 +001257: 80 02 >421 DA pnBuf ;Application's PN +001259: 00 1C >422 DA IOBuf ;1024-byte I/O buf +00125B: 00 >423 OpenRefNbr DB $00 + >424 +00125C: 02 >425 eofParm DB $02 +00125D: 00 >426 eofRefNbr DB $00 +00125E: 00 00 00 >427 theEOF DB 0,0,0 + >428 +001261: 04 >429 ReadParm DB $04 +001262: 00 >430 ReadRefNbr DB $00 +001263: 00 20 >431 DA $2000 ;Read into this location +001265: 00 00 >432 ReadLen DW $0000 +001267: 00 00 >433 DW $0000 + >434 +001269: 01 >435 ClsParm DB $01 +00126A: 00 >436 ClsRefNbr DB $00 + >437 +00126B: 04 >438 QuitParms DB $04 +00126C: 00 >439 DB $00 ;=$EE for enhanced Quit +00126D: 00 00 >440 DA $0000 ;Addr of pathname +00126F: 00 >441 DB $00 +001270: 00 00 >442 DW $0000 + >443 +001272: 0A >444 GFIParm DB $0A +001273: 00 0F >445 DA VolNameStr +001275: 00 >446 DB $00 +001276: 00 >447 DB $00 +001277: 00 00 >448 DW $0000 +001279: 00 >449 DB $00 +00127A: 00 00 >450 DW $0000 +00127C: 00 00 >451 DW $0000 +00127E: 00 00 >452 DW $0000 +001280: 00 00 >453 DW $0000 +001282: 00 00 >454 DW $0000 + >455 + >456 * Messages/Button strings + >457 +001284: 1B 43 61 6E >458 CantRunStr STR 'Can'27't run next application.' +0012A0: 14 >459 P8ErrStr DB 20 ;len byte +0012A1: 50 72 6F 44 >460 ASC 'ProDOS Error = $' +0012B1: 20 20 20 20 >461 ErrNumStr ASC ' ' +0012B5: 00 >462 nullStr DB $00 +0012B6: 17 50 6C 65 >463 insDskStr STR 'Please insert the disk:' +0012CE: 0D >464 acceptStr DB 13 +0012CF: 41 63 63 65 >465 ASC 'Accept: ' +0012D7: 1B >466 HEX 1B ;Enable mousetext chars +0012D8: 0F >467 HEX 0F ;Inverse +0012D9: 4D >468 ASC 'M' ;Return Icon +0012DA: 0E >469 HEX 0E ;Normal +0012DB: 18 >470 HEX 18 ; ;Disable mousetext chars +0012DC: 0B 43 61 6E >471 cancelStr STR 'Cancel: Esc' + 48 + +End Merlin-16 assembly, 17128 bytes, 0 errors, 11890 lines, 1672 symbols. + +Elapsed time = 16 minutes, 15 seconds. +