6502code/source/PRODOS8.TXT

11356 lines
699 KiB
Plaintext

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 #<tablIntrp ;Move interpreter loader to $800
002094: A0 23 >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 #<tabl64 ;Now move/relocate whatever we got
0020C3: A0 23 >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 #<TClkStuff ; & set up clock
002134: A0 23 >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 #<CallDisp
00213D: 8D 04 BF >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 #<DispGS ;Relocate GS dispatcher
00214D: A0 23 >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 #<DispBB ;Install Better Bye
002158: A0 23 >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 #<Disp64 ;Install old 40-col dispatcher
002169: A0 23 >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 #<cortClock ;Now set up for relocating
002253: A0 23 >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 #<ABuf+4 ;Start 1 entry past header
002430: D0 02 =2434 >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 #<gNoDev ; unassigned entry in table
002987: D0 07 =2990 >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 #<MirrorDevEntry ;Install driver that
0029E1: 99 10 BF >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 #<RAMsrc
002C8F: 86 3C >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 #<RAMdest
002C9D: 85 42 >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 #<LCdest ;Put LC address into
002CA9: 8D 26 BF >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 #<EnterCard ;Card entry point
00FF2E: 8D ED 03 >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 #<DoneWrt
00FF7A: 8D ED 03 >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 #<aftIrq ;Set up return address
00FFBE: 48 >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 #<ROMIrq
00FFC7: 48 >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 #<genBuf+4 ;Skip 4-byte blk link ptrs
00E592: 85 48 >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 mark<EOF
00EC10: DD 15 D8 >30 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 mark<eof
>15 ; 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 EOF<mark
00F22E: 20 06 F2 >368 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 eof<mark
00F64A: 88 >276 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 #<DispAdr
00FCD4: 85 3E >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 #<spStatList ;Its a statusCmd
00FD13: 84 44 >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 <sub> 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 #<ABuf
00028D: 8D BF 03 >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 #<MainWrt ;Pointers set up
0002DD: 8D ED 03 >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 page<f (<block 8) requested
00034C: 90 DA =0328 >241 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 #<NoErr ;Set up return to NoErr
0003F1: 8D ED 03 >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 #<Msg0-MsgStart ;Load offset to message into x...
001035: 20 D6 11 >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 #<Msg-MsgStart ; Load offset to message into x...
0010DB: 20 D6 11 >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 #<Err1-MsgStart ;Load x with offset to message
0011F3: D0 16 =120B >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 #<Err2-MsgStart ; Load x with offset to message
001207: D0 02 =120B >302 BNE DoError
001209: A2 79 >303 Error3 LDX #<Err3-MsgStart ;Load x with offset to message
00120B: 20 D6 11 >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.