| 30-04-2017 (2706 ) | Categoria: Apple |
Â
Transcribed and Annotated by Michael Pohoreski.
Latest version on GitHub: dos33.html
Numerous improvements have been made over the original DOS 3.3C assembly source code listing!
Â
Header Format is:
=== FILENAME - Description, Page #, Track/Sector @ $offset, $#### (Relocated address in high memory) ===
Line format is:
Addr:## ## ## L## LABEL MNEMONIC COMMENT Annotation
Legend:
Â
| Addr | Address at assemble time | ||||||||||||||
| ## ## ## | Opcode(s) or raw hex bytes (may be unspecified) | ||||||||||||||
| L## | Line number of source file | ||||||||||||||
| LABEL | All function names, variable names, branch target names, and references to Code and Data are color-coded: Function Definition Data Definition Macro Definition Const Definition |
||||||||||||||
| MNEMONIC | Assembly language instruction Function Reference Variable Reference 0-9, A-F |
||||||||||||||
| COMMENT | Official comment -- spelling mistakes and improper indentation are verbatim | ||||||||||||||
| Annotation | Modern commentary by me.
|
||||||||||||||
| Misc. |
|
WARNING: DOS 3.3 was written by an amateur. Reading this source code will probably make you angry at all the dumb shit it does. Look for all my *sigh* comments and HNTDAFS (How NOT to Design a File System) links. While knowing "What To Do" is important, knowing "What NOT To Do" is even more important. As they say, "Hindsight is 20/20."
Â
LEGAL CRAP
The intent of providing this copyrighted source code is as a convenience for the curious as a means to learn.
DISCLAIMER: YOU MAY NOT USE APPLE'S SOURCE CODE EXCEPT FOR LEARNING else you face risking the wrath of Apple's lawyers. Since Apple has already previously released this source code I'm assuming it is OK to provide a mirror of the information since I'm not presenting anything new (well, OK, my commentary, but you get the point) that isn't already publically available.
With that "legalese" out of the way ... enjoy the read!
00001 001 SBTL "DOS3.3C w/APPEND fix, U/L case"
00002 002 LST ON,VSYM
00003 003 MSB OFF
00004 004 ORIGIN EQU $1B00
00005 005 DIAGMOD EQU 0
00006 006 DOS33B EQU 1
00007 007 ULC EQU 0 ;1=ASM with lower case patch ;Address .. Addr, Track/Sector(s)
00008 008 INCLUDE RELOCTR,,2 ; $1B00 .. $1C80, T0SA - T0SB
00009 009 INCLUDE DOSINIT,,2 ; $1C81 .. $1E80, T0SB - T0SD
00010 010 INCLUDE DOSHOOK,,2 ; $1E81 .. $1FCC, T0SD - T0SE
00011 011 INCLUDE CMDSCAN,,2 ; $1FCD .. $2192, T0SE - T1S0
00012 012 INCLUDE XOPNCLS,,2 ; $2193 .. $2330, T1S0 - T1S2
00013 013 INCLUDE XLODSAV,,2 ; $2331 .. $250F, T1S2 - T1S4
00014 014 INCLUDE XMISCMD,,2 ; $2510 .. $26A7, T1S4 - T1S5
00015 015 INCLUDE DOSGOER,,2 ; $26A8 .. $27D3, T1S5 - T1S6
00016 016 INCLUDE BLDFTAB,,2 ; $27D4 .. $2883, T1S6 - T1S7
00017 017 INCLUDE CMDTBLS,,2 ; $2884 .. $2A4E, T1S7 - T1S9
00018 018 INCLUDE FDOSENT,,2 ; $2A4F .. $2B21, T1S9 - T1SA
00019 019 INCLUDE FOPCLRW,,2 ; $2B22 .. $2CEE, T1SA - T1SB
00020 020 INCLUDE FDELCAT,,2 ; $2CEF .. $2E8D, T1SB - T1SD
00021 021 INCLUDE FMTRWIO,,2 ; $2E8E .. $2FF6, T1SD - T1SE
00022 022 INCLUDE FLOCNXB,,2 ; $2FF7 .. $31C8, T1SE - T2S0
00023 023 INCLUDE FLOCSEC,,2 ; $31C9 .. $3396, T2S0 - T2S2
00024 024 INCLUDE FVCBUFS,,2 ; $3397 .. $35FD, T2S2 - T2S4
00025 025 INLUCDE BOOTLDR,,2 ; $35FE .. $37FF, T0S0 - T0S1
00026 026 INCLUDE COREQUS,,1 ; n/a
00027 027 INCLUDE PRENIBL,,1 ; $3800 .. $3829, T0S2
00028 028 INCLUDE WRITRTN,,1 ; $382A .. $38C1, T0S2
00029 029 INCLUDE POSTNRD,,1 ; $38C2 .. $3943, T0S2 - T0S3
00030 030 INCLDUE RDADSEK,,1 ; $3944 .. $39FC, T0S3
00031 031 INCLUDE MSWAITR,,1 ; $39FD .. $3C55, T0S3 - T0S6
00032 032 INCLUDE WRITADR,,1 ; $3C56 .. $3CFF, T0S6
00033 033 INCLUDE RWTSONE,,1 ; $3D00 .. $3DAA, T0S7
00034 034 INCLUDE RWTSTWO,,1 ; $3DAB .. $3EAE, T0S7 - T0S8
00035 035 INCLUDE FORMATR,,1 ; $3EAF .. $3FC7, T0S8 - T0S9
00036 036 INCLUDE DOSPTCH,,1 ; $3FC8 .. $3FFF, T0S9
00037 001 PAGE ; === Page 110 === 00038 002 ***************************************************** 00039 003 * * 00040 004 * (C) COPYRIGHT 1978,1980,1982 APPLE COMPUTER, INC. * 00041 005 * * 00042 006 ***************************************************** 00043 007 SKP 2 00044 008 ********************************* 00045 009 * * 00046 010 * ADAPTED FOR MACRO EDASM BY * 00047 011 * JOHN ARKLEY * 00048 012 * DEC 1980 * 00049 013 * * 00050 014 ********************************* 00051 015 SKP 2 00052 016 ********************************* 00053 017 * * 00054 018 * DOS 3.3 REVISION B PATCHES * 00055 019 * INSTALLED BY MARK HOUDE * 00056 020 * JUL 1982 * 00057 021 * * 00058 022 ********************************* 00059 023 SKP 2 00060 024 ********************************* 00061 025 * * 00062 026 * DOS 3.3 REV B PATCHES VER 2 * 00063 027 * INSTALLED BY FERN BACHMAN * 00064 028 * SEP 1982 * 00065 029 * * 00066 030 ********************************* 00067 031 SKP 2 00068 032 ********************************* 00069 033 * * 00070 034 * DOS33C PATCHES (APPEND & * 00071 035 * UPPER/LOWER CASE CHECK) * 00072 036 * * 00073 037 * BY * 00074 038 * GUIL BANKS * 00075 039 * 1983 * ; Note: Fixed EOL formatting in PDF 00076 040 * * 00077 041 ********************************* 00078 042 ; 00079 043 ;EQUATES REQD TO FIND THINGS IN APPLE II 00080 044 ; 00081 045 SETVID EQU $FE93 ; Monitor: 0 Ctrl-P 00082 046 SETKBD EQU $FE89 ; Monitor: 0 Ctrl-K 00083 047 PROMPT EQU $33 ; PROMPT CHAR 00084 048 OUTSW EQU $36 ; OUTPUT VECTOR SWITCH 00085 049 INSW EQU $38 ; INPUT VECTOR SWITCH 00086 050 ZPGWRK EQU $40 ; ZERO PAGE WORK CELL 00087 051 CNUM EQU $44 ; CONVERTED NUMERIC ; 16-bit input number 00088 052 LBUFF EQU $200 ; LINE BUFFER ; Keyboard buffer of 255 chars 00089 053 MULT EQU $FB63 ; MULT ROUTINE ; -- unused, never referenced --
00090 054 INPRT EQU $FE8B ; SET IN PORT ; === Page 111 === ; *sigh* Apple 2 ROM lists INPORT = $FE8B, INPRT = $FE8D 00091 055 OUTPRT EQU $FE95 ; SET OUT PORT 00092 056 IBCHN EQU $E836 ; BASIC RUN ; Integer Basic 00093 057 IBLMEM EQU $4A ; BASIC LOW MEM ; Integer Basic 00094 058 IBHMEM EQU $4C ; INTEGER BASIC HIMEM ; Integer Basic 00095 059 IBSOP EQU $CA ; INTEGER BASIC START OF CGM ; Integer Basic CGM ??? 00096 060 IBBRK EQU $E3E3 ; BASIC BREAK ; Integer Basic 00097 061 IBGO EQU $E000 ; BASIC ENTRY POINT ; Integer Basic COLD start 00098 062 IBCONT EQU $E003 ; BASIC CONTINUE ENTRY POINT ; Integer Basic WARM start 00099 063 IBSOV EQU $CC ; BASIC START OF VARIABLES ; Integer Basic 00100 064 ASSOP EQU $67 ; AS START OF PROGRAM ; Applesoft Basic 00101 065 ASEOP EQU $AF ; AS END OF PROGRAM ; Applesoft Basic 00102 066 ASEOP2 EQU $69 ; AS END-OF PGM 2 ; Applesoft Basic 00103 067 ASHM1 EQU $73 ; AS HIGH MEM 1 ; Applesoft Basic 00104 068 ASHM2 EQU $6F ; AS HIGH MEM 2 ; Applesoft Basic 00105 069 ASRNX EQU $D6 ;AS RUN-ONLY FLAG ; Applesoft Basic 00106 070 ASONERR EQU $D8 ;AS ON-ERR GOTO FLAG ; Applesoft Basic =0067 00107 071 ASLMEM EQU ASSOP ; AS LOW MEM ; Applesoft Basic -- never referenced 00108 072 ASBRK1 EQU $D865 ; AS ROM BREAK ; Applesoft Basic 00109 073 ASBRK2 EQU $1067 ; AS RAM BREAK ; Applesoft Basic 00110 074 ASCNTU1 EQU $D43C ; ROM entry point 00111 075 ASCNTU2 EQU $C3C ; RAM entry point 00112 076 ASRSEQ1 EQU $D4F2 ; ROM entry point 00113 077 ASRSEQ2 EQU $CF2 ; RAM entry point 00114 078 AITSTL EQU $E000 ; AS 1 IB TEST LOC ; Applesoft Basic E000: JMP $F128 00115 079 ATSTV EQU $4C ; AS TEST VALUE ; Applesoft Basic 00116 080 ITSTV EQU $20 ; IB TEST VALUE ; Integer Basic 00117 081 BOOTSL EQU $2E ; BOOT FROM SLOT ; Slot from Boot 00118 082 ZPGFCB EQU $42 ; ZERO PAGE WORK CELL ; File Control Block 00119 083 MONRST EQU $FF65 ;MONITOR RESET ENTRY 00120 084 MONBRK EQU $FA59 ;MONITOR BREAK ENTRY 00121 085 IORTS EQU $FF58 ;KNOWN RTS IN MONITOR ROM 00122 086 HOME EQU $FC58 ; cls(); Clear the text screen 00123 087 PRINT EQU $FDED ; putchar(); 00124 088 GETKEY EQU $FD0C ; getchar(); 00125 089 INSDS2 EQU $F88E ; Instruction Disassembly Opcode Length 00126 090 LENGTH EQU $2F 00127 091 ZRSET EQU $3F2 ;NEW MONITOR ROM RESET VECTOR 00128 092 PWCNST EQU $3F4 ;NEW MONITOR ROM POWER UP CONSTANT 00129 093 REP 40 00130 094 * 00131 095 * 00132 096 ORG ORIGIN 00133 097 * 00134 098 * 00135 099 REP 40 00136 100 PAGE 1B00:4C 84 1D 00137 101 BEGIN JMP DBINIT ; === DOS loads @ $1B00 === 00138 102 ; ; Loaded in at $38D4 00139 103 DOSREL EQU * ; Called from File BOOTLDR, Page 12, Line #298 00140 104 ; 00141 105 ; GET RELOCATION PARMS 00142 106 ; 00143 107 DR0 EQU * 00144 108 LOC1 EQU $26 ; Monitor ROM GBASL = $26, Pointer to last HGR Byte plotted 1B03:A9 BF 00145 109 LDA #$BF ; START AT BF00 ; Top of 48K 1B05:85 41 00146 110 STA ZPGWRK+1 ; TO LOOK FOR ; ZPGWRK = MemTestAdr 1B07:A2 00 00147 111 LDX #0 ; HIGH RAM 1B09:86 40 00148 112 STX ZPGWRK 1B0B:A0 00 00149 113 DR0A LDY #0 ; APPLE TEST 00150 114 DR1B EQU * ; unused label 1B0D:A1 40 00151 115 LDA (ZPGWRK,X) 1B0F:85 26 00152 116 STA LOC1 ; LOC1 = MemTestVal
1B11:98 00153 117 DR1 TYA ; === Page 112 === 1B12:45 26 00154 118 EOR LOC1 1B14:85 26 00155 119 STA LOC1 1B16:98 00156 120 TYA 1B17:41 40 00157 121 EOR (ZPGWRK,X) 1B19:81 40 00158 122 STA (ZPGWRK,X) 1B1B:C5 26 00159 123 CMP LOC1 1B1D:D0 05 00160 124 BNE DR1A ; ↓ /rant Crappy HTML name ↓ instead of simpler v 1B1F:C8 00161 125 INY 1B20:D0 EF 00162 126 BNE DR1 ; ↑ /rant Crappy HTML name ↑ instead of simpler ^ 1B22:F0 04 00163 127 BEQ DR2 ; BR IF TOOK ; v 00164 128 DR1A EQU * 1B24:C6 41 00165 129 DEC ZPGWRK+1 ; NOT RAM 1B26:D0 E3 00166 130 BNE DR0A ; TRY NEXT PAGE ; ^ 00167 131 ; 00168 132 DR2 EQU * 00169 133 ; 1B28:A5 41 00170 134 LDA ZPGWRK+1 ;BEGIN PATCH TO INSURE ***** ; note: '*****' is BEGIN_PATCH 1B2A:29 DF 00171 135 AND #$DF ; PROPER HIGH MEMORY CHECK. 1B2C:85 43 00172 136 STA ZPGFCB+1 ;(DOS MASTER 3.1 CONTAINS 1B2E:86 42 00173 137 STX ZPGFCB ; THIS ROUTINE STARTING AT LOCATION 1B30:A1 42 00174 138 LDA (ZPGFCB,X) ; $3540) 1B32:48 00175 139 PHA 1B33:85 26 00176 140 STA LOC1 ;SAVE TEST VALUE 1B35:98 00177 141 DR2A TYA ;(FIRST TIME Y=0) 1B36:45 26 00178 142 EOR LOC1 ;TEST EACH (ALLEDGED) MEMORY BYTE 1B38:85 26 00179 143 STA LOC1 ; 256 TIMES TO DETERMINE IF 1B3A:98 00180 144 TYA ; IT IS REALLY GOOD MEMORY AND 1B3B:41 40 00181 145 EOR (ZPGWRK,X) ; MIRRORED 8K LOWER IN RAM. 1B3D:81 42 00182 146 STA (ZPGFCB,X) 1B3F:C5 26 00183 147 CMP LOC1 ;DID IT PASS THIS TIME? 1B41:D0 09 00184 148 BNE DR2B ; BYTE NOT MIRRORED, THEN GOOD MEMORY ; *sigh* more crap code: S-L-O-W 1B43:C8 00185 149 INY ;MAYBE IT WAS COINCIDENCE ; Instead of testing *every* byte (256 times WTF!) 1B44:D0 EF 00186 150 BNE DR2A ; BRANCH UNLESS IT'S MATCHED 256 TIMES ; just test the last byte of every page 1B46:A4 43 00187 151 LDY ZPGFCB+1 ;HIMEM IS 8K LOWER THEN WAS ; Switch PLA, LDY, then BNE instead 1B48:68 00188 152 PLA ;ORIGINALLY THOUGHT! ; since ZPGFCB can never be on mem page $00 1B49:4C 51 1B 00189 153 JMP DR2C ; wastes 1 byte with JMP instead of BNE. See Line #151 1B4C:68 00190 154 DR2B PLA ; ORIGINAL HIMEM PROVED GOOD 1B4D:81 42 00191 155 STA (ZPGFCB,X) ;RESTORE BYTE ORIGINALLY MESSED WITH. 1B4F:A4 41 00192 156 LDY ZPGWRK+1 ;END OF PATCH ***** ; ***** = END_PATCH 1B51:C8 00193 157 DR2C INY ; NEW END OF DOS ; Y = $BF 1B52:8C 7D 1C 00194 158 STY NEPAGE 1B55:38 00195 159 SEC 1B56:98 00196 160 TYA 1B57:ED 7E 1C 00197 161 SBC DOSLNG ; MINUS DOS LENGTH 1B5A:8D 7C 1C 00198 162 STA NSPAGE ; IS NEW START OF DOS 1B5D:38 00199 163 SEC 1B5E:ED 7A 1C 00200 164 SBC RSPAGE ; MINUS OLD DOS START 1B61:F0 9D 00201 165 BEQ BEGIN ; (BREIF NO DELTA) ; ^ Giving the benefit of doubt; NOT misspelt: BRanch Equal If ? 1B63:8D 7F 1C 00202 166 STA DELTA ; IS DELTA 1B66:AD 7A 1C 00203 167 LDA RSPAGE ; RESET START PAGE TO NORMAL 1B69:8D 0D 1D 00204 168 STA ASTART+1 00205 169 ; 1B6C:A9 1D 00206 170 LDA #<DBINIT ; RESET PI RTN TO NORMAL ; PI = Post Init; @ boot defaults to us, our relocator: DOSREL 1B6E:8D 49 37 00207 171 STA DI3+2 1B71:A9 84 00208 172 LDA #>DBINIT 1B73:8D 48 37 00209 173 STA DI3+1 00210 174 ; 00211 175 ;RELOCATE ADR TABLES 00212 176 ;
1B76:A2 00 00213 177 LDX #0 ; === Page 113 === 1B78:86 40 00214 178 STX ZPGWRK 00215 179 DR3 EQU * 1B7A:BD 29 1C 00216 180 LDA ADRTAB+1,X ; [StartLo] If only we had an ($BC) LDY ADRTAB+1,X instruction ... 1B7D:A8 00217 181 TAY ; wastes 1 byte; ... to skip this useless instruction. 1B7E:BD 2A 1C 00218 182 LDA ADRTAB+2,X ; [StartHi] Oh wait, we do! /rhetorical Who knew! 1B81:85 41 00219 183 STA ZPGWRK+1 ; Evident code quality to come. :-/ 1B83:4C 93 1B 00220 184 JMP DR5 ; wastes 1 byte instead of BNE; skip low address ptr 00221 185 ; ; See software was bloated in the "good ol' days" too. :-( 00222 186 DR4 EQU * 1B86:18 00223 187 CLC 1B87:B1 40 00224 188 LDA (ZPGWRK),Y 1B89:6D 7F 1C 00225 189 ADC DELTA 1B8C:91 40 00226 190 STA (ZPGWRK),Y 1B8E:C8 00227 191 INY ; Line #203 1B8F:D) 02 00228 192 BNE DR5 1B91:E6 41 00229 193 INC ZPGWRK+1 1B93:C8 00230 194 DR5 INY 1B94:D0 02 00231 195 BNE DR6 1B96:E6 41 00232 196 INC ZPGWRK+1 00233 197 ; 00234 198 DR6 EQU * 1B98:A5 41 00235 199 LDA ZPGWRK+1 1B9A:DD 2C 1C 00236 200 CMP ADRTAB+4,X ; [EndHi] Crappy array offset, see comments starting on Line #286 1B9D:90 E7 00237 201 BCC DR4 1B9F:98 00238 202 TYA 1BA0:DD 2B 1C 00239 203 CMP ADRTAB+3,X ; [EndLo] 1BA3:90 E1 00240 204 BCC DR4 00241 205 ; 1BA5:8A 00242 206 TXA 1BA6:18 00243 207 CLC 1BA7:69 04 00244 208 ADC #4 ; 4 bytes per entry: {StartAdr,EndAdr} 1BA9:AA 00245 209 TAX 1BAA:EC 28 1C 00246 210 CPX ADRTAB ; Done all bytes? 1BAD:90 CB 00247 211 BCC DR3 00248 212 PAGE 00249 213 ; 00250 214 ;RELOCATE CODE 00251 215 ; 1BAF:A2 00 00252 216 LDX #0 1BB1:8E 9C 33 00253 217 DR7 STX TEMP1 00254 218 ; 1BB4:BD 5A 1C 00255 219 LDA CDETAB+1,X ; GET A START OF CODE ADR 1BB7:85 40 00256 220 STA ZPGWRK ; PUT IN ZPG 1BB9:BD 5B 1C 00257 221 LDA CDETAB+2,X 1BBC:85 41 00258 222 STA ZPGWRK+1 00259 223 ; 1BBE:A2 00 00260 224 DR8 LDX #0 ; GET OP CODE 1BC0:A1 40 00261 225 LDA (ZPGWRK,X) ; GO FIND OUT HOW LONG ; Since we don't have a linker, interesting hack of using 1BC2:20 8E F8 00262 226 JSR INSDS2 ; monitor ROM to get instruction opcode length 00263 227 ; 1BC5:A4 2F 00264 228 LDY LENGTH ; GET HOW LONG ; crappy var name -- length of what?? Oh OPCODE_LEN 1BC7:C0 02 00265 229 CPY #2 ; IF IT AIN'T ; *sigh* #3-1 is clearer since zero based 1BC9:D0 11 00266 230 BNE DR9 ; 3 THEN DON'T RELOC ; 300:A9 20 20 8E F8 A5 2F 09 30 4C ED FD 1BCB:B1 40 00267 231 LDA (ZPGWRK),Y ; GET PAGE FROM INST 1BCD:CD 7A 1C 00268 232 CMP RSPAGE ; IF PAGE < REL START 1BD0:90 0A 00269 233 BCC DR9 ; THEN IGNOR 1BD2:CD 7B 1C 00270 234 CMP REPAGE ; IF PAGE >= REL END 1BD5:B0 05 00271 235 BCS DR9 ; THEN IGNORE 1BD7:6D 7F 1C 00272 236 ADC DELTA ; ELSE ADD DELTA 1BDA:91 40 00273 237 STA (ZPGWRK),Y ; TO RELOCATE 00274 238 ; 1BDC:38 00275 239 DR9 SEC
1BDD:A5 2F 00276 240 LDA LENGTH ; ADD LENGTH ; === Page 114 === 1BDF:65 40 00277 241 ADC ZPGWRK ; TO PC 1BE1:95 40 00278 242 STA ZPGWRK 1BE3:A9 00 00279 243 LDA #0 1BE5:65 41 00280 244 ADC ZPGWRK+1 1BE7:85 41 00281 245 STA ZPGWRK+1 00282 246 ; 1BE9:AE 9C 33 00283 247 LDX TEMP1 ; CHECK FOR END 1BEC:DD 5D 1C 00284 248 CMP CDETAB+4,X ; OF CODE SEGMENT 1BEF:90 CD 00285 249 BCC DR8 ; BR NOT END 1BF1:A5 40 00286 250 LDA ZPGWRK 1BF3:DD 5C 1C 00287 251 CMP CDETAB+3,X 1BF6:90 C6 00288 252 BCC DR8 ; BR NOT END 00289 253 ; 1BF8:8A 00290 254 TXA 1BF9:18 00291 255 CLC 1BFA:69 04 00292 256 ADC #04 ; INCREMENT TABLE INDEX 1BFC:AA 00293 257 TAX 1BFD:EC 59 1C 00294 258 CPX CDETAB ; DONE 1C00:90 AF 00295 259 BCC DR7 ; BR IF NOT ; === T0SB === 00296 260 ; 00297 261 PAGE 00298 262 ; 00299 263 ;MOVE TO RELOCATED CODE 00300 264 ; 1C02:A9 3F 00301 265 LDA #<ENDOFDOS-$80 1C04:85 41 00302 266 STA ZPGWRK+1 ; ZPGWRK=FROM 1C06:AC 7D 1C 00303 267 LDY NEPAGE 1C09:88 00304 268 DEY 1C0A:84 43 00305 269 STY ZPGFCB+1 ; ZPGFCB = TOO 1C0C:A9 00 00306 270 LDA #0 ; /sarcasm If only we had a LDY #0 instruction ... 1C0E:85 40 00307 271 STA ZPGWRK 1C10:85 42 00308 272 STA ZPGFCB 1C12:A8 00309 273 TAY ; wastes 1 byte; ... to remove this one. See Line #270 00310 274 ; 1C13:B1 40 00311 275 DR10 LDA (ZPGWRK),Y ; BYTE FROM 1C15:91 42 00312 276 STA (ZPGFCB),Y ; BYTE TO 1C17:C8 00313 277 INY ; INCREMENT ; /sarcasm No shit, Sherlock 1C18:D0 F9 00314 278 BNE DR10 ; BR NOT FULL PAGE 1C1A:CE 80 1C 00315 279 DEC DPGCNT ; DECREMENT PAGE CNT 1C1D:F0 06 00316 280 BEQ DR11 ; BR IF DONE 1C1F:C6 41 00317 281 DEC ZPGWRK+1 ; INC FROM PAGE 1C21:C6 43 00318 282 DEC ZPGFCB+1 ; INC TOO PAGE 1C23:D0 EE 00319 283 BNE DR10 ; MOVE PAGE 00320 284 ; 1C25:4C 54 1E 00321 285 DR11 JMP DBVECT+3 ; DONE ; DOSINIT, Page 51 -> JMP DBINIT 00322 286 PAGE ; This is really crappy table formatting due to 2 reasons: ; 1) A redundant +1 offset is needed for "almost all"(*) offsets in code ; since the length of the array doesn't have its own label: ; ; ADRTABLEN DFB 9*4 ; Poor Solution: but better then original ; ; (*) "almost all" means all except one when the length IS checked on Line #210 ; ; 2) The start and end address are not on a single line ; with no visual indicators to tell what is the start or end address ; This makes it extremely hard to tell which addresses belong to ; which entry. I've added the array offset [#] to make the original code ; more readable. ; Better Solution: Place each entry on a single line ; along with the correct half-open range interval notation [,) ; then each block of memory to relocate becomes very crystal clear: ; ; ; [Start, End) ; ADRTAB DW SAT1 , EAT1 ; DW RUN , RUN ; DW IBVT , IBVT ; DW AS1VT, AS1VT ; ; Best Solution: Even better would be to use two labels ; offset by two bytes to simulate two struct member variables: ; ; ADRTABS DW SAT1 ; Start Address ; ADRTABE DW EAT ; End Address ; DW RUN , RUN ; DW IBVT , IBVT ; DW AS1VT, AS1VT ; ; While the second's line formatting, ADRTABE, is a little unorthodox ; using dual labels makes the array offsets obvious compared to ; the original non-descript code: ; ; LDY ADRTABS+0,X ; lo byte of start address; was LDA ADRTAB+1,X ; LDA ADRTABS+1,X ; hi byte of start address; was LDA ADRTAB+2,X ; CMP ADRTABE+1,X ; hi byte of end address; was CMP ADRTAB+4,X ; CMP ADRTABE+0,X ; lo byte of end address; was CMP ADRTAB+3,X ; 1C28:24 00323 287 ADRTAB DFB 9*4 ; magic number Really?! We can't do ADRTAB_LEN DFB ADRTAB_END - ADRTAB_START ??? 1C29:00 1D 00324 288 DW SAT1 ; [0] Start Address Table 1 in DOSINIT 1C2B:56 1D 00325 289 DW EAT1 ; End Address Table 1 ; wastes 4 bytes due to non-contiguous memory ; $1D56, $1D57 = CHAIN ; Solution would be to add our own stub of 3 bytes ; DOS_CHAIN_IB: JMP $E836 1C2D:58 1D 00326 290 DW RUN ; [1] Allowing us to remove 4 bytes from the table: end[0], start[1] 1C2F:5A 1D 00327 291 DW RUN+2 ; Further optimization would remove 10 bytes (5 entries) 1C31:64 1D 00328 292 DW IBVT+2 ; [2] Integer Basic Vector Table 1C33:66 1D 00329 293 DW IBVT+4 ; 1C35:6C 1D 00330 294 DW AS1VT ; [3] Applesoft (ROM) Vector Table 1C37:70 1D 00331 295 DW AS1VT+4 1C39:78 1D 00332 296 DW AS2VT ; [4] Applesoft (RAM) Vector Table 1C3B:7C 1D 00333 297 DW AS2VT+4 1C3D:7E 1D 00334 298 DW AS2VT+6 ; [5] Applesoft (RAM) Vetor Table 1C3F:80 1D 00335 299 DW AS2VT+8 1C41:C1 2A 00336 300 DW SAT2 ; [6] Start Address Table 2 in FDOSENT 1C43:FD 2A 00337 301 DW EAT2 1C45:E4 37 00338 302 DW BAIOB ; [7]
1C47:E8 37 00339 303 DW ADOSLD+2 ; === Page 115 === 1C49:EE 37 00340 304 DW IBDCTP ; [8] 1C4B:F0 37 00341 305 DW IBDCTP+2 1C4D:00 00 00 00 00342 306 DFB 0,0,0,0 ; wastes 12 bytes -- never referenced ! 1C51:00 00 00 00 00343 307 DFB 0,0,0,0 1C55:00 00 00 00 00344 308 DFB 0,0,0,0 00345 309 CDETAB EQU * ; 1C59:1C = v1980, 20 = v1983 1C59:20 00346 310 DFB 8*4 ; magic number Really?! We can't do CDETAB_LEN DFB CDETAB_END - CDETAB_START ??? 1C5A:84 1D 00347 311 DW SC1 ; [0] 1C5C:84 28 00348 312 DW EC1 1C5E:FD 2A 00349 313 DW SC2 ; [1] 1C60:97 33 00350 314 DW EC2 1C62:5D 36 00351 315 DW SC3 ; [2] 1C64:E0 37 00352 316 DW EC3 1C66:56 3C 00353 317 DW SWADR1 ; [3] 1C68:DF 3C 00354 318 DW EWADR1 1C6A:00 38 00355 319 DW ASC1 ; [4] 1C6C:11 3A 00356 320 DW AEC1 1C6E:69 3A 00357 321 DW PSC1 ; [5] 1C70:94 3A 00358 322 DW PEC1 1C72:00 3D 00359 323 DW ASC2 ; [6] 1C74:A8 3F 00360 324 DW AEC2 1C76:C8 3F 00361 325 DW SDP1 ; [7] Start Dos Patch 1C78:FF 3F 00362 326 DW EDP1 ; End Dos Patch 1C7A:1D 00363 327 RSPAGE DFB <START ; (Source) Relocation Start Page $1D00 1C7B:40 00364 328 REPAGE DFB <ENDOFDOS ; (Source) Relocation End+1 Page $4000, wastes 1 bytes; See AEND 00365 329 ; 1C7C:00 00366 330 NSPAGE DFB 0 1C7D:00 00367 331 NEPAGE DFB 0 00368 332 ; 1C7E:23 00369 333 DOSLNG DFB <ENDOFDOS-START 00370 334 ; 1C7F:00 00371 335 DELTA DFB 0 1C80:23 00372 336 DPGCNT DFB <ENDOFDOS-START 00373 337 PAGE
00374 001 HEREL HEREL EQU >* ; === Page 48 === $81 00375 002 REMDR REMDR EQU 256-HEREL ; DOS 3.3B bytes | $7F 1C81:FC FC FC 00376 003 ORG *+REMDR ; 1C81: FC FD FD | disk wastes 127 bytes padding to end of sector 1C84:FC FC FC FD ; 1C84:FD FC FD FC | Technically only 82 bytes ($1CD3-$1C81 = $52) are wasted 1C88:FC FC FF FC ; 1C88:FC FC FE FE | but FTAB DW *-45 (below) is sloppy code 1C8C:FD FC FC FF ; 1C8C:FC FE FC FC | Why isn't this "allocated" at run-time? 1C90:FF FC FE FD ; 1C90:FD FE FC FF | Meaning this should be placed after ALL the code. 1C94:FE FD FD FE ; 1C94:FC FD FC FC | See: Wasted Disk Space 1C98:FF FC FE FF ; 1C98:FC FF FC FF | 1C9C:FD FE FF FD ; 1C9C:FC FE FF FF | 1CA0:FC FD FD FC ; 1CA0:FF FF FD FE | 1CA4:FD FE FD FF ; 1CA4:FC FD FC FC | 1CA8:FC FE FC FC ; 1CA8:FC FC FD FC | 1CAC:FC FC FC FC ; 1CAC:FE FE FE FC | 1CB0:FD FC FC FE ; 1CB0:FD FF FC FC | 1CB4:FC FD FC FC ; 1CB4:FC FE FC FD | 1CB8:FF FC FC FE ; 1CB8:FC FC FC FE | 1CBC:FD FC FD FF ; 1CBC:FC FD FC FC | 1CC0:FC FF FD FE ; 1CC0:FC FD FC FD | 1CC4:FF FD FF FC ; 1CC4:FD FC FC FC | 1CC8:FC FD FE FF ; 1CC8:FD FD FC FE | ECLOSE, EDEL, EPOS, RWPOSN, CLOSFILE call 1CCC:FF FF FC FC ; 1CCC:FC FC FE FC | FILSRC (File Search) 1CD0:FF FF FC FE ; 1CD0:FC FD FD FC | [00] $1CD3 ($9CD3) Used by TSINIT, init @ Line #036 1CD4:FD FC FD FD ; 1CD4:FF FE FC FC | 1CD8:FE FF FD FE ; 1CD8:FC FC FD FC | 1CDC:FF FC FE FE ; 1CDC:FD FE FC FC | 1CE0:FC FD FC FD ; 1CE0:FD FC FF FC | 1CE4:FE FD FD FC ; 1CE4:FE FF FF FF | 1CE8:FD FC FF FD ; 1CE8:FD FC FE FE | See init @ BFT1, Line #041 1CEC:FC FF FC FC ; 1CEC:FC FC FE FC | [1E] $1CF1 ($9CF1): $9CA6 (buf1 ptr) 1CF0:FE FD FC FC ; 1CF0:FC FE FC FE | [20] $1CF3 ($9CF3): $9BA6 (buf2 ptr) 1CF4:FD FC FE FC : 1CF4:FC FE FE FC | [22] $1CF5 ($9CF5): $9AA6 (buf3 ptr) 1CF8:FC FD FF FC ; 1CF8:FE FE FC FC | $1CF8 Use by TSNXT 1CFC:FC FD FC FC ; 1CFC:FE FC FD FD | 00377 004 ; 00378 005 ;RELOCATION TABLES 00379 006 ; 00380 007 START EQU * 00381 008 SAT1 EQU * ; Start Address Table 1 of relocation 1D00:D3 1C 00382 009 FTAB DW *-45 ; === T0SC === $1CD3; Really?! Couldn't do FTAB DS 45, 0 1D02:81 1E 00383 010 CINA DW CHRIN 1D04:BD 1E 00384 011 COUTA DW CHROUT 1D06:75 2A 00385 012 FN1ADR DW FNAME1 1D08:93 2A 00386 013 FN2ADR DW FNAME2 1D0A:60 2A 00387 014 SVBLA DW SVBL 1D0C:00 1B 00388 015 ASTART DW BEGIN 1D0E:BB 35 00389 016 CCBADR DW CCB 00390 017 ; 00391 018 OUTSVT EQU * ; CHAR OUTPUT STATE VECTOR TABLE 1D10:EA 1E 00392 019 DW COS0-1 1D12:11 1F 00393 020 DW COS1-1 1D14:22 1F 00394 021 DW COS2-1 1D16:2E 1F 00395 022 DW COS3-1 1D18:51 1F 00396 023 DW COS4-1 1D1A:60 1F 00397 024 DW COS5-1 1D1C:70 1F 00398 025 DW COS6-1 00399 026 ;COMMAND EXECUTION TABLE 00400 027 CMDETB EQU * ; /sarcasm Yay for shitty 5 & 6 letter var names! See CMNDNTB for the commands entered by the user 1D1E:4E 25 00401 028 DW EINIT-1 ; [0] INIT Stupid 6502 design for RTS instruction forces -1 for func jump table 1D20:12 24 00402 029 DW ELOAD-1 ; [1] LOAD 1D22:96 23 00403 030 DW ESAVE-1 ; [2] SAVE 1D24:D0 24 00404 031 DW ERUN-1 ; [3] RUN 1D26:EF 24 00405 032 DW ECHAIN-1 ; [4] CHAIN 1D28:62 22 00406 033 DW EDEL-1 ; [5] DELETE 1D2A:70 22 00407 034 DW ELOCK-1 ; [6] LOCK 1D2C:74 22 00408 035 DW EUNLK-1 ; [7] UNLOCK /sarcasm Oh, noes! That 'OC' in 'unlOCk' is too much work to type! 1D2E:E9 22 00409 036 DW ECLOSE-1 ; [8] CLOSE 1D30:1A 25 00410 037 DW EREAD-1 ; [9] READ 1D32:C5 25 00411 038 DW EEXEC-1 ; [A] EXEC 1D34:0F 25 00412 039 DW EWRITE-1 ; [B] WRITE 1D36:DC 25 00413 040 DW EPOS-1 ; [C] POSITION 1D38:A2 22 00414 041 DW EOPEN-1 ; [D] OPEN 1D3A:97 22 00415 042 DW EAPND-1 ; [E] APPEND 1D3C:80 22 00416 043 DW EREN-1 ; [F] RENAME 1D3E:6D 25 00417 044 DW ECAT-1 ;[10] CATALOG 1D40:32 22 00418 045 DW EMON-1 ;[11] MON 1D42:3C 22 00419 046 DW ENOMON-1 ;[12] NOMON 1D44:28 22 00420 047 DW EPR-1 ;[13] PR# 1D46:2D 22 00421 048 DW EIN-1 ;[14] IN# 1D48:50 22 00422 049 DW EMAXF-1 ;[15] MAXFILES 1D4A:79 25 00423 050 DW EAS-1 ;[16] FP 1D4C:9D 25 00424 051 DW EINT-1 ;[17] INT 1D4E:30 23 00425 052 DW EBSV-1 ;[18] BSAVE *sigh* EBSAVE - I'm sorry, we blew our key budget for 'A' 1D50:5C 23 00426 053 DW EBLD-1 ;[19] BLOAD *sigh* EBLOAD - and also 'O'
1D52:8D 23 00427 054 DW EBRUN-1 ;[1A] BRUN === Page 49 === 1D54:7C 22 00428 055 DW EVAR-1 ;[1B] VERIFY last byte relocated in Entry [0] ADRTAB 00429 056 EAT1 EQU * ; End Address Table 1 00430 057 PAGE 00431 058 ; ; *note* Annotating [-] to mean addresss is not relocated in ADRTAB 00432 059 ;NON-RELOCATING ADRS 00433 060 ; ; Using a,b,c,d,e,f for abbreviated field names in IBASVT 00434 061 IBASVT EQU * ; ACTIVE table but waste disk space (12 bytes @ $56) storing it! 1D56:36 E8 00435 062 CHAIN DW IBCHN ;a[-] Really? Forces another table entry [1] in ADRTAB 1D58:E5 24 00436 063 RUN DW IBRUN ;b[1] Repeat after me: You **group** 1D5A:E3 E3 00437 064 BREAK DW IBBRK ;c[-] CONST data together THEN 1D5C:00 E0 00438 065 GO DW IBGO ;d[-] VARIABLE data together 1D5E:03 E0 00439 066 CONT DW IBCONT ; BASIC CONT ENTRY POINT ;e[-] You (almost) *never* interleave them 1D60:00 00 00440 067 ASEQ DW 0 ;f that just leads to data+code bloat ; *sigh* Too lazy to add a single empty ';' line seperator before IBVT ??? ; Intentionally adding an empty line as a spacer to improve readability *shock* ; ; *note* IBVT, AS1VT, and AS2VT are Read-Only (after being relocated to high mem.) 1D62:36 E8 00441 068 IBVT DW IBCHN ;a[-] Integer Basic Vector Table 1D64:E5 24 00442 069 DW IBRUN ;b[2] 1D66:E3 E3 00443 070 DW IBBRK ;c[-] 1D68:00 E0 00444 071 DW IBGO ;d[-] 1D6A:03 E0 00445 072 DW IBCONT ;e[-] 00446 073 IBVTL EQU *-IBVT ; Length = $1D6C - $1D62 = $A bytes so we don't over-write ASEQ 00447 074 ; ; /sarcasm Because it is obvious 1D6C:FC 24 00448 075 AS1VT DW ASRUN1 ;a[3] 1 = ROM, and 1D6E:FC 24 00449 076 DW ASRUN1 ;b[3] 2 = RAM, right? 1D70:65 D8 00450 077 DW ASBRK1 ;c[-] ASCNTU1 (Continue) S-C DocuMentor $D365 1D72:00 E0 00451 078 DW IBGO ;d[-] ASRSEQ1 (ResetQ???) 1D74:3C D4 00452 079 DW ASCNTU1 ;e[-] Why not IBCONT??? $E003: JMP $D43C ; Applesoft (Warm) RESTART 1D76:F2 D4 00453 080 DW ASRSEQ1 ;f[-] Applesoft FIX.LINKS 00454 081 AS1VTL EQU *-AS1VT 00455 082 ; ; Copied into IBASVT via INIT_AS_RAM, oh wait, INITC 1D78:06 25 00456 083 AS2VT DW ASRUN2 ;a[4] wastes 12 bytes on Apple ][+ or newer 1D7A:06 25 00457 084 DW ASRUN2 ;b[4] Type 2: AppleSoft in RAM Vector Table (early Apple 1 or ][ ???) 1D7C:67 10 00458 085 DW ASBRK2 ;c[-] 1D7E:84 1D 00459 086 DW DBINIT ;d[5] 1D80:3C 0C 00460 087 DW ASCNTU2 ;e Continue (Warm Restart) and R*s*E*q ??? 1D82:F2 0C 088 DW ASRSEQ2 ;f See Applesoft source Line #70 RESTART and Line #270 FIX LINKS 089 AS2VTL EQU *-AS2VT 090 PAGE 091 ; 092 ; DOS BASIC INTERPRETER - INITIAL ENTRY 093 ; 094 SC1 EQU * ; Start Relocate Code 1 095 DBINIT EQU * ; DB = Dos Basic 1D84:AD E9 37 096 LDA IBSLOT ; GET BOOT SLOT 1D87:4A 097 LSR A ; /sarcasm Gee, maybe we wouldn't even need the next comment 1D88:4A 098 LSR A ; if we used good variable names such as CUR_SLOTx16 1D89:4A 099 LSR A ; but who would want that? Isn't it obvious that 1D8A:4A 100 LSR A ; CS means Current Slot * 16 !? 1D8B:8D 6A 2A 101 STA CS ; SET AS CUURENT SLOT ; *spelling* CURRENT 1D8E:AD EA 37 102 LDA IBDRVN ; GET BOOT DRIVE NUMBER 1D91:8D 68 2A 103 STA CD ; SET AS CURRENT DRIVE 1D94:AD 00 E0 104 LDA AITSTL ; GET APPLESOFT/IB TEST ; ATSTV= $4C, E000:4C = JMP $abs; Applesoft 1D97:49 20 105 EOR #ITSTV ; IF AS THEN 1D99:D0 11 106 BNE IAS1 ; GO TO AS INIT ; 107 ; ; ELSE INIT FOR IB 1D9B:8D B6 2A 108 STA ASIBSW ; SET SW FOR IB ; magic number BASIC_TYPE_INTEGER = $00 ; 30 = $1D9E .. $1DBB ; -5 = Don't count opcodes at Lines #117,118 ; -18 = Replacement code at Line 118 Solution ; === 1D9E:A2 0A 109 LDX #IBVTL ; GET IB VT LENGTH ; wastes 7 bytes 1DA0:BD 61 1D 110 IIB1 LDA IBVT-1,X ; MOVE IB ADDR ; Problem: *sigh* due to IBVTL=$A != AS1VTL=$C 1DA3:9D 55 1D 111 STA IBASVT-1,X ; we end up with duplicate code (**9 times**, er, 3 times!) to 1DA6:CA 112 DEX ; copy the BASIC Vector Table! (An array of function pointers) 1DA7:D0 F7 113 BNE IIB1 ; 1DA9:4C BC 1D 114 JMP INITAA ; normally wastes 1 byte, BEQ INITAA; but see bigger optimization on Line #109 115 ; 116 IAS1 EQU * ; IAS1 = Init Applesoft ROM; /cynical "There will be a test"
1DAC:A9 40 117 LDA #$40 ; INDICATE ROM APPLESOFT ; === Page 50 === magic number BASIC_TYPE_APPLESOFT_ROM = $40 1DAE:8D B6 2A 118 STA ASIBSW ; Solution: ; a) Lines 117-118 should be moved after Line #103 to anticipate the common case, ; b) This is one of those rare times where we padd IBVT ; (with 2 bytes data on the end) ; to make IBVT, AS1VT, and AS2VT all the same length ; ; Table SourceOffset Instructios ; IBVT #$00 #IBVT -IBVT ; AS1VT #$0C #AS1VT-IBVT ; AS2VT #$1E #AS2VT-IBVT ; ; AA 109 TAX ; X = SourceOffset #$00 = IBVT ; 2C DB $2C ; BIT $abs to skip next instruction ; ; A2 0C IAS1 LDX #AS1VT-IBVTL ; SourceOffset $C = AS1VT 1DB1:A2 0C 119 LDX #AS1VTL ; A0 00 LDY #0 ; Y = DestOffset = BytesCopied 1DB3:BD 6B 1D 120 IAS1A LDA AS1VT-1,X ; MOVE ROM AS ADRS ; BD 62 1D 1AS1A LDA IBVT,X ; X = $0, $C, or $18 to start 1DB6:9D 55 1D 121 STA IBASVT-1,X ; 99 56 1D STA IBASVT,Y 1DB9:CA 122 DEX ; E8 INX 1DBA:D0 F7 123 BNE IAS1A ; C8 INY ; C0 0C CPY #C ; D0 F4 BNE copy 124 ; 125 INITAA EQU ; /sarcasm Hey, we need a new label inbetween INITA, and INITB 1DBC:38 126 SEC ; INDICATE INIT ; I know, let's call it crappy "INITAA" instead of DoneCopyBasicVectors 1DBD:B0 12 127 BCS INITA ; ↓ (always) (*note* Intentional next empty line spacer for readability) ; 1DBF:AD 62 2A 128 DBRST LDA ASIBSW ;GET APPLESOFT/INITGER BASIC FLAG ; *spelling* INTEGER; DBRST = DosBasicReset 1DC2:D0 04 129 BNE INITA1 ;BRANCH IF NOT INITGER BASIC ; *spelling* INTEGER 1DC4:A9 20 130 LDA #ITSTV ;GET INTIGER TEST VALUE AND GO SET ; *spelling* INTEGER 1DC6:D0 05 131 BNE INITA2 ; ROM SWITCH TO 'IB'. (BRANCH ALWAYS) 1DC8:0A 132 INITA1 ASL A ;TEST FOR ROM APPLESOFT ; $40 = Applesoft RAM 1DC9:10 05 133 BPL INITA3 ;BRANCH IF RAM VERSION ; /cynical Test time! INITA3 referes to InitApplesoftRAM or InitApplesoftROM ? 1DCB:A9 4C 134 LDA #ATSTV ;GET APPLESOFT TEST VALUE AND GO SET 1DCD:20 B2 25 135 INITA2 JSR SWTST ;GO SELECT PROPER ROM BASIC. ; more crappy naming: _which_ Switch Test 1DD0:18 136 INITA3 CLC 137 ; 138 INITA EQU * 1DD1:08 139 PHP ;SAVE INIT/RESET 1DD2:20 51 28 140 JSR MVCSW ; GO MOVE CHAR SWITCH 1DD5:A9 00 141 LDA #0 ; CLR MONITOR MODES ; MON C,I,O 1DD7:8D 5E 2A 142 STA MONMOD 143 ; 1DDA:8D 52 2A 144 STA OSTATE ; CLEAR OUTSTATE AND EXECUTE STATE ; what happened to STA ESTATE ?? 1DDD:28 145 PLP ; GET INIT/RESET 1DDE:6A 146 ROR A ; SHIFT CARRY TO MSB ; /sarcasm Gee, if only we could understand 6502 instructions, $00 = Reset, $80 = Init 1DDF:8D 51 2A 147 STA ISTATE ; SAVE INSTATE ; Frak-You Captain Obvious with a STA IN_STATE 1DE2:30 03 148 BMI INITB ; BR IF INIT 1DE4:6C 5E 1D 149 JMP (CONT) ; GO TO CONTINUE ENTRY ; No Shit, Sherlock; _what_ is the difference between CONT and GO ??? 1DE7:6C 5C 1D 150 INITB JMP (GO) ; GO TO GO ENTRY ; 151 PAGE 152 INITC EQU * ; Called by CHIN0 1DEA:0A 153 ASL A ; OF ISTATE NOT ON 1DEB:10 19 154 BPL INITD ; THEN NOT RAM AS ; 1DED:8D 62 2A 155 STA ASIBSW ; SET RAM AS 1DF0:A2 0C 156 LDX #AS2VTL ; more duplicate code, we should LDA #AS2VT-IBVT and JSR 118 Solution (make a subroutine) 1DF2:BD 77 1D 157 IAS2A LDA AS2VT-1,X ; MOVE RAM AS ADRS ; wastes 6 bytes, (9 - 3 for JSR SOLUTION.118) 1DF5:9D 55 1D 158 STA IBASVT-1,X ; When you see the same block of code your spidey sense should be tingling: 1DF8:CA 159 DEX ; Is there a way to refactor this common code? 1DF9:D0 F7 160 BNE IAS2A 1DFB:A2 1D 161 LDX #29 ; magic number better: 30-1, best: FILENAME_MAX-1 1DFD:BD 93 2A 162 IAS2B LDA FNAME2,X 1E00:9D 75 2A 163 STA FNAME1,X ; === T0SD === 1E03:CA 164 DEX 1E04:10 F7 165 BPL IAS2B 166 ; 167 INITD EQU * 1E06:AD B1 2A 168 LDA DFNFTS ; GO BUILD FILE TABS 1E09:8D 57 2A 169 STA CNFTBS ; AND SET MEM BOUNDS 1E0C:20 D4 27 170 JSR BLDFTB 1E0F:AD B3 2A 171 LDA ESTATE ; GET EXEC STATE 1E12:F0 09 172 BEQ INITZ ; BR IF NOT EXECUTE 1E14:48 173 PHA ; SVE CHAR ; *spelling* SAVE 1E15:20 9D 26 174 JSR MVEFTA ; GO MOVE EX FILE TAB ADR TO ZP 1E18:68 175 PLA 1E19:A0 00 176 LDA #0 1E1B:91 40 177 STA (ZPGWRK),Y ; Oh, we're still around? 178 INITZ EQU *
1E1D:20 5B 27 179 JSR CLRSTS ; SET IN AND OUT STATES TO ZERO ; === Page 51 === ClearStates 1E20:AD 5F 2A 180 LDA CMDNO ; IF NOT BOOT (DUPLICATED FROM LINES 4540, 4550) 1E23:D0 20 181 BNE INITF ; THEN DONE 1E25:A2 2F 182 LDX #IFBL 1E27:BD 51 1E 183 INITE LDA DBVECT,X ; MOVE RESTART VECTORS 1E2A:9D D0 03 184 STA $3D0,X ; magic number 1E2D:CA 185 DEX 1E2E:10 F7 186 BPL INITE 1E30:AD 53 1E 187 LDA DBVECT+2 ;SET RESET VECTORS FOR NEW MONITOR. ; WTF is the point of even using a table 1E33:8D F3 03 188 STA ZRSET+1 ;NOTE: THESE ARE NOT NORMALLY USED AND ; if you're just going to ignore part of it??? 1E36:49 A5 189 EOR #$A5 ; ARE ONLY SET ONCE ON BOOT ; magic number F800.S Ctrl-Reset Powered Up 1E38:8D F4 03 190 STA PWCNST ;POWER UP CONSTANT=COMPLIMENT OF HI RESET VECTOR. ; Checksum not constant 1E3B:AD 52 1E 191 LDA DBVECT+1 ;SET LOW VECTOR ADDRESS. ;[.. wastes 6 bytes due to Line #221 Clusterfrak 1E3E:8D F2 03 192 STA ZRSET ;NOW APPLE RESET WILL KEEP DOS IN I/O LOOP ; ..] 1E41:A9 06 193 LDA #6 ;INIDICATE RUN ; magic number TODO 1E43:D0 05 194 BNE INITF1 ;LOAD AND RUN THE 'HELLO' PROGRAM ; ↓ (always) 195 ; 196 INITF EQU * 1E45:AD 62 2A 197 LDA SVCMD 1E48:F0 06 198 BEQ INITG 1E4A:8d 5F 2A 199 INITF1 STA CMDNO 1E4D:4C 80 21 200 JMP CMDGO1 201 INITG EQU * 1E50:60 202 RTS 203 ; 204 IFB EQU * ; --- Copied to $3D0 --- 1E51:4C BF 1D 205 DBVECT JMP DBRST ; $3D0: JMP $9DBF DOS Warm RESET -- Really?? You couldn't put this in the SAME order 1E54:4C 84 1D 206 JMP DBINIT ; $3D3: JMP $9D84 DOS Cold RESET -- as BASIC: Cold THEN Warm ??? 1E57:4C FD 2A 207 JMP USERENT ;USER EXTERNAL ENTRY TO FILE MANAGER; $3D6: JMP $AAFD FM (File Manager) 1E5A:4C B5 37 208 JMP DISKIO ; $3D9: JMP $B7B5 RWTS (ReadWriteTrackSector) 209 CCBLDR EQU * ; $3DC: GetParamFM (A,Y = $B5BB, CCB = Command Control Block) 1E5D:AD 0F 1D 210 LDA CCBADR+1 1E60:AC 0E 1D 211 LDY CCBADR ; NOTE The labels CCBLDR and IOBLDR are never referenced anywhere. 1E63:60 212 RTS 213 IOBLDR EQU * ; $3E3: GetParamRWTS (A,Y = $B7E8, IOB = Input Output Block) 1E64:AD C2 2A 214 LDA AIOB+1 ; /sarcasm Really? You couldn't be consistent and call it IOBADR ??? 1E67:AC C1 2A 215 LDY AIOB 1E6A:60 216 RTS 1E6B:4C 51 28 217 JMP MVCSW ; $3EA: Set CIN/COUT to DOS 1E6E:EA 218 NOP ; $3ED: [.. Normally, this would be wastes 2 bytes -- NEVER used anywhere 1E6F:EA 219 NOP ; ... HOWEVER they ARE needed since they are used as padding to align the following BRK IRQ vector. ; ... Diversi-DOS has: 3ED: 4C DF BC JMP $BCDF ; ..] Thanks Tommy for the insight! 1E70:4C 59 FA 220 JMP MONBRK ; $3EF: JMP $FA59 Autostart BRK handler. ; Note: This is never directly called as the Autostart ROM reads the address at $3F0, $3F1 via $FA56: 6C F0 03 JMP (BRKV) 1E73:4C 65 FF 221 JMP MONRST ; $3F2: $9DBF,$38 Control-Reset - Why not DW DBRST, DB $#>DBRST ^ $A5 ??? Line #191 1E76:4C 58 FF 222 JMP IORTS ; $3F5: JMP $FF58 Ampersand handler 1E79:4C 65 FF 223 JMP MONRST ; $3F8: JMP $FF65 Ctrl-Y handler 1E7C:4C 65 FF 224 JMP MONRST ; $3FB: JMP $FF65 NMI handler 1E7F:65 FF 225 DW MONRST ; $3FE: dw $FF65 IRQ vector 226 IFBL EQU *-IFB-1 ; IFB_Length = $1E81 - 1E51 = $2F
001 PAGE
002 ;
003 ;CHRIN - CHAR RCVD VIA IN SWITCH
004 ;
005 CHRIN EQU *
1E81:20 D1 1E 006 JSR SVREGS ;
1E84:AD 51 2A 007 LDA ISTATE ; IF NOT DISKIN
1E87:F0 15 008 BEQ CHIN1 ; THEN BRANCH, ELSE
1E89:48 009 PHA ;SAVE ISTATE
1E8A:AD 5C 2A 010 LDA SVA
1E8D:91 28 011 STA ($28),Y ;REPLACE CURSOR ; magic number /sarcasm If only F800.S ROM defined BASL EQU $28
1E8F:68 012 PLA ;GET ISTATE AGAIN
1E90:30 03 013 BMI CHIN0 ;BRANCH IF NOT 'READ' FROM DISK
1E92:4C 26 26 014 JMP ICFD ; AND GET CHAR FROM DISK
1E95:20 EA 1D 015 CHIN0 JSR INITC
1E98:A4 24 016 LDY $24 ;GET CURSOR HORIZ ; magic number /sarcasm If only F800.S ROM defined CH EQU $24
1E9A:A9 60 017 LDA #$60 ;RESTORE A FLASHING CURSOR ; #' ' + FLASH ; INVERSE = $00..$3F, FLASH = $40..$7F, NORMAL = $80..FF
1E9C:91 28 018 STA ($28),Y ; TO PROMPT USER ; magic number
019 CHIN1 EQU *
1E9E:AD B3 2A 020 LDA ESTATE
1EA1:F0 03 021 BEQ CHIN2
1EA3:20 82 26 022 JSR NXTEXC ;RETURNS TO HERE ONLY WHEN 'EXEC' IS EXHAUSTED
023 CHIN2 EQU *
1EA6:A9 03 024 LDA #3 ; SET OUT CHAR ; magic number COS_INPUT_ECHO = 3
1EA8:8D 52 2A 025 STA OSTATE ; STATE TO INPUT ECHO
1EAB:20 BA 1F 026 JSR LDREGS
1EAE:20 BA 1E 027 JSR GETIN
1EB1:8D 5C 2A 028 STA SVA ; SAVE CHAR & INDEX
1EB4:8E 5A 2A 029 STX SVX
1EB7:4C B3 1F 030 JMP ORTN
031 ;
1EBA:6C 38 00 032 GETIN JMP (INSW)
033 ;
034 ;CHROUT - CHAR RCVD VIA OUTPUT SWITCH
035 ;
036 CHROUT EQU *
1EBD:20 D1 1E 037 JSR SVREGS ; SAVE REGS
038 ;
1EC0:AD 52 2A 039 LDA OSTATE ; GET OUT SPARE
1EC3:0A 040 ASL A
1EC4:0A 041 TAX
1EC5:BD 11 1D 042 LDA OUTSVT1+1,X ; GET ROUTINE ADR
1EC8:48 043 PHA
1EC9:BD 10 1D 044 LDA OUTSVT+1,X
1ECC:48 045 PHA
1ECD:AD 5C 2A 046 LDA SVA
1ED0:60 047 RTS ; GO TO ROUTINE
048 ;
049 ;SVREGS - SAVE REGS WHILE PROCESSING CHARS
050 ;
051 SVREGS EQU *
1ED1:8D 5C 2A 052 STA SVA ; SAVE ACU ; Captain Obvious to the rescue!
053 SVRGSA EQU * ; === Page 45 === SaveRegsA, uh, NO, SaveRegsXY, we _already_ saved A; this is why using nameA nameB are bad.
1ED4:8D 5A 2A 054 STX SVX ; SAVE X ; More crap names. Good variable naming such as SAVEX and SAVEY
1ED7:8C 5B 2A 055 STY SVY ; SAVE Y ; negates the need for these useless redundant comments.
1EDA:BA 056 TSX ;SAVE STACK POINTER
1EDB:E8 057 INX
1EDC:E8 058 INX ;ADJUST IT TO ORIGINAL
1EDD:8E 59 2A 059 STX SVSTK
1EE0:A2 03 060 LDX #3 ; SET FOR FOUR BYTE MOVE ; /sarcasm If only we could read assembly ...
1EE2:BD 53 2A 061 SVRB LDA SVOUTS,X ; MOVE SAVED OUT AND IN SW ; SVRB = SaVe Regs B, /sarcasm What, SVRGSB wasn't available??? (A. It is.)
1EE5:95 36 062 STA OUTSW,X ; TO APPLE OUT/IN SW
1EE7:CA 063 DEX
1EE8:10 F8 064 BPL SVRB
1EEA:60 065 RTS ; DONE ; Can someone please put Captain Obvious out of _our_ misery?
066 PAGE
067 ;
068 ; COS0 - 1ST CHAR OF PRINTED OUTPUT LINE
069 ;CHECK FOR CNTL-D ; "You say CNTL-D, I say CTRL-D"
070 ; ; We're both inconsistently dropping a consonant: CoNTRoL
071 COS0 EQU *
1EEB:AE B7 2A 072 LDX RSTATE ;FIRST CHECK FOR 'AFTER APSFT RELOC'
1EEE:F0 03 073 BEQ COS00 ;BRANCH IF NOT ; Really?! You couldn't use COS0A and COS0B like you do for the other states??
; COS0 & COS00 are crap function names; they are WAY too easy to mis-read/type
1EF0:4C 78 1F 074 JMP COS7 ; wastes 3 bytes, but since $1F78-$1EF0 > $80
; TODO We need to move COS5..COS7 before COS0; change Line #74 to BNE COS7
1EF3:AE 51 2A 075 COS00 LDX ISTATE ;IS IN STATE NOT ZERO ; I'm serious, someone please shoot Captain Obvious
1EF6:F0 08 076 BEQ COS01 ;
1EF8:C9 BF 077 CMP #'?'+$80 ; THEN IS THIS ?
1EFA:F0 75 078 BEQ COS6 ; THEN PRINT ONLY IF MONITOR
1EFC:C5 33 079 CMP PROMPT
1EFE:F0 27 080 BEQ COS2A
081 COS01 EQU * ; === T0SE ===
1F00:A2 02 082 LDX #2 ; magic number
1F02:8E 52 2A 083 STX OSTATE
1F05:CD B2 2A 084 CMP CCHAR ; IF NOT CNTL-D
1F08:D0 19 085 BNE COS2 ; THEN GO TO STATE 2
1F0A:CA 086 DEX
1F0B:8E 52 2A 087 STX OSTATE ; ELSE STATE=1
1F0E:CA 088 DEX
1F0F:8E 5D 2A 089 STX LBUFD ; AND LBUFD=0
090 ;
091 ;COS1 - ACCUMULATE CMD FROM PRINTED OUTPUT
092 ;
093 COS1 EQU *
1F12:AE 5D 2A 094 LDX LBUFD ; GET LINE BUFF DISPL
1F15:9D 00 02 095 COS1A STA LBUFF,X ; PUT CHAR IN BUFF
1F18:E8 096 INX ; INCR PTR
1F19:8E FD 2A 097 STX LBUFD ; SAVE PTR
1F1C:C9 8D 098 CMP #$8D ; WAS THIS A CR ; magic number
1F1E:D0 75 099 BNE CMDRTN ; IF NOT THEN PR CHAR
100 ;
1F20:4C CD 1F 101 JMP SCNCMD ; GO SCAN COMMAND
102 ;
103 ;COS2 - PRINTED OUTPUT, NOT FIRST CHAR
104 ;
105 COS2 EQU *
1F23:C9 8D 106 CMP #$8D ; IS IT A CR ; magic number
1F25:D0 7D 107 BNE PRRTN ; BR IF NOT
1F27:A2 00 108 COS2A LDX #0 ; SET FOR POSSIBLE C-D NEXT ; C-D = Control-D magic number COS_STATE_FIRST_CONTROL_D = 0
1F29:8E 52 2A 109 STX OSTATE ; NEXT STATE
1F2C:4C A4 1F 110 JMP PRRTN ; GO PRINT CHAR ; wastes 1 byte, $1F83 - $1F2C = $57, BEQ PRRTN
111 PAGE
112 ;
113 ;COS3 - KEY IN ECHO PRINT
114 ;
115 COS3 EQU *
1F2F:A2 00 116 LDX #0 ; === Page 46 === magic number COS_STATE_0
1F31:8E 52 2A 117 STX OSTATE ; RESET OUT STATE
1F34:C9 8D 118 CMP #$8D ; IS IT CR
1F36:F0 07 119 BEQ COS3A ; IF CR THEN CMD CHECK
1F38:AD B3 2A 120 COS3B LDA ESTATE ; ELSE: IF NOT EXECUTE
1F3B:F0 67 121 BEQ PRRTN ; THEN PRINT CHAR
1F3D:D0 5E 122 BNE DRTNI ; ELSE: PRINT IF MON INPUT ; Data Return In
1F3F:48 123 COS3A PHA ;SAVE CARRAGE RETURN
1F40:38 124 SEC ;ANTICIPATE EXEC FILE INPUT.
1F41:AD B3 2A 125 LDA ESTATE ;CHECK EXEC FLAG
1F44:D0 03 126 BNE COS3C ;BR IF WAS INPUT FROM EXEC.
1F46:20 5E 26 127 JSR TSTRUN ;GO TEST FOR RUN MODE.
1F49:68 128 COS3C PLA
1F4A:90 EC 129 BCC COS3B ;IGNORE INPUT IF RUNNING.
1F4C:AE 5A 2A 130 LDX SVX ; GET LINE INDEX
1F4F:4C 15 1F 131 JMP COS1A ; TODO Can this ever be zero??
132 ;
133 ;COS4 - DISK OUTPUT MODE
134 ;
135 COS4 EQU *
1F52:C9 8D 136 CMP #$8D ; IS IT CR
1F54:D0 05 137 BNE COS4A ; BR IF NOT CR
1F56:A9 05 138 LDA #5 ; SET STATE FOR CNTL-D
1F58:8D 52 2A 139 STA OSTATE ; EXAMINE
1F5B:20 0E 26 140 COS4A JSR OCTD ; GO OUTPUT CJHAR TO DISK ; *spelling* Char
1F5E:4C 99 1F 141 JMP DRTNO ; GO TO DATA RETURN (OUT)
142 ;
143 ;COS5 - DISK OUTPUT MODE - 1ST CHAR
144 ;
145 COS5 EQU *
1F61:CD B2 2A 146 CMP CCHAR ; IS IT CNTL D
1F64:F0 85 147 BEQ COS0 ; BR IF CNTL- D
1F66:C9 8A 148 CMP #$8A ; LINE FEED?
1F68:F0 F1 149 BEQ COS4A
1F6A:A2 04 150 LDX #4
1F6C:8E 52 2A 151 STX OSTATE ; SET NEW OUT STATE ; No Shit Sherlock, *what* is State 4 ??
1F6F:D0 E1 152 BNE COS4 ; BR IF NOT CNTL D ; ↑ (always) wastes 2 bytes, move COS5 before COS4 and remove this branch
153 ;
154 ;COS6 - DISK INPUT ECHO
155 ;
1F71:A9 00 156 COS6 LDA #0
1F73:8D 52 2A 157 STA OSTATE ; RESET OUT STATE = 0
1F76:F0 25 158 BEQ DRTNI ; GO TO DATA IN RETURN
159 ;
160 ; COS7 - SPECIAL FOR RECOVER FROM AS ROM/RAM RELOC.
161 ;
1F78:A9 00 162 COS7 LDA #0 ; RESET RELOC STATE
1F7A:8D B7 2A 163 STA RSTATE
1F7D:20 51 28 164 JSR MVCSW ;FOR COMPATABILITY ON REENTRY
1F80:4C DC 24 165 JMP ERUN1
166 PAGE
167 ;
168 ;PRRTN - PRINT CHAR RETURN
169 ;
170 ;
171 ; CMDRTN - PRINT CHAR IF MONITOR CMBS MODE ; TODO CMBS ???
172 ; DRTNO - PRINT CHAR IF MONITOR DATA OUT
173 ; DRTNI - PRINT CHAR IF MONITOR DATA IN
174 ;
175 CERTN EQU *
1F83:AD 00 02 176 LDA LBUFF ; CHECK FOR PRINTED COMMAND
1F86:CD B2 2A 177 CMP CCHAR
1F89:F0 0A 178 BEQ CMDRTN ; IF PC THEN NO RESET X REG
1F8B:A9 8D 179 LDA #$8D ; CARRAGE RETURN ; === Page 47 === magic number KEY_CR
1F8D:8D 00 02 180 STA LBUFF ; TO OUT BUFFER
1F90:A2 00 181 LDX #0 ; RESET TO SOL ; StartOfLine
1F92:8E 5A 2A 182 STX SVX
1F95:A9 40 183 CMDRTN LDA #MC
1F97:D0 06 184 BNE MODECK ; ↓ (always)
1F99:A9 10 185 DRTNO LDA #MO ; Data Return Out
1F9B:D0 02 186 BNE MODECK ; ↓ (always)
1F9D:A9 20 187 DRTNI LDA #MI ; Data Return In
188 ;
189 MODECK EQU * ; ModeCheck common entry
1F9F:2D 5E 2A 190 AND MONMOD ; AND WITH MODE
1FA2:F0 0F 191 BEQ ORTN ; BR IF NOT PRINT
1FA4:20 BA 1F 192 PRRNT JSR LDREGS
1FA7:20 C5 1F 193 JSR ORTN1
1FAA:8D 5C 2A 194 STA SVA ;SAVE REGISTERS
1FAD:8C 5B 2A 195 STY SVY
1FB0:8E 5A 2A 196 STX SVX
197 ;
198 ORTN EQU *
1FB3:20 51 28 199 JSR MVCSW ; GO MOVE CHAR I/O SWITCH
1FB6:AE 59 2A 200 LDX SVSTK ;RESTORE ORIGINAL STACK POINTER (YEEECH!) ; /sarcasm And yet you're still futzing with the Stack Pointer
1FB9:9A 201 TXS
202 LDREGS EQU *
1FBA:AD 5C 2A 203 LDA SVA ; ACU ; Captain Obvious SAVE_A
1FBD:AC 5B 2A 204 LDY SVY ; Y ; is working SAVE_Y
1FC0:AE 5A 2A 205 LDX SVX ; X ; overtime today SAVE_X
1FC3:38 206 SEC ;(FOR 'ESC' SCREEN FUNCTIONS)
1FC4:60 207 RTS ; BY PASS PRINT
208 ;
1FC5:6C 36 00 209 ORTN1 JMP (OUTSW)
210 ;
211 ; PRRIF - PRINT CR IF MON CMDS
212 ;
213 PRCRIF EQU *
1FC8:A9 8D 214 LDA #$8D ; ELSE PRINT CR ; magic number KEY_CR
1FCA:4C C5 1F 215 JMP ORTN1 ; wastes 1 byte; BNE ORTN1
001 PAGE
002 ;
003 ; SCNCMD - SCAN A COMMAND
004 ;
005 SCNCMD EQU *
006 DO ULC
007 LDX #0 ;Init X for lower case check
008 JSR UPRCASE ;Go check
009 ELSE
1FCD:A0 FF 010 LDY #$FF ;Set CMDNO to -1
1FCF:8C 5F 2A 011 STY CMDNO
012 FIN
1FD2:C8 013 INY ; INCR TABLE INDEX
1FD3:8C 62 2A 014 STY SVCMD
015 SC0 EQU *
1FD6:EE 5F 2A 016 INC CMDNO ; INCR CMD NO ; Thanks Captain Obvious
1FD9:A2 00 017 LDX #0 ; RESET LINE INDEX TO 0
1FDB:08 018 PHP ; SAVE EQ STATUS
1FDC:BD 00 02 019 LDA LBUFF,X ; GET 1ST LINE CHAR
1FDF:CD B2 2A 020 CMP CCHAR ; IS IT CONTROL D
1FE2:D0 01 021 BNE SC0A ; BR /IF NOT
1FE4:E8 022 INX ; INCR OVER CNTLD
1FE5:8E 5D 2A 023 SC0A STX LBUFD
024 ;
025 SC1X EQU *
1FE8:20 A4 21 026 JSR GNBC ; GET NON BLANK INPUT CHAR
1FEB:29 7F 027 AND #$7F ; MSB OF CHAR OFF
1FED:59 84 28 028 EOR CMDNTB,Y ; EOR WITH INPUT
1FF0:C8 029 INY ; INCREMENT TABLE INDEX
1FF1:0A 030 ASL A ; IF MSB OF EOR RESULT ON
1FF2:F0 02 031 BEQ SC1A ; IF RESULT NOT NOW ZERO
1FF4:68 032 PLA ; THEN INPUT DOES NOT
1FF5:08 033 PHP ; EQUAL ENTRY
1FF6:90 F0 034 SC1A BCC SC1X ; LOOP FOR END OF ENTRY
035 ;
1FF8:28 036 PLP ; IF INPUT EQUALS END ;
1FF9:F0 20 037 BEQ SYNTAX ; THEN GO SYNTAX
038 ;
1FFB:B9 84 A8 039 LDA CMDNTB,Y ; IF NEXT TABLE CHAR NOT ZERO
1FFE:D0 D6 040 BNE SC0 ; THENSCANTHE NEXT TABLE ENTRY ; /sarcasm whoneedsspacesanyways
041 CNF EQU * ; COMMAND NOT FOUND
2000:AD 00 02 042 LDA LBUFF ; LINE IS A CNOTROL-D ; *spelling* Control-D
2003:CD B2 2A 043 CMP CCHAR ; THEN THIS IS A
2006:F0 03 044 BEQ CNF1 ; POSSIBLE SYNTAX ERROR, ELSE
2008:4C A4 1F 045 JMP PRRTN ; ITS A BASIC INPUT LINE
046 CNF1 EQU *
200B:AD 01 02 047 LDA LBUFF+1 ; GET NEXT CHAR
200E:C9 8D 048 CMP #$8D ; IS IT A CR ; magic number KEY_CR
2010:D0 06 049 BNE CSERR ; BR IF CR
2012:20 5B 27 050 JSR CLRSTS ; CLEAR THE STATES
2015:4C 95 1F 051 JMP CMDRTN ; CNTL-D ONLY
052 ;
2018:4C C4 26 053 CSERR JMP ESYNTX
054 PAGE ; === Page 17 ===
055 ;
056 ; SYNTAX - FIGURE OUT WHAT WE GOT HERE
057 ;
058 SYNTAX EQU *
201B:0E 5F 2A 059 ASL CMDNO
201E:AC 5F 2A 060 LDY CMDNO
2021:20 5E 26 061 JSR TSTRUN
2024:90 0C 062 BCC SYN1
2026:A9 02 063 LDA #RNONLY
2028:39 09 29 064 AND CMDSTB,Y
202B:F0 05 065 BEQ SYN1
202D:A9 0F 066 LDA #$F ; magic number ERR_NOT_DIRECT
202F:4C D2 26 067 JMP ERROR
2032:C0 06 068 SYN1 CPY #6 ; magic number TODO CMD_RUN
2034:D0 02 069 BNE SYN1A
2036:84 33 070 STY PROMPT ; CHANGE PROMPT TO INSURE APPLESOFT RUN DETECT.
2038:A9 20 071 SYN1A LDA #FN1
203A:39 09 29 072 AND CMDSTB,Y
203D:F0 61 073 BEQ SN10
203F:20 95 20 074 JSR CLRFNS
2042:08 075 PHP ; SAVE EQ STATUS
076 ;
077 SN2 EQU *
2043:20 A4 21 078 JSR GNBC ; GET NON BLANK CHAR
2046:F0 1E 079 BEQ SN6 ; BR IF CR OR COMMA
2048:0A 080 ASL A ; TEST FOR ALPHA
2049:90 05 081 BCC SN2A ; BR IF ALPHA
204B:30 03 082 BMI SN2A ; BR IF APLHA
204D:4C 00 20 083 JMP CNF ; LURCH IF NOT ALPHA
2050:6A 084 SN2A ROR A ; RESTORE BITS
2051:4C 59 20 085 JMP SN4 ; AWAY WE GO
2054:20 93 21 086 SN3 JSR GNXTC ; GO GET NEXT CHAR ; GetNextChar
2057:F0 0D 087 BEQ SN6 ; BR IF COMMA OR CR
2059:99 75 2A 088 SN4 STA FNAME1,Y ; PUT INTO FILENAME
205C:C8 089 INY ; INC FN INDEX ; Total filenames length < 60 ?
205D:C0 3C 090 CPY #60 ; ATFN CHAR LIMIT ; At Filename Character Limit TODO What triggers this?
205F:90 F3 091 BCC SN3 ; BR IF NOT
2061:20 93 21 092 SN5 JSR GNXTC ; LOOP UNTIL CR OR COMMA
2064:D0 FB 093 BNE SN5
094 ;
2066:28 095 SN6 PLP ; WAS THIS FN2 L OO ; TODO Was this filename 2 _length_ _ok_???
2067:D0 0F 096 BNE SN7 ; BR IF IT WAS
097 ;
2069:AC 5F 2A 098 LDY CMDNO
206C:A9 10 099 LDA #FN2
206E:39 09 29 100 AND CMDSTB,Y ; IF FN2 NOT REQD THEN
2071:F0 0C 101 BEQ SN8 ; BRANCH
102 ;
2073:A0 1E 103 LDY #30 ; SET FN2 INDEX ; @filename2[0] magic number MAX_FILENAME_LEN
2075:08 104 PHP ; INDICATE FN2 SEEK
2076:D0 CB 105 BNE SN2 ; GO LOOK FOR FN2
106 ;
2078:AD 93 2A 107 SN7 LDA FNAME2 ; IF 1ST CHAR OF
207B:C9 A0 108 CMP #$A0 ; FN2 IS BLANK THEN
207D:F0 13 109 BEQ SERR1 ; SYNTAX ERROR
110 ;
207F:AD 75 2A 111 SN8 LDA FNAME1 ; IF 1ST CHAR OF
2082:C9 A0 112 CMP #$A0 ; FN1 IS NOT BLANK
2084:D0 4B 113 BNE SOPTS ; THEN GO LOOK FOR OPTIONS
114 ;
2086:AC 5F 2A 115 LDY CMDNO
2089:A9 C0 116 LDA #NPB+NPE ; IF CMD MUST HAVE FILENAME ; === Page 18 ===
208B:39 09 29 117 AND CMDSTB,Y ; THEN
208E:F0 02 118 BEQ SERR1 ; THIS IS ERROR, ELSE
119 ;
2090:10 3F 120 BPL SOPTS ; ITS EXCUTABLE WITHOUT ; *spelling* Executable
121 ;
2092:4C 00 20 122 SERR1 JMP CNF
123 ;
124 CLRFNS EQU *
2095:A0 3C 125 LDY #60 ; magic number MAX_FILENAME_LEN * 2
126 CLRFNA EQU *
2097:A9 A0 127 LDA #$A0
2099:99 74 2A 128 SN1 STA FNAME1-1,Y ; CLEAR FN1, FN2 ; *sigh* instead of -1 offset, LDY #2*MAX_FILENAME_LEN-1
209C:88 129 DEY
209D:D0 FA 130 BNE SN1
209F:60 131 RTS
132 PAGE
133 SN10 EQU * ; FILE NAMES NOT REQD
20A0:8D 75 2A 134 STA FNAME1
20A3:A9 0C 135 LDA #NUM1+NUM2 ; IF NEITHER NUM1
20A5:39 09 29 136 AND CMDSTB,Y ; OR NUM2 IS REQD
20A8:F0 27 137 BEQ SOPTS ; THEN GO LOOK AT OPTIONS
138 ;
20AA:20 B9 21 139 JSR GETNUM ; GO GET NUMERICS
20AD:B0 1F 140 BCS SERR2
141 ;
20AF:A8 142 TAY ; IF HIGH DIGIT NOT
20B0:D0 17 143 BNE SERR3 ; ZERO THEN BAD
144 ;
20B2:E0 11 145 CPX #17 ; IF LOW DIGIT GT 16
20B4:B0 13 146 BCS SERR3 ; THEN BAD
147 ;
20B6:AC 5F 2A 148 LDY CMDNO
20B9:A9 08 149 LDA #NUM1
20BB:39 09 29 150 AND CMDSTB,Y ; IF WE WANT NUM2
20BE:F0 06 151 BEQ SN11
152 ;
20C0:E0 08 153 CPX #8 ; IF NUM2>1
20C2:B0 CE 154 BCS SERR1 ; THEN ERROR, ELSE
20C4:90 0B 155 BCC SOPTS ; GO SCAN OPTIONS
156 ;
157 SN11 EQU *
20C6:8A 158 TXA ; IF NUM1=0
20C7:D0 08 159 BNE SOPTS ; THEN ERROR, ELSE GET OPTIONS
160 ;
20C9:A9 02 161 SERR3 LDA #2 ;RANGE ERROR! ; magic number
20CB:4C D2 26 162 JMP ERROR
20CE:4C C4 26 163 SERR2 JMP ESYNTX ;DISK CMD SYNTAX ERROR
164 ;
165 PAGE
166 ;
167 ; SOPTS - LOOK FOR SYNTAX OPTIONS
168 ;
169 SOPTS EQU *
20D1:A9 00 170 LDA #0
20D3:8D 65 2A 171 STA INOPTS ; CLEAR INPUT OPTIONS
20D6:8D 74 2A 172 STA IMBITS
20D9:8D 66 2A 173 STA CV ;DEFAULT VOLUME=0
20DC:8D 6C 1A 174 STA CL
20DF:8D 6D 2A 175 STA CL+1
20E2:20 DC 3F 176 JSR CLRBYTE ;PATCH FOR BYTE PARAMETER (WAS STA TEMP1A)
20E5:AD 5D 2A 177 LDA LBUFD ; SET PASS 1
178 ; ; === Page 19 ===
20E8:20 A4 21 179 SP1 JSR GNBC ; GO GET NON-BLANK CHAR
20EB:D0 1F 180 BNE SP2 ; BR IF NOT COMMA OR CR
20ED:C9 8D 181 CMP #$8D ; IF CHAR IS COMMA ; magic number KEY_CR
20EF:D0 F7 182 BNE SP1 ; THEN GO GET CHAR
183 ;
20F1:AE 5F 2A 184 LDX CMDNO ; OPTIONS INPUT = I
20F4:AD 65 2A 185 LDA INOPTS ; ALLOW OPTS = A
20F7:1D 0A 29 186 ORA CMDSTB+1,X ; IF (A OR I)
20FA:5D 0A 29 187 EOR CMDSTB+1,X XOR A NOT =0 THEN
20FD:D0 93 188 BNE SERR1 ; WE HAVE UNALLOWED OPTIONS
189 ;
20FE:AE 62 2A 190 LDX TEMP1A ; IF THIS IS PASS2 ; === T1S0 ===
2102:F0 76 191 BEQ CMDGO ; THEN DONE,
2104:8D 63 2A 192 STA TEMP1A ; ELSE SET PASS
2107:8E 5D 2A 193 STX LBUFD ; RESTORE LBUFD AND
210A:D0 DC 194 BNE SP1 ; GO DO PASS 2
195 ;
210C:A2 0A 196 SP2 LDX #OPT1L ; COMPARE CHAR HAVE WITH
210E:DD 40 29 197 SP3 CMP OPTAB1-1,X ; CHARS IN OPT TABLE
2111:F0 F5 198 BEQ SP4 ; IF FOUND CONTINUE,
2113:CA 199 DEX
2114:D0 F8 200 BNE SP3 ; IF NOT FOUND
2116:F0 B6 201 SERR2A BEQ SERR2 ; THEN SYNTAX ERROR
202 ;
2118:BD 4A 29 203 SP4 LDA OPTAB2-1,X ; IF CORRESPONDING OP TAB 2 IS
211B:30 47 204 BMI SP8 ; MINUS THEN IT MONITOR BITS ; C,I,O were all flagged with +$80, see OPTAB2
211D:0D 65 2A 205 ORA INOPTS
2120:8D 65 2A 206 STA INOPTS
2123:CA 207 DEX
208 ;
2124:8E 64 2A 209 STX TEMP2A ; ELSE A NUMERIC MUST FOLLOW
2127:20 B9 21 210 JSR GETNUM ; FOLLOW
212A:B0 A2 211 BCS SERR2
212 ;
212C:AD 64 2A 213 LDA TEMP2A ; GET IOTION NUMBER
212F:0A 214 ASL A ; MULT BY 4
2130:0A 215 ASL A
2131:A8 216 TAY
217 ; ; Compare 16-bit cnum >= low, cnum < max
2132:A5 45 218 LDA CNUM+1 ; IF RESULT NUM HI IS ; +1 = cnum.hi; is cnum < 256 ? i.e. only 8-bit
2134:D0 09 219 BNE SP5 ; GT 0, THEN GT LOW RANGE
2136:A5 44 220 LDA CNUM ; TEST RESULT LOW ; +0 = cnum.low <
2138:D9 55 29 221 CMP OPTAB3,Y ; WITH LOW RANGE (LOW) ; +0 = OptValMin[x].Lo ?
213B:90 8C 222 BCC SERR3 ; BR IF RESULT < LR
213D:A5 45 223 LDA CNUM+1 ; +1 = cnum.hi <
213F:D9 58 29 224 SP5 CMP OPTAB3+3,Y ; +3 = OptValMax[x].Hi ?
2142:90 0B 225 BCC SP6 ; BR IF LESS
2144:D0 83 226 SERR3A BNE SERR3 ; BR IF GREATER
2146:A5 44 227 LDA CNUM
2148:D9 57 29 228 CMP OPTAB3+2,Y ; +2 = OptValMax[x].Lo
214B:90 02 229 BCC SP6 ; BR IF LESS
214D:D0 F5 230 BNE SERR3A ; BR IF GREATER
231 ;
214F:AD 63 2A 232 SP6 LDA TEMP1A ; IF PASS 1, THEN
2152:D0 94 233 BNE SP1 ; DONT STORE RESULT
2154:98 234 TYA
2155:4A 235 LSR A
2156:A8 236 TAY
237 ;
2157:A5 45 238 LDA CNUM+1 ; STORE THE RESULT
2159:99 67 2A 239 STA CUROPT+1,Y
215C:A5 44 240 LDA CNUM
215E:99 66 2A 241 STA CUROPT,Y ; === Page 20 ===
2161:4C E8 20 242 SP7 JMP SP1 ; GO FOR NEXT OPT
243 ;
244 SP8 EQU * ; MONITOR REQ ; Have 'C', 'I', or 'O'
2164:48 245 PHA ; SAVE TYPE REQ
2165:A9 80 246 LDA #CIO ; SET OPTION OF CIO
2167:0D 65 2A 247 ORA INOPTS
216A:8D 65 2A 248 STA INOPTS
216D:68 249 PLA ; RESTOERE REQ
216E:29 7F 250 AND #$7F ; CLEAR CIO ; magic number Why not ~CIO ? Crappy tool (assembler)??
2170:0D 74 2A 251 ORA IMBITS ; OR WITH PREV IMBITS
2173:8D 74 2A 252 STA IMBITS
2176:D0 E9 253 BNE SP7 ; GO FOR NEXT
254 ;
2178:F0 9C 255 BEQ SERR2A ;BRANCH ALWAYS
256 ;
217A:20 80 21 257 CMDGO JSR CMDGO1 ; CMDGO - EXECUTE COMMAND
217D:4C 83 1F 258 JMP CERTN
259 ;
260 CMDGO1 EQU *
2180:20 5B 27 261 JSR CLRSTS ; Clear States
2183:20 AE 21 262 JSR CLRCCB ; GO CLEAR CCB ; /sarcasm I never would have guessed
263 ECMD EQU *
2186:AD 5F 2A 264 LDA CMDNO ; COMMAND NO ; Think, McFly!
2189:AA 265 TAX ; IS CMD EXEC TAB INDEX ; wastes 1 byte /sarcasm If only we had LDX CMDNO on Line #264
218A:BD 1F 1D 266 LDA CMDETB+1,X ; GET CMD ADR ;[..
218D:48 267 PHA ; ONTO STACK ; ..
218E:BD 1E 1D 268 LDA CMDETB,X ; ..
2191:48 269 PHA ; .. Classic technique of 6502 jump table,
2192:60 270 RTS ; AND GOTO COMMAND ; ..] use RTS to "call" the function pointer
001 PAGE
002 ; ; Setup: LineLength (current char offset in Line Buffer to process)
003 ; GNXTC - GET NEXT CHAR ; In : n/a
004 ; ; Out : A=char in LineBuffer, (X=LineLength if CR else X=LineLength+1)
005 GNXTC EQU * ; Z=1 if CR or COMMA, else Z=0
2193:AE 5D 2A 006 LDX LBUFD
2196:BD 00 02 007 LDA LFUFF,X ; GET NEXT CHAR AND IF ; char c = LineBuffer[ LineLength ];
2199:C9 8D 008 CMP #$8D ; IS IT A CR ; gEqual = (c == 'r');
219B:F0 06 009 BEQ GNXTCR ; THEN RETURN WITHOUT ; if( gEqual )
219D:E8 010 INX ; INCR TO NEXT CHAR ; return c;
219E:8E 5D 2A 011 STX LBUFD ; LineLength++;
21A1:C9 AC 012 CMP #','+$80 ; TEST FOR COMMA ; gEqual = (c == ',');
21A3:60 013 GNXTCR RTS ; return c;
014 ;
015 ; GNBC - GET NON BLANK CHAR
016 ;
017 GNBC EQU * ; char c;
21A4:20 93 21 018 JSR GNXTC ; GO GET NEXT CHAR ; do {
21A7:F0 FA 019 BEQ GNXTCR ; BR IF COMMA OR CR ; c = GetNextChar();
21A9:C9 A0 020 CMP #$A0 ; IS IT BLANK ; if (gEqual) break;
21AB:F0 F7 021 BEQ GNBC ; BR IF BLANK ; } while (c == ' ');
21AD:60 022 RTS ; DONE ; o7 Captain Obvious
023 ;
024 ; CLRCCB - CLEAR CCB
025 ;
026 CLRCCB EQU *
21AE:A9 00 027 LDA #0
21B0:A0 16 028 LDY #CCBLEN ; CCBLENGTH
21B2:99 BA 35 029 CLC1 STA CCB-1,Y ; CLEAR BYTE
21B5:88 030 DEY
21B6:D0 FA 031 BNE CLC1
21B8:60 032 RTS
033 PAGE
034 ;
035 ; GETNUM - CONVERT ASCII INPUT TO NUMERIC
036 ;
037 GETNUM EQU * ; cnum = atoi();
21B9:A9 00 038 LDA #0 ; CLEAR WORK AREA
21BB:85 44 039 STA CNUM
21BD:85 45 040 STA CNUM+1
21BF:20 A4 21 041 JSR GNBC ; GetNonBlankChar()
21C2:08 042 PHP ; need to save flags since testing for hex num nukes them
21C3:C9 A4 043 CMP #$A4 ; magic number #'$'+$80 (improvement), CHAR_DOLLAR (better), or OPT_NUM_HEX (best)
21C5:F0 3C 044 BEQ HEXNUM ; ↓ $2203
21C7:28 045 PLP
21C8:4C CE 21 046 JMP GN2A ; wastes 1 byte, BMI GN2A
047 ;
21CB:20 A4 21 048 GN2 JSR GNBC ; GET NEXT NON BLANK
049 GN2A EQU *
21CE:D0 06 050 BNE GN3 ; BR NOT COMMA OR CR
21D0:A6 44 051 LDX CNUM ; X=RESULT LOW
21D2:A5 45 052 LDA CNUM+1 ; Y=RESULT HI ; *sigh* *spelling* A=Result Hi as Y isn't even used!
21D4:18 053 CLC
21D5:60 054 RTS ; DONE ; === Page 151 === o7 Captain Obvious
055 ;
21D6:38 056 GN3 SEC ; GetDigit
21D7:E9 B0 057 SBC #$B0 ; SUBTRACT ASCII 0 ; You keep using this word ASCII, it doesn't mean what you think it means., #'0'+$80
21D9:30 21 058 BMI GN4 ; BR IF NOT SUM
21DB:C9 0A 059 CMP #10
21DD:B0 1D 060 BCS GN4 ; BR IF NOT NUM
21DF:20 FE 21 061 JSR GN5 ; OLD*2 ; Test Time: 1. Describe what GN5 does without looking at the code.
21E2:65 44 062 ADC CNUM ; PLUS NEW ; 2. Describe what MUL2CNUM does.
21E4:AA 063 TAX ; n*10 = n*8 + n*2
21E5:A9 00 064 LDA #0
21E7:65 45 065 ADC CNUM+1
21E9:A8 066 TAY
21EA:20 FE 21 067 JSR GN5 ; OLD*4
21ED:20 FE 21 068 JSR GN5 ; OLD*8
21F0:8A 069 TXA ; OLD*8 + OLD*2 + NEW
21F1:65 44 070 ADC CNUM
21F3:85 44 071 STA CNUM ; =OLD*10 + NEW
21F5:98 072 TYA
21F6:65 45 073 ADC CNUM+1
21F8:85 45 074 STA CNUM+1
21FA:90 CF 075 BCC GN2
076 ;
077 GN4 EQU *
21FC:38 078 SEC
21FD:60 079 RTS ; DONE
080 GN5 EQU *
21FE:06 44 081 ASL CNUM ; CNUM * 2
2200:26 45 082 ROL CNUM+1 ; === T1S1 ===
2202:60 083 RTS
084 PAGE
085 ;
086 HEXNUM EQU *
2203:28 087 PLP
088 HN0 EQU *
2204:20 A4 21 089 JSR GNBC ; GO GET CHAR
2207:F0 C5 090 BEQ GN2A ; BR IF CR OR COMMA
091 ;
2209:38 092 SEC
220A:E9 B0 093 SBC #$B0 ; CHAR - ASCII0 ; ASCII is 7-bit, not 8-bit, SBC #'0'+$80
220C:30 EE 094 BMI GN4 ; BR IF LT0 ; signed c = GetNextLineBufferChar()
220E:C9 0A 095 CMP #10 ; IS IT LT10 ; if ((c - '0') < 0) return;
2210:90 08 096 BCC HN1 ; BR IF LT ; if (c >= 10) c -= ('A' -'9');
2212:E9 07 097 SBC #$7 ; SUB 7 FOR ASCII A ; magic number 7 = ('A' -'9')
2214:30 E6 098 BMI GN4 ; BR IF LT A
2216:C9 10 099 CMP #16 ; TEST GT 15
2218:B0 E2 100 BCS GN4 ; BR GT 15 ; A = digit = 0..F
221A:A2 04 101 HN1 LDX #4 ; CNUM <<= 4; // shift left one nibble
221C:20 FE 21 102 HN2 JSR GN5 ; OLD*16
221F:CA 103 DEX ;LOOP 4 TIMES ONLY
2220:D0 FA 104 BNE HN2
2222:05 44 105 ORA CNUM ; OR IN NEW ; CNUM += digit
2224:85 44 106 STA CNUM ; SAVE NEW
2226:4C 04 22 107 JMP HN0 ; GO FOR NEXT CHAR
108 PAGE
109 ;
110 ; EPR - EXECUTE PR#
111 ;
112 EPR EQU * ; CMDETB [13]
2229:A5 44 113 LDA CNUM ; GET PORT ; Get *slot* #, not port
222B:4C 95 FE 114 JMP OUTPRT ; GO DO IT
115 ;
116 ; EIN - EXECUTE IN#
117 ; ; === 152 ===
118 EIN EQU * ; CMDETB [14]
222E:A5 44 119 LDA CNUM ; GET PORT
2230:4C 8B FE 120 JMP INPRT ; GO DO IT
121 ;
122 ; EMON - EXECUTE MONITOR CMD
123 ;
124 EMON EQU * ; CMDETB [11]
2233:AD 5E 2A 125 LDA MONMOD ; GET CURRENT BITS
2236:0D 74 2A 126 ORA IMBITS ; OR IN NEW BITS
2239:8D 5E 2A 127 STA MONMOD ; SET NEW MODE
223C:60 128 RTS
129 ;
130 ; ENOMON - EXECUTE NO MONITOR CMD
131 ;
132 ENOMON EQU * ; CMDETB [12]
223D:2C 74 2A 133 BIT IMBITS
2240:50 03 134 BVC ENM1
2242:20 C8 1F 135 JSR PRCRIF
136 ENM1 EQU *
2245:A9 70 137 LDA #$70 ; magic number
2247:4D 74 2A 138 EOR IMBITS ; INVERT INPUT BITS
224A:2D 5E 2A 139 AND MONMOD ; AND WITH CURRENT
224D:8D 5E 2A 140 STA MONMOD ; SET NEW MODE
2250:60 141 RTS
142 PAGE
143 ;
144 ; EMAXF - EXECUTE MAX FILES
145 ;
146 EMAXF EQU * ; CMDETB [15]
2251:A9 00 147 LDA #0 ; RESET EXECUTE
2253:8D B3 2A 148 STA ESTATE
2256:A5 44 149 LDA CNUM ; SAVE NEW NO FILES
2258:48 150 PHA
2259:20 16 23 151 JSR CLALL ; GO CLOSE ALL FILES
225C:68 152 PLA
225D:8D 57 2A 153 STA CNFTBS ; SET NEW NO FILE TBLS
2260:4C D4 27 154 JMP BLDFTB ; GO BUILD NEW ONES
155 ;
156 ; EDEL - DELETE A FILE
157 ;
158 EDEL EQU * ; CMDETB [5]
2263:A9 05 159 LDA #CRQDEL
2265:20 AA 22 160 JSR OPEN
2268:20 64 27 161 JSR FILSRC
226B:A0 00 162 LDY #0 ; Common Code WHY isn't this a common subroutine ZEROFILE ??
226D:98 163 TYA ; BFT1, CLS, and the Append bug patch CLOSFILE all do the same thing!
226E:91 40 164 STA (ZPGWRK),Y ; RESET FN ; Sadly, INITD can't be re-factored.
2270:60 165 RTS ;
166 ;
167 ; ELOCK - LOCK A FILE
168 ;
169 ELOCK EQU * ; CMDETB [6]
2271:A9 07 170 LDA #CRQLCK ; SET LOCK
2273:D0 02 171 BNE ELGO ; wastes 1 byte, use DFB $2C ; BIT $abs to skip next instruction
172 ;
173 ; EUNLK - UNLOCK A FILE
174 ;
175 EUNLK EQU * ; CMDETB [7]
2275:A9 08 176 LDA #CRQUNL ; SET UNLOCK
177 ELGO EQU * ; Holy shit! Common Code for ELOCK, EUnlock, EVerify but not to rain on our parade ...
2277:20 AA 22 178 JSR OPEN ; OPEN FILE & UNLOCK ; ... Common Code Why is ELGO and LCKGO different???
227A:4C EA 22 179 JMP ECLOSE ; CLOSE IT
180 ; ; === Page 153
181 ; EVAR - VERIFY A FILE
182 ;
183 EVAR EQU * ; CMDETB [1B]
227D:A9 0C 184 LDA #CRQVAR ; SET VARIFY ; *spelling* Damnit Jim, I wish you would VARIFY your spelling.
227F:D0 F6 185 BNE ELGO
186 PAGE
187 ;
188 ; EREN - RENAME
189 ;
190 EREN EQU *
2281:AD 08 1D 191 LDA FN2ADR ; MOVE FILE NAME2
2284:8D BD 35 192 STA CCBFN2
2287:AD 09 1D 193 LDA FN2ADR+1
228A:8D BE 35 194 STA CCBFN2+1
228D:A9 09 195 LDA CRQRNM
228F:8D 63 2A 196 STA TEMP1A ; SET RENAME
2292:20 C8 22 197 JSR EO3 ; GO OPEN AND RENAME
2295:4C EA 22 198 JMP ECLOSE ; GO CLOSE
199 ;
200 ; EAPND - OPEN FILE FOR APPEND
201 ;
202 EAPND EQU * ; CMDETB [E]
2298:20 A3 22 203 JSR EOPEN ; GO OPEN
204 AP1 EQU *
229B:20 8C 26 205 JSR RBYTE ; READ A BYTE
229E:D0 FB 206 BNE AP1 ; BR IF NOT ZERO
207 ; ; Test Time! Without looking at the code, give a summary of why
22A0:4C 71 36 208 JMP BUMPER ; GO TO PATCH FOR APPEND FIX ; a) BUMPER exists, and
209 PAGE ; b) APPEND_FIX.
210 ;
211 ; EOPEN - OPEN A FILE
212 ;
22A3:A9 00 213 EOPEN LDA #0 ;FIX TYPE MISMATCH DETECTION ; CMDETB [D]
22A5:4C D5 23 214 JMP SV1 ;(CALLS EOPN1) ; Why not JSR SV1??? EASAV, EBSV, and EBLD all do JSR SV1
22A8:A9 01 215 EOPN1 LDA #CRQOPN
216 OPEN EQU * ; Common entry point for EDEL, EUNLK, EBSV, EINIT, ECAT, and indirectly EOPEN, EPOS,
22AA:8D 63 2A 217 STA TEMP1A
22AD:AD 6C 2A 218 LDA CL ; IF NO LENGTH ENTERED
22B0:D0 0A 219 BNE EO1 ; THEN SET DEFAULT OF 1 ;↓
22B2:AD 6D 2A 220 LDA CL+1
22B5:D0 05 221 BNE EO1 ;↓
22B7:A9 01 222 LDA #1
22B9:8D 6C 2A 223 STA CL
224 EO1 EQU *
22BC:AD 6C 2A 225 LDA CL ; MOVE REC LENGTH
22BF:8D BD 35 226 STA CCBRLN
22C2:AD 6D 2A 227 LDA CL+1
22C5:8D BE 35 228 STA CCBRLN+1
229 EO3 EQU *
22C8:20 EA 22 230 JSR ECLOSE ; GO CLOSE IF OPEN
231 EO4 EQU *
22CB:A5 45 232 LDA CNUM+1 ; GET AVALL ENTRY ; *Spelling* Avail
22CD:D0 03 233 BNE EO5 ; BR IF ONE AVAIL
22CF:4C C8 26 234 JMP ENFA ; DONE - NO FILES AVAIL
235 EO5 EQU *
22D2:85 41 236 STA ZPGWRK+1 ; MOVE AVAIL SLOT TO ZPG
22D4:A5 44 237 LDA CNUM
22D6:85 40 238 STA ZPGWRK
239 EO6 EQU *
22D8:20 43 27 240 JSR MVFN1 ; GO MOVE FILE NAME
22DB:20 4E 27 241 JSR MVBUFP ; GO MOVE BUF PTRS
22DE:20 1A 27 242 JSR OPNSUP ; GO SET UP OPEN
22E1:AD 63 2A 243 LDA TEMP1A ; SET OPEN REQ ; === 154 ===
22E4:8D BB 35 244 STA CCBREQ
22E7:4C A8 26 245 JMP DOSGO ; GO OPEN
246 PAGE
247 ;
248 ; ECLOSE - EXECUTE CLOSE FILE COMMAND
249 ;
250 ECLOSE EQU * ; CMDETB [8]
22EA:AD 75 2A 251 LDA FNAME1
22ED:C9 A0 252 CMP #$A0 ; #' '+$80 aka SPC_HI
22EF:F0 25 253 BEQ CLALL
22F1:20 64 27 254 JSR FILSRC ; GO FIND FILE
22F4:B0 3A 255 BCS CL2 ; BR IF NOT FOUND
22F6:20 FC 22 256 JSR CLOSE ; GO CLOSE
22F9:4C EA 22 257 JMP ECLOSE ; GO SEE IF ANY MORE OPEN
258 ;
259 ; CLOSE - CLOSE A FILE
260 ;
261 CLOSE EQU *
22FC:20 AF 27 262 JSR TSTEXC
22FF:D0 05 263 BNE CLX ; === T1S2 ===
2301:A9 00 264 LDA #0
2303:8D B3 2A 265 STA ESTATE
266 CLX EQU *
2306:A0 00 267 LDY #0 ; CLEAR 1ST FN ; [.. wastes 2 bytes, see ZEROFILE note
2308:98 268 TYA ; CHAR TO ZERO ; ..
2309:91 40 269 STA (ZPGWRK),Y ; ..]
230B:20 4E 27 270 JSR MVBUFP ; MOVE BUFFER PTRS
230E:A9 02 271 LDA #CRQCLS ; SET CLOSE
2310:8D BB 35 272 STA CCBREQ
2313:4C A8 26 273 JMP DOSGO
274 ;
275 ; CLALL - CLOSE ALL FILES
276 ;
277 CLALL EQU *
2316:20 92 27 278 JSR TSINIT ; GO INIT FILE SEARCH
2319:D0 05 279 BNE CL1 ;↓
280 CL0 EQU *
231B:20 9A 27 281 JSR TXNXT ; NEXT ENTRY
231E:F0 10 282 BEQ CL2 ; BR IF NO MORE
283 CL1 EQU *
2320:20 AF 27 284 JSR TXTEXC
2323:F0 F6 285 BEQ CL0 ;↑
2325:20 AA 27 286 JSR TSTOPEN ; GO TEST OPEN
2328:F0 F1 287 BEQ CL0 ; BR NOT OPEN
232A:20 FC 22 288 JSR CLOSE ; GO CLOSE
232D:4C 16 23 289 JMP CLALL ; START OVER
2330:60 290 CL2 RTS ; DONE
001 PAGE
002 ;
003 ; EBSV - EXECUTE BINARY SAVE
004 ;
005 EBSV EQU * ; CMDETB [18] "BSAVE"
2331:A9 09 006 LDA #ADR+L ; IF A&L
2333:2D 65 2A 007 AND INOPS ; NOT GIVEN
2336:C9 09 008 CMP #ADR+L
2338:F0 03 009 BEQ EBSV1
233A:4C 00 20 010 JMP CNF ; THEN ERROR
011 EBSV1 EQU *
233D:A9 04 012 LDA #4 ; SET BINARY FILE ; magic number FILE_TYPE_BINARY EQU 4
233F:20 D5 23 013 JSR SV1 ; GO OPEN & TEST
2342:AD 73 2A 014 LDA CA+1 ; OUTPUT ADR OF BLOCK
2345:AC 72 2A 015 LDY CA
2348:20 E0 23 016 JSR SV2
234B:AD 6D 2A 017 LDA CL+1 ; GO OPEN AND TEST
234E:AC 6C 2A 018 LDY CL
2351:20 E0 23 019 JSR SV2 ; OUTPUT LENGTH
2354:AD 73 2A 020 LDA CA+1 ; GET ADR GIVEN
2357:AC 72 2A 021 LDY CA
235A:4C FF 23 022 JMP SV3 ; OUTPUT BLOCK
023 ;
024 ; EBLD - EXECUTE BINARY LOAD
025 ;
026 EBLD EQU * ; CMDETB [19] "BLOAD"
235D:20 A8 22 027 JSR EOPN1 ;(CHANGED 11/1/78 FOR TYPE MISMATCH)
028 EBLD2 EQU * ; *sigh* If only the local labels were in alphabetical order ...
2360:A9 7F 029 LDA #$7F ; magic number ~FILE_LOCK
2362:2D C2 35 030 AND CCBFUC
2365:C9 04 031 CMP #4 ; magic number FILE_TYPE_BINARY
2367:F0 03 032 BEQ EBLD3
2369:4C D0 26 033 JMP ETYP ;TYPE MISMATCH ERROR MESSAGE
034 EBLD3 EQU *
236C:A9 04 035 LDA #4 ; SET BINARY FILE ; magic number /sarcasm if only we had FILE_TYPE_BINARY EQU 4
236E:20 D5 23 036 JSR SV1 ; GO OPEN & TEST
2371:20 7A 24 037 JSR LD2 ; GO GET ADR
2374:AA 038 TAX
2375:AD 65 2A 039 LDA INOPTS
2378:29 01 040 AND #ADR ; IF ADR NOT GIVEN
237A:D0 06 041 BNE EBLD1 ; ↓
237C:8E 72 2A 042 STX CA ; THEN USE ADR FROM FILE
237F:8C 73 2A 043 STY CA+1
044 EBLD1 EQU *
2382:20 7A 24 045 JSR LD2 ; GET LENGTH
2385:AE 72 2A 046 LDX CA ; GET GIVEN ADR
2388:AC 73 2A 047 LDY CA+1
238B:4C 71 24 048 JMP LD3 ; GO GET BLOCK ; Why is this +128 bytes away??
049 ;
050 ; EBRUN - EXECUTE BINARY RUN
051 ;
238E:20 5D 23 052 EBRUN JSR EBLD ; CMDETB [1A] "BRUN"
2391:20 51 28 053 JSR MVCSW ; GO RESTORE CHAR I/O SW
2394:6C 72 2A 054 JMP (CA) ; GO EXEC THE STUFF ; === Page 141 ===
; How Not To Design an OS
; Problem : This (indirect) JMP is why Binary programs can't use RTS to return to DOS
; Solution: The otherwise excellent 6502 has a short-Sighted design
; it lacks indirect mode: JSR ($addr):
; Regular 6502 solution requires self-modifying code.
; LDA CA
; STA GOBRUN+1 ; ** SELF-MODIFYING ! **
; LDA CA+1
; STA GOBRUN+2 ; ** SELF-MODIFYING ! **
; GOBRUN JSR $0000 ; NOTE: Self-Modifying code
; JMP DBRST ; Warmstart DOS
055 PAGE
056 ;
057 ; ESAVE - EXECUTE SAVE REQUEST
058 ;
059 ESAVE EQU *
2397:AD B6 2A 060 LDA ASIBSW ; IF IB THEN
239A:F0 20 061 BEQ EIBSV ; GO TO IB SAVE
239C:A5 D6 062 LDA ASRNX ; CAN NOT DO AS SAVE WHEN RUN-ONLY PROG.
239E:10 03 063 BPL EASAV ; BRANCH IF OK TO SAVE, OTHERWISE
23A0:4C CC 26 064 JMP MFERR ; PRINT "PROGRAM TOO LARGE", THAT OUGHT TO GET 'EM.
23A3:A9 02 065 EASAV LDA #2 ; GET APPLESOFT PGM ; magic number FILE_TYPE_APPLESOFT EQU 2
23A5:20 D5 23 066 JSR SV1 ; GO OPEN AND TEST
067 ;
23A8:38 068 SEC ; BLOCK LENGTH
23A9:A5 AF 069 LDA ASEOP ; =EOP-SOP
23AB:E5 67 070 SBC ASSOP
23AD:A8 071 TAY
23AE:A5 B0 072 LDA ASEOP+1 ; single letter difference asEop
23B0:E5 68 073 SBC ASSOP+1 ; is never a good idea: asSop
23B2:20 E0 23 074 JSR SV2 ; GO OUTPUT LENGTH
075 ;
23B5:A5 68 076 LDA ASSOP+1 ; BLOCK ADR
23B7:A4 67 077 LDY ASSOP ; =SOP
23B9:4C FF 23 078 JMP SV3 ; GO OUTPUT BLOCK
079 ;
080 EIBSV EQU *
23BC:A9 01 081 LDA #1 ; SET IB PGM ; PGM = Program, magic number FILE_TYPE_INTEGER_BASIC EQU 1
23BE:20 D5 23 082 JSR SV1 ; GO OPEN AND TEST
083 ;
23C1:38 084 SEC ; BLOCK LENGTH
23C2:A5 4C 085 LDA IBHMEM ; =HIMEM-SOP
23C4:E5 CA 086 SBC IBSOP
23C6:A8 087 TAY
23C7:A5 4D 088 LDA IBHMEM+1
23C9:E5 CB 089 SBC IBSOP+1
23CB:20 E0 23 090 JSR SV2 ; GO OUTPUT LENGTH
091 ;
23CE:A5 CB 092 LDA IBSOP+1 ; BLOCK ADR
23D0:A4 CA 093 LDY IBSOP ; =SOP
23D2:4C FF 23 094 JMP SV3 ; GO OUTPUT BLOCK
095 ;
096 SV1 EQU *
097 SV1A EQU *
23D5:8D C2 35 098 STA CCBFUC ; SET PGM TYPE
23D8:48 099 PHA ; SAVE PGM TYPE
23D9:20 A8 22 100 JSR EOPN1 ; GO OPEN FILE (CHGED 11/1/78)
23DC:68 101 PLA ; GET SAVE TYPE
23DD:4C C4 27 102 JMP TSTFUC ; GO CHECK
103 ;
104 SV2 EQU *
23E0:8C C1 35 105 STY CCBBLN ; SET BLOCK LENGTH ; === HNTDAFS #5 ===
23E3:8C C3 35 106 STY CCBDAT ; AND DATA BYTE ; You never store file meta-data
23E6:8D C2 35 107 STA CCBBLN+1 ; File Length
23E9:A9 04 108 LDA #CRQWR ; INDICATE WRITE ; in the file itself!
23EB:8D BB 35 109 STA CCBREQ
23EE:A9 01 110 LDA #CRNBT ; NEXT BYTE
23F0:8D BC 35 111 STA CCBRQM
23F3:20 A8 26 112 JSR DOSGO ; GO WRITE
23F6:AD C2 35 113 LDA CCBBLN+1 ; OTHER BYTE TOO
23F9:8D C3 35 114 STA CCBDAT
23FC:4C A8 26 115 JMP DOSGO ; === Page 142 ===
116 ;
23FF:8C C3 35 117 SV3 STY CCBBBA ; SET BLOCK ADR
2402:8D C4 35 118 STA CCBBBA+1
2405:A9 02 119 LDA #CRMNBL ; INDICATE BLOCK I/O
2407:4C 86 36 120 JMP VPATCH ;VERIFY AFTER SAVE
240A:20 A8 26 121 GODOS JSR DOSGO ; GO DO IT
240D:4C EA 22 122 JMP ECLOSE ; CLOSE FILE
123 PAGE
2410:4C D0 26 124 NBPER NBPER JMP ERNU1 ; Not Basic Program Error called from ELD1
125 ;
126 ; ELOAD - EXECUTE LOAD REQUEST
127 ;
128 ELOAD EQU *
2413:20 16 23 129 JSR CLALL
2416:20 A8 22 130 ELOAD0 JSR EOPN1
131 ;
132 ELD1 EQU * ; *sigh* Pick a bloody consistent naming schema: ELOAD# or ELD#
2419:A9 23 133 LDA #$23 ; STRIP UNRELATED STUFF ; magic number TODO WTF do these bits mean???
241B:2D C2 35 134 AND CCBFUC ; OUT OF FUC
241E:F0 F0 135 BEQ NBPER ; BR IF ERROR
136 ; ISOLATE IB & AS
137 ELD2 EQU *
2420:8D C2 35 138 STA CCBFUC ; SAVE IB/AS ONLY
2423:AD B6 2A 139 LDA ASISBSW ; IF IB THEN
2426:F0 28 140 BEQ EIBL ; GO TO IB LOAD ; ↓
2428:A9 02 141 LDA #2 ; magic number FILE_TYPE_APPLESOFT EQU 2
242A:20 B1 24 142 JSR LD1 ; GO OPEN AND TEST
143 ;
242D:20 7A 24 144 JSR LD2 ; GO GET BLOCK LENGTH ; wastes 3 bytes, LD1 should fall into LD2
145 ; ; While EBLD2 (ExecBload2) calls LD2 by itself, LD1 is always followed by LD2
2430:18 146 CLC
2431:65 67 147 ADC ASSOP ; ADD BLOCK LENGTH TO SOP
2433:AA 148 TAX
2434:98 149 TYA
2435:65 68 150 ADC ASSOP+1
151 ;
2437:C5 74 152 CMP ASHM1+1 ; IF BL+SOP >= HMEM ; If Block.Length + StartOfProgram >= High Memory
2439:B0 70 153 BCS MFULL ; THEN WON'T FIT ; Memory Full
154 ;
155 EASL1 EQU *
243B:85 B0 156 STA ASEOP+1 ; SET NEW EOP ADR
243D:85 6A 157 STA ASEOP2+1
243F:86 AF 158 STX ASEOP
2441:86 69 159 STX ASEOP2
2443:A6 67 160 LDX ASSOP ; GET ADR WHERE TO LOAD
2445:A4 68 161 LDY ASSOP+1
2447:20 71 24 162 JSR LD3 ; GO LOAD
244A:20 51 28 163 JSR MVCSW ;RESTORE I/O ; TODO Why??? Did something change CIN/COUT ???
244D:6C 60 1D 164 JMP (ASEQ) ;RELOC FOR THIS VERSION OF APPLSOFT
165 ;
166 EIBL EQU *
2450:A9 01 167 LDA #1 ; SET IB PGM ; Yup, almost 99% the same as ELD2
2452:20 B1 24 168 JSR LD1 ; GO OPEN AND TEST
169 ;
2455:20 7A 24 170 JSR LD2 ; GO GET BLOCK LENGTH ; wastes 3 bytes, see Line #141
171 ;
2458:38 172 SEC ; HMEM - BLOCK LENGTH
2459:A5 4C 173 LDA IBHMEM ; IS NEW SOP
245B:ED 60 2A 174 SBC SVBL
245E:AA 175 TAX
245F:A5 4D 176 LDA IBHMEM+1
2461:ED 61 2A 177 SBC SVBL+1
2464:90 45 178 BCC MFULL ; === Page 143 ===
2466:A8 179 TAY
180 ;
2467:C4 4B 181 CPY IBLMEM+1 ; IF NEW SOP <= LMEM
2469:90 40 182 BCC MFULL
246B:F0 3E 183 BEQ MFULL
246D:84 CB 184 STY IBSOP+1 ; SET NEW SOP
246F:86 CA 185 STX IBSOP
186 LD3 EQU *
2471:8E C3 35 187 STX CCBBBA ; SET BLOCK ADDR ; Googoo, Gaga? A single underscore '_' would go a LONG way towards readability
2474:8C C4 35 188 STY CCBBBA+1 ; CCB_BBA
2477:4C 0A 24 189 JMP GODOS
190 ;
191 LD2 EQU * ; By putting this before LD1 this forces 6 byes to be wasted, see Line #143
247A:AD 0A 1D 192 LDA SVBLA ; MOVE ADR OF WHERE
247D:8D C3 35 193 STA CCBBA ; TO PUT DATA TO
2480:AD 0B 1D 194 LDA SVBLA+1 ; CCBN
2483:8D C4 35 195 STA CCBBBA+1
2486:A9 00 196 LDA #0
2488:8D C2 35 197 STA CCBBLN+1 ; READ INTO
248B:A9 02 198 LDA #2
248D:8D C1 35 199 STA CCBBLN
2490:A9 03 200 LDA #CRQRD ; READ
2492:8D BB 35 201 STA CCBREQ
2495:A9 02 202 LDA #CRMNBL ; BLOCK
2497:8D BC 35 203 STA CCBRQM
249A:20 A8 26 204 JSR DOSGO
249D:AD 61 2A 205 LDA SVBL+1
24A0:8D C2 35 206 STA CCBBLN+1
24A3:A8 207 TAY
24A4:AD 60 2A 208 LDA SVBL
24A7:8D C1 35 209 STA CCBBLN
24AA:60 210 RTS
211 ;
212 MFULL1 EQU *
24AB:20 EA 22 213 JSR ECLOSE ; GO CLOSE FILE
24AE:4C CC 26 214 JMP MFERR ; AND GIVE ERR MSG
215 LD1 EQU *
24B1:CD C2 35 216 CMP CCBFUC ; TEST TYPE
24B4:F0 1A 217 BEQ LD1C ; BR IF MATCH
24B6:AE 5F 2A 218 LDX CMDNO
24B9:8E 62 2A 219 STX SVCMD
24BC:4A 220 LSR A
24BD:F0 03 221 BEQ LD1A ; BR IF PGM IS AS
24BF:4C 9E 25 222 JMP EINT ; GO FOR INTG BASIC
223 ;
224 LD1A EQU *
24C2:A2 1D 225 LDX #29 ; SAVE FILENAME ; magic number FILENAME_MAX-1
24C4:BD 75 2A 226 LD1B LDA FNAME1,X ; INCASE IS RAM APPLESOFT
24C7:9D 93 2A 227 STA FNAME2,X
24CA:CA 228 DEX
24CB:10 F7 229 BPL LD1B
24CD:4C 7A 25 230 JMP EAS ; GO FOR AS
231 ;
24D0:60 232 LD1C RTS
233 PAGE
234 ;
235 ; ERUN - EXECUTE RUN REQUEST
236 ;
237 ERUN EQU *
24D1:AD B6 2A 238 LDA ASIBSW ; IF APPLESOFT THEN RELOC FLAG SET
24D4:F0 03 239 BEQ ERUN0
24D6:8D B7 2A 240 STA RSTATE ; INDICATE APSFT RUN
24D9:20 13 24 241 ERUN0 JSR ELOAD ; LOAD PGM ; === 144 ===
24DC:20 C8 1F 242 ERUN1 JSR PRCRIF ;REENTRY POINT FOR ASFT RELOC
24DF:20 51 28 243 JSR MVCSW ; GO RESTORE CHAR I/O SW ; What keeps futzing with CIN / COUT ? Guilty Party → SVREGS
24E2:6C 58 1D 244 JMP (RUN)
245 ;
246 ; IBRUN - INT BASIC RUN
247 ;
248 IBRUN EQU *
24E5:A5 4A 249 LDA IBLMEM ; RESET START OF VARS
24E7:85 CC 250 STA IBSOV
24E9:A5 4B 251 LDA IBLMEM+1
24EB:85 CD 252 STA IBSOV+1
24ED:6C 56 1D 253 JMP (CHAIN)
254 ;
255 ; EHCAIN - EXECUTE CHAIN REQUEST ; *spelling* ECHAIN
256 ;
257 ECHAIN EQU *
24F0:20 16 24 258 JSR ELOAD0 ; LOAD PGM WITHOUT CLOSING READ FILES
24F3:20 C8 1F 259 JSR PRCRIF
24F6:20 51 28 260 JSR MVCSW ; GO RESTORE CHAR I/O SW
24F9:6C 56 1D 261 JMP (CHAIN)
24FC:20 65 D6 262 ASRUN1 JSR $D665 ; ROM ; magic number
24FF:85 33 263 STA PROMPT ;INSURES APPLESOFT RUN DETECT (A=0) ; === T1S4 ===
2501:85 D8 264 STA ASONERR ;RESET APPLESOFT ONERR FLAG
2503:4C D2 D7 265 JMP $D7D2 ; magic number
2506:20 65 0E 266 ASRUN2 JSR $E65 ; RAM ; magic number AS2VT has pointer to us
2509:85 33 267 STA PROMPT ;INSURES APPLESOFT RUN DETECT (A=0) ; (dead code) wastes 10 bytes on Apple ][+ or later
250B:85 D8 268 STA ASONER ;RESET APPLESOFT ONERR FLAG ;
250D:4C D4 0F 269 JMP $FD4 ; magic number
001 PAGE
002 ;
003 ; EWRITE - WRITE CMD EXECUTE
004 ;
005 EWRITE EQU *
2510:20 26 25 006 JSR RWPOSN ; GO POSITION FILE IF REQD
2513:A9 05 007 LDA #5 ; WTF is state 5 ?? OK, COS5 And the state table transition is where again?
2515:8D 52 2A 008 STA OSTATE ; SET OSTATE=5 ; /sarcasm No Shit, Sherlock
2518:4C 83 1F 009 JMP CERTN
010 ;
011 ; EREAD - READ COMD EXECUTE
012 ;
013 EREAD EQU *
251B:20 26 25 014 JSR RWPOSN ; GO POSITION FILE IF REQD ;↓
251E:A9 01 015 LDA #1
2520:8D 51 2A 016 STA ISTATE ; SET I STATE = DISK INPUT ; /voice="Nick Burns" See, that wasn't so hard!
2523:4C 83 1F 017 JMP CERTN ;↑ wastes 1 bytes, BNE EREAD-3
018 ;
019 ; RWPOSN - POSTION FOR READ/WRITE
020 ;
021 RWPOSN EQU *
2526:20 64 27 022 JSR FILSRC ; FIND THE FILE ;↓
2529:90 06 023 BCC RWP1 ; BR IF FILE FOUND ;↓
252B:20 A3 22 024 JSR EOPEN ; GO OPEN FOR KLUTZ ;↓ ??? if file doesn't exist, open it ???
252E:4C 34 25 025 JMP RWP2 ; THEN SKIP NEXT LINE ;↓ wastes 1 byte, should be TODO
026 RWP1 EQU *
2531:20 4E 27 027 JSR MVBUFP ; MOVE BUFF POINTERS ;↓ /sarcasm WHICH way Einstein?
028 RWP2 EQU *
2534:AD 65 2A 029 LDA INOPTS ; GET IN OPTIONS
2537:29 06 030 AND #R+B ; WAS IT B OR R
2539:F0 13 031 BEQ RWPR ; BR IF NOT ;↓ Should be BEQ LD1C ;↑
253B:A2 03 032 LDX #3
253D:BD 6E 2A 033 RWP2A LDA CR,X ; MOVE REL REC
2540:9D BD 35 034 STA CCBRRN,X ; AND REL BYTE
2543:CA 035 DEX
2544:10 F7 036 BPL RWP2A ;↑
037 RWP3 EQU *
2546:A9 0A 038 LDA #CRQPOS ; INDICATE POISTION REQUEST ; *spelling* Position
2548:8D BB 35 039 STA CCBREQ
254B:20 A8 26 040 JSR DOSGO ;↓ [.. wastes 1 byte next instruction RTS, should be JMP
254E:60 041 RWPR RTS ; ..]
042 PAGE
043 ;
044 ;
045 ; EINIT - EXECUTE INIT COMMAND
046 ;
047 EINIT EQU * ; "INIT" -- also see FFMT
254F:A9 40 048 LDA #V ; MUST HAVE
2551:2D 65 2A 049 AND INOPTS ; VOL OPTION
2554:F0 05 050 BEQ DFVOL ;GO SET DEFAULT VOLUME=254
2556:AD 66 2A 051 LDA CV ;CAN'T SPECIFY VOL=0
2559:D0 05 052 BNE EINITA
255B:A9 FE 053 DFVOL LDA #$FE ;SET DEFAULT VOLUME NUMBER ; magic number DEFAULT_VOLUME
255D:8D 66 2A 054 STA CV ; === Page 146 ===
2560:AD 0D 1D 055 EINITA LDA ASTART+1
2563:8D BC 35 056 STA CCBBSA
2566:A9 0B 057 LDA #CRQFMT
2568:20 AA 22 058 JSR OPEN
256B:4C 97 23 059 JMP ESAVE
060 ;
061 ;
062 ; ECAT - PRINT CATALOG
063 ;
064 ECAT EQU *
256E:A9 06 065 LDA #CRQDIR
2570:20 AA 22 066 JSR OPEN ; GO PRETEND OPEN
2573:AD BF 35 067 LDA CCBVOL
2576:8D 66 2A 068 STA CV
2579:60 069 RTS
070 PAGE
071 ;
072 ; EAS - EXECUTE APPLESOFT REQUEST
073 ;
074 EAS EQU *
257A:A9 4C 075 LDA #ATSTV ; GET APPLESOFT TEST VALUE
257C:20 B2 25 076 JSR SWTST ; GO SWITCH AND TEST
257F:F0 2E 077 BEQ GOINIT ; BR IF APPLESOFT
2581:A9 00 078 LDA #0 ; magic number LANGUAGE_APPLESOFT
2583:8D B6 2A 079 STA ASIBSW
080 ;
081 EAS0 EQU *
2586:A0 1E 082 LDY #30 ; magic number MAX_FILENAME_LEN-1
2588:20 97 20 083 JSR CLRFNA ; ClearFileName1
258B:A2 09 084 LDX #FASBL
258D:BD B7 2A 085 EAS1 LDA FASB-1,X ; MOVE SYSTEM FILENAME ; No, copy
2590:9D 74 2A 086 STA FNAME1-1,X
2593:CA 087 DEX
2594:D0 F7 088 BNE EAS1
089 ;
090 EAS2 EQU *
2596:A9 C0 091 LDA #$C0 ; magic number $80 + $40
2598:8D 51 2A 092 STA ISTATE ; FOR RAM APPLESOFT
259B:4C D1 24 093 JMP ERUN
094 ;
095 ; EINT - EXECUTE INTEGER REQUEST
096 ;
097 EINT EQU *
259E:A9 20 098 LDA #ITSTV ; GET IB TEST VALUE
25A0:20 B2 25 099 JSR SWTST ; GO SWITCH AND TEST
25A3:F0 05 100 BEQ GOINT ;BR IF INTIGER BASIC ; *spelling* Integer
25A5:A9 01 101 LDA #1 ;LANGUAGE NOT AVIALABLE, TOO BAD... ; *spelling* Available magic number
25A7:4C D2 26 102 JMP ERROR
25AA:A9 00 103 GOINT LDA #0 ;RESET RSTATE ; magic number
25AC:8D B7 2A 104 STA RSTATE ; FOR NON APPLESOFT PROG.
105 GOINIT EQU *
25AF:4C 84 1D 106 JMP DBINIT ; GO INIT DOS
107 SWTST EQU *
25B2:CD 00 E0 108 CMP AITSTL ; TEST CURRENT VALUE
25B5:F0 0E 109 BEQ SWTR
25B7:8D 80 C0 110 STA $C080 ; TRY SWITCH 1 ; magic number
25BA:CD 00 E0 111 CMP AITSTL ; TEST AGAIN
25BD:F0 06 112 BEQ SWTR ; BR IF NOW SAME
25BF:8D 81 C0 113 STA $C081 ; TRY SWITCH 2 ; magic number
25C2:CD 00 E0 114 CMP AITSTL ; TEST AND
25C5:60 115 SWTR RTS ; RETURN
116 ;
117 PAGE ; === Page 147 ===
118 ;
119 ; EEXEC - EXECUTE EXEC CMD
120 ;
121 EEXEC EQU * ; "EXEC"
25C6:20 A3 22 122 JSR EOPEN ; OPEN FILE
25C9:AD 4F 2A 123 LDA CFTABA ; MOVE TABLE POINTERS
25CC:8D B4 2A 124 STA EFTABA
25CF:AD 50 2A 125 LDA CFTABA+1
25D2:8D B5 2A 126 STA EFTABA+1
25D5:AD 75 2A 127 LDA FNAME1 ; USE FILNAME ; *spelling* Filename
25D8:8D B3 2A 128 STA ESTATE ; SET EXSTATE NON ZERO
25DB:D0 0E 129 BNE EXP2
130 ;
131 ;
132 ; EPOS - EXECUTE POSITION
133 ;
134 EPOS EQU * ; "POSITION"
25DD:20 64 27 135 JSR FILSRC
25E0:90 06 136 BCC EXP1
25E2:20 A3 22 137 JSR EOPEN
25E5:4C EB 25 138 JMP EXP2
25E8:20 4E 27 139 EXP1 JSR MVBUFP
140 EXP2 EQU *
25EB:AD 65 2A 141 LDA INOPTS ; GET OPTIONS
25EE:29 04 142 AND #R ; TEST R
25F0:F0 1B 143 BEQ EX2 ; BR NOT R
144 ;
25F2:AD 6E 2A 145 EX0 LDA CR ; IF CR NOT ZERO
25F5:D0 08 146 BNE EX1A ; THEN DECREMENT
25F7:AE 6F 2A 147 LDX CR+1
25FA:F0 11 148 BEQ EX2
25FC:CE 6F 2A 149 DEC CR+1
25FF:CE 6E 2A 150 EX1A DEC CR
2602:20 8C 26 151 EX1 JSR RBYTE ; AND READ A RECORD
2605:F0 38 152 BEQ ICFD4
2607:C9 8D 153 CMP #$8D ; UNTIL CR ; magic number KEY_CR
2609:D0 F7 154 BNE EX1
260B:F0 E5 155 BEQ EX0 ; THEN TEST CR AGAIN
156 ;
260D:60 157 EX2 RTS
158 PAGE
159 ;
160 ; OCTD - OUTPUT A CHAR TO DISK
161 ;
162 OCTD EQU *
260E:20 5E 26 163 JSR TSTRUN ; GO TEST RUN
2611:B0 66 164 BCS ICFDB ;BRANCH IF NOT RUN MODE
2613:AD 5C 2A 165 LDA SVA ; CHAR IN SAVED ACU
2616:8D C3 35 166 STA CCBDAT ; PUT INTO CCBDATA AREA
2619:A9 04 167 LDA #CRQWR ; SET WRITE
261B:8D BB 35 168 STA CCBREQ
261E:A9 01 169 LDA #CRMNBT ; SET NEXT BYTE
2620:8D BC 35 170 STA CCBRQM
2623:4C A8 26 171 JMP DOSGO ; GO WRITE BYTE
172 ;
173 ; INCFD - INPUT A CHAR FROM DISK
174 ;
175 ICFD EQU *
2626:20 5E 26 176 JSR TSTRUN ; GO TEST RUN
2629:B0 4E 177 BCS ICFDB ;BRANCH IF NOT RUN MODE
262B:A9 06 178 LDA #6 ; SET OUT STE = 6 ; magic number
179 ICFD3 EQU *
262D:8D 52 2A 180 STA OSTATE ; TO CATCH ECHO ; === Page 148 ===
2630:20 8C 26 181 JSR RBYTE
2633:D0 0F 182 BNE ICFD1 ; BR IF NOT ZERO CHAR
183 ICFD2 EQU *
2635:20 FC 22 184 JSR CLOSE
2638:A9 03 185 LDA #3 ; magic number
263A:CD 52 2A 186 CMP OSTATE
263D:F0 CE 187 BEQ EX2
188 ICFD4 EQU *
263F:A9 05 189 LDA #CREEOF
2641:4C D2 26 190 JMP ERROR ; GO TO ERROR ; /sarcasm No shit, Sherlock -- HOW did we get here?
191 ICFD1 EQU *
2644:C9 E0 192 CMP #$E0 ;CHECK FOR LOWER CASE
2646:90 02 193 BCC ICFNLC ;BRANCH IF NOT LOWER-CASE
2648:29 7F 194 AND #$7F ;STRIP HI BIT TO FOOL GETLINE
195 ICFNLC EQU *
264A:8D 5C 2A 196 STA SVA ; PUT INTO SAVED ACU
264D:AE 5A 2A 197 LDX SVX ; MUST CHECK LAST FOR LOWER CASE
2650:F0 09 198 BEQ ICFD0 ;IGNORE IF FIRST CHAR.
2652:CA 199 DEX
2653:BD 00 02 200 LDA LBUFF,X
2656:09 80 201 ORA #$80 ;RESET HI BIT
2658:9D 00 02 202 STA LBUFF,X ; EVEN THOUGH IT MAY NOT NEED IT
203 ICFD0 EQU *
265B:4C B3 1F 204 JMP ORTN ; GO RESTORE REGS AND RTS
205 ;
265E:48 206 TSTRUN PHA
265F:AD B6 2A 207 LDA ASIBSW ; GET AS/INT BASIC SWITCH
2662:F0 0E 208 BEQ TR1 ; BR IF INT
2664:A6 76 209 LDX $76 ;CHECK APPLESOFT RUN FLAG ; magic number
2666:E8 210 INX ;(NOT RUN=0 AFTER INCREMENT)
2667:F0 0D 211 BEQ NOTRUN ;IF SAYS RUNNING MAKE SURE WITH PROMPT.
2669:A6 33 212 LDX PROMPT ;TEST APPLESOFT RUNNING.
266B:E0 DD 213 CPX #']'+$80
266D:F0 07 214 BEQ NOTRUN ; BR IF NOT RUN
266F:68 215 TR0 PLA
2670:18 216 CLC ;INDICATE PROGRAM RUNNING
2671:60 217 RTS
218 TR1 EQU *
2672:A5 D9 219 LDA $D9 ; GET INT RUN FLAG ; magic number
2674:30 F9 220 BMI TR0 ; BR IF RUN
2676:68 221 NOTRUN PLA ;INDICATE PROGRAM NOT RUNNING
2677:38 222 SEC ; WITH CARRY SET.
2678:60 223 RTS
224 ;
225 ICFDB EQU * ; NOT RUN MODE
2679:20 FC 22 226 JSR CLOSE ; GO CLOSE FILE
267C:20 5B 27 227 JSR CLRSTS ; GO CLEAR STATES
267F:4C B3 1F 228 JMP ORTN ;
229 PAGE
230 ;
231 ; NXTEXC - NEXT EXECUTE CHAR
232 ;
233 NXTEXC EQU *
2682:20 9D 26 234 JSR MVEFTA
2685:20 4E 27 235 JSR MVBUFP ; GO MOVE PTRS
2688:A9 03 236 LDA #3
268A:D0 A1 237 BNE ICFD3 ; ↑ (always)
238 ;
239 ; RBYTE - READ NEXT BYTE
240 ;
241 RBYTE EQU *
268C:A9 03 242 LDA #CRQRD ; SET READ ; === Page 149 ===
268E:8D BB 35 243 STA CCBREQ
2691:A9 01 244 LDA #CRMNBT ; SET NEXT BYTE
2693:8D BC 35 245 STA CCBRQM
2696:20 A8 26 246 JSR DOSGO ; GO TO DOS
2699:AD C3 35 247 LDA CCBDAT ; GET THE DATA BYTE
269C:60 248 RTS
249 MVEFTA EQU *
269D:AD B5 2A 250 LDA EFTABA+1 ; MOVE TABLE ADR
26A0:85 41 251 STA ZPGWRK+1 ; NO ZPG
26A2:AD B4 2A 252 LDA EFTABA
26A5:85 40 253 STA ZPGWRK
26A7:60 254 RTS
001 PAGE
002 ;
003 ; DOSGO - GOTO DOS
004 ;
005 DOSGO EQU *
26A8:20 06 2B 006 JSR DOSENT ; GO TO DOS
26AB:90 16 007 BCC DG3 ; BR IF NOT ERROR
008 ;
26AD:AD C5 35 009 LDA CCBSTA ;GET RETURN CODE
26B0:C9 05 010 CMP #5 ; magic number TODO
26B2:F0 03 011 BEQ YESEOF
26B4:4C 5E 36 012 JMP CLOSFILE ;NO. CLOSE & COMPLAIN
26B7:4C 92 36 013 YESEOF JMP EOFFIX ;MAYBE FIX IT UP?
26BA:EA 014 NOP ; wastes 1 byte
015 ***************************
016 *
017 * DOS 3.3 (REV B) PATCH
018 *
019 ***************************
020 DO DOS33B
26BB:20 69 3A 021 DOSGO2A JSR MOVEOF ; MOVE END OF FILE PATCH ; Called from BACK
022 ELSE
023 NOP
024 DOSGO2A NOP Why isn't this label on the previous line???
025 NOP
026 FIN
26BE:A2 00 027 LDX #0 ; SET OTHER EIF
26C0:8E C3 35 028 STX CCBDATA
26C3:60 029 DG3 RTS
030 ;
031 PAGE
032 ;
033 ; ERROR ROUTINE
034 ;
26C4:A9 0B 035 ESYNTX LDA #CREFLK+1 ; I'd like to buy a vowel, 'A'.
26C6:D0 0A 036 BNE ERROR ; Sorry, we're fresh out.
26C8:A9 0C 037 ENFA LDA #CREFLK+2
26CA:D0 06 038 BNE ERROR ; ↓ (always)
26CC:A9 0E 039 MFERR LDA #CREFLK+4
26CE:D0 02 040 BNE ERROR ; ↓ (always) wastes 1 byte, $2C bit $abs to skip next instruction
041 ETYP EQU *
26D0:A9 0D 042 ERNU1 LDA #CREFLK+3
043 ; ; Intentional fall into ERROR
044 ERROR EQU *
26D2:8D 5C 2A 045 STA SVA ; SAVE MSG NUMBER
26D5:20 E6 3F 046 JSR CLRSTS1 ;PATCH TO CLR RSTATE TOO (WAS JSR CLRSTS)
26D8:AD B6 2A 047 LDA ASIBSW ; GET AS/IN BASIC SWITCH
26DB:F0 04 048 BEQ ERNAS ; BR IF NOT APPLESOFT
26DD:A5 D8 049 LDA ASONERR ;GET AS ERR FLAG
26DF:30 0E 050 BMI ERRTN ; BRT IF ON ERR IS GO
051 ERNAS EQU *
26E1:A2 00 052 LDX #0
26E3:20 02 27 053 JSR EMPR ; GO OUTPUT ; === Page 41 ===
26E6:AE 5C 2A 054 LDX SVA ; GET SAVE MSG
26E9:20 02 27 055 JSR EMPR ; GO OUTPUT MSG
26EC:20 C8 1F 056 JSR PRCRIF ;OUTPUT A CARRIAGE RETURN AFTER MESSAGE
26EF:20 51 28 057 ERRNT JSR MVCSW ; GO MOVE CHAR I/ SW
26F2:20 5E 26 058 JSR TSTRUN
26F5:AE 5C 2A 059 LDX SVA
26F8:A9 03 060 LDA #03 ; magic number
26FA:B0 03 061 BCS ERRTN1 ;DON'T GOTO BREAK HANDLER IF NOT RUNNING
26FC:6C 5A 1D 062 JMP (BREAK)
26FF:6C 5E 1D 063 ERRTN1 JMP (CONT) ;REENTER CONT IF NOT RUN ; === T1S6 ===
064 ;
065 EMPR EQU *
2702:BD 3F 2A 066 LDA EMDTB,X ; GET ITS DISPL
2705:AA 067 TAX ; INTO X
068 EMPR1 EQU *
2706:8E 63 2A 069 STX TEMP1A ; SAVE DISPL
2709:BD 71 29 070 LDA EMSG,X ; GET MSG CHAR
270C:48 071 PHA ; SAVE CHAR
270D:09 80 072 ORA #$80 ; SET MSB ON
270F:20 C5 1F 073 JSR ORTN1 ; OUTPUT CHAR
2712:AE 63 2A 074 LDX TEMP1A ; GET INDEX
2715:E8 075 INX ; INCREMENT IT
2716:68 076 PLA ; RE-LOAD CHAR
2717:10 ED 077 BPL EMPR1 ; BR IF MORE CHARS
2719:60 078 RTS ; DONE
079 PAGE
080 ;
081 ; OPNSUP - OPEN SET UP
082 ;
083 OPNSUP EQU * ; If only these were contiguous
271A:AD 66 2A 084 LDA CV ; VOLUME
271D:8D BF 35 085 STA CCBVOL ;
2720:AD 68 2A 086 LDA CD ; DRIVE
2723:8D C0 35 087 STA CCBDRV
2726:AD 6A 2A 088 LDA CS ; SLOT
2729:8D C1 35 089 STA CCBSLT
272C:AD 06 1D 090 LDA FN1ADR ; FILENAME 1 ADR
272F:8D C3 35 091 STA CCBFN1
2732:AD 07 1D 092 LDA FN1ADR+1
2735:8D C4 35 093 STA CCBFN1+1
2738:A5 40 094 LDA ZPGWRK
273A:8D 4F 2A 095 STA CFTABA
273D:A5 41 096 LDA ZPGWRK+1
273F:8D 50 2A 097 STA CFTABA+1
2742:60 098 RTS
099 ;
100 ; MVFN1 - MOVE FILE NAME 1 TO FILE PTR
101 ;
102 MVFN1 EQU *
2743:A0 1D 103 LDY #29 ; magic number MAX_FILENAME-1
2745:B9 75 2A 104 MVFN1A LDA FNAME1,Y
2748:91 40 105 STA (ZPGWRK),Y
274A:88 106 DEY
274B:10 F8 107 BPL MVFN1A
274D:60 108 RTS
109 ;
110 ; MVBUFP - MOVE BUFFER PTR TO CCB
111 ;
112 MVBUFP EQU *
274E:A0 1E 113 LDY #30 ; magic number MAX_FILENAME
2750:B1 40 114 MVBP1 LDA (ZPGWRK),Y ; === Page 42 ===
2752:99 A9 35 115 STA CCBFCB-30,Y ; magic number MAX_FILENAME
2755:C8 116 INY
2756:C0 26 117 CPY #38 ; magic number MAX_FILENAME + HEADER.SIZE (See BLDFTAB)
2758:D0 F6 118 BNE MVBP1
275A:60 119 RTS
120 ;
121 ; CLRSTS - CLEAR STATES ; Which states?? Input and Ouput
122 ;
123 CLRSTS EQU *
275B:A0 00 124 LDY #0
275D:8C 51 2A 125 STY ISTATE
2760:8C 52 2A 126 STY OSTATE
2763:60 127 RTS ; Should be FLS4 SEC, RTS for FILSRC not found exit optimization
128 PAGE ; Callers: CMDGO1, CNF1, ERROR, INITZ, don't use carry.
129 ;
130 ; FILSRC - SEARCH FOR FILE NAME1
131 ;
132 FILSRC EQU *
2764:A9 00 133 LDA #0 ; CLEAR SV AVAIL
2766:85 45 134 STA CNUM+1
135 ;
2768:20 92 27 136 JSR TSINIT ; GO INIT SEARCH ; ↓
276B:4C 73 27 137 JMP FLS1A ; wastes 1 byte, CLALL has JSR TSINIT, BNE SKIPNEXT so why JMP ???
276E:20 9A 27 138 FLS1 JSR TSNXT ; LOOK AT NEXT
2771:F0 1D 139 BEQ FLS4 ; BR IF NO NET
140 ;
2773:20 AA 27 141 FLS1A JSR TSTOPN ; GO TEST OPEN
2776:D0 0A 142 BNE FLS2 ; BR IF OPEN
143 ;
2778:A5 40 144 LDA ZPGWRK ; SAVE AVAIL ENTRY ADR
277A:85 44 145 STA CNUM
277C:A5 41 146 LDA ZPGWRK+1
277E:85 45 147 STA CNUM+1
2780:D0 EC 148 BNE FLS1 ; GO LOOK SOME MORE
149 ;
2782:A0 1D 150 FLS2 LDY #29 ; FILE HAD 30 CHARS ; magic number MAX_FILENAME-1
2784:B1 40 151 FLS3 LDA (ZPGWRK),Y ; GET CHAR
2786:D9 75 2A 152 CMP FNAME1,Y TEST CHAR ; Missing ; for comment
2789:D0 E3 153 BNE FLS1 ; BR NOT
278B:88 154 DEY
278C:10 F6 155 BPL FLS3 ; LOOK AT 30 CHARS
278E:18 156 CLC ; FOUND
278F:60 157 RTS
158 ;
2790:38 159 FLS4 SEC ; NOT FOUND ;[.. wastes 1 byte, these 2 bytes should be moved to Line #127
2791:60 160 RTS ; DONE ; ..]
161 PAGE
162 ;
163 ; TSINIT - INITIALIZE FOR FTAB SEARCH
164 ; TSNXT - GET NEXT FTAB ENTRY
165 ;
166 TSINIT EQU *
2792:AD 00 1D 167 LDA FTAB ; GET 1ST PTR ADR
2795:AE 01 1D 168 LDX FTAB+1
2798:D0 0A 169 BNE TSST
170 TSNXT EQU *
279A:A0 25 171 LDY #37 ; GET LINK ; magic number HEADER.LINK+1 (See BLDFTB)
279C:B1 40 172 LDA (ZPGWRK),Y
279E:F0 09 173 BEQ TSR ; BR IF NO LINK
174 ;
27A0:AA 175 TAX
27A1:88 176 DEY ; HEADER.LINK+0
27A2:B1 40 177 LDA (ZPGWRK),Y ; === Page 43 ===
178 TSST EQU *
27A4:86 41 179 STX ZPGWRK+1
27A6:85 40 180 STA ZPGWRK
27A8:8A 181 TXA ; SET NE CC
27A9:60 182 TSR RTS ; RTN
183 ;
184 ; TSTOPN - TST FOR OPEN FILE ; TST? Really?? You have to abbreviate the description too ?!
185 ;
186 TSTOPN EQU *
27AA:A0 00 187 LDY #0 ; GET 1ST CHAR OF FN
27AC:B1 40 188 LDA (ZPGWRK),Y
27AE:60 189 RTS
190 ;
191 ; TSTEXC - TEST CURRENT FILE FOR EXECUTE
192 ;
193 TSTEXC EQU *
27AF:AD B3 2A 194 LDA ESTATE ; IF ESTATE = 0
27B2:F0 0E 195 BEQ TXC1 ; THEN NO EXECUTE FILE
27B4:AD B4 2A 196 LDA EFTABA ; TEST CURRENT
27B7:C5 40 197 CMP ZPGWRK
27B9:D0 08 198 BNE TXC2 ; IS NOT
27BB:AD B5 2A 199 LDA EFTABA+1
27BE:C5 41 200 CMP ZPGWRK+1
27C0:F0 01 201 BEQ TXC2 ; IS
27C2:CA 202 TXC1 DEX ; IS NOT
27C3:60 203 TXC2 RTS ; DONE ; /sarcasm Thanks, Caption Obvious
204 PAGE
205 ;
206 ; TSTFUC - TEST FILE USE CODE FOR PGM
207 ;
208 TSTFUC EQU *
27C4:4D C2 35 209 EOR CCBFUC
27C7:F0 0A 210 BEQ TFUCR ; Forces TFUCR to waste 1 byte, should be BEQ TXC2
27C9:29 7F 211 AND #$7F ; magic number
27CB:F0 06 212 BEQ TFUCR ; Forces TFUCR to waste 1 byte, should be BEQ TXC2
27CD:20 EA 22 213 JSR ECLOSE ; GO CLOSE THE SOB
27D0:4C D0 26 214 JMP ERNU1
27D3:60 215 TFUCR RTS ; wastes 1 byte due to Lines #210 and #212
001 PAGE
002 ;
003 ; BLDFTB - BUILD FILE TABLES
004 ; TABLE MAP: ; $9600 = Array of File Tables
005 ; HIMEM,SOP ; $9D00 = SOP = Start of Program
006 ; SBUFF N (256)
007 ; DBUFF N (256)
008 ; FTB N (FCBLEN) ; FVCBUFS, Line #186
009 ; HEADER N (38) ; See Header Map below
010 ; .
011 ; .
012 ; SBUFF 1
013 ; DBUFF 1
014 ; FTB 1
015 ; HEADER 1
016 ; THIS PROGRAM
017 ;
018 ; HEADER MAP:
019 ; FILENAME (30)
020 ; FTB PTR (2)
021 ; DBUF PTR (2)
022 ; SBUF PTR (2)
023 ; LINK (2)
024 ;
025 BLDFTB EQU *
27D4:38 026 SEC
27D5:AD 00 1D 027 LDA FTAB ; START OF FTAB AREA ;
27D8:85 40 028 STA ZPGWRK ; IS 1ST FTB PTR ; $1D00: ptr $1CD3
27DA:AD 01 1D 029 LDA FTAB+1 ; HEADER
27DD:85 41 030 STA ZPGWRK+1
27DF:AD 57 2A 031 LDA CNFTBS ; MOVE NO FTABS ; DFNFTS default 3 buffers, INITD
27E2:8D 63 2A 032 STA TEMP1A ; TO TEMP ; fdosent, 60
033 ;
27E5:A0 00 034 BFT1 LDY #0 ; [.. wastes 2 bytes, should JSR ZEROFILE
27E7:98 035 TYA ; ...
27E8:91 40 036 STA (ZPGWRK),Y ; 1ST CHAR FN=0 ; ..] Init [00] $9CD3: 00
27EA:A0 1E 037 LDY #30 ; INC Y TO FCB PTR ; [[FTAB] + offset $1E] = $1CF1 magic number MAX_FILENAME_LEN
27EC:38 038 SEC
27ED:A5 40 039 LDA ZPGWRK ; END OF PTR HEADER
27EF:E9 2D 040 SBC #FCBLEN ; MINUS FTAB LENGTH
27F1:91 40 041 STA (ZPGWRK),Y ; IS START OF FTB ; Init [1E] $9CD3 = $9CF1: $9CA6 buf #1 ptr
27F3:48 042 PHA ; SAVE LOW ADR BYTE
27F4:A5 41 043 LDA ZPGWKR+1
27F6:E9 00 044 SBC #0
27F8:C8 045 INY
27F9:91 40 046 STA (ZPGWKR),Y ; [1F] = page
27FB:AA 047 TAX
27FC:CA 048 DEX ; FTB ADR - 256
27FD:68 049 PLA ; IS ADR DIR BUFF
27FE:48 050 PHA
27FF:C8 051 INY
2800:91 40 052 STA (ZPGWRK),Y ; SET DIR BUF PTR ; === T1S7 === [20] $9CD3 = $9BF3: $9BA6 buf #2 ptr
2802:8A 053 TXA
2803:C8 054 INY ; === Page 5 ===
2804:91 40 055 STA (ZPGWRK),Y ; [21] = page
2806:AA 056 TAX
2807:CA 057 DEX ; DIR BUFF - 256
2808:68 058 PLA ; IS SBUFF ADR
2809:48 059 PHA
280A:C8 060 INY
280B:91 40 061 STA (ZPGWRK),Y ; [22] $9CD3 = $9CF5: $9AA6
280D:C8 062 INY
280E:8A 063 TXA
280F:91 40 064 STA (ZPGWRK),Y
065 ;
2811:CE 63 2A 066 DEC TEMP1A ; DECREMENT TABLE INDEX ; Init all buffers?
2814:F0 17 067 BEQ BFT2 ; COUNT AND BR IF DONE ; v
2816:AA 068 TAX
2817:68 069 PLA
2818:38 070 SEC
2819:E9 26 071 SBC #38 ; SBUFF ADR - 38 ; magic number HEADER_SIZE
281B:C8 072 INY
281C:91 40 073 STA (ZPGWRK),Y ; IF ADR OF NEXT TAB ; [24] $9CD3 = $9CF7: $9A80
281E:48 074 PHA ; WHICH GOES INTO
281F:8A 075 TXA ; LINK
2820:E9 00 076 SBC #0
2822:C8 077 INY
2823:91 40 078 STA (ZPGWRK),Y
2825:85 41 079 STA ZPGWRK+1 ; AND INTO ZPGWRK
2827:68 080 PLA ; FOR NEXT ENTRY
2828:85 40 081 STA ZPGWRK ; BUILD
282A:4C E5 27 082 JMP BFT1 ; ^ BFT1 @ $A7E4 wastes 1 byte, A = addr lo: $80
083 ;
084 BFT2 EQU *
282D:48 085 PHA
282E:A9 00 086 LDA #0 ; SET LAST LINK
2830:C8 087 INY ; TO ZERO
2831:91 40 088 STA (ZPGWRK),Y
2833:C8 089 INY
2834:91 40 090 STA (ZPGWRK),Y
091 ;
2836:AD B6 2A 092 LDA ASIBSW ; IF IB THEN GO ; Integer Basic
2839:F0 0B 093 BEQ BFTIB
094 ;
283B:68 095 PLA
283C:85 74 096 STA ASHM1+1
283E:85 70 097 STA ASHM2+1
2840:68 098 PLA
2841:85 73 099 STA ASHM1
2843:85 6F 100 STA ASHM2
2845:60 101 RTS
102 ;
103 BFTIB EQU *
2846:68 104 PLA ; SET IB
2847:85 4D 105 STA IBHMEM+1 ; UPPER MEM LIMITS
2849:85 CB 106 STA IBSOP+1
284B:68 107 PLA
284C:85 4C 108 STA IBHMEM
284E:85 CA 109 STA IBSOP
2850:60 110 RTS
111 PAGE
112 ;
113 ; MVISW - MOVE INPUT SWITCH
114 ;
115 MVCSW EQU *
2851:A5 39 116 LDA INSW+1
2853:CD 03 1D 117 CMP CINA+1 ; === Page 6 ===
2856:F0 12 118 BEQ MVOSW
2858:8D 56 2A 119 STA SVINS+1
285B:A5 38 120 LDA INSW ; SAVE CHAR IN SWITCH
285D:8D 55 2A 121 STA SVINS
122 ;
2860:AD 02 1D 123 LDA CINA ; SET DFB CHAR IN ADR
2863:85 38 124 STA INSW
2865:AD 03 1D 125 LDA CINA+1
2868:85 39 126 STA INSW+1
127 ;
128 ;
129 ; MVOSW - MOVE OUTPUT SWITCH
130 ;
131 MVOSW EQU *
286A:A5 37 132 LDA OUTSW+1
286C:CD 05 1D 133 CMP COUTA+1
286F:F0 12 134 BEQ MVSRTN
2871:8D 54 2A 135 STA SVOUTS+1
2874:A5 36 136 LDA OUTSW ; SAVE CHAR OUT SWITCH
2876:8D 53 2A 137 STA SVOUTS
138 ;
2879:AD 04 1D 139 LDA COUTA ; SET DFB CHAR OUT ADR
287C:85 36 140 STA OUTSW
287E:AD 05 1D 141 LDA COUTA+1
2881:85 37 142 STA OUTSW+1
143 MVSRTN EQU *
2883:60 144 RTS
001 PAGE
002 ; ; Smart Operating System design separates
003 ; COMMAND NAME TABLE ; * Kernel
004 ; ; * Shell (Command Interpretor)
005 EC1 EQU * ; This gives each program the maximum amount of run-time memory
006 CMDNTB EQU * ; Alas, DOS is not that smart
2884:49 4E 49 D4 007 DCI "INIT" ; HNTODAOS: #1 Why is INIT listed first??? CATALOG is used far more then INIT
2888:4C 4F 41 C4 008 DCI "LOAD" ; Either sort these by:
288C:53 41 56 C5 009 DCI "SAVE" ; a) frequency of use, (best)
2890:52 55 CE 010 DCI "RUN" ; b) alphabetical (better)
2893:43 48 41 49 011 DCI "CHAIN" ; i.e. "Power Users" are more likely to use BRUN, BLOAD, BSAVE before they use DELETE
2897:CE
2898:44 45 4C 45 012 DCI "DELETE"
289C:54 C5
289E:4C 4F 43 CB 013 DCI "LOCK"
28A2:55 4E 4C 4F 014 DCI "UNLOCK"
28A6:43 CB
28A8:43 4C 4F 53 015 DCI "CLOSE"
28AC:C5
28AD:52 45 41 C4 016 DCI "READ"
28B1:45 58 45 C3 017 DCI "EXEC" ; inconsistent abbreviation: EXECUTE
28B5:57 52 49 54 018 DCI "WRITE"
28B9:C5
28BA:50 4F 53 49 019 DCI "POSITION"
28BE:54 49 4F CE
28C2:4F 50 45 CE 020 DCI "OPEN" ; Calls EOPEN
28C6:41 50 50 45 021 DCI "APPEND"
28CA:4E C4
28CC:52 45 4E 41 022 DCI "RENAME"
28D0:4D C5
28D2:43 41 54 41 023 DCI "CATALOG" ; HNTODAOS: #2 Let's slow users down forcing them type 7 characters
28D6:4C 4F C7 ; Which has a higher error rate of typos?
28D9:4D 4F CE 024 DCI "MON" ; easier to type 3 characters CAT or DIR or 7 character CATALOG ?
28DC:4E 4F 4D 4F 025 DCI "NOMON" ; /sarcasm Oh I see, we abbreviate the uncomon MONITOR but not the common CATALOG
28E0:CE
28E1:50 52 A3 026 DCI "PR#"
28E4:49 4E A3 027 DCI "IN#"
28E7:4D 41 58 46 028 DCI "MAXFILES"
28EB:49 4C 45 D3
28EF:46 D0 029 DCI "FP"
28F1:49 4E D4 030 DCI "INT"
28F4:42 53 41 56 031 DCI "BSAVE"
28F8:C5
28F9:42 4C 4F 41 032 DCI "BLOAD"
28FD:C4
28FE:42 52 55 CE 033 DCI "BRUN" ; === T1S8 ===
2902:56 45 52 49 034 DCI "VERIFY"
2906:46 D9
2908:00 035 DFB 0 ; end sentinel, see TODO
036 PAGE
037 ; ; *sigh* Typical crap names; bitmask flags should be prefixed with common name:
038 ; COMMAND SYNTAX OP EQUATES FOR SYNTAX BYTE ONE ; P1_ (better)
039 ; ; PARAM1_ (best, but will concede a short name is extremely convenient)
;
;(better)
040 NPB EQU $80 ; NO PARMS OK, COMMAND GOES TO BASIC ; P1_BAS The first sign of an amateur programmer:
041 NPE EQU $40 ; NO PARMS OK, COMMAND TO EXECUTION RTN ; P1_EXC Poor variable names
;
; Having 2 variable names differ by only 1 character,
;
; such as NPE, NPB,
; or worse NUM1, NUM2
;
; is a recipe for disaster.
; "Silient" errors (uncaught typos) are a debugging nightmare.
; Using unique names lets us minimize this error.
042 FN1 EQU $20 ; FILE NAME1 REGD ; P1_SRC
043 FN2 EQU $10 ; FILE NAME2 REQD : P1_DST
044 NUM1 EQU $08 ; NUMERIC 0-7 REGD ; P1_SLT -- WTF is the range of NUM 1 ??? Slot tells us 3-bit
045 NUM2 EQU $04 ; NUMERIC 1-10 REQD ; P1_DEC -- WTF is the range of NUM 2 ??? Decimal tells us 8-bit
046 RNONLY EQU $02 ; RUN TIME ONLY FLAG. ; P1_RUN
047 CREFLG EQU $01 ; FLAG TO INDICATE CMDS THAT MAY ; P1_CRE -- FLaG tells us nothing, ALL of these are flags!
048 ; ; Q. Why we would encode the type of paramater such as 1st or 2nd in the name?
049 ; COMMAND SYNTAX OP EQUATES FOR SYNTAX BYTE TWO ; A. It helps us to visually catch typos:
050 ; ; LDA PARAM2
051 V EQU $40 ; VOLUME ALLOWED ; CMP PARAM1_CREATE ; ↠param 2 doesnâ€t match param 1 above
052 D EQU $20 ; DRIVE ALLOWED ; === Page 22 ===
053 S EQU $10 ; SLOT ALLOWED
054 L EQU $08 ; LENGTH ALLOWED
055 R EQU $04 ; RECORD NUMBER ALLOWED
056 B EQU $02 ; BYTE NUMBER ALLOWED
057 ADR EQU $01 ; ADDRESS ; crappy asm tools reserve A for implicit 6502 Accumulator, e.g. LSR A
058 CIO EQU $80 ; C,I, OR O ALLOWED ; CIO = FLAG_CIO = $80 = minus, See CIO, CMDSCAN, Line #204, and OPTAB2
059 ;
060 ; COMMAND SYNTAX TABLE
061 ; EACH COMMAND HAS TWO BYTE ENTRY
062 ;
063 CMDSTB EQU * ; This is another complete clusterfrak of bad formatting
;
; The second sign of an amateur programmer:
; One who doesn't understand the importance of whitespace. (Horizontal and Vertical)
;
; 1. Horizontal alignment improves readability 1000%
; 2. List the common cases, such as FN1, and V+D+S, first
;
; Notice how using a 2D grid it becomes trivial to check for typo's:
;
; FN1 +CREFLAG, V+D+S ; INIT
; FN1+NPB , V+D+S ; LOAD
; FN1+NPB +CREFLAG, V+D+S ; SAVE
; FN1+NPB , V+D+S ; RUN
; FN1 , V+D+S ; CHAIN
; FN1 , V+D+S ; DELETE
; FN1 , V+D+S ; LOCK
; FN1 , V+D+S ; UNLOCK
; FN1 +NPE , V+D+S ; CLOSE
; FN1 +RNONLY , B+R ; READ
; FN1 , V+D+S +R ; EXEC
; FN1 +RNONLY , B+R ; WRITE
; FN1 +RNONLY , R ; POSITION
; FN1 +RNONLY+CREFLAG, V+D+S +L ; OPEN
; FN1 +RNONLY , V+D+S ; APPEND
; FN1+FN2 , V+D+S ; RENAME
; NPE , V+D+S ; CATALOG
; NPE , CIO ; MONITOR
; NPE , CIO ; NO MONITOR
; NUM1 , 0 ; PR#
; NUM1 , 0 ; IN#
; NUM2 , 0 ; MAXFILES
; NPE , V+D+S ; APPLESOFT
; NPE , 0 ; INT
; FN1 +CREFLAG, V+D+S +L+ADR ; BSAVE
; FN1 , V+D+S +ADR ; BLOAD
; FN1 , V+D+S +ADR ; BRUN
; FN1 , V+D+S ; VERIFY
2909:21 70 064 DFB FN1+CREFLG,V+D+S ; INIT
290B:A0 70 065 DFB NPB+FN1,V+D+S ; LOAD
290D:A1 70 066 DFB NPB+FN1+CREFLG,V+D+S ; SAVE
290F:A0 70 067 DFB NPB+FN1,V+D+S ; RUN
2911:20 70 068 DFB FN1,V+D+S ; CHAIN
2913:20 70 069 DFB FN1,V+D+S ; DELETE
2915:20 70 070 DFB FN1,V+D+S ; LOCK
2917:20 70 071 DFB FN1,V+D+S ; UNLOCK
2919:60 00 072 DFB NPE+FN1,0 ; CLOSE
291B:22 06 073 DFB FN1+RNONLY,B+R ; READ
291D:20 74 074 DFB FN1,R+V+D+S ; EXEC
291F:22 06 075 DFB FN1+RNONLY,B+R ; WRITE
2921:22 04 076 DFB FN1+RNONLY,R ; POSITION
2923:23 78 077 DFB FN1+RNONLY+CREFLG,L+V+D+S ; OPEN
2925:22 70 078 DFB FN1+RNONLY,V+D+S ; APPEND
2927:30 70 079 DFB FN1+FN2,V+D+S ; RENAME
2929:40 70 080 DFB NPE,V+D+S ; CATALOG
292B:40 80 081 DFB NPE,CIO ; MONITOR
292D:40 80 082 DFB NPE,CIO ; NO MONITOR
292F:08 00 083 DFB NUM1,0 ; PR#
2931:08 00 084 DFB NUM1,0 ; IN#
2933:04 00 085 DFB NUM2,0 ; MAXFILES
2935:40 70 086 DFB NPE,V+D+S ; APPLESOFT
2937:40 00 087 DFB NPE,0 ; INT
2939:21 79 088 DFB FN1+CREFLG,V+D+S+ADR+L ; BSAVE
293B:20 71 089 DFB FN1,V+D+S+ADR ; BLOAD
293D:20 71 090 DFB FN1,V+D+S+ADR ; BRUN
293F:20 70 091 DFB FN1,V+D+S ; VERIFY
092 PAGE
093 ;
094 ; OPTAB - OPTIONAL PARMS SYNTAX TABLES
095 ;
096 OPTAB1 EQU * ; Problem: Keeping 2 tables in sync can lead to subtle bugs.
; Solution: It would be better to interleave OPTAB1 and OPTAB2
; to prevent synchronization mistakes:
; MSB ON
2941:D6 C4 D3 CC 097 DFB 'V'+$80,'D'+$80,'S'+$80,'L'+$80' ; DFB 'V', V ; /sarcasm Apparently MSB ON was broken
2945:D2 C2 C1 C3 098 DFB 'R'+$80,'B'+$80,'A'+$80,'C'+$80' ; DFB 'D', D
2949:C9 CF 099 DFB 'I'+$80,'O'+$80' ; DFB 'S', S ; What's the point of compacting the lines???
100 OPT1L EQU *-OPTAB1 ; DFB 'L', L ; You write code for HUMANS not computers.
101 MI EQU $20 ; DFB 'R', R ; TODO does MI alias FN1? See DRTNI
102 MO EQU $10 ; DFB 'B', B ; TODO does MO alias FN2? See DRTNO
103 OPTAB2 EQU * ; DFB 'A', ADR
294B:40 20 10 08 104 DFB V,D,S,L ; DFB 'C', CIO+MC ; MC was defined in FDOSENT, MC
294F:04 02 01 C0 105 DFB R,B,ADR,CIO+MC ; DFB 'I', CIO+MI ; CIO = FLAG_CIO = $80 = minus
2953:A0 90 106 DFB CIO+MI,CIO+MO ; DFB 'O', CIO+MO ; See CIO, CMDSCAN, Line #204, and OPTAB2
107 OPTAB3 EQU * ; /sarcasm Yay for more crappy table formatting and naming
; [Min, Max]
; OptValMin DW 0 ; Volume
; OptValMax DW 254
; DW 1, 2 ; Drive
; DW 1, 7 ; Slot
; DW 1, 32767 ; Length
; DW 0, 32767 ; Record Number
; DW 0, 32767 ; Record byte number
; DW 0, $FFFF ; Address
2955:00 00 108 DW 0 ; [0]
2957:FE 00 109 DW 254 ; VOL RANGE
2959:01 00 110 DW 1 ; [1]
295B:02 00 111 DW 2 ; DRIVE RANGE
295D:01 00 112 DW 1 ; [2]
295F:07 00 113 DW 7 ; SLOT RANGE
2961:01 00 114 DW 1 ; [3] BSAVE MEM.48K,A$0,L$C000 won't work without patching DOS
2963:FF 7F 115 DW 32767 ; LENGTH RANGE ; === Page 23 === A963:FF BF to save > 32KB (48KB)
2965:00 00 116 DW 0 ; [4]
2967:FF 7F 117 DW 32767 ; REC NO RANGE
2969:00 00 118 DW 0 ; [5]
296B:FF 7F 119 DW 32767 ; REC BYTE NO RANGE
296D:00 00 120 DW 0 ; [6]
296F:FF FF 121 DW $FFFF ; ADDRESS RANGE
122 PAGE
123 ;
124 ; ERROR MESSAGE TABLES
125 ;
126 EMSG EQU *
2971:0D 07 8D 127 DFB $0D, $07, $8D ; magic number CR, BELL, CR + #$80
128 EM1 EQU *-EMSG
2974:4C 41 4E 47 129 DCI "LANGUAGE NOT AVAILABLE"
2978:55 41 47 45
297C:20 4E 4F 54
2980:20 41 56 41
2984:49 4C 41 42 130 EM2 EQU *-EMSG ; unnecessary duplicate
2988:4C C5 131 EM3 EQU *-EMSG
298A:52 41 4E 47 132 DCI "RANGE ERROR"
298E:45 20 45 52
2992:52 4F D2 133 EM4 EQU *-EMSG
2995:57 52 49 54 134 DCI "WRITE PROTECTED"
2999:45 20 50 52
299D:4F 54 45 43
29A1:54 45 C4 135 EM5 EQU *-EMSG
29A4:45 4E 44 20 136 DCI "END OF DATA"
29A8:4F 46 20 44
29AC:41 54 C1 137 EM6 EQU *-EMSG
29AF:46 49 4C 45 138 DCI "FILE NOT FOUND"
29B3:20 4E 4F 54 139 EM7 EQU *-EMSG
29B7:20 46 4F 55
29BB:4E C4
29BD:56 4F 4C 55 140 DCI "VOLUME MISMATCH"
29C1:4D 45 20 4D
29C5:49 53 4D 41
29C9:54 43 C8 141 EM8 EQU *-EMSG
29CC:49 2F 4F 20 142 DCI "I/O ERROR"
29D0:45 52 52 4F 143 EM9 EQU *-EMSG
29D4:D2
29D5:44 49 53 4B 144 DCI "DISK FULL"
29D9:20 46 55 4C 145 EM10 EQU *-EMSG
29DD:CC
29DE:46 49 4C 45 146 DCI "FILE LOCKED"
29E2:20 4C 4F 43 147 EM11 EQU *-EMSG
29E6:4B 45 C4
29E9:53 59 4E 54 148 DCI "SYNTAX ERROR"
29ED:41 58 20 45
29F1:52 52 4F D2 149 EM12 EQU *-EMSG
29F5:4E 4F 20 42 150 DCI "NO BUFFERS AVAILABLE"
29F9:55 46 46 45
29FD:52 53 20 41 ; === T1S9 ===
2A01:56 41 49 4C
2A05:41 42 4C C5 151 EM13 EQU *-EMSG
2A09:46 49 4C 45 152 DCI "FILE TYPE MISMATCH"
2A0D:20 54 59 50
2A11:45 20 4D 49
2A15:53 4D 41 54
2A19:43 C8 153 EM14 EQU *-EMSG
2A1B:50 52 4F 47 154 DCI "PROGRAM TOO LARGE"
2A1F:52 41 4D 20
2A23:54 4F 4F 20
2A27:4C 41 52 47 155 ;
2A2B:C5
156 EM15 EQU *-EMSG
2A2C:4E 4F 54 20 157 DCI "NOT DIRECT COMMAND"
2A30:44 49 52 45
2A34:43 54 20 43
2A38:4F 4D 4D 41
2A3C:4E C4
2A3E:8D 158 DFB $8D ; KEY_CR
159 EMDTB EQU * ; Array of (byte) Pointers to start of each error message
2A3F:00 03 19 19 160 DFB 0,EM1,EM2,EM3 ; wastes 1 byte for redundant error message EM3
2A43:24 33 3E 4C 161 DFB EM4,EM5,EM6,EM7
2A47:5B 64 6D 78 162 DFB EM8,EM9,EM10,EM11
2A4B:84 98 AA 163 DFB EM12,EM13,EM14
2A4E:BB 164 DFB EM15
001 PAGE
002 ;
003 ; MISC BUT REQD CELLS
004 ;
2A4F:00 00 005 CFTABA DDB 0 ; CURRENT FILE TABLE POINTER ; Why Big Endian??? DW is easier to tell this is 2 bytes then DFB DDB confusions
2A51:00 006 ISTATE DFB 0 ; INPUT STATE
2A52:00 007 OSTATE DFB 0 ; OUTPUT STATE
2A53:00 00 008 SVOUTS DDB 0 ; SAVED OUT SWITCH ; Why Big Endian???
2A55:00 00 009 SVINS DDB 0 ; SAVED IN SWITCH ; Why Big Endian???
2A57:00 010 CNFTBS DFB 0 ; CURRENT NO FILE TABLES ; "NO" == Number
2A58:03 011 DFNFB DFB 3 ; DEFAULT NO FILE TABLES ; Does anyone actually use > 2 ?
2A59:00 012 SVSTK DFB 0 ; SAVED STACK PTR
2A5A:00 013 SVX DFB 0 ; DSAVED X REG ; *spelling* Saved
2A5B:00 014 SVY DFB 0 : SAVED Y REG
2A5C:00 015 SVA DFB 0 ; SAVED ACU
2A5D:00 016 LBUFD DFB 0 ; LINE BUFF DISPL
2A5E:00 017 MONMOD DFB 0 ; MONITOR MODE BITS
018 MC EQU $40 ; MONITOR CMDS
019 *MI EQU $20 ; MONITOR INPUT ; Moved to CMDTBLS, MI
020 *MO EQU $10 ; MONITOR OUTPUT ; Moved to CMDTBLS, MO
2A5F:00 021 CMDNO DFB $00 ; COMMAND NO IS ZERO FOR BOOT UP
2A60:00 00 022 SVBL DFB 0,0 ; SaVed Binary Length $AA60:Length of last BLOAD, BSAVE
2A62:00 023 SVCMD DFB 0 ; SaVed CoMmanD
2A63:00 024 TEMP1A DFB 0
2A64:00 025 TEMP2A DFB 0
2A65:00 026 INOPTS DFB 0 ; INPUT OPTIONS
027 CUROPT EQU * ; CURRENT OPTIONS ; /sarcasm So we can type CUR ... but too lazy to type CUR_VOL, CUR_DRV, CUR_SLT??
; Note: OPTAB3 and CUROPT must be keep in size sync!
2A66:00 00 028 CV DW 0 ; VOLUME ; [0] normally wastes 1 byte; all numbers 16-bit, See CMDSCAN, Line #239
2A68:00 00 029 CD DW 0 ; DRIVE ; [2] normally wastes 1 byte, all numbers 16-bit, /sarcasm because DBINIT, OPNSUP
2A6A:00 00 030 CS DW 0 ; SLOT ; [4] normally wastes 1 byte, all numbers 16-bit, need 2 bytes bytes, right?
2A6C:01 00 031 CL DW 1 ; RECORD LENGTH ; [6]
2A6E:00 00 032 CR DW 0 ; RECORD NUMBER ; [8] Not Carriage Return, but Current Record. /sarcasm Obvious, right?
2A70:00 00 033 CB DW 0 ; RECORD BYTE ; [A]
2A72:00 00 034 CA DW 0 ; ADDRESS ; [C] $AA72:Address of last BLOAD
2A74:00 035 IMBITS DFB 0 ; TODO: Input Monitor Bits??? Used in EMON
036 MSB ON ; We can't DS 30-5,$A0 ???
2A75:C8 C5 CC CC 037 FNAME1 ASC "HELLO " ; FILENAME 1"
2A79:CF A0 A0 A0
2A7D:A0 A0 A0 A0
2A81:A0 A0 A0 A0
2A85:A0 A0 A0 A0
2A89:A0 A0 A0 A0
2A8D:A0 A0 A0 A0
2A91:A0 A0
038 MSB OFF
2A93:A0 A0 A0 A0 039 FNAME2 DS 30,$A0 ;FILENAME 2 ; Too lazy to leave MSB ON, and ASC " " x30 ??
2A97:A0 A0 A0 A0
2A9B:A0 A0 A0 A0
2A9F:A0 A0 A0 A0
2AA3:A0 A0 A0 A0
2AA7:A0 A0 A0 A0
2AAB:A0 A0 A0 A0
2AAF:A0 A0
2AB1:03 040 DFNFTS DFB 3 ; DEFAULT FILE TABLES = 3 ; INITD copies to CNFTBS
2AB2:84 041 CCHAR DFB $84 ; CONTROL CHAR ; Control-D actives DOS for next ASCII command magic number KEY_CTRL_D
2AB3:00 042 ESTATE DFB 0 ; EXECUTE STATE
2AB4:00 00 043 EFTABA DFB 0,0 ; EXECUTE FILE TABLE POINTER
2AB6:00 044 ASIBSW DFB 0 ; APPLESOFT, IB SWITCH ; 00=Integer, 40=Applesoft ROM, 80=Applesoft RAM
2AB7:00 045 RSTATE DFB 0 ; FOR APPLESOFT RUN PROGRAM AFTER RELOC
2AB8:C1 D0 D0 CC 046 FASB DFB $C1,$D0,$D0,$CC ;'APPLESOFT' WITH BIT 7 HIGH; /sarcasm If only we had MSB ON and ASC directives
2ABC:C5 D3 CF C6 047 DFB $C5,$D3,$CF,$C6 ; Binary to run if Integer active and user types FP
2AC0:D4 048 DFB $D4
049 FASBL EQU *-FASB ; Filename Length of Applesoft binary, copied in EAS0
050 PAGE
051 ;
052 ; DOS ADR TABLES (RELOCATED)
053 ; ; === Page 61
054 SAT2 EQU * ; Start Address Table
; Gee, we couldn't have put this at $1D00 to save 4 bytes in ADRTAB ?!
2AC1:E8 37 055 AIOB DW IOB ; 5-ADR IOB ; Also see BAIOB; What happened to 1 .. 4 ??? At RVT, WVT ?
2AC3:BB 33 056 AVTOC DW VTOC ; 6-ADR VTOC
2AC5:BB 34 057 AVOLDR DW VOLDIR ; 7-ADR VOLDIR
2AC7:00 40 058 AEND DW ENDOFDOS ;END OF DOS ; See REPAGE
059 ; ; File Manager
2AC9:7E 33 060 CMDVT DW GOODIO-1 ; 0-NULL ; [0] wastes 2 bytes → $B37E
2ACB:21 2B 061 DW FOPEN-1 ; 1-OPEN FILE ; [1]
2ACD:05 2C 062 DW FCLOSE-1 ; 2-CLOSE FILE ; [2]
2ACF:57 2C 063 DW FREAD-1 ; 3-READ DATA ; [3]
2AD1:6F 2C 064 DW FWRITE-1 ; 4-WRITE DATA ; [4]
2AD3:2A 2D 065 DW FDEL-1 ; 5-DELETE FILE ; [5]
2AD5:97 2D 066 DW RDIR-1 ; 6-READ DIRECTORY ; [6] /sarcasm Yay for consistent naming: FDIR
2AD7:EE 2C 067 DW FLOCK-1 ; 7-LOCK A FILE ; [7]
2AD9:F5 2C 068 DW FUNLCK-1 ; 8-UNLOCK A FILE ; [8]
2ADB:39 2C 069 DW FRNME-1 ; 9-RENAME ; [9]
2ADD:11 2D 070 DW FPOSTN-1 ; 10-POSITION A FILE ; [A]
2ADF:8D 2E 071 DW FFMT-1 ; FORMAT ; [B]
2AE1:17 2D 072 DW FVAR-1 ; VARIFY ; [C] *spelling* VERIFY
2AE3:7E 33 073 DW GOODIO-1 ; 11-SPARE ; [D] wastes 2 bytes due to fencepost error
; Uh, calling 13 "eleven" doesn't make it so.
074 ; ; See DOSENT: CCBREQ (FileManager.command) >= CRQMAX
; AAE3:00 00 ; (was 7E B3) to prove this is never called
; 0300:20 DC 03 JSR CCBLDR ; $9E5D GetCCBAdr ; $9D0E: dw $B5BB = CCB
; 0303:84 FD STY $FD
; 0305:85 FE STA $FE
; 0307:A9 0D LDA #$D ; Command = CRQMAX
; 0309:A0 00 LDY #0 ; FileManager.Command = Command
; 030B:91 FD STA ($FD),Y
; 030D:4C D6 03 JMP USERENT ; $AAFD FileManager
075 RVT EQU * ; USERENT calls FREAD
2AE5:7E 33 076 DW GOODIO-1 ; [0] wastes 2 bytes; See CRMNUL
2AE7:89 2C 077 DW RNXBYT-1 ; 1-RD NEXT BYTE ; [1]
2AE9:95 2C 078 DW NXBLK-1 ; 1-RD NEXT BLOCK ; [2] *sigh* copy-paste
2AEB:86 2C 079 DW RSPBYT-1 ; 2-RD SPECIFIC BYTE ; [3]
2AED:92 2C 080 DW RSPBLK-1 ; 3 - RD SPECIFIC BLOCK ; [4]
2AEF:7E 33 081 DW GOODIO-1 ; 4 - SPARE ; [5] wastes 2 bytes off-by-1 allocation, see CRMMAX, FREAD
082 ;
083 WVT EQU *
2AF1:7E 33 084 DW GOODIO-1 ; [0] wastes 2 bytes; Stop, please stop this stupidity
2AF3:BD 2C 085 DW WNXBYT-1 ; 1-WR NEXT BYTE ; [1]
2AF5:C9 2C 086 DW WNXBLK-1 ; WR NEXT BLOCK ; [2] *sigh* copy-paste
2AF7:BA 2C 087 DW WSPBYT-1 ; 2-WR SPECIFIC BYTE ; [3]
2AF9:C6 2C 088 DW WSPBLK-1 ; 3-WR SPECIFIC BLOCK ; [4]
2AFB:7E 33 089 DW GOODIO-1 ; 4 - SPARE ; [5] wastes 2 bytes
090 EAT2 EQU *
091 PAGE
092 ;
093 ; USERENT - DOS EXTERNAL ENTRY POINT (USER ENTRY)
094 ; ENTRY PARM:
095 ; A= HIGH ADDRESS OF CCB
096 ; Y= LOW ADDRESS OF CCB
097 ; X= 0 IF CREATE DESIRED
098 ; X> 0 IF CREATE NOT DESIRED
099 ; EXIT PARM:
100 ; CARRY CLEAR = OPERATION OK
101 ; CARRY SET = ERROR
102 ;
103 SC2 EQU * ; See: [1] CDETAB
2AFD:E0 00 104 USERENT CPX #0 ;IF X=0 THEN FILE CREATED IF NOT
2AFF:F0 02 105 BEQ USRCR ; FOUND. NOTE: FILE NOT FOUND ERROR STILL IS RETURNED ; === T1SA ===
2B01:A2 02 106 LDX #2 ;INDICATE NO CREATE ALLOWED
2B03:8E 5F 2A 107 USRCR STX CMDNO ;SET UP FOR CREATE CAPIBILITY ; *spelling* CAPABILITY
108 DOSENT EQU * ; /sarcasm Is that like our potential to be cap'd or knock'd off :-)
2B06:BA 109 TSX
2B07:8E 9B 33 110 STX ENTSTK
2B0A:20 6A 2E 111 JSR CLCFCB ; GO CALCULATE FCB
2B0D:AD BB 35 112 LDA CCBREQ ; GET REQUEST
2B10:C9 0D 113 CMP #CRQMAX ; TTEST REQ RANGE ; /sarcasm South Park: Jimmy
2B12:B0 0B 114 BCS ERR2 ; BR OUT OF RANGE ; === Page 62 === A-a-n-d you still have an of-of-of-off-by-one bug allocation in array CMDVT!
2B14:0A 115 ASL A ; REQ CODE *2
2B15:AA 116 TAX
2B16:BD CA 2A 117 LDA CMDVT+1,X ; PUSH ADR ONTO STACK
2B19:48 118 PHA
2B1A:BD C9 2A 119 LDA CMDVT,X
2B1D:48 120 PHA
2B1E:60 121 DENRTS RTS
2B1F:4C 63 33 122 ERR2 JMP ERROR2
001 PAGE
002 ;
003 ; FOPEN - OPEN A FILE
004 ;
005 FOPEN EQU *
2B22:20 28 2B 006 JSR DOPEN ; ↓
2B25:4C 7F 33 007 JMP GOODIO
008 ;
009 DOPEN EQU *
010 ;
2B28:20 DC 2B 011 JSR DCBSUP
012 ;
013 ;
2B2B:A9 01 014 LDA #1
2B2D:8D E3 35 015 STA DCBSDL+1
2B30:AE BE 35 016 LDX CCBRLN+1 ; MOVE RECORD LENGTH
2B33:AD BD 35 017 LDA CCBRLN
2B36:D0 05 018 BNE F01
2B38:E0 00 019 CPX #0
2B3A:D0 01 020 BNE F02
2B3C:E8 021 INX ; SET RL=256
2B3D:8D E8 35 022 F02 STA DCBRCL
2B40:8E E9 35 023 STX DFBRCL+1
024 ;
2B43:20 C9 31 025 JSR FNDFIL ; GO FIND FILE
2B46:90 5E 026 BCC F03 ; BR IF FOUND
027 ;
028 * CREATE FILE IF COMMAND IS SAVE, OPEN, BSAVE
029 ;
2B48:8E 9C 33 030 STX TEMP1 ; SAVE DIR. INDEX
2B4B:AE 5F 2A 031 LDX CMDNO ;TEST COMMAND FOR CREATE FLAG
2B4E:BD 09 29 032 LDA CMDSTB,X ; (BIT 0 MUST=1)
2B51:AE 9C 33 033 LDX TEMP1 ;RESTORE DIR INDEX
2B54:4A 034 LSR A ;SHIFT CREFLAG BIT TO CARRY
2B55:B0 0D 035 BCS F02B ;BRANCH ON VALID INSTR.
2B57:AD 51 2A 036 LDA ISTATE ;FIND OUT IF TRYING TO LOAD APPLESOFT
2B5A:C9 C0 037 CMP #$C0 ; magic number
2B5C:D0 03 038 BNE F02A ; NO GO
2B5E:4C 5F 33 039 JMP ERROR1 ; Which error message?? "LANGUAGE NOT AVAILABLE"
2B61:4C 73 33 040 F02A JMP ERROR6 ; PRINT "FILE NOT FOUND" MESSAGE.
2B64:A9 00 041 F02B LDA #0 ; 0001 Little Endian
2B66:9D E8 34 042 STA VDFILE+34,X ; magic number VDFILE + CAT_FILE_NUM_SEC+0 (See VDFILE)
2B69:A9 01 043 LDA #1
2B6B:9D E7 34 044 STA VDFILE+33,X ; magic number VDFILE + CAT_FILE_NUM_SEC+1
2B6E:8E 9C 33 045 STX TEMP1 ; SAVE VDIR INDEX ; Why?? wastes 2 bytes, Line #30 already saved
2B71:20 44 32 046 JSR GETSEC ; GO ALLOCATE SECTOR
2B74:AE 9C 33 047 LDX TEMP1
2B77:9D C7 34 048 STA VDFILE+1,X ; PUT SECTOR INTO VDIR ; magic number VDFILE + CAT_FILE_SECTOR
2B7A:8D D2 35 049 STA DCBFDS ; PUT SECTOR AS 1ST FILE DIR
2B7D:8D D4 35 050 STA DCBCDS ; PUT SECTOR AS CURRENT FILE DIR
051 ;
2B80:AD F1 35 052 LDA DCBATK ; GET ALLOCATED TRACK
2B83:9D C6 34 053 STA VDFILE,X ; PUT INTO VDIR ; === Page 78 === magic number VDFILE + CAT_FILE_TRACK
2B86:8D D1 35 054 STA DCBFDT ; AND AS 1ST FILE DIR ; More crappy variable names : dcbFdt
2B89:8D D3 35 055 STA DCBCDT ; AND AS CURRENT FILE DIR ; that differ by a single letter: dcbCdt
056;
2B8C:AD C2 35 057 LDA CCBFUC ; SET USE CODE
2B8F:9D C8 34 058 STA VDFILE+2,X ; INTO DIRECTORY ; magic number VDFILE + CAT_FILE_TYPE
059 ;
2B92:20 37 30 060 JSR WRVDIR ; GO WRITE VOL DIRECTORY
061 ;
2B95:20 0C 2F 062 JSR MVFCBD ; MOVE FILE DIR ADR TO ZP
2B98:20 D6 37 063 JSR CLRSEC ; GO CLEAR IT
2B9B:20 3A 2F 064 JSR WRFDGO ; GO WRITE FILE DIRECTORY
065 ; DONE CREATION
2B9E:AE 9C 33 066 LDX TEMP1 ; RE-GET INDEX ; Which index?? VDFILE offset
2BA1:A9 06 067 LDA #CREFNF
2BA3:8D C5 35 068 STA CREFNF
069 ;
070 F03 EQU *
2BA6:BD C6 34 071 LDA VDFILE,X ; MOVE FILE DIR TRACK ; magic number VDFILE + CAT_FILE_TRACK
2BA9:8D D1 35 072 STA DCBFDT
2BAC:BD C7 34 073 LDA VDFILE+1,X ; MOVE FILE DIR SECTOR ; magic number VDFILE + CAT_FILE_SECTOR
2BAF:8D D2 35 074 STA DCBFDS
2BB2:BD C8 34 075 LDA VDFILE+2,X ; 7OVE FILE USE CODE ; *spelling* Move; magic number VDFILE + CAT_FILE_TYPE
2BB5:8D C2 35 076 STA CCBFUC
2BB8:8D F6 35 077 STA DCBFUC
2BBB:BD E7 34 078 LDA VDFILE+33,X ; magic number VDFILE + CAT_FILE_NUM_SEC
2BBE:8D EE 35 079 STA DCBNSA
2BC1:BD E8 34 080 LDA VDFILE+34,X ; magic number VDFILE + CAT_FILE_NUM_SEC+1
2BC4:8D EF 35 081 STA DCBNSA+1
2BC7:8E D9 35 082 STX DCBVDI ;SAVE DIRECTORY INDEX
083 ;
2BCA:A9 FF 084 LDA #255 ; INDICATE NO SECTOR
2BCC:8D E0 35 085 STA DCBCMS ; IN MEMORY ; More crappy variable names : dcbCms
2BCF:8D E1 35 086 STA DCBCMS+1
2BD2:AD E2 33 087 LDA VTDMS ; MOVE MAX FD SECTS
2BD5:8D DA 35 088 STA DCBDMS ; TODCB ; that differ by a single letter: span class='code'>dcbDms
2BD8:18 089 CLC
2BD9:4C 5E 2F 090 JMP RDFDIR ; READ 1ST DIRECTORY RECORD ; Read inode
091 ;
092 ;
093 ;
094 ;
095 DCBSUP EQU *
2BDC:A9 00 096 LDA #0
2BDE:AA 097 TAX
2BDF:9D D1 35 098 F01 STA FCBDCB,X ; CLEAR DCB
2BE2:E8 099 INX
2BE3:E0 2D 100 CPX #DCBLEN ; Over-writes unused memory DCBSPR
2BE5:D0 F8 101 BNE F01
102 ;
2BE7:AD BF 35 103 LDA CCBVOL ; MOVE VOL
2BEA:49 FF 104 EOR #$FF ; INVERT VOL BITS ; Why??
2BEC:8D F9 35 105 STA DCBVOL
2BEF:AD C0 35 106 LDA CCBDRV ; MOVE DRIVE
2BF2:8D F8 35 107 STA DCBDRV
2BF5:AD C1 35 108 LDA CCBSLT ; GET USER SPEC SLOT
2BF8:0A 109 ASL A ; SLOT*16
2BF9:0A 110 ASL A
2BFA:0A 111 ASL A
2BFB:0A 112 ASL A
2BFC:AA 113 TAX
114 F01A EQU *
2BFD:8E F7 35 115 STX DCBSLT
; === Page 79 ===
; === T1SB ===
2C00:A9 11 116 LDA #17 ;[.. wastes 5 bytes; magic number FILESYSTEM_VTOC_CAT_TRACK = $11
2C02:8D FA 35 117 STA DCBVTN ; ..] due to unitialized DCBVTN DS 1 Because this can change???
2C05:60 118 RTS
119 PAGE
120 ;
121 ; FCLOSE - CLOSE A FILE
122 ;
123 FCLOSE EQU *
2C06:20 1D 2F 124 JSR WRSECT ; WRITE OPEN SECTOR
2C09:20 34 2F 125 JSR WRFDIR ; GO WRITE FILE DIRECTORY ; Asinine comments like this wouldn't even be needed with proper names
2C0C:20 C3 32 126 JSR FRETRK ; FREE UNUSED SECTORS ; JSR WR_FILE_DIR
2C0F:A9 02 127 LDA #IBCWTS
2C11:2D D5 35 128 AND DCBWRF
2C14:F0 21 129 BEQ FC2
130 ;
2C16:20 F7 2F 131 JSR RDVTOC
2C19:A9 00 132 LDA #0
2C1B:18 133 CLC
134 FC1 EQU *
2C1C:20 11 30 135 JSR RDVDIR ; READ VDIR ; TODO A = ???
2C1F:38 136 SEC
2C20:CE D8 35 137 DEC DCBVDR ; TODO Why DEC ? -- Sector offset set in FNDFIL
2C23:D0 F7 138 BNE FC1
2C25:AE D9 35 139 LDX DCBVDI ; Volume Directory Index: X = file entry offset in CATALOG sector
2C28:AD EE 35 140 LDA DCBNSA ; MOVE NO SECTORS ALLOCATED ; You keep using this word move, it doesn't mean what you think it means.
2C2B:9D E7 34 141 STA VDFILE+33,X ; magic number VDFILE + CAT_FILE_NUM_SEC
2C2E:AD EF 35 142 LDA DCBNSA+1
2C31:9D E8 34 143 STA VDFILE+34,X ; magic number VDFILE + CAT_FILE_NUM_SEC
2C34:20 37 30 144 JSR WRVDIR ; WRITE VOL DIR REC ; Should be common entry point; See "wastes 3 bytes" note below
145 ;
146 ;
147 FC2 EQU *
2C37:4C 7F 33 148 JMP GOODIO ; DONE
149 PAGE
150 ;
151 * FRNAME - RENAME A FILE
152 ;
153 FRNME EQU *
2C3A:20 28 2B 154 JSR DOPEN ; GO OPEN FILE
2C3D:AD F6 35 155 LDA DCBFUC ; GET USE CODE
2C40:30 2B 156 BMI ER10 ; BR IF LOCKED
2C42:AD BD 35 157 LDA CCBFN2 ; MOVE NEW FN
2C45:85 42 158 STA ZPGFCB ; MOVE PTR TO ZPG
2C47:AD BE 35 159 LDA CCBFN2+1
2C4A:85 43 160 STA ZPGFCB+1
2C4C:AE 9C 33 161 LDX TEMP1 ; GET VDIR INDEX ; TODO Does DOPEN set this?
2C4F:20 1C 32 162 JSR MVFN ; MOVE FILE NAME
2C52:20 37 30 163 JSR WRVDIR ; GO WRITE VDIR ; [.. wastes 3 bytes: Should be JMP FC2-3
2C55:4C 7F 33 164 JMP GOODIO ; DONE RENAME ; ..] and this JMP GOODIO can be removed entirely
165 PAGE
166 ;
167 * FREAD - READ A FILE
168 ;
169 FREAD EQU *
170 ;
2C58:AD BC 35 171 LDA CCBRQM ; GET REQ MOD
2C5B:C9 05 172 CMP #CRMMAX ; TEST LIMIT
2C5D:B0 0B 173 BCS ERR3A ; BR BAD
174 ;
; Current code uses: 32 bytes
; 11 bytes $2C5F..$2C69 FREAD
; 11 bytes $2C7C..$2C86 FWRITE
; 10 bytes $2189..$2192 ECMD
;
; New code uses: 31 bytes + reloc table entries
; 4 bytes (Setup code)
; 2C5F:A2 E6 LDX # ; lo byte of func table address
; 2C61:A0 2A LDY #>RVT ; hi byte of func table address
; ; ... intentional fall into CallFunc ...
; 14 bytes FREAD (Common code)
; 2C63:0A CallFunc ASL ; main entry point if A not SHL
; 2C64:86 48 SaveFunc STX IOBPL ; 2nd entry point if A is SHL
; 2C66:84 49 STY IOBPH ;
; 2C68:A8 TAY
; 2C69:B1 48 LDA (IOBPL),Y ; B9 FF FF LDA $FFFF,Y
; 2C6B:48 PHA
; 2C6C:88 DEY
; 2C6D:B1 48 LDA (IOBPL),Y
; 2C6F:48 PHA
; 2C74:60 RTS
;
; 6 bytes FWRITE
; 2C7C:A2 F1 LDX # ; lo byte of func table address
; 2C7E:A0 2A LDY #>WVT ; hi byte of func table address
; 2C80:90 DF BCC CallFunc
;
; 7 bytes ECMD
; 2189:A2 1E LDX #
; 218B:A0 1D LDY #>CMDETB
; 218D:4C 63 2C JMP SaveFunc
2C5F:0A 175 ASL A ; CODE*2 ;[.. Data*2 = Array of 16-bit Function Pointers
2C60:AA 176 TAX ; ..
2C61:BD E6 2A 177 LDA RVT+1,X ; GET READ ROUTINE ; ..
2C64:48 178 PHA ; .. old code
2C65:BD E5 2A 179 LDA RVT,X ; .. === Page 80 ===
2C68:48 180 PHA ; AND ; ..
2C69:60 181 RTS ; GO TO IT ; ..]
182 ;
2C6A:4C 67 33 183 ERR3A JMP ERROR3 ; What is → CREMRE: EM3 "RANGE ERROR"
2C6D:4C 7B 33 184 ER10 JMP ERRR10 ; error#? → CREFLK: EM10 "FILE LOCKED"
185 ; ; /sarcasm Really?! Have to abbreviate 'o' in ERROR10 ???
;
; Problem:
; FD2 has
; $2D34 BPL FD3
; $2D36 JMP ERROR10
;
; To remove the 3 byte jump & take advantage of existing
; code ER10 @ $2C6D JMP ERR10,
; we need to invert the branch to target ER10
;
; $2D34 BMI ER10
;
; But $2D36 - $2C6D = $C7 which is > $80 bytes away for BMI
; Can ER10 be safely moved closer to FD2?
;
; Solution:
; The first reference to ER10 is in FRNME @ $2C40
;
; $2C3D LDA DCBFUC
; $2C40 BMI ER10
;
; We need to keep ER10 within the 128 byte range of FRNME.
;
; The max branch address for FRNME is $2C42 + $80 = $2CC2
; The min branch address for FD2 is $2D36 - $80 = $2CB6
;
; Since the two 128-byte ranges overlap we can move ER10 !
; The perfect spot is @ $2CBB (just after EOFIN)
;
; This is a good example of where:
;
; maximing locality
;
; can open up new opportunities for optimizing.
186 * FWRITE - WRITE A FILE
187 ;
188 FWRITE EQU *
2C70:AD F6 35 189 LDA DCBFUC ; IS FILE LOCKED
2C73:30 F8 190 BMI ER10 ; BR IF LOCKED
2C75:AD BC 35 191 LDA CCBRQM ; GET REQ MOD
2C78:C9 05 192 CMP #CRMMAX ; IN RANGE ; Off by 1 bug
2C7A:B0 EE 193 BCS ERR3A ; BR IF NOT IN RANGE ;
194 ; ;
2C7C:0A 195 ASL A ;[.. Alternative:
2C7D:AA 196 TAX ; .. (See above)
2C7E:BD F2 2A 197 LDA WVT+1,X ; GET ROUTINE ADR ; ..
2C81:48 198 PHA ; .. LDX # ; lo byte of func table address
2C82:BD F1 2A 199 LDA WVT,X ; .. LDY #>WVT ; hi byte of func table address
2C85:48 200 PHA ; .. BCC CallFunc ↑ (always)
2C86:60 201 RTS ; ..]
202 PAGE
203 ;
204 * RSPBYT - READ A SPECIFIC BYTE
205 ;
206 RSPBYT EQU *
2C87:20 00 33 207 JSR LOCSEC ; GO GET REQD REL SECTOR
208 ;
209 * RNXBYT - READ NEXT BYTE
210 ;
2C8A:20 A8 2C 211 RNXBYT JSR GETBYT ; GO GET BYTE
2C8D:8D C3 35 212 STA CCBDAT ; PUT IN CCB
2C90:4C 7F 33 213 JMP GOODIO ; DONE
214 ;
215 * RSPBLK - READ A SPECIFIC BLOCK
216 ;
2C93:20 00 33 217 RSPBLCK JSR LOCSEC ; GO LOCATE REL SECTOR
218 ;
219 * RNXBLK - READ NEXT BLOCK
220 ;
221 RNXBLK EQU *
2C96:20 B5 31 222 JSR DTBLN ; GO DECR LEN (NOT RTN IF=0)
2C99:20 A8 2C 223 JSR GETBYT ; GO GET BYTE
2C9C:48 224 PHA
2C9D:20 A2 31 225 JSR MIBDA ; GO MOVE BLOCK ADR AND INCR
2CA0:A0 00 226 LDY #0
2CA2:68 227 PLA
2CA3:91 42 228 STA (ZPGFCB),Y ; SET DATA BYTE
2CA5:4C 96 2C 229 JMP RNXBLK ; GO FOR NEXT BYTE
230 ;
231 * GETBYT - GET A DATA BYTE
232 ;
233 GETBYT EQU *
2CA8:20 B6 30 234 JSR LOCNXB ; LOCATE NEXT BYTE
2CAB:B0 0B 235 BCS EOFIN ; BR IF EOF
2CAD:B1 42 236 LDA (ZPGFCB),Y ; GET DAT BYTE
2CAF:48 237 PHA ; SAVE IT ; INCBYT Should be common code for PB0 as well
2CB0:20 5B 31 238 JSR INCRRB ; INCR REC BYTE ; What is the difference between these two???
2CB3:20 94 31 239 JSR INCSCB ; INCR SEC BYTE ;
2CB6:68 240 PLA ; GET SAVED BYTE ; Stop treating the reader like an idiot with redundant comments
2CB7:60 241 RTS ; RETURN ; All this does is just add visual noise
242 ; ; === Page 81 ===
2CB8:4C 6F 33 243 EOFIN JMP ERROR5 ; GOTO EOF RTN ; CREEOF → EM5: "END OF DATA"
244 PAGE
245 ;
246 * WSPBYT - WRITE SPECIFIC BYTE
247 ;
248 WSPBYT EQU *
2CBB:20 00 33 249 JSR LOCSEC ; GO LOCATE SECTOR
250 ;
251 * WNXBYT - WRITE NEXT BYTE
252 ;
253 WNXBYT EQU *
2CBE:AD C3 35 254 LDA CCBDAT ; GET THE BYTE
2CC1:20 DA 2C 255 JSR PUTBYT ; GO WRITE BYTE
2CC4:4C 7F 33 256 JMP GOODIO ; DONE
257 ;
258 * WSPBLK - WRITE A SPECIFIC BLOCK
259 ;
260 WSPBLK EQU *
2CC7:20 00 33 261 JSR LOCSEC ; GO LOCATE SECTOR
262 ;
263 * WNXBLK - WRITE NEXT BLOCK
264 ;
265 WNXBLK EQU *
2CCA:20 A2 31 266 JSR MIBDA ; GO MOVE ADR TO ZPG AND DEC
2CCD:A0 00 267 LDY #0
2CCF:B1 42 268 LDA (ZPGFCB),Y ; GET DATA BYTE
2CD1:20 DA 2C 269 JSR PUTBYT ; GO PUT IT
2CD4:20 B5 31 270 JSR DTBLN ; GO DEC BLK LEN (NOT RTN IF = 0)
2CD7:4C CA 2C 271 JMP WNXBLK
272 ;
273 * PUTBYT - PUT OUT ONE BYTE
274 ;
275 PUTBYT EQU *
2CDA:48 276 PHA ; SAVE DATA BYTE
2CDB:20 B6 30 277 JSR LOCNXB ; GO LOCATE NEXT BYTE
278 ;
2CDE:68 279 PB0 PLA ; GET SAVED BYTE
2CDF:91 42 280 STA (ZPGFCB),Y ; PUT THE BYTE
2CE1:A9 40 281 LDA #$40 ; SET WRITE SECTOR REQD ; magic number WRITE_FLAG_SECTOR, See GNWSEC
2CE3:0D D5 35 282 ORA DCBWRF
2CE6:8D D5 35 283 STA DCBWRF
284 ;
2CE9:20 5B 31 285 JSR INCRRB ; INCR REL REC BYTE ;[.. wastes 3 bytes
2CEC:4C 94 31 286 JMP INCSCB ; INCR SECTOR BYTE ; ..] JMP INCBYT = (GETBYT+7) = Line #237
001 PAGE
002 ;
003 * FLOCK - LOCK A FILE
004 ;
2CEF:A9 80 005 FLOCK LDA #$80 ; REMEMBER LOCK ; magic number LOCK_MASK = $80
2CF1:8D 9E 33 006 STA TEMP3 ; [.. wastes 3 bytes, BNE line #12
2CF4:D0 05 007 BNE LCKGO ; ..] even better, change to DB $2C (BIT $abs) which causes to next instruction to be skipped → BIT $00A9
008 ;
009 * FUNLOCK - UNLOCK A FILE
010 ;
2CF6:A9 00 011 FUNLCK LDA #00 ; REMEMBER UNLOCK ; magic number
2CF8:8D 9E 33 012 STA TEMP3
013 ;
014 LCKGO EQU *
015 ;
2CFB:20 28 2B 016 JSR DOPEN ; GO OPEN FILE
2CFE:AE 9C 33 017 LDX TEMP1 ; === T1SC ===
2D01:BD C8 34 018 LDA VDFILE+2,X ; GET FILE USE CODE ; magic number*
2D04:29 7F 019 AND #$7F ; TURN OFF LOCK ; magic number ~LOCK_MASK
2D06:0D 9E 33 020 ORA TEMP3
2D09:9D C8 34 021 STA VDFILE+2,X
2D0C:20 37 30 022 JSR WRVDIR
2D0F:4C 7F 33 023 GOGOOD JMP GOODIO
024 ;
025 * FPOSTN - POSITION A FILE
2D12:20 00 33 026 FPOSTN JSR LOCSEC ; GO POSITION
2D15:4C 7F 33 027 JMP GOODIO ; DONE
028 ;
029 ;
030 * FVAR - VARIFY A FILE ; *spelling* VERIFY
031 ;
032 FVAR EQU *
2D18:20 28 2B 033 JSR DOPEN ; OPEN FILE
2D1B:20 B6 30 034 VAR1 JSR LOCNXB ; READ A SECTOR
2D1E:B0 EF 035 BCS GOGOOD ; BR IF EOF
2D20:EE E4 35 036 INC DCBCRS ; INCREMENT SECTOR
2D23:D0 F6 037 BNE VAR1 ; Can't save > 32KB, See OPTAB3 32767
2D25:EE E5 35 038 INC DCBCRS+1 ; Therfore Current Relative Sector can never overflow to zero
2D28:4C 1B 2D 039 JMP VAR1 ; READ THIS ONE ; wastes 1 bytes BNE VAR1
040 PAGE
041 ;
042 * FDEL - DELETE A FILE
043 ;
044 FDEL EQU *
2D2B:20 28 2B 045 JSR DOPEN ; GO OPEN FILE
046 ;
2D2E:AE 9C 33 047 FD2 LDX TEMP1 ; SAVED INDEX
2D31:BD C8 34 048 LDA VDFILE+2,X ; IS FILE LOCKED ; magic number VDFILE + CAT_FILE_TYPE
2D34:10 03 049 BPL FD3 ; Should be BMI ER10 (once ER10 is moved)
2D36:4C 7B 33 050 JMP ERROR10 ; wastes 3 bytes with JMP, See ER10 optimization above
051 ;
052 FD3 EQU *
2D39:AE 9C 33 053 LDX TEMP ; GET SAVED INDEX
; === Page 56 ===
2D3C:BD C6 34 054 LDA VDFILE,X ; GET DIR TRACK ; magic number VDFILE + CAT_FILE_TRACK
2D3F:8D D1 35 055 STA DCBFDT ; SET AS 1ST FD TRACK ; LC = last character
2D42:9D E6 34 056 STA VDFILE+32,X ; SAVE IN LC OF FN ; magic number VDFILE + CAT_FILE_NAME + MAX_FILENAME_LEN - 1
2D45:A9 FF 057 LDA #$FF ; DELETED FILE MARKER ; magic number FILE_TYPE_DELETED
2D47:9D C6 34 058 STA VDFILE,X ; CLEAR ENTRY ; magic number VDFILE + CAT_FILE_TRACK
2D4A:BC C7 34 059 LDY VDFILE+1,X ; GET DIR SECTOR ; magic number VDFILE + CAT_FILE_SECTOR
2D4D:8C D2 35 060 STY DCBFDS ; SET AS 1ST FD SEC
2D50:20 37 30 061 JSR WRVDIR ; GO WRITE VOLUME DIR
2D53:18 062 CLC
2D54:20 5E 2F 063 FD4 JSR RDFDIR ; GET 1ST FILE DIR SECTOR
2D57:B0 2A 064 BCS FD7 ; BR IF NO MORE
2D59:20 0C 2F 065 JSR MVFCBD ; MOVE DIR TO ZPG
2D5C:A0 0C 066 LDY #FDENT ; POINT Y TO 1ST SEC ENT
2D5E:8C 9C 33 067 FD5 STY TEMP1 ; SAVE Y ; School of Commenting on Useless Observations
2D61:B1 42 068 LDA (ZPGFCB),Y ; GET REACK ; *spelling* Track
2D63:30 0B 069 BMI FD6 ; BR IF NONE
2D65:F0 09 070 BEQ FD6 ; BR IF END OF FILE
2D67:48 071 PHA ; SAVE TRK
2D68:C8 072 INY
2D69:B1 42 073 LDA (ZPGFCB),Y ; GET SECTOR
2D6B:A8 074 TAY ; TO Y
2D6C:68 075 PLA ; GET TRK
2D6D:20 89 2D 076 JSR FDSUB ; GO FREE SECTOR ; /sarcasm What? FREESECS wasn't available??? (It is but FRESEC is used)
2D70:AC 9C 33 077 FD6 LDY TEMP1 ; GET DIR INDEX
2D73:C8 078 INY ; INCR TO NEXT INDEX
2D74:C8 079 INY
2D75:D0 E7 080 BNE FD5 ; BR NOT DONE THIS DIR
2D77:AD D3 35 081 LDA DCBCDT ; GET THIS DIR TRK
2D7A:AC D4 35 082 LDY DCBCDS ; AND SECTOR
2D7D:20 89 2D 083 JSR FDSUB ; AND GO FREE IT
2D80:38 084 SEC ; GO
2D81:B0 D1 085 BCS FD4 ; READ NEXT DIR ; ↑ (always)
086 FD7 EQU *
2D83:20 FB 2F 087 JSR WRVTOC
2D86:4C 7F 33 088 JMP GOODIO
089 ;
090 FDSUB EQU *
2D89:38 091 SEC ; SET FOR REUSE OF SEC
2D8A:20 DD 32 092 JSR FRESEC ; GO FREE SECTOR
2D8D:A9 00 093 LDA #0 ; CLEAR DCB BIT MAP
2D8F:A2 05 094 LDX #5 ; CLEAR ALL OF TRK BITMAP SO ; magic number sizeof( DCBALS=1 + DCBATK=1 + DCBABM=4 ) = 6-1 = 5
095 * ;>16 SECTORS/TRK WILL WORK ; Assumes DCBALS DCBATK DCBABM are contiguous, should be: 4 + DCBABM - DCBALS - 1
2D91:9D F0 35 096 FDS1 STA DCBALS,X ; Intentional BUFFER OVERFLOW
2D94:CA 097 DEX ;
2D95:10 FA 098 BPL FDS1 ;
2D97:60 099 RTS
100 PAGE
101 ;
102 * RDIR - PRINT DIRECTORY ; "CATALOG"
103 ;
104 RDIR EQU *
2D98:20 DC 2B 105 JSR DCBSUP
2D9B:A9 FF 106 LDA #$FF
2D9D:8D F9 35 107 STA DCBVOL
2DA0:20 F7 2F 108 JSR RDVTOC
2DA3:A9 16 109 LDA #22 ; SET 21 LINES ;[.. wastes 1 bytes, JSR NewPage
2DA5:8D 9D 33 110 STA TEMP2 ; ..]
2DA8:20 2F 2E 111 JSR PRCR ; GO PRINT ; Should be JSR PRCR2
2DAB:20 2F 2E 112 JSR PRCR ; PRINT ANOTHER CHAR ; wastes 3 bytes
2DAE:A2 0B 113 LDX #VML ; VOLUME MSG LENGTH
2DB0:BD AF 33 114 RD0 LDA VOLMES,X ; GET MSG CHAR ;
2DB3:20 ED FD 115 JSR PRINT ; PRINT IT ; > More stupid commenting stating the obvious
2DB6:CA 116 DEX ; DECREMENT COUNT ; /
2DB7:10 F7 117 BPL RD0 ; BR IF MORE ; === Page 57 ===
118 ;
2DB9:86 45 119 STX CNUM+1 ; X=0 → CNUM+1, clear high byte for printing
2DBB:AD F6 37 120 LDA IBSMOD ; MOVE VOL NO FOR
2DBE:85 44 121 STA CNUM ; CONVERSION
2DC0:20 42 2E 122 JSR PRNUM ; GO PRINT VOL NO
123 ;
2DC3:20 2F 2E 124 JSR PRCR ; PRINT CR ; Should be JSR PRCR2
2DC6:20 2F 2E 125 JSR PRCR ; AND AGAIN ; wastes 3 bytes
126 ;
2DC9:18 127 CLC ; FIRST RECORD
128 ;
2DCA:20 11 30 129 RD1 JSR RDVDIR ; GO READ REC
2DCD:B0 5D 130 BCS RD5
2DCF:A2 00 131 LDX #0 ; SET INDEX=0
2DD1:8E 9C 33 132 RD2 STX TEMP1 ; SAVE INDEX
2DD4:BD C6 34 133 LDA VDFILE,X ; GET TRACK ; magic number VDFILE + CAT_FILE_TRACK
2DD7:F0 53 134 BEQ RD5 ; BR IF END OF DIR
2DD9:30 4A 135 BMI RD4 ; BR IF DELETED
136 ;
2DDB:A0 A0 137 LDY #$A0 ; BLANK ; KEY_SPACE
2DDD:BD C8 34 138 LDA VDFILE+2,X ; GET TYPE ; magic number VDFILE + CAT_FILE_TYPE
2DE0:10 02 139 BPL RD2A ; BR IF NOT LOCKED
2DE2:A0 AA 140 LDY #'*'+$80 ; AST ; Asterisk, KEY_ASTERISK
2DE4:98 141 RD2A TYA ; ACU = AST OR BLANK
2DE5:20 ED FD 142 JSR PRINT ; PRINT ACU ; Character Out
143 ;
2DE8:BD C8 34 144 LDA VDFILE+2,X ; GET TYPE ; magic number VDFILE + CAT_FILE_TYPE
2DEB:29 7F 145 AND #$7F ; MASK OUT MISC ; magic number FILE_LOCKED_MASK
2DED:A0 07 146 LDY #7 ; SET INDEX = 7 ; Using a bit mask instead of a enumeration is dumb
2DEF:0A 147 ASL A ;GET RID OF HI BIT ; Instead of the simple
2DF0:0A 148 RD2B ASL A ; SHIFT OUT MSB ; LDX FILE_TYPE
2DF1:B0 03 149 BCS RD2C ; BR IF TYPE BIT OUT ; LDA CHAR_FILE_TYPE,X
2DF3:88 150 DEY ; DEC INDEX ; We waste 9 bytes
2DF4:D0 FA 151 BNE RD2B ; BR IF NOT ACC BITS
152 RD2C EQU *
2DF6:B9 A7 33 153 LDA FTTAB,Y ; GET TYPE CODE
2DF9:20 ED FD 154 JSR PRINT ; PRINT IT ; o7 Captain Obvious
2DFC:A9 A0 155 LDA #$A0 ; BLANK
2DFE:20 ED FD 156 JSR PRINT ; PRINT ; === T1SD ===
157 ; ; NOT File length, this is Number of Sectors Allocated
2E01:BD E7 34 158 LDA VDFILE+33,X ; MOVE FILE LENGTH ; magic number VDFILE + CAT_FILE_NUM_SEC+0
2E04:85 44 159 STA CNUM
2E06:BD E8 34 160 LDA VDFILE+34,X ; MOVE FILE LENGTH ; magic number VDFILE + CAT_FILE_NUM_SEC+1
2E09:85 45 161 STA CNUM+1
2E0B:20 42 2E 162 JSR PRNUM ; GO PRINT NUMBER
2E0E:A9 A0 163 LDA #$A0 ; BLANK
2E10:20 ED FD 164 JSR PRINT ; PRINT
165 ;
2E13:E8 166 INX
2E14:E8 167 INX
2E15:E8 168 INX
2E16:A0 1D 169 LDY #29 ; magic number MAX_FILENAME-1
2E18:BD C6 34 170 RD3 LDA VDFILE,X ; GET CHAR
2E1B:20 ED FD 171 JSR PRINT ; PRINT CHAR
2E1E:E8 172 INX
2E1F:88 173 DEY
2E20:10 F6 174 BPL RD3 ;↑
175 RD3A EQU *
2E22:20 2F 2E 176 JSR PRCR ; GO PRINT CR
2E25:20 30 32 177 RD4 JSR VDINC ; INCR INDEX
2E28:90 A7 178 BCC RD2 ; BR IF MORE IN DIR ;↑
2E2A:B0 9E 179 BCS RD1 ; GO READ NEXT DIR ;↑
180 ;
2E2C:4C 7F 33 181 RD5 JMP GOODIO ; DONE ;↓
182 ; ; === Page 58 ===
183 PRCR EQU *
2E2F:A9 8D 184 LDA #$8D ; CR
2E31:20 ED FD 185 JSR PRINT ; PRINTED
2E34:CE 9D 33 186 DEC TEMP2 ; DEC LINE COUNT
2E37:D0 08 187 BNE PRCR1 ; BR IF NOT ZERO
2E39:20 0C FD 188 JSR GETKEY ; WAIT FOR INPUT
2E3C:A9 15 189 LDA #21 ; RESET LINE COUNTER ; magic number NewPage, Should read Text Window Height: (WNDBTM = $23) - (WNDTOP = $22)
2E3E:8D 9D 33 190 STA TEMP2
2E41:60 191 PRCR1 RTS ; DONE
192 PAGE
193 PRNUM EQU * ; Print 16-bit CNUM as 3 decimal digits with leading zeroes
2E42:A0 02 194 LDY #2 ; 3 DIGITS
2E44:A9 00 195 PRN1 LDA #0 ; INIT DIGIT TO ZERO
2E46:48 196 PHA ; SAVE IT
197 ;
2E47:A5 44 198 PRN2 LDA CNUM ; GET NUMBER
2E49:D9 A4 33 199 CMP CVTAB,Y ; IF NUM < CVTAB ENTRY ; Crap comment: What is CVTAB??? Is digit < power of 10
2E4C:90 12 200 BCC PRN3 ; THEN DONE THIS DIGIT ;↓
201 ;
2E4E:F9 A4 33 202 SBC CVTAB,Y ; SUBTRACT TABLE ENTRY
2E51:85 44 203 STA CNUM
2E53:A5 45 204 LDA CNUM+1
2E55:E9 00 205 SBC #0
2E57:85 45 206 STA CNUM+1
2E59:68 207 PLA ; INCREMENT DIGIT
2E5A:69 00 208 ADC #0
2E5C:48 209 PHA
2E5D:4C 47 2E 210 JMP PRN2 ; TRY AGAIN ; wastes 1 byte, A is > 0, A < $80, BNE PRN2
211 ;
212 PRN3 EQU *
2E60:68 213 PLA ; GET DIGIT
2E61:09 B0 214 ORA #$B0 ; ADD ASCII 0 ; magic number #'0'+$80 or KEY_0
2E63:20 ED FD 215 JSR PRINT ; PRINT IT ; Gee I wonder what PRINT does ...
2E66:88 216 DEY ; DECREMENT DIGIT COUNT
2E67:10 DB 217 BPL PRN1 ; BR IF MORE DIGIT
218 ;
2E69:60 219 RTS ; DONE
220 PAGE
221 ;
222 * CLCFCB - GET FCB VIA INDEX AND MOVE IT ; You keep using this word move, it doesn't mean what you think it means
223 ;
224 CLCFCB EQU * ; /sarcasm Oh I see, CLC_FB is clearer then COPY_FCB
225 ;
2E6A:20 08 2F 226 JSR MVFCBP ; MOVE FCB PTR TO ZP
2E6D:A0 00 227 LDY #0
2E6F:8C C5 35 228 STY CCBSTA
2E72:B1 42 229 CF3 LDA (ZPGFCB),Y ; MOVE FCB TO
2E74:99 D1 35 230 STA FCB,Y ; FCB WORK AREA ; $B5BB
2E77:C8 231 INY
2E78:C0 2D 232 CPY #FCBLEN
2E7A:D0 F6 233 BNE CF3
234 ;
2E7C:18 235 CLC
2E7D:60 236 RTS
237 ;
238 * RTNFCB - MOVE FCB FROM WORK AREA TO FCB
239 ;
240 RTNFCB EQU *
2E7E:20 08 2F 241 JSR MVFCBP ; MOVE FCB ADR TO ZPG
242 ;
2E81:A0 00 243 LDY #0 ; === Page 59 ===
2E83:B9 D1 35 244 RF1 LDA FCB,Y
2E86:91 42 245 STA (ZPGFCB),Y
2E88:C8 246 INY
2E89:C0 2D 247 CPY #FCBLEN
2E8B:D0 F6 248 BNE RF1
2E8D:60 249 RTS
001 PAGE
002 ;
003 * FFMT - Execute Format Request ; "INIT"
004 ;
005 FFMT EQU *
2E8E:20 DC 2B 006 JSR DCBSUP ; SET UP DCB
2E91:A9 04 007 LDA #IBFMT
2E93:20 58 30 008 JSR DCBIO2
2E96:AD F9 35 009 LDA DCBVOL
2E99:49 FF 010 EOR #$FF ; TODO Is this the reason why not possible to format with Volume=0
2E9B:8D C1 33 011 STA VVOLNO
2E9E:A9 11 012 LDA #17 ; magic number LDA VDIRTK; FILESYSTEM_VTOC_CAT_TRACK
2EA0:8D EB 33 013 STA VALCA1 ; ALOCATE BYTE 1 ; *spelling* Allocate; Crappy name, should be: ALLOC_TRK
2EA3:A9 01 014 LDA #1 ; +$01 inwards to T22
2EA5:8D EC 33 015 STA VALCA2 ; ADD BYTE 2 ; Crappy name, should be: ALLOC_DIR
016 ;
2EA8:A2 38 017 LDX #VSECAL-VTOC ; Skip VTOC header
2EAA:A9 00 018 LDA #0
2EAC:9D BB 33 019 NT1 STA VTOC,X ; CLEAR SECTOR AREA ; We only care about 4 tracks set to used: T0,T1,T2,T17
2EAF:E8 020 INX
2EB0:D0 FA 021 BNE NT1
022 ;
2EB2:A2 0C 023 LDX #3*4 ; START AT TRACK 3 ; Idiotic 4 bytes/track , magic number FIRST_EMPTY_TRACK
2EB4:E0 8C 024 NT2 CPX #35*4 ; END AT TRACK 35 ; instead of 2 bytes/trk, magic number LAST_EMPTY_TRACK
2EB6:F0 14 025 BEQ NT4
2EB8:A0 03 026 LDY #3 ; 4 BYTES OF INFO
2EBA:B9 A0 33 027 NT3 LDA ALC10S,Y ; 10 SECTORS ALLOCATE ; 16 ($10) sectors used bitmask: 0=free, 1=used
2EBD:9D F3 33 028 STA VSECAL,X
2EC0:E8 029 INX
2EC1:88 030 DEY
2EC2:10 F6 031 BPL NT3
2EC4:E0 44 032 CPX #17*4 ; AT TRACK 17 ; magic number FILESYSTEM_VTOC_CAT_TRACK * ALLOC_BYTE_PER_TRACK;
2EC6:D0 EC 033 BNE NT2
2EC8:A2 48 034 LDX #18*4 ; SKIP TO 18
2ECA:D0 E8 035 BNE NT2 ; ↑ (always)
036 ;
2ECC:20 FB 2F 037 NT4 JSR WRVTOC ; WRITE NEW VTOC
038 ;
2ECF:A2 00 039 LDX #0
2ED1:8A 040 TXA
2ED2:9D BB 34 041 NT5 STA VOLDIR,X ; CLEAR VOLDIR
2ED5:E8 042 INX
2ED6:D0 FA 043 BNE NT5
044 ;
2ED8:20 45 30 045 JSR MVVDBA ; MOVE BUF PTRS
046 ;
2EDB:A9 11 047 LDA #17 ; TRACK 17 ; magic number FILESYSTEM_VTOC_CAT_TRACK = $11
2EDD:AC F0 33 048 LDY VNOSEC ; S16
2EE0:88 049 DEY ; S15 CATALOG [0]
2EE1:88 050 DEY ; S14 CATALOG [1]
2EE2:8D EC 37 051 STA IBTRK ; INTO IOB
2EE5:8D BC 34 052 NT6 STA VDLTRK ; INTO LINK
2EE8:8C BD 34 053 NT7 STY VDLSEC ;
2EEB:C8 054 INY ; === Page 74 ===
2EEC:8C ED 37 055 STY IBSECT
2EEF:A9 02 056 LDA #IBCWTS
2EF1:20 58 30 057 JSR DCBIO2
2EF4:AC BD 34 058 LDY VDLSEC
2EF7:88 059 DEY ; DECREMENT SECTOR
2EF8:30 05 060 BMI NT8 ; BR LAST WRITTEN
2EFA:D0 EC 061 BNE NT7 ; BR NOT LAST
2EFC:98 062 TYA ; lAST, SET LINK TRK=0
2EFD:F0 E6 063 BEQ NT6 ;↑
064 ;
065 NT8 EQU *
2EFF:20 C2 37 066 JSR DLDSUP ; GO SET UP FOR DOSLDR ; === T1SE ===
2F02:20 4A 37 067 JSR WBOOT ; GO WRITE THE BOOT
2F05:4C 7F 33 068 JMP GOODIO ; DONE
069 PAGE
070 ;
071 * MVFCBX - MOVE FCB ADRS TO ZPGFCB
072 ;
2F08:A2 00 073 MVFCBP LDX #0 ; MOVE FCB ADR ; magic number TODO
2F0A:F0 06 074 BEQ MVF1 ;↓
2F0C:A2 02 075 MVFCBD LDX #2 ; MOVE FCB DIR BUFF ; magic number TODO
2F0E:D0 02 076 BNE MVF1 ;↓ wastes 1 byte, $2C bit $abs
2F10:A2 04 077 MVFCBS LDX #4 ; MOVE FCB SECTOR BUFF ; magic number TODO
078 ;
079 MVF1 EQU *
2F12:BD C7 35 080 LDA CFCBAD,X ; DO THE MOVE
2F15:85 42 081 STA ZPGFCB
2F17:BD C8 35 082 LDA CFCBAD+1,X
2F1A:85 43 083 STA ZPGFCB+1
2F1C:60 084 RTS
085 ;
086 PAGE
087 ;
088 * WRSECT - WRITE CURRENT SECTOR IF REQD
089 ;
090 WRSECT EQU *
2F1D:2C D5 35 091 BIT DCBWRF ; GET WRITE REQD FLAG
2F20:70 01 092 BVS WRSGO ; BR IF WRITE SECTOR REQD ; [.. Should be: BVC WRFDIR-1
2F22:60 093 RTS ; RTS ; o7 Captain Obvious is Obvious ..] wastes 1 byte with RTS
094 ;
095 WRGO EQU *
2F23:20 E4 2F 096 JSR MVSBA ; GO MOVE SECT BUFF ADR ; MoveSectorBufferAddress
097 ;
2F26:A9 02 098 LDA #IBCWTS ; GET COMMAND
2F28:20 52 30 099 JSR DCBIO ; GO FILL IN IOB AND DO IO
100 ;
2F2B:A9 BF 101 LDA #$BF ; SET WRITE SECTOR REQD BIT OFF ; magic number $BF = 1011_1111 FLAG_W_CUR_SECTOR EQU $40; LDA ~FLAG_W_CUR_SECTOR
2F2D:2D D5 35 102 AND DCBWRF
2F30:8D D5 35 103 STA DCBWRF
2F33:60 104 RTS ; DONE
105 PAGE
106 ;
107 * WRFDIR - WRITE FILE DIRECTRY IF REQD ; *spelling* Directory
108 ;
109 WRFDIR EQU *
2F34:AD D5 35 110 LDA DCBWRF ; GET WRITE REQD FLAG
2F37:30 01 111 BMI WRFDGO ; BR IF NOT DIR REQD ;[.. Should be: BPL WRFDIR-1
2F39:60 112 RTS ; ..] wastes 1 byte with RTS
113 ;
114 WRFDGO EQU *
2F3A:20 4B 2F 115 JSR MVFDBA ; Yet another crappy name. Quick what is the difference between: MVVDBA or MVFDBA ?
116 ; ; MoveFileDirectoryBufferAddress
2F3D:A9 02 117 LDA #IBCWTS ; GET WRITE CMD ; === Page 75 ===
2F3F:20 52 30 118 JSR DCBIO ; GO FILL IN IOB AND DO I/O
119 ;
2F42:a9 7F 120 LDA #$7F ; TURN WRITE DIR REQD BIT OFF ; magic number $7F = 0111_1111 FLAG_W_FIL_SECTOR EQU $80; LDA ~FLAG_W_FIL_SECTOR
2F44:2D D5 35 121 AND DCBWRF
2F47:8D D5 35 122 STA DCBWRF
2F4A:60 123 RTS
124 ;
125 * MVFDBA - MOVE FILE DIRECTORY BUFF ASDR TO IOD
126 ;
127 MVFDBA EQU *
2F4B:AD C9 35 128 LDA CFCBDR ; MOVE ADR
2F4E:8D F0 37 129 STA IBBUFP
2F51:AD CA 35 130 LDA CFCBDR+1
2F54:8D F1 37 131 STA IBBUFP+1
2F57:AE D3 35 132 LDX DCBCDT ; GET TRACK
2F5A:AC D4 35 133 LDY DCBCDS ; GET SECTOR
2F5D:60 134 RTS
135 PAGE
136 ;
137 * RDFDIR - READ FILE DIRECTORY
138 ;
139 RDFDIR EQU *
2F5E:08 140 PHP ; SAVE STATUS
2F5F:20 34 2F 141 JSR WRFDIR ; GO WRITE CURRENT DIR IF REQD
2F62:20 4B 2F 142 JSR MVFDBA ; GO MOVE DBUFF ADR TO IOB
2F65:20 0C 2F 143 JSR MVFCBD ; MOVE DBUFF ADR TO ZPG
2F68:28 144 PLP ; GET SAVED STATUS
2F69:B0 09 145 BCS RFDNXT ; BR IF RD NEXT
146 ;
2F6B:AE D1 35 147 LDX DCBFDT ; GET TRACK ;DCBFDT != DCBCDT Line #132
2F6E:AC D2 35 148 LDY DCBFDS ; GET SECTOR ;DCBFDS != DCBCDS Line #133
2F71:4C B5 2F 149 JMP RFDIO1 ; GO READ
150 ;
151 RFDNXT EQU *
2F74:A0 01 152 LDY #FDLTRK ; GET LINK TRACK
2F76:B1 42 153 LDA (ZPGFCB),Y
2F78:F0 08 154 BEQ RFDNL ; NR NO LINK ; BUG: Can't have file on T0 BPL RFDNL
2F7A:AA 155 TAX ; PUT TRACK INTO X ; o7 Captain Obvious
2F7B:C8 156 INY
2F7C:B1 42 157 LDA (ZPGFCB),Y ; GET LINK SECTOR
2F7E:A8 158 TAY ; PUT SECTOR INTO Y
2F7F:4C B5 2F 159 JMP RFDIO1 ; GO DO I/O
160 ;
161 RFDNL EQU * ; Read File Dir Next Link
2F82:AD BB 35 162 LDA CCBREQ ; THIS A WRITE
2F85:C9 04 163 CMP #CRQWR
2F87:F0 02 164 BEQ RFDNL1 ; BR IF WRITE ; ↓ TODO Should be BNE ...
2F89:38 165 SEC ; SET EOF
2F8A:60 166 RTS ; RETURN ; o7 Captain Obvious
167 ;
168 RFDNL1 EQU *
2F8B:20 44 32 169 JSR GETSEC ; GET A SECTOR
2F8E:A0 02 170 LDY #FDLSEC ;
2F90:91 42 171 STA (ZPGFCB),Y ; PUT IN LINK
2F92:48 172 PHA ; SAVE SECTOR
2F93:88 173 DEY
2F94:AD F1 35 174 LDA DCBATK ; GET TRACK
2F97:91 42 175 STA (ZPGFCB),Y ; PUT IN LINK
2F99:48 176 PHA ; SAVE TRACK
2F9A:20 3A 2F 177 JSR WRFDGO ; Go WRITE OLD DIR DEC
178 ;
2F9D:20 D6 37 179 JSR CLRSEC ; CLEAN OUT DIR
2FA0:A0 05 180 LDY #FDFRS ; SET NEW DIR SEC 1ST REL ; === Page 76 ===
2FA2:Ad DE 35 181 LDA DCBDNF ; FILE SECTOR
2FA5:91 42 182 STA (ZPGFCB),Y
2FA7:C8 183 INY
2FA8:AD DF 35 184 LDA DCBDNF+1
2FAB:91 42 185 STA (ZPGFCB),Y
186 ;
2FAD:68 187 PLA ; GET SAVED TRACK
2FAE:AA 188 TAX ; INFO X
2FAF:68 189 PLA ; GET SAVED TRACK
2FB0:A8 190 TAY ; INFO Y
2FB1:A9 02 191 LDA #IBCWTS ; SET WRITE CMD
2FB3:D0 02 192 BNE RFDIO2 ; GO DO I/O
193 ;
2FB5:A9 01 194 RFDIO1 LDA #IBCRTS ; SET READ CMD
2FB7:8E D3 35 195 RFDIO2 STX DCBCDT ; SET CURR TRACK
2FBA:8C D4 35 196 STY DCBCDS ; SET CUR SECTOR
2FBD:20 52 30 197 JSR DCBIO ; GO I/O
198 ;
2FC0:A0 05 199 RDFDC LDY #FDFRS ; GET POINTER TO FIRST REL SECTOR
2FC2:B1 42 200 LDA (ZPGFCB),Y ; GET FRS ; First Relative Sector
2FC4:8D DC 35 201 STA DCBDFS ; SET INTO DCB
2FC7:18 202 CLC
2FC8:6D DA 35 203 ADC DCBDMS ; ADD MAX SECTORS
2FCB:8D DE 35 204 STA DCBDNF ; PUT INTO DCB
205 ;
2FCE:C8 206 INY ; DO SAME FOR HI BYTE
2FCF:B1 42 207 LDA (ZPGFCB),Y
2FD1:8D DD 35 208 STA DCBDFS+1
2FD4:6D DB 35 209 ADC DCBDMS+1
2FD7:8D DF 35 210 STA DCBDNF+1
211 ;
2FDA:18 212 CLC
2FDB:60 213 RTS ; DONE
214 PAGE
215 ;
216 ;RDSECT - READ A SECTOR
217 ;
218 RDSECT EQU * ; X = Track, Y = Sector
2FDC:20 E4 2F 219 JSR MVSBA ; GO MOVE SECTOR BUFFER ADR
220 ;
2FDF:A9 01 221 LDA #IBCRTS
2FE1:4C 52 30 222 JMP DCBIO ; GO DO I/O ; wastes 1 byte, BNE DCBIO ($3052 - $2FE3 = $6F < $80)
223 ;
224 ;MVSBA - MOVE SECTOR BUFFER ADR FOR I/O
225 ;
226 MVSBA EQU *
2FE4:AC CB 35 227 LDY CFCBSB ; GET SECTOR BUFF ADR
2FE7:AD CC 35 228 LDA CFCBSB+1
2FEA:8C F0 37 229 MSB1 STY IBBUFP ; SET IOB SECTOR
2FED:8D F1 37 230 STA IBBUFP+1 ; BUFF PTR
2FF0:AE D6 35 231 LDX DCBTRK ; GET TRACK
2FF3:AC D7 35 232 LDY DCBSEC ; GET SECTOR
2FF6:60 233 RTS ; RTN
001 PAGE
002 ;
003 ;RDVTOC - READ VTOC
004 ;WRVTOC - WRITE VTOC
005 ;
006 RDVTOC EQU *
2FF7:A9 01 007 LDA #IBCRTS ; READ
2FF9:D0 02 008 BNE VTIO ; wastes 1 byte, FIX: HEX 2C bit $abs
009 WRVTOC EQU *
2FFB:A9 02 010 LDA #IBCWTS ; WRITE
011 ;
2FFD:AC C3 2A 012 VTIO LDY AVTOC ; MOVE BUFF ADR
3000:8C F0 37 013 STY IBBUFP ; === T1SF === $B000
3003:AC C4 2A 014 LDY AVTOC+1
3006:8C F1 37 015 STY IBBUFP+1
016 ;
3009:AE FA 35 017 LDX DCBVTN ; GET TRACK ; $B5FA = VTN = VTOC Track Number = $11
300C:A0 00 018 LDY #0 ; VTOC Sector Number = $0 magic number FILESYSTEM_VTOC_SECTOR EQU 0
300E:4C 52 30 019 JMP DCBIO ; GO DO I/O ; wastes 1 byte, FIX: BPL DCBIO ↓ (always)
020 PAGE
021 ;
022 ;RDVDIR - READ VOLUME DIRECTOR
023 ;
024 RDVDIR EQU *
3011:08 025 PHP ; SAVE STATUS
3012:20 45 30 026 JSR MVVDBA
027 ;
3015:28 028 PLP ; GET STATUS
3016:B0 08 029 BCS RVDA ; BR IF R0 NEXT
030 ;
3018:AC BD 33 031 RVDC LDY VDIRSC ; READ 1ST SECTOR
301B:AE BC 33 032 LDX VDIRTK ; GET FIRST TRK
301E:D0 0A 033 BNE RVDGO ; GO READ ; BUG: Catalog can't be on T0, FIX: BPL RVDGO
034 ;
035 RVDA EQU *
3020:AE BC 34 036 LDX VDLTRK ; GET LINK TRACK
3023:D0 02 037 BNE RDVC ; BR IF A LINK ; BUG: Catalog can't be on T0, FIX: BPL RDVC
3025:38 038 SEC ; SET END OF DIR
3026:60 039 RTS
040 ;
3027:AC BD 34 041 RDVC LDY VDLSEC ; GET SECTOR ; Volume Directory Link Sector
042 RDVDGO EQU *
302A:8E 97 33 043 STX CVDTRK ; SET CUR TRACK
302D:8C 98 33 044 STY CVDSEC ; SET CUR SECTOR
3030:A9 01 045 LDA #IBCRTS ; GET CMD ; No shit Sherlock Q. Which command? A. ReadTrackSector
3032:20 52 30 046 JSR DCBIO ; GO DO I/O
3035:18 047 CLC
3036:60 048 RTS
049 PAGE
050 ;
051 ;WRVDIR - WRITE VOLUME DIRECTORY SECTOR
052 ;
053 WRVDIR EQU *
3037:20 45 30 054 JSR MVVDBA ; === 64 ===
055 ;
303A:AE 97 33 056 LDX CVDTRK ; CURRENT TRACK
303D:AC 98 33 057 LDY CVDSEC ; CURRENT SECTOR
3040:A9 02 058 LDA #IBCWTS ; WRITE COMMAND
3042:4C 52 30 059 JMP DCBIO ; GO DO I/O ; wastes 1 byte, BNE DCBIO ↓ (always)
060 ;
061 ; MVVDBA - MOVE VOL DIR BUF ADR TO IOB
062 ;
063 MVVDBA EQU *
3045:AD C5 2A 064 LDA AVOLDR
3048:8D F0 37 065 STA IBBUFP
304B:AD C6 2A 066 LDA AVOLDR+1
304E:8D F1 37 067 STA IBBUFP+1
3051:60 068 RTS
069 PAGE
070 ;
071 ;DCBIO - DO I/O FOR A DCB ; Prologue should be:
072 ; ; LDA #IBCWTS
073 DCBIO EQU *
3052:8E EC 37 074 STX IBTRK ; TRACK ; As this is called from Page 74 and 75
3055:8C ED 37 075 STY IBSECT ; SECTOR
076 DCBIO2 EQU *
3058:8D F4 37 077 STA IBCMD ; COMMAND
305B:C9 02 078 CMP #IBCWTS
305D:D0 06 079 BNE DCBIO1 ; Read
305F:0D D5 35 080 ORA DCBWRF
3062:8D D5 35 081 STA DCBWRF
082 DCBIO1 EQU * ; *Sigh* Couldn't list DCBI01 then DCBI02??
; *Double Sigh* Perfect example why a var shouldn't contain both I and 1.
; Better names would be: DCB_IOa DCB_IOb
3065:AD F9 35 083 LDA DCBVOL ; VOL ;[..wastes 2 bytes
3068:49 FF 084 EOR #$FF ; UNINVERT VOL BITS ; .. 0. Why was it inverted in the first place???
306A:8D EB 37 085 STA IBVOL ; .. 1. More crappy names; Since DCB and IB are used all the time,
306D:AD F7 35 086 LDA DCBSLT ; SLOT ; .. a single letter prefix with an underscore '_' would
3070:8D E9 37 087 STA IBSLOT ; .. a) improve readability significantly, and
3073:AD F8 35 088 LDA DCBDRV ; DRIVE ; .. b) require less typing to boot
3076:8D EA 37 089 STA IBDRVN ; .. Compare and constrast the two:
3079:AD E2 35 090 LDA DCBSDL ; LENGTH ; .. D_SLOT DCBSLT
307C:8D F2 37 091 STA IBDLEN ; .. I_SLOT IBSLOT
307F:AD E3 35 092 LDA DCBSDL+1 ; .. 2. Note: Length is 16-bit
3082:8D F3 37 093 STA IBDLEN+1 ; ..] 3. Over-engineered memcpy() to marshall DCB to/from IOB
; Due to the contiguous layout (/saracasm Who knew!)
;
; [26] DCBSLT <-> [1] IBSLOT
; [27] DCBDRV <-> [2] IBDRVN
; [28] DCBVOL <-> [3] IBVOL
;
; This entire mem copy can be simplified: (18 vs 20 org. bytes)
; LDX #0
; DCB2IOB LDA DCBSLT,X
; STA IBSLOT,X
; INX
; CPX #IBVOL-IBSLOT ; copy 3 fields (3 bytes)
; BNE DCB2IOB
; EOR #$FF ; Invert Volume
; STA IBSLOT,X
;
; If we didn't have the bad design of DCBSDL
; being not contiguous with the above 3 fields,
;
; [11] DCBSDL != [A] IBDLEN
;
; Which should be:
;
; [24] DCBSDL <-> [0] IBDLEN
;
; Then we could instead have:
;
; LDX #0
; DCB2IOB LDA DCBSDL,X
; STA IBDLEN,X
; INX
; CPX #IBVOL-IBDLEN ; copy 4 fields (5 bytes)
; EOR #$FF ; Invert Volume
; STA IBSLOT,X
;
; Also, if we didn't have to deal with that stupid VOLUME EOR #$FF
; It could be simplified even more: (11 bytes vs 32bytes!)
;
; LDX #IBVOL-IBDLEN ; copy 4 fields (5 bytes)
; DCB2IOB LDA DCBSLT,X
; STA IBSLOT,X
; DEX
; BPL DCB2IOB
;
3085:A9 01 094 LDA #1 ; IOB TYPE ;[.. wastes 5 bytes, magic number IOB_OFFSET_TYPE
3087:8D E8 37 095 STA IBTYPE ; ..] never referenced!
096 ;
308A:AC C1 2A 097 LDY AIOB
308D:AD C2 2A 098 LDA AIOB+1
3090:20 B5 37 099 JSR DISKIO
100 ;
3093:AD F6 37 101 LDA IBSMOD ; Hack
3096:8D BF 35 102 STA CCBVOL
3099:A9 FF 103 LDA #$FF ; RESET VOL
309B:8D EB 37 104 STA IBVOL
309E:B0 01 105 BCS BADIO ; BR IF BAD
30A0:60 106 RTS ; RTN IF GOOD
107 ;
30A1:AD F5 37 108 BADIO LDA IBSTAT ; GET STATUS
30A4:A0 07 109 LDY #CREVMM
30A6:C9 20 110 CMP #IBVMME ; WAS IT VOLUME MISMATCH
30A8:F0 08 111 BEQ BD2 ; BR IF YES
30AA:A0 04 112 LDY #CREPRO
30AC:C9 10 113 CMP #IBWPER
30AE:F0 02 114 BEQ BD2
30B0:A0 08 115 LDY #CREIOE
30B2:98 116 BD2 TYA
30B3:4C 85 33 117 JMP ERRROB ; === 65 ===
118 PAGE
119 ;
120 ;LOCNXB - LOCATE NEXT BYTE
121 ;
122 LOCNXB EQU *
30B6:AD E4 35 123 LDA DCBCRS ; IS THE CURRENT RELATIVE SECTOR
30B9:CD E0 35 124 CMP DCBCMS ; EQUAL TO THE CURRENT MEM SECTOR
30BC:D0 08 125 BNE LNB1 ; BR IF NOT EQ
30BE:AD E5 35 126 LDA DCBCRS+1
30C1:CD E1 35 127 CMP DCBCMS+1
30C4:F0 66 128 BEQ LNB8 ; BR IF REQD SECTOR IN MEM
129 ;
130 LNB1 EQU * ; NEED A DIFFERENT SECTOR IN MEM
30C6:20 1D 2F 131 JSR WRSECT ; GO WRITE SECTOR (IF REQD)
132 ;
30C9:AD E5 35 133 LNB2 LDA DCBCRS+1 ; IS CURRENT REL SECTORY
30CC:CD DD 35 134 CMP DCBDFS+1 ; IN CURRENT DIRECTORY (LOW LIMIT)
30CF:90 1C 135 BCC LNB4 ; BR IF IN A PREVIOUS DIR
30D1:D0 08 136 BNE LNB3 ; BR IF MAYBE IN THIS ONE
30D3:AD E4 35 137 LDA DCBCRS ; TEST LOW BYTES
30D6:CD DC 35 138 CMP DCBDFS
30D9:90 12 139 BCC LNB4 ; BR IF IN PREVIOUS DIR
140 ;
30DB:AD E5 35 141 LNB3 LDA DCBCRS+1 ; CURRENT REL SECTOR
30DE:CD DF 35 142 CMP DCBDNF+1 ; IN CURRENT DIRECTOR (HI LIMIT)
30E1:90 10 143 BCC LNB6 ; BR IF IN THIS ONE
30E3:D0 08 144 BNE LNB4
30E5:AD E4 35 145 LDA DCBCRS
30E8:CD DE 35 146 CMP DCBDNF
30EB:90 06 147 BCC LNB6
148 ;REQD SECTOR IN A NEXT DIRECTORY
30ED:20 5E 2F 149 LNB4 JSR RDFDIR
30F0:90 D7 150 BCC LNB2
30F2:60 151 RTS
152 ;
153 ;
154 LNB6 EQU * ; CALCULATE DISPL INTO DIR
30F3:38 155 SEC
30F4:AD E4 35 156 LDA DCBCRS ;
30F7:ED DC 35 157 SBC DCBDFS
30FA:0A 158 ASL A ; TIMES 2
30FB:69 0C 159 ADC #FDENT ; PLUS DISPL TO 1ST
30FD:A8 160 TAY
30FE:20 0C 2F 161 JSR MVFCBD ; MOVE DIR ADR TO ZPG
3101:B1 42 162 LDA (ZPGFCB),Y ; GET TRACK
3103:D0 0F 163 BNE LNB7 ; BR IF NOT ZERO ; should be BPL, Filesystem Design FLAW: Can't store data on Track 0
3105:AD BB 35 164 LDA CCBREQ
3108:C9 04 165 CMP #CRQWR ; WRITE!
310A:F0 02 166 BEQ LNB7A
310C:38 167 SEC
310D:60 168 RTS
310E:20 34 31 169 LNB7A JSR GNWSEC ; GO GET A NEW SECTOR ; A=C0
3111:4C 20 31 170 JMP LNBCON ;↓ wastes 1 byte 1 byte, BNE LNBCON
3114:8D D6 35 171 LNB7 STA DCBTRK ; SET TRK INTO DCB
3117:C8 172 INY
3118:B1 42 173 LDA (ZPGFCB),Y ; GET SECTOR
311A:8D D7 35 174 STA DCBSEC ; PUT INTO DCB
311D:20 DC 2F 175 JSR RDSEC ; GO READ SECTOR
3120:AD E4 35 176 LNBCON LDA DCBCRS ; MOVE CUR REL SECTOR
3123:8D E0 35 177 STA DCBCMS
3126:AD E5 35 178 LDA DCBCRS+1 ; TO CUR MEM SECTOR
3129:8D E1 35 179 STA DCBCMS+1
180 ; ; === 66 ===
181 LNB8 EQU *
312C:20 10 2F 182 JSR MVFCBS ; MOVE SECTOR BUFF ADR TO ZP
312F:AC E6 35 183 LDY DCBCSB ; GET SECT BYTE
3132:18 184 CLC ; CARRY CLEAR = ALL OK
3133:60 185 RTS ; DONE
186 PAGE
187 ;
188 ;
189 GNWSEC EQU * ; NEED NEW SECTOR
3134:8C 9D 33 190 STY TEMP2 ; SAVE DIR INDEX
3137:20 44 32 191 JSR GETSEC ; GET A SECTOR
313A:AC 9D 33 192 LDY TEMP2
313D:C8 193 INY
313E:91 42 194 STA (ZPGFCB),Y ; SET NEW SECTOR
3140:8D D7 35 195 STA DCBSEC
3143:88 196 DEY
3144:AD F1 35 197 LDA DCBATK ; Allocated track?
3147:91 42 198 STA (ZPGFCB),Y ; SET NEW TRACK
3149:8D D6 35 199 STA DCBTRK
200 ;
314C:20 10 2F 201 JSR MVFCBS
314F:20 D6 37 202 JSR CLRSEC ; GO CLEAR SECTOR
203 ;
204 ;
3152:A9 C0 205 LDA #$C0 ; INDICATE BOTH ; magic number WRITE_FLAG_SECTOR | WRITE_FLAG_DIR
3154:0D D5 35 206 ORA DCBWRF ; DIR AND SECTOR ; TODO DIRECTORY or DIRECTION ???
3157:8D D5 35 207 STA DCBWRF ; MUST BE WRITTEN
315A:60 208 RTS ; DONE ; For the love of god, WHY do you keep stating the obvious???
209 PAGE
210 ;
211 ;INCRRB - INCREMENT RELATIVE RECORD BYTE
212 ;
213 INCRRB EQU *
315B:AE EA 35 214 LDX DCBCRR ; MOVE BYTE JUST READ OR WRITTEN
315E:8E BD 35 215 STX CCBRRN
3161:AE EB 35 216 LDX DCBCRR+1
3164:8E BE 35 217 STX CCBRRN+1
3167:AE EC 35 218 LDX DCBCRB ; X=REL BYTE (LOW)
316A:AC ED 35 219 LDY DCBCRB+1 ; Y=REL BYTE HI
316D:8E BF 35 220 STX CCBBYT
3170:8C C0 35 221 STY CCBBYT+1
3173:E8 222 INX ; INC REL BYTE (LOW)
3174:D0 01 223 BNE INCR1 ; BR IF NO CARRY
3176:C8 224 INY
225 ;
3177:CC E9 35 226 INCR1 CPY DCBRCL+1 ; REL BYTE=REC LENGTH
317A:D0 11 227 BNE INCR2 ; BR IF NOT
317C:EC E8 35 228 CPX DCBRCL
317F:D0 0C 229 BNE INCR2
3181:A2 00 230 LDX #0
3183:A0 00 231 LDY #0 ; RESET REL BYTE TO ZERO
3185:EE EA 35 232 INC DCBCRR ; AND INCR
3188:D0 03 233 BNE INCR2 ; RELATIVE RECORD
318A:EE EB 35 234 INC DCBCRR+1
235 ;
318D:8E EC 35 236 INCR2 STX DCBCRB ; SAVE NEW RELATIVE BYTE
3190:8C ED 35 237 STY DCBCRB+1
238 ;
3193:60 239 RTS
240 PAGE
241 ;
242 ;INCSCB - INCREMENT SECTOR BYTE
243 ; ; === 67 ===
244 INCSCB EQU *
3194:EE E6 35 245 INC DCBCSB ; INC SECTOR BYTE
3197:D0 08 246 BNE INCS2 ; BR IF NOT FULL
3199:EE E4 35 247 INC DCBCRS ; AND INCR
319C:D0 03 248 BNE INCS2 ; RELATIVE SECTOR
319E:EE E5 35 249 INC DCBCRS+1
250 ;
251 ;
252 INCS2 EQU *
31A1:60 253 RTS
254 PAGE
255 ;
256 ;MIBDA - MOVE AND INCREMENT CCBDAT
257 ;
258 MIBDA EQU *
31A2:AC C3 35 259 LDY CCBBBA ; Y=ADR LOW
31A5:AE C4 35 260 LDX CCBBBA+1 ; X=ADR HI
31A8:84 42 261 STY ZPGFCB ; PUT ADR INTO ZPG
31AA:86 43 262 STX ZPGFCB+1
263 ;
31AC:EE C3 35 264 INC CCBBA ; INC ADR LOW
31AF:D0 03 265 BNE MIB1 ; BR IF NOT ZERO
31B1:EE C4 35 266 INC CCBBA+1 ; DONE
31B4:60 267 MIB1 RTS ; DONE
268 ;
269 ;DTBLN - DECREMENT BLONG LENGTH AND TEST ZERO
270 ;
271 DTBLN EQU *
31B5:AC C1 35 272 LDY CCBBLN ; GET LEN LOW
31B8:D0 08 273 BNE DTB1 ; BR IF NOT ZERO ; No shit Caption Obvious!
31BA:AE C2 35 274 LDX CCBBLN+1 ; GET LEN HI
31BD:F0 07 275 BEQ DTB2 ; BR IF LEN=0
31BF:CE C2 35 276 DEC CCBBLN+1 ; DEC LEN (HIGH)
31C2:CE C1 35 277 DTB1 DEC CCBBLN ; DEC LEN (LOW)
31C5:60 278 RTS ; DONE
279 ;
31C6:4C 7F 33 280 DTB2 JMP GOODIO ; FINISHED BLOCK
001 PAGE
002 ;
003 ;FNDFIL - FIND FILE NAME IN VOLUUME DIR ; *spelling* VOLUME
004 ;
005 FNDFIL EQU *
31C9:20 F7 2F 006 JSR RDVTOC ; GO GET VTOC
31CC:AD C3 35 007 LDA CCBFN ; MOVE FN PTR
31CF:85 42 008 STA ZPGFCB ; TO ZERO PAGE
31D1:AD C4 35 009 LDA CCBFN+1
31D4:85 43 010 STA ZPGFCB+1
31D6:A9 01 011 LDA #1 ; *sigh* magic number TODO
31D8:8D 9D 33 012 FF1 STA TEMP2
31DB:A9 00 013 LDA #0
31DD:8D D8 35 014 STA DCBVDR
31E0:18 015 CLC
016 FF2 EQU *
31E1:EE D8 35 017 INC DCBVDR ;
31E4:20 11 30 018 JSR RDVDIR ; GO GET VDIR SECTOR
31E7:B0 51 019 BCS FF4A ;↓
31E9:A2 00 020 LDX #0 ; SET FOR 1ST FILE
021 ;
31EB:8E 9C 33 022 FF3 STX TEMP1 ; SAVE INDEX
31EE:BD C6 34 023 LDA VDFILE,X ; GET FILE TRK
31F1:F0 1F 024 BEQ FF6 ; BR IF LAST ENTRY ;↓ TODO NTODAFS can't store data on track 0; Should be NOP NOP
31F3:30 22 025 BMI FF7 ; BR IF DELETED ENTRY ;↓
31F5:A0 00 026 LDY #0 ; X=X+3
31F7:E8 027 INX
31F8:E8 028 INX
31F9:E8 029 FF4 INX
31FA:B1 42 030 LDA (ZPGFCB),Y ; GET FN CHAR
31FC:DD C6 34 031 CMP VDFILE,X ; COMPARE TO ENTRY CHAR
31FF:D0 0A 032 BNE FF5 ; BR IF NOT SAME ;↓
3201:C8 033 INY
3202:C0 1E 034 CPY #30 ; ALL 30 CHARS ; magic number FILENAME_MAX
3204:D0 F3 035 BNE FF4 ; BR IF NOT ;↑
3206:AE 9C 33 036 LDX TEMP1 ; GET INDEX
3209:18 037 CLC ; FILE FOUND
320A:60 038 RTS ; RETURN
039 ;
040 FF5 EQU *
320B:20 30 32 041 JSR VDINC
320E:90 DB 042 BCC FF3 ;↑
3210:B0 CF 043 BCS FF2 ;↑
044 ;
3212:AC 9D 33 045 FF6 LDY TEMP2 ; LOOKING FOR DELETED ; *sigh* Found Last Catalog Entry
3215:D0 C1 046 BNE FF1 ; BR IF NOT (DO) ;↑ (always?) This is why you don't use crappy function names
047 ; ; that only differ by one digit
3217:AC 9D 33 048 FF7 LDY TEMP2 ; LOOKING FOR EMPTY ; *sigh* Found Deleted
321A:D0 EF 049 BNE FF5 ; BR IF NOT ;↑ (always?)
050 ;
051 MVN EQU *
321C:A0 00 052 LDY #0 ; HAVE NEW ENTRY
321E:E8 053 INX
321F:E8 054 INX ; === 69 ===
3220:E8 055 FF8 INX
3221:B1 42 056 LDA (ZPGFCB),Y ; MOVE FILENAME
3223:9D C6 34 057 STA VDFILE,X
3226:C8 058 INY
3227:C0 1E 059 CPY #30 ; magic number FILENAME_MAX
3229:D0 F5 060 BNE FF8 ;↑
061 ;
322B:AE 9C 33 062 LDX TEMP1 ; GET INDEX
322E:38 063 SEC ; TODO PASS? FAIL?
322F:60 064 RTS
065 VDINC EQU *
3230:18 066 CLC
3231:AD 9C 33 067 LDA TEMP1 ; pCatalog++;
3234:69 23 068 ADC #35 ; magic number FILENAME_ENTRY_SIZE
3236:AA 069 TAX
3237:E0 F5 070 CPX #VDFLEN
3239:60 071 RTS
072 FF4A EQU *
323A:A9 00 073 LDA #0
323C:AC 9D 33 074 LDY TEMP2 ; /cynical What? Can't do FILE_ENTRY_OFFSET = TEMP2
323F:D0 97 075 BNE FF1 ;
3241:4C 77 33 076 JMP ERROR9 ; NOT EM9: I/O ERROR, but CRENSA → "NO SECTORS AVAILABLE"
077 PAGE
078 ;
079 ;GETSEC - GET A SECTOR
080 ;
081 GETSEC EQU *
3244:AD F1 35 082 LDA DCBATK ; GET ALLOCATED TRK
3247:F0 21 083 BEQ GSS1 ; BR IF NONE ; DESIGN FLAW: Can't store file on track 0 !
084 ;
085 GS0 EQU *
3249:CE F0 35 086 DEC DCBALS ; DECREMENT SECTOR NO
324C:30 17 087 BMI CS2 ; BR IF NO SECTORS REM
088 ;
324E:18 089 CLC
324F:A2 04 090 LDX #4 ; 4 BYTE SHIFT ; TODO magic number sizeof( DCBABM ), See: ALC10S)
3251:3E F1 35 091 GS1 ROL DCBABM-1 ; SHIFT BYTE LEFT ; ???
3254:CA 092 DEX
3255:D0 FA 093 BNE GS1
3257:90 F0 094 BCC GS0
095 ;
3259:EE EE 35 096 INC DCBNSA
325C:D0 03 097 BNE GS1A ;↓
325E:EE EF 35 098 INC DCBNSA+1
3261:AD F0 35 099 GS1A EQU *
3264:60 100 LDA DCBALS ; GET ALLOCATED SECTOR
101 RTS ; RETURN
102 ;
3265:A9 00 103 CS2 LDA #0 ; CLEAR ALLOCATED
3267:8D F1 35 104 STA DCBATK ; TRK
105 ;
326A:A9 00 106 GSS1 LDA #0 ; SET SEARCH STATE=0
326C:8D 9E 33 107 LDA TEMP3
326F:20 F7 2F 108 JSR RDVTOC ; GET VTOC
109 ;
110 GS2 EQU *
3272:18 111 CLC
3273:AD EB 33 112 LDA VALCA1 ; GET LAST ALLOCATED TRK
3276:6D EC 33 113 ADC VALCA2 ; AD (+1) OR (-1)
3279:F0 09 114 BEQ GS3 ; BR IF DECK TO ZERO ; TODO Can't allocate data on Track 0
327B:CD EF 33 115 CMP VNOTRK
327E:90 14 116 BCC GS5 ; BR IF NOT AT OUTER LIMIT
3280:A9 FF 117 LDA #$FF ; SET (-1) ; === Page 70 ===
3282:D0 0A 118 BNE GS4 ;↓ Allways
3284:AD 9E 33 119 GS3 LDA TEMP3 ; GET SEARCH STATE
3287:D0 37 120 BNE ERR9 ; BR IF NOT ZERO
3289:A9 01 121 LDA #1 ; SET (+1)
328B:8D 9E 33 122 STA TEMP3 ; SET SEARCH SATE = 1
328E:8D EC 33 123 GS4 STA VALCA2 ; SET NEW (+1) OR (-1)
3291:18 124 CLC
3292:69 11 125 ADC #17 ; ADD VTOC TRK NO ; magic number CAT_FILE_TRACK, FILESYSTEM_VTOC_CAT_TRACK = $11
3294:8D EB 33 126 GS5 STA VALCA1 ; SET NEW LAST ALLOCATED
3297:8D F1 35 127 STA DCBATK ; PUT IN DCB
128 ;
329A:A8 129 TAY ; ALLOCATED TRACK
329B:0A 130 ASL A ; TIME 4 ; HARD-CODED 4 bytes/VTOC
329C:0A 131 ASL A
329D:A8 132 TAY ; See HNTDAFS #3 Wastes 4 bytes/track for free sector bitmap, sizeof( DCBABM )
329E:A2 04 133 LDX #4 ; magic number VTOC_BITMAP_BYTES_PER_TRACK = sizeof(DCBABM), See: ALC10S
32A0:18 134 CLC
32A1:B9 F6 33 135 GS6 LDA VSECAL+3,Y ; MOVE BIT MAP BYTE
32A4:9D F1 35 136 STA DCBABM-1,X
32A7:F0 06 137 BEQ GS7 ; BR IF NO BITS ON
32A9:38 138 SEC ; SET HAVE SECTOR
32AA:A9 00 139 LDA #0 ; CLEAR VTOC BYTE
32AC:99 F6 33 140 STA VSECAL+3,Y
32AF:88 141 GS7 DEY
32B0:CA 142 DEX
32B1:D0 EE 143 BNE GS6 ; BR IF MORE TO MOVE
32B3:90 BD 144 BCC GS2
32B5:20 FB 2F 145 JSR WRVTOC ; GO WRITE VTOC
32B8:AD F0 33 146 LDA VNOSEC ; GET NO SECTORS
32BB:8D F0 35 147 STA DCBALS ; SET IN DCB SECTOR BYTE
32BE:D0 89 148 BNE GS0 ; GO ALLOCATED SECTOR ;↑
32C0:4C 77 33 149 GS8 JMP ERROR9
150 PAGE
151 ;
152 ;FRETRK - FREE TRACK OF SECTORS
153 ;
154 FRETRK EQU *
32C3:AD F1 35 155 LDA DCBATK ; GET ALLOCATED TRACK
32C6:D0 01 156 BNE FT1 ; BR IF NONE ;↓ DESIGN FLAW: Can't store data on track 0, TODO
32C8:60 157 RTS
32C9:48 158 FT1 PHA
32CA:20 F7 2F 159 JSR RDVTOC ; GET VTOC
32CD:AC F0 35 160 LDY DCBALS ; GET SECTORS
32D0:68 161 PLA ; GET TRACK
32D1:18 162 CLC ; SET FREE
32D2:20 DD 32 163 JSR FRESEC ; GO FREE
32D5:A9 00 164 LDA #0 ; CLEAR ALLOCATED TRK
32D7:8D F1 35 165 STA DCBATK
32DA:4C FB 2F 166 JMP WRVTOC ; WRITE VTOC
167 ;
168 ;FRESEC - FREE A SECTOR
169 ;A=TRK, Y=SECTOR, C=ON/OFF
170 ;
171 FRESEC EQU *
32DD:A2 FC 172 FS1 LDX #252 ; 4 BYTE SHIFT ; magic number 256 - sizeof(DCBABM), See: ALC10S
32DF:7E F6 34 173 FS2 ROR DCBABM-252 ; SHIFT IN CARRY
32E2:E8 174 INX ; NEXT BYTE
32E3:D0 FA 175 BNE FS2 ; BR IF NOT DONE
32E5:C8 176 INY ; INC SECTOR NO
32E6:CC F0 33 177 CPY VNOSEC ; NORMAL
32E9:D0 F2 178 BNE FS1 ; BR IF NOT
179 ;
32EB:0A 180 ASL A ; TRACK*4 ; === Page 71 ===
32EC:0A 181 ASL A
32ED:A8 182 TAY
32EE:F0 0F 183 BEQ FS4 ; See HNTDAFS #3 Wastes 4 bytes/track for free sector bitmap, sizeof( DCBABM )
32F0:A2 04 184 LDX #4 ; magic number VTOC_BITMAP_BYTES_PER_TRACK, See: ALC10S
32F2:BD F1 35 185 FS3 LDA DCBABM-1,X ; GET BIT MAP BYTE
32F5:19 F6 33 186 ORA VSECAL+3,Y ; OR WITH VTOC BM
32F8:99 F6 33 187 STA VSECAL+3,Y
32FB:88 188 DEY
32FC:CA 189 DEX
32FD:D0 F3 190 BNE FS3
32FF:60 191 FS4 RTS ; DONE
192 PAGE
193 ;
194 ;LOCSEC - LOCATE SECTOR FOR RECORD I/O
195 ;
196 ;RELSEC = (REL REC * RECLEN + RELBYTE)/256
197 ;SECBYT = REMAINDER
198 ;
199 LOCSEC EQU * ; Proper variable names such as
3300:AD BD 35 200 LDA CCBRRN ; RELATIVE RECORD NUMBER ; === T2S2 === CCB_REL_REC_NUM
3303:8D E6 35 201 STA DCBCSB ; TO CSB FOR MULT ; Would negate the need for
3306:8D EA 35 202 STA DCBCRR ; AND CRR FOR SAVE ; 50% of comments
3309:AD BE 35 203 LDA CCBRRN+1 ; But's let abbreviate the fuck out of everything
330C:8D E4 35 204 STA DCBCRS ; Quick! What's the difference between DCBCRR and DCBCRS
330F:8D EB 35 205 STA DCBCRR+1
3312:A9 00 206 LDA #0
3314:8D E5 35 207 STA DCBCRS+1 ; HIGH CRS=0
3317:A0 10 208 LDY #16 ; 16 BIT MULT
209 ;
3319:AA 210 LS1 TAX ; SAVE MS BYTE
331A:AD E6 35 211 LDA DCBCSB
331D:4A 212 LSR A ; IF NO CARRY THEN NO PART PROD
331E:B0 03 213 BCS LS1A
3320:8A 214 TXA
3321:90 0E 215 BCC LS2
3323:18 216 LS1A CLC
3324:AD E5 35 217 LDA DCBCRS+1 ; FPORM PARTIAL PROD ; *spelling* FORM
3327:6D E8 35 218 ADC DCBRCL
332A:8D E5 35 219 STA DCBCRS+1
332D:8A 220 TXA
332E:6D E9 35 221 ADC DCBRCL+1
222 ;
3331:6A 223 LS2 ROR A ; MULT BY 2
3332:6E E5 35 224 ROR DCBCRS+1
3335:6E E4 35 225 ROR DCBCRS
3338:6E E6 35 226 ROR DCBCSB
333B:88 227 DEY ; DEC BIT COUNT
333C:D0 DB 228 BNE LS1 ; BR IF MORE BITS
229 ;
230 DO DOS33B ; Proof that the designer didn't THINK about the user and file sizes.
333E:18 231 CLC ; FOR FILE LENGTH > $7FFF BYTES ; /sarcastic What? It was too hard to realize that someone will try to do: BSAVE RAM.48K,A$0,L$C000 ???
232 FIN ; THINK, McFLY!
333F:AD BF 35 233 LDA CCBBYT ; ADD REL BYTE RESULT
3342:8D EC 35 234 STA DCBCRB ; (SAVE REL BYTE)
3345:6D E6 35 235 ADC DCBCSB
3348:8D E6 35 236 STA DCBCSB
334B:AD C0 35 237 LDA CCBBYT+1
334E:8D ED 35 238 STA DCBCRB+1 ; (SAVE REL BYTE)
3351:6D E4 35 239 ADC DCBCRS
3354:8D E4 35 240 STA DCBCRS
241 DO DOS33B
3357:90 03 242 BCC DONTINC
3359:EE E5 35 243 INC DCBCRS+1 ; === Page 72 ===
335C:60 244 DONTINC RTS
335D:00 00 245 DS 2,$00 ; wastes 2 bytes. Line 231 = 1 byte + 8 bytes keep remaining Entry Points @ same address
246 ELSE ; 9 bytes
247 LDA #0
248 ADC DCBCRS+1
249 STA DCBCRS+1
250 RTS
251 FIN
252 PAGE
335F:A9 01 253 ERROR1 LDA #CREFUN ; "FCB UNALLOCATED" - JMP'd from exactly ONE spot: F02
3361:D0 22 254 BNE ERRORA ;↓ wastes 2 bytes, above should be located at F02: LDA #CREFUN, JMP ERRORA
3363:A9 02 255 ERROR2 LDA #CRERR ; "CCB REQ RANGE ERR" - JMP'd from exactly ONE spot: ERR2
3365:D0 1E 256 BNE ERRORA ;↓ wastes 2 bytes, above should be located at ERR2: LDA #CRERR, JMP ERRORA
3367:A9 03 257 ERROR3 LDA #CREMRE ; "REQ MOD RANGE ERR" - JMP'd from exactly ONE spot: ERR3A
3369:D0 1A 258 BNE ERRORA ;↓ wastes 2 bytes, above should be located at ERR3A: LDA #CREMRE, JMP ERRORA
336B:A9 04 259 ERROR4 LDA #CREPRO ; "WRITE PROTECT" - [.. wastes 4 bytes -- never referenced!
336D:D0 16 260 BNE ERRORA ;↓ ..]
336F:A9 05 261 ERROR5 LDA #CREEOF ; "END OF FILE ON READ" - JMP'd from exactly ONE spot: EOFIN
3371:D0 12 262 BNE ERRORA ;↓ wastes 2 bytes, above should be located at EOFIN: LDA #CREEOF, JMP ERRORA
3373:A9 06 263 ERROR6 LDA #CREFNF ; "FILE NOT FOUND" - JMP'd from exactly ONE spot: F02A
3375:D0 0E 264 BNE ERRORA ;↓ wastes 2 bytes, above should be located at F02A: LDA #CREFNF, JMP ERRORA
; "VOL MIS MATCH" - What happened to error 7 ???
; "I/O ERR" - What happened to error 8 ???
3377:4C ED 3F 265 ERROR9 JMP ERROR9X ;MUST CLOSE ALL FILES (WAS LDA #CRENSA) ; "NO SECTORS AVAILABLE"
337A:EA 266 NOP ;↓ wastes 1 byte to keep Entry Point address unchanged
337B:A9 0A 267 ERROR10 LDA #CREFLK ; "FILE LOCKED"
337D:D0 06 268 BNE ERRORA ;↓
337F:AD C5 35 269 GOODIO LDA CCBSTA ; Default to no change in status
3382:18 270 CLC ; CARRY=CLR ; No Shit Sherlock, Comment WHY, _not_ how; C=0 → No error
3383:90 01 271 BCC RETURN ; GO RETURN
272 ERRORA EQU *
3385:38 273 ERRORB SEC ; CARRY SET ; STOP documenting stupid shit! Instead, WHAT significance does C=1 have? → C=1 ERROR
274 RETURN EQU *
3386:08 275 PHP
3387:8D C5 35 276 STA CCBSTA ; SET STA
338A:A9 00 277 LDA #0 ;(FIX FOR APPLE SYS MONITOR $48 USED BY RWTS)
338C:85 48 278 STA $48 ;(THIS ADDED 11/1/78) ; magic number NOT ALLDONE DFB $24 SEC, but TODO
338E:20 7E 2E 279 JSR RTNFCB ; GO RTN FCB
3391:28 280 PLP ; GET STATUS
3392:AE 9B 33 281 LDX ENTSTK ; GET ENT STACK
3395:9A 282 TXS ; RESTORE STACK ; o7 Captain Obvious
3396:60 283 RTS ; DONE
284 EC2 EQU *
"Show me your code and I'll have to guess at your data (structures), Show me your data and I won't have to see your code, I'll already know it." -- Michael, paraphrasing Fred Brooks "Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowcharts; they'll be obvious." -- Fred Brooks Let the complete clusterfrak of bad design commence in 3..2..1..PUFF! 001 PAGE ; This is why I partially dislike old source code: 002 ;MISC DOS WORK CELLS ; (almost) Everything has been abbreviated 003 ; ; (almost) to the point of obfuscation. 3397:00 004 CVDTRK DFB 0 ; CUR VOL DIR TRK ; i.e. 3398:00 005 CVDSEC DFB 0 ; CUR VOL DIR SECTOR ; ENT = Entry 3399:00 00 006 CURCCB DFB 0,0 ; CURRENT CCB ADR ; ALC = Allocation 339B:00 007 ENTSTK DFB 0 ; ENTRY STACK POINTER ; Why are we futzing with the stack pointer??? 339C:00 008 TEMP1 DFB 0 ; TEMP BYTE1 ; /sarcasm o7 Captain Obvious 339D:00 009 TEMP2 DFB 0 ; TEMP BYTE 2 ; *note* All the cool kids use "o7" for salute these days 339E:00 010 TEMP3 DFB 0 ; TEMP BYTE 3 ; Used by FLOCK, FUNLCK and GSS1 339F:00 011 ENTSLT DFB 0 ; BOOT SLOT SAVE 33A0:00 00 FF FF 012 ALC10S DFB 0,0,$FF,$FF ; ALLOCATION TRACK BIT MAP ; wastes 2 bytes/track free sector bitmap mask, used in NT3; See DCBABM, ; The thinking (if there even was any) was probably: ; DOS 3.2 = 13 sector ; DOS 3.3 = 16 sector ; DOS 3.4 > 16 sector -- See VNOSEC ; === HNTDAFS #1 === ; Anytime you see the word reserved or unused in a (file) format ; your spidey sense should be tingling. ; Translation: I pulled this out of my ass -- ; because I didn't actually measure what is needed!" 33A4:01 0A 64 013 CVTAB DFB 1,10,100 ; CONVERSION TABLE ; Powers of 10; sadly Applesoft's DECTBL @ $EE6C is useless :-/ 014 MSC ON ; Switch ASCII to Apple Text (high bit set) 33A7:D4 C9 C1 C2 015 FTTAB ASC "TIAB" ; FILE TYPE CONVERSTION TABLE" ; File Types You couldn't use file types that make visual hex editing easier?? ; Type Code Dumb Smart ; Applesoft Basic A 02 Ctrl-B 01 Ctrl-A ; Binary B 04 Ctrl-D 02 Ctrl-B ; c 03 ; d 04 ; e 05 ; f 06 ; g 07 ; h 08 ; Integer Basic I 01 Ctrl-A 09 Ctrl-I ; You have 3 guesses to tell which DOS uses and the first 2 don't count. 33AB:D3 D2 C1 C2 016 ASC "SRAB" ; *sigh* Really, you just had to re-use AB ?? ; === HNTDAFS #2 === ; Gee, how about using, oh I don't know: CD ; At the very least D = "user Defined" or *shock* directory: ; C = Child (directory) Parent Track/Sector, e.g. T$11S$F ; D = Directory (child), e.g. T$12S$F ; Yeah, yeah 20/20 33AF:A0 C5 CD D5 017 VOLMES ASC " EMULOV KSID" ; "DISK VOLUME " BACKWARDS ; *sigh* Micro-optimization; Not that these are bad but 33B3:CC CF D6 A0 ; /sarcasm Lets focus on a single tree, 33B7:CB D3 C9 C4 ; and completely miss the entire fraking forest! 018 MSB OFF ; Switch back to 7-bit ASCII 019 VML EQU *-VOLMES-1 ; Used by File FDELCAT, Func RDIR, Line 113 020 PAGE ; 021 ;VTOC RECORD AREA ; === VTOC === 022 VTOC EQU * ; T11S0 [offset], Right side = normal snarky commentary 33BB:04 023 VDOST DFB 4 ; DOS TYPE ; [00] wastes 1 byte -- never referenced ! ; magic number /sarcasm If only FILESYSTEM_TYPE_VTOC EQU $4 33BC:11 024 VDIRTK DFB 17 ; COLUME DIRECTORY SECTOR ; [01] *spelling* VOLUME, *sigh* TRACK not sector -- read the bloody variable name! ; Used by VTIO ; *note* This is only a copy. To change DOS while running ; F01A+4:11 → DCBVTN ; $2C01:11 → $35FA ; $AC01:11 → $B5FA 33BD:0F 025 VDIRSC DFB 15 ; VOLUME DIRECTORY SECTOR ; [02] Used by File FLOCNXB, Func RVDC, Line ?? 33BE:04 026 VDOSRN DFB 4 ; DOS RELEASE NUMBER ; [03] *sarcasm* I guess VERSION made too much sense. 33BF:00 027 DFB 0 ; SPARE ; [04] wastes 1 byte /sarcasm "Because someday these might be used ... ?" 33C0:00 028 DFB 0 ; SPARE ; [05] wastes 1 byte ಠ_ಠUh-huh. 33C1:FE 029 VVOLNO DFB $FE ; VOLUME NUMBER ; [06] Design for today, not someday 33C2:FC FD FF FC 030 DS 32 ; SPARE ; [07] wastes 32 bytes, WTF ! 33C6:FF FC FC FE ; Gee, here's an idea: 33CA:FF FC FD FF ; Instead of wasting space in the VTOC 33CE:FE FF FD FE ; 1) Pack our data by removing all the unused crap: 33D2:FF FD FD FD ; Total 1+1+32+8 = 42 bytes! 33D6:FF FE FD FF ; 2) Put VTOC data as first XX bytes in the T11SF CATALOG 33DA:FC FF FF FD ; 33DE:FD FC FE FE ; 33E2:7A 031 VTDMS DFB 122 ; MAX SECTORS IN A FILE DIR ; [27] *sigh* not 128 so we can BMI (Branch on Minus) ??? (Copied to DCBDMS) 33E3:FE FD FF FD 032 VSPARE DS 8 ; SPARES ; [28] wastes 8 bytes, Oh FFS already ... 33E7:FE FE FF FC 033 ; ; Who 1) designed, and 2) implemented this crap?!?! 33EB:11 034 VALCA1 DFB 17 ; ALOCATION ALGORITHM BYTE 1 ; [30] ALLOC_TRK Last allocated track TODO Cross-Ref 33EC:01 035 VALCA2 DFB 1 ; AA BYTE2 ; [31] ALLOC_DIR Direction of last track allocation -- Used by GS4 ; +1 = $01 inwards to T22, ; -1 = $FF outwards to T00. 33ED:00 036 VALCA3 DFB 0 ; AA BYTE3 ; [32] wastes 1 byte /sarcasm I really don't know what we 33EE:00 037 VALCA4 DFB 0 ; AA BYTE4 ; [33] wastes 1 byte would do without you Captain Obvious! 33EF:23 038 VNOTRK DFB 35 ; NO TRACKS ON VOL ; [34] *note* "No" = Number; To format more then 35 tracks: ; $AEFE:## ($3EFE), See: FORMATR, Line #054 33F0:10 039 VNOSEC DFB 16 ; NO SECTORS PER TRACK ; [35] Evidence that one day DOS 3.4+ might support: 33F1:00 01 040 VSECLN DW 256 ; NO. BYTES PER SECTOR ; [36] (Little) > 16 sectors/track 041 ; ; [37] (Endian) and > 256 bytes/sector. 042 VSECAL EQU * ; *note* Actual VTOC header is $F3-$BB = $38 bytes ; But we only really use: ; VVOLNO (dubious value; ProDOS users don't miss it.) ; VALCA1 ; VALCA2 ; a total of 3 bytes out of 56! ; That is ~5% usage!?!? ; wastes 70 bytes (35 tracks * 2) due to allocating 32 sectors/track! 043 ;SECTORS ALLOCATED BY BIT MAP ;struct TrackBitmap { // Bits = MSB.LSB 044 ;4 BYTES OF BITS PER TRACK ; uint8_t _f_8; //[0] Sectors: FEDCBA98 0=Used 045 ;LEFT MOST BIT REPRESENTS SECTOR ; uint8_t _7_0; //[1] Sectors: 76543210 1=Free 046 ;WHERE N=NO SECTORS PER TRACK ; uint8_t pad1; //[2] *sigh* 1 byte unused 047 ; ; uint8_t pad2; //[3] *sigh* 1 byte unused 048 ; ; } FreeSectors[ $22 ]; // Technically have room for $31 (49) tracks ;*sigh* Bytes stored : 35*4 bytes = 140 bytes ($8C) ; When we only need: 35*2 bytes = 70 bytes ($46) ;As Mike Acton says: "Solve the actual problem, ; NOT the one you think you have." 049 PAGE ;B3F3 =T00 33F3:FF 050 ORG VTOC+256 ; [38]=T00 00,00,FF,FF See HNTDAFS #3; Why not simply DS 256-VSECAL-VTOC,0 ??? 33F4:FC FC FD FC ; [3C]=T01 00,00,FF,FF Uninitialized memory is never a good idea 33F8:FE FC FC FD ; [40]=T02 00,00,FF,FF See HNTDAFS #4 33FC:FD FE FC FC ; [44]=T03 === T2S3 === disk wastes an entire sector for a single byte!? 3400:FF FC FC FD ; [48]=T04 The real kicker? VDTCDE isn't even bloody used! *facepalm* 3404:FC FD FD FC ; [4C]=T05 3408:FF FE FC FC ; [50]=T06 We then proceed to waste $C8 bytes (256-VSECAL-VTOC) 340C:FC FC FE FE ; [54]=T07 to force us to span 2 sectors with this dumb shit 3410:FC FD FC FC ; [58]=T08 instead of copying the VTOC header ($38 byte) 3414:FC FE FC FD ; [5C]=T09 into a new temporary page on init! 3418:FC FC FE FC ; [60]=T0A 341C:FC FC FE FC ; [64]=T0B === HNTDAFS #4 === 3420:FC FF FC FC ; [68]=T0C DOS reserves the entire Track 2 even though it only uses T2S0 - T2S4 !? 3424:FC FC FD FD ; [6C]=T0D 3428:FC FF FF FC ; [70]=T0E Instead of wasting yet another track T11 for meta data 342C:FE FD FE FD ; [74]=T0F 3430:FE FC FF FC ; [78]=T10 S0 = VTOC, S1-SF = CATALOG 3434:FE FF FD FC ; [7C]=T11 00,00,FF,FF 3438:FF FC FC FC ; [80]=T12 if we weren't dumb then both the 343C:FD FE FD FE ; [84]=T13 VTOC & CATALOG would reside on T2S5 - T2SF 3440:FC FC FC FF ; [88]=T14 3444:FE FC FC FD ; [8C]=T15 === HNTDAFS #3 === 3448:FC FD FF FC ; [90]=T16 DOS is unable to use Track 0 to store user files. 344C:FC FC FC FE ; [94]=T17 This means a non-bootable data disk is robbed of an additional 15 sectors! 3450:FD FC FD FC ; [98]=T18 (Boot sector would display non-bootable message) 3454:FC FC FD FC ; [9C]=T19 See File FLOCSEC, Func GETSEC, Line #83; Trk Free FRESEC, Line #183; Trk Allocation todo 3458:FD FF FC FE ; [A0]=T1A The smart thing to have done would be to 345C:FD FC FC FD ; [A4]=T1B put the VTOC and CATALOG on T0SF or T0S1 3460:FC FC FC FC ; [A8]=T1C That way both a bootable and data disk would 3464:FC FC FF FF ; [AC]=T1D get an extra 16 sectors of free disk space. 3468:FE FC FF FC ; [B0]=T1E 346C:FD FF FE FF ; [B4]=T1F The BOOTLDR would just need to move the 3470:FE FE FC FC ; [B8]=T20 disk head to track T1 and continue loading as normal. 3474:FD FC FC FC ; [BC]=T21 3478:FE FE FE FD ; [C0]=T22 (Normal last 35th accessible track) 347C:FE FD FC FE ; [C4]=T23 (Extra 36th track) 3480:FD FD FC FC ; [C8]=T24 (Extra 37th track) 3484:FE FE FC FC ; [CC]=T25 (Extra 38th track) 3488:FD FC FC FE ; [D0]=T26 (Extra 39th track) 348C:FC FC FD FC ; [D4]=T27 (Extra 40th track) 3490:FE FE FC FD ; [D8]=T28 3494:FC FC FC FC ; [DC]=T29 wastes 40 bytes [$D8..$FF] = $28 3498:FC FD FD FC ; [E0]=T2A *note* Tracks 41+ are not accessible 349C:FE FD FC FC ; [E4]=T2B on any drive that I know of. 34A0:FE FC FC FC ; [E8]=T2C That's not to say that they don't 34A4:FC FC FE FC ; [EC]=T2D exist but >basic engineering and repair 34A8:FD FD FC FF ; [F0]=T2E should tell us that accessing 34AC:FD FC FE FE ; [F4]=T2F more then 40 tracks is not possible. 34B0:FC FD FD FE ; [F8]=T30 Write for today, not "someday" 34B4:FF FD FE FF ; [FC]=T31 (Extra 50th track) 34B8:FE FF FC ; 051 ; 052 ;VOLUME DIRECTORY AREA ; 053 ; ; [--] T11SF offsets === CATALOG ===
054 VOLDIR EQU * ; ; === Page 87 === 34BB:02 055 VDTCDE DFB 2 ; VOLUME DIRECTORY TYPE CODE ; [00] wastes 1 byte -- and not even used !?!?! ; magic number /sarcasm If only FILESYSTEM_TYPE_CATALOG EQU $02 34BC:FC 056 VDLTRK DS 1 ; VD LINK TRACK ; [01] ($11) 34BD:FD 057 VDLSEC DS 1 ; VD LINK SECTOR ; [02] ($0E) 34BE:FC 058 VDNF DS 1 ; VD NUMBER FILES THIS SECTOR ; [03] wastes 1 byte -- never referenced 34BF:FC FC FE FE 059 VDSPAR DS 7 ; SPARES ; [04] wastes 7 bytes -- never referenced 34C3:FE FD FE 060 ; ; /sarcasm Glad to see this was put to good use ... NOT! 061 VDFILE EQU * ; FILE ALLOCATION AREA (7 FILES); [0B] NO, this is the _not_ the allocation; this is the *meta* data 062 ;EACH FILE: ; What can't do DSECT VDFILE *note* indented "struct FileEntry" for readability 063 ; FILE DIR TRK ; DFB CAT_FILE_TRACK ;[00] (0) inode (FILDIR) track 064 ; FILE DIR SECTOR ; DFB CAT_FILE_SECTOR ;[01] (1) inode (FILDIR) sector 065 ; FILE USE CODE ; DFB CAT_FILE_TYPE ;[02] (2) 066 ; FILE NAME (30) ; DS CAT_FILE_NAME ;[03] (3) WTF -- sizeof( FileEntry ) == 35 bytes; make it 27 067 ; FILE SECTOR COUNT (2) ; DW CAT_FILE_NUM_SEC ;[21] (33) so entire struct is 32 bytes 34C6:FF FE 068 ORG VOLDIR+256 ; wastes 256 bytes of disk space spanning two sectors *double facepalm* 34C8:FC FC FC FC 34CC:FC FE FC FD 34D0:FC FC FF FD 34D4:FC FE FC FC 34D8:FD FE FE FF 34DC:FC FE FF FD 34E0:FF FE FC FC 34E4:FE FE FD FF 34E8:FE FF FF FD 34EC:FC FE FF FC 34F0:FE FD FE FC 34F4:FE FC FF FE 34F8:FE FE FC FD 34FC:FD FE FF FC 3500:FC FC FC FC ; === T2S4 === 3504:FC FE FC FD 3508:FD FC FF FD ; /sarcasm Who cares, we have 140KB, right! 350C:FC FE FE FC 3510:FE FD FC FF 3514:FF FC FC FE 3518:FE FD FE FD 351C:FE FE FC FC 3520:FE FD FD FC 3524:FE FD FC FC 3528:FE FC FC FE 352C:FC FC FD FC 3530:FD FD FC FF 3534:FD FC FE FD 3538:FC FD FF FC 353C:FE FC FC FC 3540:FC FC FC FD 3544:FC FC FE FC 3548:FD FC FC FF 354C:FC FC FE FD 3550:FC FD FF FC 3554:FF FD FE FF 3558:FD FF FE FC 355C:FD FF FF FF 3560:FC FC FE FC 3564:FC FF FF FC 3568:FC FD FC FE 356C:FC FC FC FC 3570:FC FE FC FC 3574:FD FD FC FC 3578:FE FC FD FC 357C:FC FE FE FC 3580:FC FC FC FC 3584:FF FC FC FC 3588:FC FD FD FC 358C:FF FC FC FE 3590:FF FC FD FF 3594:FC FF FD FE 3598:FF FD FD FD 359C:FF FE FD FF 35A0:FC FF FD FD 35A4:FD FC FE FC 35A8:FC FF FE FC 35AC:FC FE FC FC 35B0:FE FC FD FD 35B4:FC FF FD FC 35B8:FE FC FC 069 VDEND EQU * 070 VDLEN EQU *-VOLDIR ; VDEND - VOLDIR = $35BB - $34BB = 256 071 VDFLEN EQU *-VDFIL ; VDEND - VDFIL = $35BB - $34C6 = $F5 072 ; 073 PAGE 074 ; 075 ;COMMAND CONTROL BLOCK (CCB) 076 ; 077 CCB EQU * ;$B5BB CCB Buffer; FM = File Manager 35BB:FF 078 CCBREQ DS 1 ; USER REQUEST BYTE ; [0] FM_Command = 0, See GetCCBAdr aka CCBLDR 079 CRQNUL EQU 0 ; 0-NO REQUEST ; WTF!!! NO ONE will ever call DOS's NOP!!! 080 CRQOPN EQU 1 ; 1-OPEN FILE ; Crap abbreviations: CMD_FILE_OPEN 081 CRQCLS EQU 2 ; 2-CLOSE FILE ; CMD_FILE_CLOSE 082 CRQRD EQU 3 ; 3-READ DATA ; CMD_FILE_READ 083 CRQWR EQU 4 ; WRITE DATA ; What happened to 4? CMD_FILE_WRITE 084 CRQDEL EQU 5 ; 5-DELETE FILE ; CMD_FILE_DELETE 085 CRQDIR EQU 6 ; 6-READ DIRECTORY ; CMD_DIR_READ 086 CRQLCK EQU 7 ; 7-LOCK FILE ; CMD_FILE_LOCK 087 CRQUNL EQU 8 ; 8-UNLOCK FILE ; CMD_FILE_UNLOCK 088 CRQRNM EQU 9 ; 9-RENAME ; CMD_FILE_RENAME 089 CRQPOS EQU 10 ; 10-POSITION FILE ; CMD_FILE_SEEK 090 CRQFMT EQU 11 ; 11-FORMAT ; CMD_DISK_FORMAT 091 CRQVAR EQU 12 ; 12 - VERIFY ; Really? CMD_DISK_VERIFY 092 CRQMAX EQU 13 ; ; You couldn't be consistent with first 11? 093 ; 094 CCBBSA EQU * ; FORMAT - BOOT START ADR PAG 35BC:FF 095 CCBRQM DS 1 ; RREQUEST MODIFIER BYTE ; [1] FM_RequestMod = 1 (SubCommand) *spelling* RREQUEST. RRReally?? 096 CRMNUL EQU 0 ; NO MODIFIER ; And this serves what purpose again ??? 097 CRMNBT EQU 1 ; R/W - 1 - NEXTBYTE 098 CRMNBL EQU 2 ; R/W - 2 - NEXTBLOCK 099 CRMSBT EQU 3 ; R/W - 3 - SPECIFCBYTE 100 CRMSBL EQU 4 ; R/W - 4 - SPECIFIC BLOCK 101 CRMMAX EQU 5 102 ; 103 CCBRRN EQU * ; I/O - RELATIVE RECORD NUMBER ; Relative Record Number, see LOCSEC 104 CCBFN2 EQU * ; RENAME - FILE NAME 2 PTR ; Address of FileNameDst 35BD:FC FC 105 CCBRLN DS 2 ; OPEN - RECORD LENGTH ; [2] FM_RelRecordNum 106 ; 107 CCBBYT EQU * ; I/O - RELATIVE BYTE NO (2 BYTES) 35BF:FD 108 CCBVOL DS 1 ; OPEN - VOL NO. ; [4] FM_Volume 35C0:FC 109 CCBDRV DS 1 ; OPEN - DRIVE ; [5] FM_Drive 110 ; 111 CCBBLN EQU * ; I/O - BLOCK LENGTH (2 BYTES) ; FM_BLockLength 35C1:FE 112 CCBSLT DS 1 ; OPEN - SLOT NO ; [6] FM_Slot 35C2:FE 113 CCBFUC DS 1 ; OPEN - FILE USE CODE ; [7] FM_FileUseCode (File Type), See TSTFUC, FRNME 114 ; 115 CCBFN1 EQU * ; OPEN, DELETE, LOCK, UNLOCK, RENAME - FILENAME
116 CCBBBA EQU * ; BLOCKK I/O - BLOCK BUFFER PTR ; === Page 88 === *spelling* BLOCK, OKKK 35C3:FE FC 117 CCBDAT DS 2 ; BYTE I/O - DATA BYTE ; [8] 118 ; 35C5:FF 119 CCBSTA DS 1 ; RESULT STATUS ; [A] Return Code 120 CREFUN EQU 1 ; FCB UNALLOCATED ; See: ERROR1 121 CRERR EQU 2 ; CCB REQ RANGE ERR ; See: ERROR2 122 CREMRE EQU 3 ; REQ MOD RANGE ERR ; See: ERROR3 123 CREPRO EQU 4 ; WRITE PROTECT ; See: ERROR4 124 CREEOF EQU 5 ; END OF FILE ON READ ; See: ERROR5 125 CREFNF EQU 6 ; FILE NOT FOUND ; See: ERROR6 126 CREVMM EQU 7 ; VOL MIS MATCH 127 CREIOE EQU 8 ; I/O ERR 128 CRENSA EQU 9 ; NO SECTORS AVAILABLE ; See: ERROR9 129 CREFLK EQU 10 ; FILE LOCKED ; See: ERROR10 130 ; 35C6:FC 131 CCBSM DDS 1 ; STATUS MODIFIER ; [B] FM_WASTED1 wastes 1 byte; never used! Can't remove since middle of struct. 35C7:FF FC 132 CCBFCB DDS 2 ; FCB PTR ; [C] FM_FCB_PTR 35C9:FF FF 133 CCBDBP DDS 2 ; DIR BUF PTR ; [E] FM_DIR_PTR 35CB:FE FC 134 CCBSBP DDS 2 ; SECTOR BUF PTR ;[10] FM_SEC_PTR 35CD:FE FC FD FF 135 CCBSPR DDS 4 ; SPARE ;[12] FM_WASTED2 wastes 4 bytes /sarcasm Someday, someday. 136 CCBLEN EQU *-CCB ; CCB LENGTH ;$16 137 CFCBAD EQU CCBFCB 138 CFCBDR EQU CCBDBP 139 CFCBSB EQU CCBSBP 140 PAGE 141 ; 142 ;FILE CONTROL BLOCK (FCB) DEFINITION 143 ;DCB - FILE DATA CONTROL BLOCK 144 ; 145 FCB EQU * 146 ; 147 ;DATA CONTROL BLOCK 148 ; 149 FCBDCB EQU * 35D1:FF 150 DCBFDT DS 1 ; 1ST FILE DIRECTORY TRACK ; [00] 35D2:FD 151 DCBFDS DS 1 ; 1ST FILE DIRECTORY SECTOR ; [01] 35D3:FD 152 DCBCDT DS 1 ; CURRENT FILE DIRECTORY TRACK ; [02] 35D4:FE 153 DCBCDS DS 1 ; CURRENT FILE DIRECTORY SECTOR ; [03] 35D5:FC 154 DCBWRF DS 1 ; WRITE REQD FLAG ; [04] 155 ;$80=WRITE FILE DIR 156 ;$40=WRITE SECTOR DIR 35D6:FC 157 DCBTRK DS 1 ; SECTOR TRACK ADR ; [05] 35D7:FC 158 DCBSEC DS 1 ; SECTOR ADR ; [06] 35D8:FC 159 DCBVDR DS 1 ; VOL DIR REC ; [07] DEC by FC1 35D9:FC 160 DCBVDI DS 1 ; VOL DIR INDEX ; [08] FNDFIL: X = File entry offset in CATALOG sector, FOPEN, FCLOSE 35DA:FE FD 161 DCBDMS DS 2 ; MAX NO DIRECTORY SECTORS ; [09] 35DC:FD FF 162 DCBDFS DS 2 ; CURRENT DIR 1ST REL SECTOR ; [0B] 35DE:FE FC 163 DCBDNF DS 2 ; REL SECTOR OF NXT DIR ; [0D] 35E0:FE FC 164 DCBCMS DS 2 ; SECTOR CURRENTLY IN MEMORY ; [0F] 35E2:FC FC 165 DCBSDL DS 2 ; SECTOR DATA LENGTH ; [11] 35E4:FF FC 166 DCBCRS DS 2 ; CURRENT RELATIVE SECTOR ; [13] See FVAR 35E6:FC FE 167 DCBCSB DS 2 ; CURRENT SECTOR BYTE ; [15] 35E8:FE FC 168 DCBRCL DS 2 ; RECORD LENGTH ; [17] 35EA:FE FC 169 DCBCRR DS 2 ; CURRENT RELATIVE REC ; [19] 35EC:FC FC 170 DCBCRB DS 2 ; CURRENT RELATIVE BYTE ; [1B] 35EE:FF FC 171 DCBNSA DS 2 ; NO SECTORS ALLOCATED ; [1D] Number of Sectors Allocated 172 ; 35F0:FC 173 DCBALS DS 1 ; ALLOCATION SECTOR BYTE ; [1F] 35F1:FC 174 DCBATK DS 1 ; ALLOCATION TRACK ; [20] 35F2:FE FC FC FF 175 DCBABM DS 4 ; ALLOCATION TRACK SECTOR BIT MAP;[21] wastes 2 bytes, See FS3 and Line #184 176 ; 35F6:FD 177 DCBFUC DS 1 ; FILE USE CODE ; [25] 35F7:FE 178 DCBSLT DS 1 ; SLOT NUMBER ; [26]
35F8:FC 179 DCBDRV DS 1 ; DRIVE NUMBER ; [27] === Page 89 === 35F9:FC 180 DCBVOL DS 1 ; VOLUME DRIVER ; [28] 35FA:FD 181 DCBVTN DS 1 ; VTOC TRACK NUMBER ; [29] Why isn't this DFB 17?? See F01A 182 ; 35FB:FC FC FF 183 DCBSPR DS 3 ; SPARES ; [2A] wastes 3 bytes, Zeroed via DCBSUP, *unused* 184 ; 185 DCBLEN EQU *-FCBDCB ; DCB LENGTH ; $2D = $35FE - $35D1 = $002D, used in exactly 1 place DCBSUP 186 FCBLEN EQU *-FCB ; FCB LENGTH ; $2D = $35FE - $35D1 = $002D 187 ;
001 SBTL '16-SECTOR DOS BOOT'
002 HERE3L EQU >* ; $FE End of FVCBUFS = $35FD, * = $35FE
003 REMDR3 EQU 256-HERE3L ; $02 Remainder 2 bytes for page alignment
35FE:FD FC 004 ORG *+REMDR3 ; $3600 wastes 2 bytes to page align BOOTLDR
005 TRK0LDR EQU *
006 DO >TRK0LDR ; Low byte of address controls if macro is on/off
007 ??? ;DELIBERATE ERROR IF NOT AT PAGE BOUNDARY
008 FIN
009 ***************************
010 * *
011 * 16-SECTOR DOS BOOTSTRAP *
012 * *
013 * RICK AURICCHIO *
014 * 10/10/79 *
015 * *
016 ***************************
017 * *
018 * THIS PROGRAM RESIDES IN *
019 * TRACK 0,SECTOR 0 OF A *
020 * DOS DISKETTE. ITS SOLE *
021 * PURPOSE IS TO READ THE *
022 * DOS LOADER PROGRAM IN *
023 * FROM TRACK 0, SECTORS *
024 * 1-9. CONTROL IS THEN *
025 * TRANSFERRED TO THAT *
026 * PROGRAM. *
027 * *
028 * NOTE: THE DOS LOADER *
029 * CONTAINS THE ENTIRE *
030 * SET OF 16-SECTOR CORE *
031 * ROUTINES; THOSE CORE *
032 * ROUTINES ARE USED TO *
033 * LOAD THE REST OF THE *
034 * DOS IMAGE INTO MEMORY. *
035 * *
036 ***************************
037 POINTA EQU $26 ;BUFFER POINTER
038 BSLOT EQU $2B ;BOOT BSLOT
039 BSECTR EQU $3D ;LAST BSECTR READ
040 BTEMP EQU $3E ;ADDRESS BTEMP
041 BRETRY EQU $5C ;OFFSET TO READER
042 *
043 MONINIT EQU $FB2F ;MONINIT SCREEN
044 BHERE3 EQU >* ; unused $00, TRK0LDR already used to test page alignment.
045 BOOTCNT EQU $800+BHERE3 ; unused but used as placeholder for P6 ROM
3600:01 046 DFB 01 ; We could store $10 here to have the P6 PROM read 16 sectors but nah,
047 PAGE ; let's waste $839-$801 = $38 (56) bytes instead!
3601:A5 27 048 LDA POINTA+1 ;WHERE DID BSECTR GET LOADED? ;[.. wastes 56 bytes; Get memory page of last load
3603:C9 09 049 CMP #09 ; (AT 0800)? ; ..
3605:D0 18 050 BNE READNEXT ;=>NO. WE'RE LOADING SOMETHING ; ..
051 * WE'VE BEEN BOOTED. SET UP ; ..
052 * PARAMS FOR BOOT PROM SO ; ..
053 * THAT WE'LL READ IN TRACK 0, ; .. === Page 9 ===
054 * BSECTRS 00-09. ; ..
3607:A5 2B 055 LDA BSLOT ;GET BOOT SLOT ; ..
3609:4A 056 LSR A ;CONVERT TO CX00 ; ..
360A:4A 057 LSR A ; ..
360B:4A 058 LSR A ; ..
360C:4A 059 LSR A ; ..
360D:09 C0 060 ORA #$C0 ; ..
360F:85 3F 061 STA BTEMP+1 ; .. magic number IO_SLOT_PAGE EQU $C0
3611:A9 5C 062 LDA #BRETRY ; PROM ROUTINE OFFSET ; ..
3613:85 3E 063 STA BTEMP ; ..
3615:18 064 CLC ;BUMP LOAD ADDRESS UP TO ; ..
3616:AD FE 08 065 LDA LOADADDR+1 ; LAST PAGE SO WE ; ..
3619:6D FF 08 066 ADC BGRPGC ; CAN LOAD 'EM BACKWARDS ; ..
361C:8D FE 08 067 STA LOADADDR+1 ; ..
068 * READ IN ANOTHER BSECTR FROM ; ..
069 * TRACK ZERO... ; ..
361F:AE FF 08 070 READNEXT LDX BGRPGC ; ..
3622:30 15 071 BMI GOLOADER ;=>ALL DONE...EXECUTE IT! ; ..
3624:BD 4D 08 072 LDA TABLE,X ;GET PHYSICAL BSECTR NUMBER ; .. /sarcasm Real original name there guys. WTF does TABLE refer to???
3627:85 3D 073 STA BSECTR ; AND SET FOR BOOT PROM READ ; .. You couldn't call it LOGSECTR for LOGical SECToR??
3629:CE FF 08 074 DEC BGRPGC ;ONE LESS BELL TO ANSWER... ; ..
362C:AD FE 08 075 LDA LOADADDR+1 ;GET LOAD ADDRESS ; ..
362F:85 27 076 STA POINTA+1 ; FOR BSECTR READ ; ..
3631:CE FE 08 077 DEC LOADADDR+1 ;MOVE LOAD ADDRESS DOWN A PAGE ; ..
3634:A6 2B 078 LDX BSLO ;RESTORE BSLOT NUMBER ; ..
3636:6C 3E 00 079 JMP (BTEMP) ;READ MORE OF TRACK 0 ; ..]
3639:EE FE 08 080 GOLOADER INC LOADADDR+1 ;ENTRY AT SECOND PAGE
363C:EE FE 08 081 INC LOADADDR+1
363F:20 89 FE 082 JSR SETKBD ;CLEAR IN#X
3642:20 93 FE 083 JSR SETVID ; AND PR#X
3645:20 2F FB 084 JSR MONINIT ;MONINIT THE SCREEN PARAMS
3648:A6 2B 085 LDX BSLOT ;PASS BSLOT NBR TO LOADER
364A:6C FD 08 086 JMP (LOADADDR) ;OFF TO LOOADER! ; *spelling* Loader
087 * TABLE OF PHYSICAL BSECTR NUMBERS
088 * WHICH CORRESPOND TO THE LOGICAL
089 * BSECTRS 0-F ON TRACK ZERO...
090 BHERE2 EQU >* ; $4D low byte (modern assemblers use > as high byte meaning)
091 TABLE EQU $800+BHERE2 ; $084D Our native address is $3600 but also loaded at $0800
;
; This is one time where you don't want to compact lines
; Problem: Compare & contrast this clusterfrak
364D:00 0D 0B 092 DFB $00,13,11 ;00->00,01->13,02->11 ; WHY is this grouped in triplets??? *sigh* inconsistent $00 code
3650:09 07 05 093 DFB 09,07,05 ;03->09,04->07;05->05 ; We have a sector interleave of two! *sigh* inconsistent: ; comment
3653:03 01 0E 094 DFB 03,01,14 ;06->03,07->01,08->14 ; The last line having an even number
3656:0C 0A 08 095 DFB 12,10,08 ;09->12,10->10,11->08 ; of terms wasn't your first clue!?!
3659:06 04 02 0F 096 DFB 06,04,02,15 ;12->6,13->04,14->02,15->15 ; *sigh* inconsistent 6 comment
; Solution:
; LOG_TO_PHYS EQU *
; DFB $0 ; [0] 0
; DFB $D ; [1] 13
; DFB $B ; [2] 11
; DFB $9 ; [3] 9
; DFB $7 ; [4] 7
; DFB $5 ; [5] 5
; DFB $3 ; [6] 3
; DFB $1 ; [7] 1
; DFB $E ; [8] 14
; DFB $C ; [9] 12
; DFB $A ; [A] 10
; DFB $8 ; [B] 8
; DFB $6 ; [C] 6
; DFB $4 ; [D] 4
; DFB $2 ; [E] 2
; DFB $F ; [F] 15
097 PAGE
098 REP 40 ; alias for ****************************************
099 * APPEND BUG PATCHES
100 ****************************
101 SC3 EQU *
365D:00 102 EOFFLAG DFB 0
103 CLOSFILE EQU *
365E:20 64 27 104 JSR FILSRC ;FILE BUFFER FOUND?
3661:B0 08 105 BCS NOTFOUND ;=> NO, SO SKIP IT.
3663:A9 00 106 LDA #0 ;YES, CLOSE IT ;magic number
3665:A8 107 TAY
3666:8D 5D 36 108 STA EOFFLAG
3669:91 40 109 STA (ZPGWRK),Y ;RIGHT NOW
366B:AD C5 35 110 NOTFOUND LDA CCBSTA ;ORIGINAL INSTRUCTION
366E:4C D2 26 111 JMP ERROR ;BACK TO ERROR HANDLER
112 ****************************
113 BUMPER EQU *
3671:AD 5D 36 114 LDA EOFFLAG ;SHOULD WE?
3674:F0 08 115 BEQ GOBACK ;=> NO
3676:EE BD 35 116 INC CCBRRN ;BUMP CCB RECORD NUMBER ; === Page 10 ===
3679:D0 03 117 BNE GOBACK
367B:EE BE 35 118 INC CCBRRN+1 ;TO GET TO NEXT SECTOR
367E:A9 00 119 GOBACK LDA #0
3680:8D 5D 36 120 STA EOFFLAG ;TURN FLAG OFF
; Note: Code here can be used to tell the version of DOS 3.3: DOS 3.3A AUG 1980, DOS 3.3B JAN 1983, or DOS 3.3C 1983 !
; Oh look, we have lowercase support for when CapsLock is on the Apple //e!
4C 46 25 JMP FIXIT2 ; DOS 3.3A AUG 1980 4C 46 25 → JMP $A546
4C 84 3A JMP FIXIT2 ; DOS 3.3B JAN 1983 4C 84 3A → JMP $BA84 -- see Line #144 in MSWAITR below--
3683:4C B3 36 121 JMP FIXIT2 ;Go to FIXIT2 as exit ;↓ DOS 3.3C ??? 1983 4C B3 36 → JMP $B6B3 Page 36, D/001B80:8D 5D 36 4C B3 36
122 REP 40
123 VPATCH EQU *
3686:8D BC 35 124 STA CCBRQM ;ORIGINAL INSTRUCTION
3689:20 A8 26 125 JSR DOSGO ;GO SAVE
368C:20 EA 22 126 JSR ECLOSE ;CLOSE THE FILE
368F:4C 7D 22 127 JMP EVAR ;GO VERIFY IT AFTER SAVE
128 ****************************
129 EOFFIX EQU *
3692:A0 13 130 LDY #$13 ;PEEK INTO THE FCB: IF ; magic number FCB_CUR_REL_SEC
3694:B1 42 131 CHKFILE LDA (ZPGFCB),Y ;DCBCRS,DCBCSB ARE ZEROS,
3696:D0 14 132 BNE FIXIT ; THEN WE HAVE EMPTY FILE
3698:C8 133 INY
3699:C0 17 134 CPY #$17 ; magic number FCB_REC_LEN
369B:D0 F7 135 BNE CHKFILE
369D:A0 19 136 LDY #$19 ; magic number FCB_CUR_REL_REC
369F:B1 42 137 MOVE LDA (ZPGFCB),Y ; DCBCRR,DCBCRB
36A1:99 A4 35 138 STA CCBRRN-$19,Y;INTO CCBRRN,CCBBYT ; magic number FCB_CUR_REL_REC
36A4:C8 139 INY
36A5:C0 1D 140 CPY #$1D ; magic number FCB_NUM_SEC_ALLOC
36A7:D0 F6 141 BNE MOVE
36A9:4C BB 26 142 BACK JMP DOSGO2A ;NOW LET APPEND CONTINUE
143 FIXIT EQU *
36AC:A2 FF 144 LDX #$FF ;SET FLAG SO APPEND WILL ; magic number FLAG_EOF_SEC_BOUNDARY EQU $0
36AE:8E 5D 36 145 STX EOFFLAG ;KNOW TO CROSS SECTOR BOUNDARY
36B1:D0 F6 146 BNE BACK ;ALWAYS TAKEN ; ↑
147 PAGE
148 REP 40
149 * END OF BOOT PAGE DATA SETUP
150 REP 40
151 *
152 * FIXIT2 was developed to fix the wrap around ; Note: This is NOT at this address in DOS 3.3A 1980 or DOSB 3.3B 1983
153 * problem APPEND has when trying to APPEND to ; In DOS 3.3B it was located at $3A84 (see line 121 above)
154 * a sequential file which is > 255 sectors in length.
155 *
156 * Fix by
157 *
158 * Fern Bachman
159 * Guil Banks
160 * September 28, 1982
161 *
162 * Fix to fix added to correctly APPEND to a SECTOR
163 * 255 bytes in length
164 *
165 * by
166 * Guil Banks
167 * July 11, 1983
168 *
169 REP 30
170 SKP 1
171 FIXIT2 EQU *
36B3:AD BD 35 172 LDA CCBRLN ;Current record length lo
36B6:8D E6 35 173 STA DCBCSB ;Current sector byte
36B9:8D EA 35 174 STA DCBCRR ;Current relative record
36BC:AD Be 35 175 LDA CCBRLN+1 ;Do hi as well
36BF:8D E7 35 176 STA DCBCSB+1
36C2:8D EB 35 177 STA DCBCRR+1
36C5:8D E4 35 178 STA DCBCRS ;Set current relative sector
36C8:BA 179 TSX ; === Page 11 ===
36C9:8E 9B 33 180 STX ENTSTK
36CC:4C 7F 33 181 JMP GOODIO
182 SKP 2
183 REP 30
184 *
185 * Upper/Lower case patch
186 * for DOS 3.3C and BASIC
187 *
188 * by
189 * Guil Banks
190 * Mark Houde
191 *
192 REP 10
193 *
194 * This routine converts all characters
195 * that are not between quotes to
196 * upper case and returns them to the
197 * input buffer ($200). This works with
198 * DOS, Integer & Applesoft.
199 *
200 * Upon entry -
201 *
202 * X Reg = 0
203 *
204 * Upon exit -
205 *
206 * Y Reg = $FF
207 * ACCUM = $8D
208 * X Reg = unknown
209 *
210 REP 30
211 DO ULC
212 UPRCASE EQU *
213 LUP1 LDA LBUFF,X ;Get a char
214 CMP #'"+$80 ;Is it a quote?
215 BNE CHK4UC ;=> if not
216 LUP2 INX ;Bump to next char
217 LDA LBUFF,X ;Get it
218 CMP #'"+$80 ;Closing quote?
219 BEQ NEXTCHR ;=> if so
220 CMP #$8D ;End of Line? ; magic number KEY_CR
221 BNE LUP2 ;=> if not
222 ULFINI LDY #$FF ;Do what DOS wants
223 STY CMDNO
224 RTS ; & exit
225 CHK4UC EQU *
226 CMP #$E0 ;Upper case?
227 BCC CHK4CR ;=> if not
228 AND #$DF ;Make upper case
229 STA LBUFF,X ; & restore
230 CHK4CR CMP #$8D,X ;End of input? ; magic number KEY_CR
231 BEQ ULFINI ;=> if so
232 NEXTCHR INX ;Bump to next char
233 BNE LUP1 ;=> always ; ↑ No, not always, 256 times
234 FIN ; Patch incomplete! Where is the RTS??? Called from SCNCMD
235 SKP 1
236 BHERE1 EQU >*
36CF:00 237 DS $FD-BHERE1,0 ;[.. wastes 46 bytes ($36FD - $36CF = $2E)
; .. ; === DOS 3.3A JAN 1980 EASTER EGG === secret message @ 36D0 ($B6D0): "B01-00"
36D0:00 00 00 00 ; .. PRBYTE EQU $FDDA Print A as 2 hex digits
36D4:00 00 00 00 ; .. 36D0:20 58 FC JSR HOME
36D8:00 00 00 00 ; .. 36D3:A9 C2 LDA #'B'+$80
36DC:00 00 00 00 ; .. 36D5:20 ED FD JSR COUT
36E0:00 00 00 00 ; .. 36D8:A9 01 LDA #$01
36E4:00 00 00 00 ; .. 36DA:20 DA FD JSR PRBYTE
36E8:00 00 00 00 ; .. 36DD:A9 AD LDA #'-'+$80
36EC:00 00 00 00 ; .. 36DF:20 ED FD JSR COUT
36F0:00 00 00 00 ; .. 36E2:A9 00 LDA #$00
36F4:00 00 00 00 ; .. 36E4:20 DA FD JSR PRBYTE Really?? Wastes 1 byte with JSR/RTS
36F8:00 00 00 00 ; .. 36E7:60 RTS instead of JMP
36FC:00 ; ..] === DOS 3.3 EASTER EGG ===
238 * LOAD ADDRESS FOR CODE (PG BDY)
239 * ENTRY AFTER BOOT IS AT LOADADDR+256 (SECOND PAGE LOADED)
240 *
241 BHERE4 EQU >* ; $FD
242 LOADADDR EQU $800+BHERE4 ; $08FD === Page 12 ===
36FD:00 243 DFB 0
36FE:36 244 GRSPG DFB <TRK0LDR ;CONTAINS PAGE#-1 OF TRK 0, SEC 1 LOAD ADDRESS
245 * LAST LOGICAL BSECTOR TO READ STARTING AT $00
246 BHERE5 EQU >* ; $FF
247 BGRPGC EQU $800+BHERE5 ; $08FF
36FF:09 248 GRPGC DFB <ENDOFDOS-TRK0LDR-$100
249 ********************
250 PAGE
251 DOSLODR EQU * ; $3700
252 DO >DOSLODR
253 ??? ;ERROR IF NOT ON PAGE BOUNDARY
254 FIN
255 REP 40
256 * FAST BOOT AT 2:1 INTERLEAVE ; "You keep using this word fast,
257 * FOR 16-SECTOR DISKETTES ; it doesn't mean what you think it means."
258 REP 40 ; Copy ][+ has a FAST boot via 4&4 encoding, not 6&2 encoding.
3700:8E E9 37 259 STX IBSLOT ; SET BOOT SLOT ; === T0S1 ===
3703:8E F7 37 260 STX IBPSLT ; SET PREVIOUS SLOT
3706:A9 01 261 LDA #1 ; SET PREV DRIVE ; Assumes boot was from drive 1; Sadly there is no hardware support to tell which drive is currently active.
3708:8D F8 37 262 STA IBPDRV ; More crappy names differing by a single letter:
370B:8D EA 37 263 STA IBDRVN ; IBPDRV IB_PRV_DRV
264 ; ; IBDRVN IB_CUR_DRV
370E:AD E0 37 265 LDA NDPGS ; COPY NO PAGES TO GET
3711:8D E1 37 266 STA BRWCNT
3714:A9 02 267 LDA #2
3716:8D EC 37 268 STA IBTRK ; SET TRACK 0 ; Uhm, T2S4, not T0S4
3719:A9 04 269 LDA #4 ;ENDING SECTOR OF DOS IMAGE
371B:8D ED 37 270 STA IBSECT ;TO IOB
371E:AC E7 37 271 LDY ADOSLD+1 ;END PAGE OF DOS IMAGE
3721:88 272 DEY ;IS ONE LESS THAN
3722:8C F1 37 273 STY IBBUFP+1 ;START OF DOSLDR+BOOT
274 ;
3725:A9 01 275 LDA #IBCRTS ; SET READ
3727:8D F4 37 276 STA IBCMD ; So it IS possible to use symbolic names instead of magic numbers! /s See Line #313
277 ;
372A:8A 278 TXA ; SET PREV TRACK = 0
372B:4A 279 LSR A
372C:4A 280 LSR A
372D:4A 281 LSR A
372E:4A 282 LSR A
372F:AA 283 TAX ; The 40x24 text screen has "memory holes" that are NOT displayed
3730:A9 00 284 LDA #0 ; reserved for each Slot 1..7 as "scratchpad" or temp vars
3732:9D F8 04 285 STA $4F8,X ; magic number /sarcasm What, DRV2TRK wasn't available???
3735:9D 78 04 286 STA $478,X ; magic number /sarcasm What, DRV1TRK wasn't available???
3738:20 93 37 287 JSR BOOTIO ; GO READ DOS
288 ;
289 ;DOSINT - INITIALIZE DOS ; /sarcasm Couldn't afford extra 'i' in "dosinIt"
290 ;
291 DOSINT EQU * ; Ironically in Boot Loader, not Dos Init
373B:A2 FF 292 LDX #$FF
373D:9A 293 TXS
373E:8E EB 37 294 STX IBVOL
3741:4C C8 3F 295 JMP RCPATCH ; Should be JSR RCPATCH to prevent stupid JMP RCBACK
3744:20 89 FE 296 RCBACK JSR SETKBD
297 ;
3747:4C 03 1B 298 DI3 JMP DOSREL ; GO TO POST INIT ROUTINE ; Relocate DOS to high mem DOS 3.3 1980: JMP $1B03
299 PAGE
300 WBOOT EQU * ; Write Boot; part of the INIT process
374A:AD E7 37 301 LDA ADOSLD+1
374D:38 302 SEC
374E:ED F1 37 303 SBC IBBUFP+1
3751:8D E1 37 304 STA BRWCNT ;COMPUT PAGE COUNT ; === Page 13 === *spelling* Compute
3754:AD E7 37 305 LDA ADOSLD+1
3757:8D F1 37 306 STA IBBUFP+1 ;BUFFER=LAST PAGE OF RWTS
375A:CE F1 37 307 DEC IBBUFP+1
375D:A9 02 308 LDA #2 ; magic number TODO sizeof( PROGRAM ) / 16
375F:8D EC 37 309 STA IBTRK ;ENDING TRACK
3762:A9 04 310 LDA #4
3764:8D ED 37 311 STA IBSECT ;ENDING SECTOR
3767:A9 02 312 LDA #2 ; magic number Why not IBCWTS ???
3769:8D F4 37 313 STA IBCMD ;COMMAND = WRITE
376C:20 93 37 314 JSR BOOTIO ;WRITE DOS IMAGE TRK 2, SEC 4
315 * ;BACKWARDS TO TRK 0,SEC C
376F:AD E7 37 316 LDA ADOSLD+1
3772:8D FE 36 317 STA GRSPG ;BOOTSTRAP LOAD ADDRESS
3775:18 318 CLC
3776:69 09 319 ADC #9
3778:8D F1 37 320 STA IBBUFP+1 ;BUFFER ADDRESS OF END OF BOOT
377B:A9 0A 321 LDA #10
377D:8D E1 37 322 STA BRWCNT ;SECTOR COUNT TO WRITE ; /sarcasm If only NUM_SEC_WRITE
3780:38 323 SEC
3781:E9 01 324 SBC #1
3783:8D FF 36 325 STA GRPGC ;BOOT LAST SECTOR #
3786:8D ED 37 326 STA IBSECT ;START AT END OF RWTS&BOOT
3789:20 93 37 327 JSR BOOTIO ;AND WRITE DOWN TO ZERO
378C:60 328 RTS
378D:00 00 00 00 329 DS 6,0 ;FILL WITH BRKS ; wastes 6 bytes -- WHY ???
3791:00 00 330 PAGE
331 BOOTIO EQU *
3793:AD E5 37 332 LDA BAIOB+1 ; wastes 3 bytes; BAIOB → IOB, JSR IOBLDR loads AIOB → IOB
3796:AC E4 37 333 LDY BAIOB
3799:20 B5 37 334 JSR DISKIO
335 ;
379C:AC ED 37 336 LDY IBSECT ; GET SECTOR
379F:88 337 DEY ; DECREMENT TO NEXT ; Stupid Commenting - stop treating the reader as a moron
37A0:10 07 338 BPL BIO1 ;AT END OF TRACK? ; See now this is a useful comment in contradistinction to the one above
37A2:A0 0F 339 LDY #15 ;SET TO SECTOR 15 ; as it tells us WHY we are branching
37A4:EA 340 NOP ; [.. wastes 2 bytes
37A5:EA 341 NOP ; ..]
37A6:CE EC 37 342 DEC IBTRK
37A9:8C ED 37 343 BI01 STY IBSECT ; SET NEXT SECTOR
344 ;
37AC:CE F1 37 345 DEC IBBUFP+1 ; DECREMENT BUFFER POINTER
37AF:CE E1 37 346 DEC BRWCNT ; DECREMENT PAGE COUNTER
37B2:D0 DF 347 BNE BOOTIO ; BR IF NOT DONE
37B4:60 348 RTS
349 ;
350 PAGE
37B5:08 351 DISKIO PHP ;SAVE INTERUPT STATUS ; *spelling* Interrupt
37B6:78 352 SEI ;INHIBIT INTERUPT WHILE ; *spelling* Interrupt
37B7:20 00 3D 353 JSR RWTS ; ACCESSING DISK
37BA:B0 03 354 BCS DSKERR ;MUST PASS BACK CARRY FLAG & INTERUPT ; *spelling* Interrupt
37BC:28 355 PLP
37BD:18 356 CLC
37BE:60 357 RTS
37BF:28 358 DISKERR PLP ;CARRY SET MEANS ERROR
37C0:38 359 SEC
37C1:60 360 RTS
37C2:AD BC 35 361 DLDSUP LDA CCBBSA ;SET UP FOR DOS LOADER
37C5:8D F1 37 362 STA IBBUFP+1 ;START ADDRESS
37C8:A9 00 363 LDA #0
37CA:8D F0 37 364 STA IBBUFP
37CD:AD F9 35 365 LDA DCBVOL ;INVERT VOLUME NUMBER
37D0:49 FF 366 EOR #$FF ; === Page 14 ===
37D2:8D EB 37 367 STA IBVOL
37D5:60 368 RTS
369 ;
37D6:A9 00 370 CLRSEC LDA #0 ;CLEAR SECTOR
37D8:A8 371 TAY
37D9:91 42 372 CS1 STA (ZPGFCB),Y
37DB:C8 373 INY
37DC:D0 FB 374 BNE CS1
37DE:60 375 RTS
37DF:00 376 BRK ; wastes 1 byte -- Why???
377 EC3 EQU *
37E0:1B 378 NDPGS DFB <TRK0LDR-BEGIN ;CALC #PAGES IN DOS WITHOUT RWTS
37E1:00 379 BRWCNT DFB 0 ;WRK CTR FOR BOOTIO
37E2:0A 380 DFB $0A ;[.. wastes 2 bytes -- never used!
37E3:1B 381 DFB $1B ; ..]
37E4:E8 37 382 BAIOB DW IOB ; BAIOB and AIOB both point to IOB
37E6:00 36 383 ADOSLD DW TRK0LDR
384 PAGE
385 ;
386 IOB - INPUT / OUTPUT CONTROL BLOCK
387 ;THE IOB IS USED FOR THE INTERFACE
388 ;BETWEEN DOS AND THE DISK I/O ROUTINES
389 ;
390 IOB EQU * ; Descriptive Names
37E8:01 391 IBTYPE DFB 1 ; IOB TYPE CODE ; [0] IOB_OFFSET_TYPE wastes 1 bytes, hard-coded to 1 in FLOCNXB, Line #95 !
37E9:60 392 IBSLOT DFB 6*16 ; CONTROLELR SLOT NO. ; [1] IOB_OFFSET_SLOT
37EA:01 393 IBDRVN DFB 1 ; DRIVE NUMBER ; [2] IOB_OFFSET_DRV_NUM
37EB:00 394 IBVOL DFB $00 ; VOLUME NUMBER ; [3] IOB_OFFSET_VOL
37EC:00 395 IBTRK DFB 0 ; TRACK NUMBER ; [4] IOB_OFFSET_TRK
37ED:00 396 IBSECT DFB 0 ; SECTOR NUMBER ; [5] IOB_OFFSET_SEC
37EE:FB 37 397 IBDCTP DW DCT ; [6] IOB_OFFSET_DCT Why is the Device Characteristics Table
37F0:00 00 398 IBBUFP DW 0 ; POINTER TO BUFFER ; [8] IOB_OFFSET_BUF even exposed to the caller???
37F2:00 01 399 IBDLEN DW 256 ; DATA LENGTH ; [A] IOB_OFFSET_LEN These values never change!
37F4:00 400 IBCMD DFB 0 ; COMMAND ; [C] IOB_OFFSET_CMD
401 IBCNUL EQU 0 ; 0-NULL COMMAND ; Stop with the shitty API already!
402 IBCRTS EQU 1 ; 1-READ TRACK, SECTOR ; IB_CMD_R And it is important these be bit flags why again?
403 IBCWTS EQU 2 ; 2-WRITE TRACK,SECTOR ; IB_CMD_W
404 IBFMT EQU 4 ; 4-FORMAT DISK ; IB_CMD_FORMAT
405 IBBOOT EQU 8 ; 8-WRITE BOOT ; IB_CMD_X_BOOT
37F5:00 406 IBSTAT DFB 0 ; STATUS ; [D] IOB_OFFSET_STATUS
407 IBRERR EQU $80 ; READ ERR ; IB_ERR_R Interleaving const and struct types
408 IBDERR EQU $40 ; DRIVE ERR ; IB_ERR_DRV makes for extremely poor readability
409 IBVMME EQU $20 ; VOLUME MISMATCH ; IB_ERR_VOL
410 IBWPER EQU $10 ; WRITE PROTECT ERROR ; IB_ERR_W
37F6:00 411 IBSMOD DFB 0 ; STATUS MODIFIER BYTE ; [E] IOB_OFFSET_MOD
37F7:60 412 IBPSLT DFB 6*16 ; PREVIOUS SLOT ; [F] IOB_OFFSET_PREV_SLOT Why isn't this set at boot ???
37F8:01 413 IBPDRV DFB 1 ; PREVIOUS DRIVE ;[10] IOB_OFFSET_PREV_DRV
37F9:00 00 414 IBSPAR DS 2,0 ; IOB SPARES ;[11] wastes 2 bytes
37FB:00 01 EF D8 415 DCT DFB 0,1,$EF,$D8 ; ; magic number More crappy formatting, values defined in RWTSONE
; Put these values on one per line for readability like this:
; DCT_TYPE DFB 0 ; Device Type, $0 = Disk II
; DCT_PHASES DFB 1 ; Phases per Track
; DCT_MOTOR DW $D8EF ; Motor on time in 100 microseconds
37FF:00 416 DS 1,0 ; FILL IN 3700 PAGE ; wastes 1 byte
417 PAGE
418 ;
419 ; FILE DIRECTORY DEFINITION ; META-DATA: FTOC = array of Track/Sectors belonging to a file
420 ; ; Note: The brain dead Track/Sector is equivalent to Unix i-nodes
421 DSECT ; ProDOS switched to BlockIndex
422 FILDIR EQU * ;T12SF HNTDAFS #6; Really?, couldn't call it FILEDIR???,
423 FDUCDE DS 1 ; FILE USE CODE ; [00] wastes 1 byte -- never referenced! I presume FILESYSTEM_TYPE_FILE EQU $1
424 FDLTRK DS 1 ; LINK TO NEXT DIR TRACK ; [01] e.g. $12 ($00 = none), see RFDNXT
425 FDLSEC DS 1 ; LINK TO NEXT DIR SECTOR ; [02] e.g. $0E ($00 = none)
426 FDNSA DS 1 ; NO SECTORS ALLOCATED ; [03] wastes 1 byte -- never referenced!
427 FDLSDL DS 1 ; LAST SECTOR DATA LENGTH ; [04] wastes 1 byte -- never referenced!
428 FDFRS DS 2 ; 1ST RELATIVE SECTOR IN THIS DIR ; [05] read by RFDNL1 and RDFDC in FMTRWIO
429 FDSPAR DS 5 ; SPARES ; [07] === Page 15 === -- never referenced!
430 ; ; wastes 5 bytes on disk for EVERY catalog sector!
431 FDENT DS 1 ; START OF FILE ENTRIES (122) ; [0C]
432 FDTRK EQU 0 ; TRACK
433 FDSEC EQU 1 ; SECTOR
434 ;
435 FDLAST EQU FILDIR+256 ; $3900 ($B900) -- never referenced
436 DEND
001 SBTL '16-SECTOR CORE ROUTINES'
002 ***************************
003 * *
004 * DISC-II *
005 * 16-SECTOR FORMAT *
006 * READ AND WRITE *
007 * SUBROUTINES *
008 * *
009 ***************************
010 * *
011 * *
012 * COPYRIGHT 1979 *
013 * APPLE COMPUTER INC. *
014 * *
015 * ALL RIGHTS RESERVED *
016 * *
017 ***************************
018 * *
019 * MAR 18, 1979 *
020 * WOZ *
021 * *
022 ***************************
023 ASC1 EQU * ;TELL RELOCATOR WHERE CORE STARTS
024 PAGE
025 ***************************
026 * *
027 * CRITICAL TIMING *
028 * REQUIRES PAGE BOUND *
029 * CONSIDERATIONS FOR *
030 * CODE AND DATA *
031 * *
032 * -----CODE----- *
033 * *
034 * VIRTUALLY THE ENTIRE *
035 * 'WRITE16' ROUTINE *
036 * MUST NOT CROSS *
037 * PAGE BOUNDARIES. *
038 * *
039 * THE WRITE16, READ16 *
040 * AND RDADR16 SUBRS *
041 * WHICH MUST NOT CROSS *
042 * PAGE BOUNDARIES ARE *
043 * NOTED IN COMMENTS. *
044 * *
045 * -----DATA----- *
046 * *
047 * NBUF1 AND NBUF2 ARE *
048 * 256-BYTE AND 86-BYTE *
049 * NIBL BUFFERS IN RAM. *
050 * BOTH MUST BEGIN ON *
051 * PAGE BOUNDARIES. *
052 * *
053 * NIBLIZING TABLE 'NIBL' *
054 * (64 BYTES) MAPS 6-BIT * ; === Page 25 ===
055 * NIBLS INTO VALID 7-BIT *
056 * NIBLS. THIS TABLE *
057 * MUST NOT CROSS A PAGE *
058 * BOUNDARY. *
059 * *
060 * DENIBLIZING TABLE *
061 * 'DNIBL' MAPS 7-BIT *
062 * NIBLS INTO 6-BIT *
063 * NIBLS. IT MUST BEGIN *
064 * ON A PAGE BOUNDARY, *
065 * BUT ONLY DNIBL,$96 TO *
066 * DNIBL,$FF ARE USED. *
067 * *
068 ***************************
069 PAGE
070 ***************************
071 * *
072 * EQUATES *
073 * *
074 ***************************
075 * *
076 * ----PRENIBL16---- *
077 * AND POSTNB16 *
078 * (16-SECTOR FORMAT) *
079 * *
080 ***************************
081 BUF EQU $3E TWO BYTE POINTER.
082 *
083 * POINTS TO 256-BYTE
084 * USER BUFFER ANYWHERE
085 * IN MEMORY. PRENIBL16
086 * CONVERTS USER DATA
087 * (IN BUF) INTO 6-BIT
088 * NIBLS 00ABCDEF IN
089 * NBUF1 AND NBUF2 PRIOR
090 * TO 'WRITE'. POSTNBL16
091 * CONVERTS 6-BIT NIBLS
092 * 00ABCDEF BACK TO USER
093 * DATA IN BUF AFTER 'READ'.
094 *
095 T0 EQU $26 TEMP FOR POSTNBL16
096 ************************
097 * *
098 * ----RDADR16---- *
099 * *
100 ************************
101 COUNT EQU $26 'MUST FIND' COUNT.
102 LAST EQU $26 'ODD BIT' NIBLS.
103 CSUM EQU $27 CHECKSUM BYTE.
104 CSSTV EQU $2C FOUR BYTES, ; Read forward, stored in backwards order due to RDA5
105 * CHECKSUM, SECTOR, TRACK, AND VOLUME.
106 *
107 ************************
108 * *
109 * ---WRITE16--- *
110 * *
111 * USES NBUF1, NBUF2, *
112 * AND 64-BYTE TABLE *
113 * 'NIBL'. *
114 * *
115 ************************
116 WTEMP EQU $26 TEMP FOR DATA AT NBUF2,0.
117 SLOTZ EQU $27 SLOTNUM IN Z-PAG LOC. ; === Page 26 ===
118 SLOTABS EQU $678 SLOTNUM IN NON-ZPAG LOC.
119 *
120 ************************
121 * *
122 * ----READ16----- *
123 * (16-SECTOR FORMAT) *
124 * *
125 * USES NBUF1,NBUF2. *
126 * USES LAST 106 BYTES *
127 * OF A DATA PAGE FOR *
128 * SIGNIFICANT BYTES *
129 * OF DNIBL16 TABLE. *
130 * *
131 ************************
132 IDX EQU $26 INDEX INTO (BUF).
133 *
134 ************************
135 * *
136 * ---- SEEK ---- *
137 * *
138 ************************
139 TRKCNT EQU $26 HALFTRKS MOVED COUNT.
140 PRIOR EQU $27 PRIOR HALFTRACK.
141 TRKN EQU $2A DESIRED TRACK.
142 SLOTTEMP EQU $2B SLOT NUM TIMES $10.
143 CRKTRK EQU $478 CURRENT TRACK ON ENTRY. ; "Current Track" Drive 1, Why is this defined AGAIN? DRV1TRK
144 *
145 ************************
146 * *
147 * ---- MSWAIT ---- *
148 * *
149 ************************
150 MONTIMEL EQU $46 MOTON-ON TIME
151 MONTIMEH EQU $47 COUNTERS.
152 *
153 ************************
154 * *
155 * ---- WRADR16 ---- *
156 * *
157 ************************
158 AA EQU $3E ;TIMING CONSTANT ; *sigh* Really people you couldn't pick any other variable name?!, See: DSKFORM
159 NSECT EQU $3F ;SECTOR NUMBER
160 NVOL EQU $41 ;VOLUME NUMBER
161 TRK EQU $44* ;TRACK NUMBER
162 *
163 ************************
164 * *
165 * DEVICE ADDRESS *
166 * ASSIGNMENTS *
167 * * ; See ONTABLE, and OFFTABLE
168 ************************ ; Typical B.A.D. (Beneath Apple Dos) shenanigans (Page 6-3):
169 PHASEOFF EQU $C080 STEPPER PHASE OFF. ; "The timing between accesses to these locations is
170 PHASEON EQU $C081 STEPPER PHASE ON. ; critical, making this a non-trivial exercise." WHICH IS???
171 Q6L EQU $C08C Q7L,Q6L=READ ; *sigh* /sarcasm Riiight, because it is _obvious_ what Q7L & Q7H
172 Q6H EQU $C08D Q7L,Q6H=SENSE WPROT ; do -- but let's keep copy/paste these shitty non-descript names!
173 Q7L EQU $C08E Q7H,Q6L=WRITE ; DRIVE_MODE_R
174 Q7H EQU $C08F Q7H,Q6H=WRITE STORE ; DRIVE_MODE_W
001 SBTL '16-SECTOR PRENIBLIZE'
002 ****************************
003 * *
004 * PRENIBLIZE SUBR *
005 * (16-SECTOR FORMAT) *
006 * *
007 ****************************
008 * *
009 * CONVERTS 256 BYTES OF *
010 * USER DATA IN (BUF),0 *
011 * TO (BUF),255 INTO 342 *
012 * 6-BIT NIBLS (00ABCDEF) *
013 * IN NBUF1 AND NBUF2. *
014 * *
015 * ---- ON ENTRY ---- *
016 * *
017 * BUF IS 2-BYTE POINTER *
018 * TO 256 BYTES OF USER *
019 * DATA. *
020 * *
021 * ---- ON EXIT ----- *
022 * *
023 * A-REG UNCERTAIN. *
024 * X-REG HOLDS $FF. *
025 * Y-REG HOLDS $FF. *
026 * CARRY SET. *
027 * *
028 * NBUF1 AND NBUF2 CONTAIN *
029 * 6-BIT NIBLS OF FORM *
030 * 00ABCDEF. *
031 * *
032 ****************************
3800:A2 00 033 PRENIB16 LDX #$0 ;START NBUF2 INDEX. CHANGED BY WOZ
3802:A0 02 034 LDY #2 ;START USER BUF INDEX. CHANGED BY WOZ.
3804:88 035 PRENIB1 DEY ;NEXT USER BYTE.
3805:B1 3E 036 LDA (BUF),Y
3807:4A 037 LSR A ;SHIFT TWO BITS OF
3808:3E 00 3C 038 ROL NBUF2,X ;CURRENT USER BYTE
380B:4A 039 LSR A ;INTO CURRENT NBUF2
380C:3E 00 3C 040 ROL NBUF2,X ;BYTE.
380F:99 00 3B 041 STA NBUF1,Y ;(6 BITS LEFT).
3812:E8 042 INX ;FROM 0 TO $55.
3813:E0 56 043 CPX #$56
3815:90 ED 044 BCC PRENIB1 ;BR IF NO WRAPAROUND.
3817:A2 00 045 LDX #0 ;RESET NBUF2 INDEX.
3819:98 046 TYA ;USER BUF INDEX.
381A:D0 E8 047 BNE PRENIB1 ;(DONE IF ZERO)
381C:A2 55 048 LDX #$55 ;NBUF2 IDX $55 TO 0.
381E:BD 00 3C 049 PRENIB2 LDA NBUF2,X
3821:29 3F 050 AND #$3F ;STRIP EACH BYTE
3823:9D 00 3C 051 STA NBUF2,X ;OF NBUF2 TO 6 BITS.
3826:CA 052 DEX
3827:10 F5 053 BPL PRENIB2 ;LOOP UNTIL X NEG. ; === Page 105 ===
3829:60 054 RTS ;RETURN. ; o7 Captain Obvious
001 SBTL '16-SECTOR WRITE'
002 ************************
003 * *
004 * WRITE SUBR *
005 * (16-SECTOR FORMAT) *
006 * *
007 ************************
008 * *
009 * WRITES DATA FROM *
010 * NBUF1 AND NBUF2 *
011 * CONVERTING 6-BIT *
012 * TO 7-BIT NIBLS *
013 * VIA 'NIBL' TABLE. *
014 * *
015 * FIRST NBUF2, *
016 * HIGH TO LOW. *
017 * THEN NBUF1, *
018 * LOW TO HIGH. *
019 * *
020 * ---- ON ENTRY ---- *
021 * *
022 * X-REG: SLOTNUM *
023 * TIMES $10. *
024 * *
025 * NBUF1 AND NBUF2 *
026 * HOLD NIBLS FROM *
027 * PRENIBL SUBR. *
028 * (00ABCDEF) *
029 * *
030 * ---- ON EXIT ----- *
031 * *
032 * CARRY SET IF ERROR. *
033 * (W PROT VIOLATION) *
034 * *
035 * IF NO ERROR: *
036 * *
037 * A-REG UNCERTAIN. *
038 * X-REG UNCHANGED. *
039 * Y-REG HOLDS $00. *
040 * CARRY CLEAR. *
041 * *
042 * SLOTABS, SLOTZ, *
043 * AND WTEMP USED. *
044 * *
045 * ---- ASSUMES ---- *
046 * *
047 * 1 USEC CYCLE TIME *
048 * *
049 ************************
382A:38 050 WRITE16 SEC ;ANTICIPATE WPROT ERR. ; === Reloc @ $B82A ===
382B:86 27 051 STX SLOTZ ;FOR ZERO PAGE ACCESS.
382D:8E 78 06 052 STX SLOTABS ;FOR NON-ZERO PAGE.
3830:BD 8D C0 053 LDA Q6H,X
3833:BD 8E C0 054 LDA Q7L,X ;SENSE WPROT FLAG. ; === Page 138 ===
3836:30 7C 055 BMI WEXIT ;IF HIGH, THEN ERR. ; v
3838:AD 00 3C 056 LDA NBUF2
383B:85 26 057 STA WTEMP ;FOR ZERO-PAGE ACCESS.
383D:A9 FF 058 LDA #$FF ;SYNC DATA
383F:9D 8F C0 059 STA Q7H,X ;(5) WRITE 1ST NIBL.
3842:1D 8C C0 060 ORA Q6L,X ;(4)
3845:48 061 PHA ;(3)
3846:68 062 PLA ;(4) CRITICAL TIMING!
3847:EA 063 NOP ;(2)
3848:A0 04 064 LDY #4 ;(2) FOR 5 NIBLS.
384A:48 065 WSYNC PHA ;(3) EXACT TIMING ; --- Sync FF ---
384B:68 066 PLA ;(4) EXACT TIMING
384C:20 B9 38 067 JSR WNIBL7 ;(13,9,6) WRITE SYNC
384F:88 068 DEY ;(2)
3850:D0 F8 069 BNE WSYNC ;(2*) MUST NOT CROSS PAGE! ; ^
3852:A9 D5 070 LDA #$D5 ;(2) 1ST DATA MARK. ; --- Data Header D5 AA AD ---
3854:20 B8 38 071 JSR WNIBL9 ;(15,9,6)
3857:A9 AA 072 LDA #$AA ;(2) 2ND DATA MARK.
3859:20 B8 38 073 JSR WNIBL9 ;(15,9,6)
385C:A9 AD 074 LDA #$AD ;(2) 3RD DATA MARK.
385E:20 B8 38 075 JSR WNIBL9 ;(15,9,6)
3861:98 076 TYA ;(2) CLEAR CHECKSUM
3862:A0 56 077 LDY #$56 ;(2) NBUF2 INDEX.
3864:D0 03 078 BNE WDATA1 ;(3) ALWAYS. NO PAGE CROSS!! ; v
3866:B9 00 3C 079 WDATA0 LDA NBUF2,Y ;(4) PRIOR 6-BIT NIBL.
3869:59 FF 3B 080 WDATA1 EOR NBUF2-1,Y ;(5) XOR WITH CURRENT.
081 * (NBUF2 MUST BE ON PAGE BOUNDARY FOR TIMING!!)
386C:AA 082 TAX ;(2) INDEX To 7-BIT NIBL
386D:BD 29 3A 083 LDA NIBL,X ;(4) MUST NOT CROSS PAGE!
3870:A6 27 084 LDX SLOTZ ;(3) CRITICAL TIMING!
3872:9D 8D C0 085 STA Q6H,X ;(5) WRITE NIBL.
3875:BD 8C C0 086 LDA Q6L,X ;(4)
3878:88 087 DEY ;(2) NEXT NIBL.
3879:D0 EB 088 BNE WDATA0 ;(2*) MUST NOT CROSS PAGE! ; ^
387B:A5 26 089 LDA WTEMP ;(3) PRIOR NIBL FROM BUF6.
387D:EA 090 NOP ;(2) CRITICAL TIMING.
387E:59 00 3B 091 WDATA2 EOR NBUF1,Y ;(5) XOR WITH CURRENT.
3881:AA 092 TAX ;(2)
3882:BD 29 3A 093 LDA NIBL,X ;(4)
3885:AE 78 06 094 LDX SLOTABS ;(4) TIMING CRITICAL
3888:9D 8D C0 095 STA Q6H,X ;(5) WRITE NIBL.
388B:BD 8C C0 096 LDA Q6L,X ;(4)
388E:B9 00 3B 097 LDA NBUF1,Y ;(4) PRIOR 6-BIT NIBL.
3891:C8 098 INY ;(2)NEXT NBUF1 NIBL.
3892:D0 EA 099 BNE WDATA2 ;(2*) MUST NOT CROSS PAGE! ; ^
3894:AA 100 TAX ;(2)
3895:BD 29 3A 101 LDA NIBL,X ;(4) INDEX TO 7-BIT NIBL
3898:A6 27 102 LDX SLOTZ ;(3)
389A:20 BB 38 103 JSR WNIBL ;(6,9,6) WRITE CHKSUM
389D:A9 DE 104 LDA #$DE ;(2) DM4, BIT SLIP MARK. ; magic number TODO
389F:20 B8 38 105 JSR WNIBL9 ;(15,9,6) WRITE IT.
38A2:A9 AA 106 LDA #$AA ;(2) DM5, BIT SLIP MARK.
38A4:20 B8 38 107 JSR WNIBL9 ;(15,9,6) WRITE IT.
38A7:A9 EB 108 LDA #$EB ;(2) DM6, BIT SLIP MARK.
38A9:20 B8 38 109 JSR WNIBL9 ;(15,9,6) WRITE IT.
38AC:A9 FF 110 LDA #$FF ;(2) TURN-OFF BYTE.
38AE:20 B8 38 111 JSR WNIBL9 ;(15,9,9) WRITE IT. ; TODO: 15,9,6??
38B1:BD 8E C0 112 LDA Q7L,X ;OUT OF WRITE MODE.
38B4:BD 8C C0 113 WEXIT LDA Q6L,X ;TO READ MODE.
38B7:60 114 RTS ;RETURN FROM WRITE.
115 *****************************
116 * *
117 * 7-BIT NIBL WRITE SUBRS * ; === WRITRTN, Page 139 ===
118 * *
119 * A-REG OR'D PRIOR EXIT *
120 * CARRY CLEARED *
121 * *
122 *****************************
38B8:18 123 WNIBL9 CLC ; (2) 9 CYCLES, THEN WRITE.
38B9:48 124 WNIBL7 PHA ; (3) 7 CYCLES, THEN WRITE.
38BA:68 125 PLA ; (4)
38BB:9D 8D C0 126 WNIBL STA Q6H,X ; (5) NIBL WRITE SUB.
38BE:1D 8C C0 127 ORA Q6L,X ; (4) CLOBBERS ACC, NOT CARRY
38C1:60 128 RTS
001 SBTL '16-SECTOR POSTNIBLIZE'
002 ***************************
003 * *
004 * POSTNIBLIZE SUBR *
005 * 16-SECTOR FORMAT *
006 * *
007 ***************************
008 * *
009 * CONVERTS 6-BIT NIBLS *
010 * OF FORM 00ABCDEF IN *
011 * NBUF1 AND NBUF2 INTO *
012 * 256 BYTES OF USER *
013 * DATA IN BUF. *
014 * *
015 * ---- ON ENTRY ---- *
016 * *
017 * X-REG: HOLDS SLOTNUM *
018 * TIMES $10. *
019 * *
020 * BUF IS 2-BYTE POINTER *
021 * TO 256 BYTES OF USER *
022 * DATA TO BE CONVERTED *
023 * TO 6-BIT NIBLS IN *
024 * NBUF1 AND NBUF2 *
025 * PRIOR TO WRITE. *
026 * *
027 * T0 CONTAINS BYTE COUNT *
028 * CODE0 = 256 BYTES *
029 * CODE1 = 1 BYTE *
030 * CODE2 = 2 BYTER *
031 * *
032 * CODE 255=255 BYTES *
033 * *
034 * ---- ON EXIT ----- *
035 * *
036 * A-REG UNCERTAIN. *
037 * Y-REG SAME AS T0. *
038 * X-REG UNCERTAIN. *
039 * CARRY SET. *
040 * *
041 * 6-BIT NIBLS OF FORM *
042 * 00ABCDEF IN NBUF1 *
043 * AND NBUF2. *
044 * (342 NIBLS) *
045 ***************************
38C2:A0 00 046 POSTNB16 LDY #$0 ; USER DATA BUF IDX. ; T0S2 TODO
38C4:A2 56 047 POST1 LDX #$56 ; INIT NBUF2 INDEX.
38C6:CA 048 POST2 DEX ; NBUF IDX $55 TO $0
38C7:30 FB 049 BMI POST1 ; WRAPAROUND IF NEG. ;↑
38C9:B9 00 3B 050 LDA NBUF1,Y
38CC:5E 00 3C 051 LSR NBUF2,X ; SHIFT 2 BITS FROM
38CF:2A 052 ROL A ; CURRENT NBUF2 NIBL
38D0:5E 00 3C 053 LSR NBUF2,X ; INTO CURRENT NBUF1
38D3:2A 054 ROL A NIBL. ; === Page 102 ===
38D4:91 3E 055 STA (BUF),Y BYTE OF USER DATA.
38D6:C8 056 INY NEXT USER BYTE.
38D7:C4 26 057 CPY T0 DONE IF EQUAL T0.
38D9:D0 EB 058 BNE POST2 ; ^
38DB:60 059 RTS RETURN.
060 SBTL '16-SECTOR READ'
061 **************************
062 * *
063 * READ SUBROUTINE *
043 * (16-SECTOR FORMAT) *
065 * *
066 **************************
067 * *
068 * READS 6-BIT NIBLS *
069 * (00ABCDEF) INTO *
070 * NBUF1 and NBUF2 *
071 * CONVERTING 7-BIT *
072 * NIBLS TO 7-BIT *
073 * VIA 'DNIBL' TABLE *
074 * *
075 * FIRST READS NBUF2 *
076 * HIGH TO LOW *
077 * THEN READS NBUF1 *
078 * LOW TO HIGH *
079 * *
080 * ---- ON ENTRY ---- *
081 * *
082 * X-REG: SLOTNUM *
083 * TIMES $10. *
084 * *
085 * READ MODE (Q6L, Q7L) *
086 * *
087 * ---- ON EXIT ----- *
088 * *
089 * CARRY SET IF ERROR *
090 * *
091 * IF NO ERROR: *
092 * A-REG HOLDS $AA. *
093 * X-REG UNCHANGED. *
094 * Y-REG HOLDS $00. *
095 * CARRY CLEAR. *
096 * *
097 * NBUF1 AND NBUF2 *
098 * HOLD 6-BIT NIBLS *
099 * (00ABCDEF) *
100 * *
101 * USES TEMP 'IDX'. *
102 * *
103 * ---- CAUTION ----- *
104 * *
105 * OBSERVE *
106 * 'NO PAGE CROSS' *
107 * WARNIGNS ON *
108 * SOME BRANCHES!! *
109 * *
110 * ---- ASSUMES ---- *
111 * *
112 * 1 USEC CYCLE TIME *
113 * *
114 **************************
38DC:A0 20 115 READ16 LDY #$20 'MUST FIND' COUNT.
38DE:88 116 RSYNC DEY IF CAN'T FIND MARKS
38DF:F0 61 117 BEQ RDERR ;THEN EXIT WITH CARRY SET ; === Page 103 ===
38E1:BD 8C C0 118 READ1 LDA Q6L,X READ NIBL.
38E4:10 FB 119 BPL READ1 *** NO PAGE CROSS! ***
38E6:49 D5 120 RSYNC1 EOR #$D5 DATA MARK 1?
38E8:D0 F4 121 BNE RSYNC LOOP IF NOT.
38EA:EA 122 NOP DELAY BETWEEN NIBLS.
38EB:BD 8C C0 123 READ2 LDA Q6L,X
38EE:10 FB 124 BPL READ2 *** NO PAGE CROSS! ***
38F0:C9 AA 125 CMP #$AA DATA MARK 2?
38F2:D0 F2 126 BNE RSYNC1 (IF NOT, IS IT DM1?) ; NUM_6N2_NIBBLES = 342
38F4:A0 56 127 LDY #$56 INIT NBUF2 INDEX ; magic number NUM_6N2_NIBBLES - 256
128 * (ADDED NIBL DELAY)
38F6:BD 8C C0 129 READ3 LDA Q6L,X
38F9:10 FB 130 BPL READ3 *** NO PAGE CROSS! ***
38FB:C9 AD 131 CMP #$AD DATA MARK 3?
38FD:D0 E7 132 BNE RSYNC1
133 * (CARRY SET IF DM3!) ; And this imporant why??
38FF:A9 00 134 LDA #$00 INIT CHECKSUM
3901:88 135 RDATA1 DEY
3902:84 26 136 STY IDX
3904:BC 8C C0 137 READ4 LDY Q6L,X
3907:10 FB 138 BPL READ4 *** NO PAGE CROSS! ***
3909:59 00 3A 139 EOR DNIBL,Y XOR 6-BIT NIBL.
390C:A4 26 140 LDY IDX
390E:99 00 3C 141 STA NBUF2,Y STORE IN NBUF2 PAGE.
3911:D0 EE 142 BNE RDATA1 TAKEN IF Y-REG NONZERO.
3913:84 26 143 RDATA2 STY IDX
3915:BC 8C C0 144 READ5 LDY Q6L,X
3918:10 FB 145 BPL READ5 *** NO PAGE CROSS! ***
391A:59 00 3A 146 EOR DNIBL,Y XOR 6-BIT NIBL.
391D:A4 26 147 LDY IDX
391F:99 00 3B 148 STA NBUF1,Y STORE IN NBUF1 PAGE.
3922:C8 149 INY
3923:D0 EE 150 BNE RDATA2
3925:BC 8C C0 151 READ6 LDY Q6L,X READ 7-BIT CSUM NIBL.
3928:10 FB 152 BPL READ6 *** NO PAGE CROSS! ***
392A:D9 00 3A 153 CMP DNIBL,Y IF LAST NBUF1 NIBL NOT
392D:D0 13 154 BNE RDERR EQUAL CHKSUM NIBL THEN ERR.
392F:BD 8C C0 155 READ7 LDA Q6L,X
3932:10 FB 156 BPL READ7 *** NO PAGE CROSS! ***
3934:C9 DE 157 CMP #$DE FIRST BIT SLIP MARK?
3936:D0 0A 158 BNE RDERR (ERR IF NOT)
3938:EA 159 NOP DELAY BETWEEN NIBLS.
3939:BD 8C C0 160 READ8 LDA Q6L,X
393C:10 FB 161 BPL READ8 *** NO PAGE CROSS! ***
393E:C9 AA 162 CMP #$AA SECOND BIT SLIP MARK?
3940:F0 5C 163 BEQ RDEXIT (DONE IF IT IS)
3942:38 164 RDERR SEC INDICATE 'ERROR EXIT'.
3943:60 165 RTS FROM READ16 OR RDADR16.
001 SBTL '16-SECTOR READ ADDRESS'
002 ****************************
003 * *
004 * READ ADDRESS FIELD *
005 * SUBROUTINE *
006 * (16-SECTOR FORMAT) *
007 * *
008 ****************************
009 * *
010 * READS VOLUME, TRACK *
011 * AND SECTOR *
012 * *
013 * ---- ON ENTRY ---- *
014 * *
015 * XREG: SLOTNUM TIMES $10 *
016 * *
017 * READ MODE (Q6L, Q7L) *
018 * *
019 * ---- ON EXIT ----- *
020 * *
021 * CARRY SET IF ERROR. *
022 * *
023 * IF NO ERROR: *
024 * A-REG HOLDS $AA. *
025 * Y-REG HOLDS $00. *
026 * X-REG UNCHANGED. *
027 * CARRY CLEAR. *
028 * *
029 * CSSTV HOLDS CHKSUM, *
030 * SECTOR, TRACK, AND *
031 * VOLUME READ. *
032 * *
033 * USES TEMPS COUNT, *
034 * LAST, CSUM, AND *
035 * 4 BYTES AT CSSTV. *
036 * *
037 * ---- EXPECTS ---- *
038 * *
039 * ORIGINAL 10-SECTOR *
040 * NORMAL DENSITY NIBLS *
041 * (4-BIT), ODD BITS, *
042 * THEN EVEN. *
043 * *
044 * ---- CAUTION ---- *
045 * *
046 * OBSERVE *
047 * 'NO PAGE CROSS' *
048 * WARNINGS ON *
049 * SOME BRANCHES!! *
050 * *
051 * ---- ASSUMES ---- *
052 * *
053 * 1 USEC CYCLE TIME *
054 * * ; === Page 107 ===
055 ****************************
3944:A0 FC 056 RDADR16 LDY #$FC
3946:84 26 057 STY COUNT 'MUST FIND' COUNT.
3948:C8 058 RDASYN INY
3949:D0 04 059 BNE RDA1 LOW ORER OF COUNT.
394B:E6 26 060 INC COUNT (2K NIBLS TO FIND)
394D:F0 F3 061 BEQ RDERR (ADR MARK, ELSE ERR)
394F:BD 8C C0 062 RDA1 LDA Q6L,X READ NIBL.
3952:10 FB 063 BPL RDA1 *** NO PAGE CROSS! ***
3954:C9 D5 064 RDASN1 CMP #$D5 ADR MARK 1? ; magic number DISK_ADR_PROLOG_1 EQU #$D5
3956:D0 F0 065 BNE RDASYN (LOOP IF NOT)
3958:EA 066 NOP ADDED NIBL DELAY.
3959:BD 8C C0 067 RDA2 LDA Q6L,X
395C:10 FB 068 BPL RDA2 *** NO PAGE CROSS! ***
395E:C9 AA 069 CMP #$AA ADR MARK 2? ; magic number DISK_ADR_PROLOG_2 EQU #$AA
3960:D0 F2 070 BNE RDASN1 (IF NOT, IS IT AM1?)
3962:A0 03 071 LDY #$3 INDEX FOR 4-BYTE READ. ; Technically, we read 8 disk nibbles &rarrow; 4 memory bytes
072 * (ADDED NIBL DELAY)
3964:BD 8C C0 073 RDA3 LDA Q6L,X
3967:10 FB 074 BPL RDA3 *** NO PAGE CROSS! ***
3969:C9 96 075 CMP #$96 ADR MARK 3? ; magic number DISK_ADR_PROLOG_3 EQU #$96
396B:D0 E7 076 BNE RDASN1 (IF NOT, IS IT AM1?)
077 * (LEAVES CARRY SET!) ; C=1, And this important WHY? Carry becomes Bit 0 of 4&4 Checksum odd nibble, Line #082
396D:A9 00 078 LDA #$0 INIT CHECKSUM.
396F:85 27 079 RDAFLD STA CSUM
3971:BD 8C C0 080 RDA4 LDA Q6L,X READ 'ODD BIT' NIBL. ; Technically, read odd bits
3974:10 FB 081 BPL RDA4 *** NO PAGE CROSS! *** ; A=1a1c1e1g
3976:2A 082 ROL A ;ALIGN ODD BITS, '1' into LSB. ; A=a1c1e1gC, and C stays set
3977:85 26 083 STA LAST
3979:BD 8C C0 084 RDA5 LDA Q6L,X READ 'EVEN BIT' NIBL. ; Technically, read even bits
397C:10 FB 085 BPL RDA5 *** NO PAGE CROSS! *** ; A=1b1d1f1h
397E:25 26 086 AND LAST MERGE ODD AND EVEN BITS ; &=a1c1e1g1
3980:99 2C 00 087 STA CSSTV,Y STORE DATA BYTE. ; A=abcdefgh, Store bytes in reverse order due to Y counting down
3983:45 27 088 EOR CSUM XOR CHECKSUM
3985:88 089 DEY
3986:10 E7 090 BPL RDAFLD LOOP ON 4 DATA BYTES.
3988:A8 091 TAY IF FINAL CHECKSUM
3989:D0 B7 092 BNE RDERR NONZERO, THEN ERROR.
398B:BD 8C C0 093 RDA6 LDA Q6L,X FIRST BIT-SLIP NIBL.
398E:10 FB 094 BPL RDA6 *** NO PAGE CROSS! ***
3990:C9 DE 095 CMP #$DE ; magic number DISK_ADR_EPILOG_1 EQU #$DE
3992:D0 AE 096 BNE RDERR ERROR IF NONMATCH.
3994:EA 097 NOP DELAY BETWEEN NIBLS.
3995:BD 8C C0 098 RDA7 LDA Q6L,X SECOND BIT-SLIP NIBL.
3998:10 FB 099 BPL RDA7 *** NO PAGE CROSS! ***
399A:C9 AA 100 CMP #$AA ; magic number DISK_ADR_EPILOG_2 EQU #$AA
399C:D0 A4 101 BNE RDERR ERROR IF NONMATCH. ; Uh, what happened to checking the last disk nibble!?!?! DISK_ADR_EPILOG_3 EQU #$EB
399E:18 102 RDEXIT CLC CLEAR CARRY ON ; This probably deserves a "No shit, Sherlock"
399F:60 103 RTS NORMAL READ EXITS. ; Brilliant hardware engineers tend to clutter up code with useless trivial comments. :-/
104 SBTL '16-SECTOR SEEK'
105 **************************
106 * *
107 * FAST SEEK SUBROUTINE * ; A fast seek is completely useless
108 * * ; if READING forces extra disk spins due to buffer bloat
109 **************************
110 * *
111 * ---- ON ENTRY ---- *
112 * *
113 * X-REG HOLDS SLOTNUM *
114 * TIMES $10. *
115 * *
116 * A-REG HOLDS DESIRED *
117 * HALFTRACK, * ; === Page 108 ===
118 * (SINGLE PHASE) *
119 * *
120 * CURTRK HOLDS CURRENT *
121 * HALFTRACK. *
122 * *
123 * ---- ON EXIT ----- *
124 * *
125 * A-REG UNCERTAIN. *
126 * Y-REG UNCERTAIN. *
127 * X-REG UNCERTAIN. *
128 * *
129 * CURTRK AND TRKN HOLD *
130 * FINAL HALFTRACK. *
131 * *
132 * PRIOR HOLDS PRIOR *
133 * HALFTRACK IF SEEK *
134 * WAS REQUIRED. *
135 * *
136 * MONTIMEL AND MONTIMEH *
137 * ARE INCREMENTED BY *
138 * THE NUMBER OF *
139 * 100 USEC QUANTUMS *
140 * REQUIRED BY SEEK *
141 * FOR MOTOR ON TIME *
142 * OVERLAP. *
143 * *
144 * --- VARIABLES USED --- *
145 * *
146 * CURTRK, TRKN, COUNT, *
147 * PRIOR, SLOTTEMP *
148 * MONTIMEL, MONTIMEH *
149 * *
150 **************************
39A0:86 2B 151 SEEK STX SLOTTEMP ;SAVE X-REG
39A2:85 2A 152 STA TRKN ;SAVE TARGET TRACK
39A4:CD 78 04 153 CMP CURTRK ON DESIRED TRACK? ;
39A7:F0 53 154 BEQ SEEKRTS ;YES, RETURN
39A9:A9 00 155 LDA #$0
39AB:85 26 156 STA TRKCNT ;HALFTRACK COUNT.
39AD:AD 78 04 157 SEEK2 LDA CURTRK ;SAVE CURTRK FOR
39B0:85 27 158 STA PRIOR ; DELAYED TURNOFF.
39B2:38 159 SEC
39B3:E5 2A 160 SBC TRKN ;DELTA-TRACKS.
39B5:F0 33 161 BEQ SEEKEND ;BR IF CURTRK=DESTINATION
39B7:B0 07 162 BCS OUT (MOVE OUT, NOT IN)
39B9:49 FF 163 EOR #$FF CALC TRKS TO GO
39BB:EE 78 04 164 INC CURTRK INCR CURRENT TRACK (IN).
39BE:90 05 165 BCC MINTST (ALWAYS TAKEN)
39C0:69 FE 166 OUT ADC #$FE CALC TRKS TO GO.
39C2:CE 78 04 167 DEC CURTRK DECR CURRENT TRACK (OUT).
39C5:C5 26 168 MINTST CMP TRKCNT ; crappy abbreviation: Min Test
39C7:90 02 169 BCC MAXTST AND 'TRKS MOVED'.
39C9:A5 26 170 LDA TRKCNT ; crappy abbreviation: Max Test
39CB:C9 0C 171 MAXTST CMP #$C ; magic number ON_TIME_SIZE EQU $C, or even OFFTABLE - ONTABLE
39CD:B0 01 172 BCS STEP2 ;IF TRKCNT>$B LEAVE Y ALONE (Y=$B).
39CF:A8 173 STEP TAY ;ELSE SET ACCELERATION INDEX IN Y
174 STEP2 EQU *
39D0:38 175 SEC ;CARRY SET=PHASE ON
39D1:20 EE 39 176 JSR SETPHASE ;PHASE ON
39D4:B9 11 3A 177 LDA ONTABLE,Y FOR 'ONTIME'.
39D7:20 00 3A 178 JSR MSWAIT (100 USEC INTERVALS)
179 *
39DA:A5 27 180 LDA PRIOR ; === Page 109 ===
39DC:18 181 CLC ;CARRY CLEAR=PHASE OFF
39DD:20 F1 39 182 JSR CLRPHASE ;PHASE OFF
39E0:B9 1D 3A 183 LDA OFFTABLE,Y THEN WAIT 'OFFTIME'.
39E3:20 00 3A 184 JSR MSWAIT (100 USEC INTERVALS)
39E6:E6 26 185 INC TRKCNT 'TRACKS MOVED' COUNT.
39E8:D0 C3 186 BNE SEEK2 (ALWAYS TAKEN)
187 *
188 SEEKEND EQU *
39EA:20 00 3A 189 JSR MSWAIT ;A=0: WAIT 25 MS SETTLE
39ED:18 190 CLC
191 *
192 * TURN HEAD STEPPER PHASE ON/OFF
193 *
194 SETPHASE EQU *
39EE:AD 78 04 195 LDA CURTRK ;GET CURRENT PHASE
196 CLRPHASE EQU *
39F1:29 03 197 AND #3 ;MASK FOR 1 OF 4 PHASES
39F3:2A 198 ROL A ;DOUBLE FOR PHASE INDEX
39F4:05 2B 199 ORA SLOTTEMP
39F6:AA 200 TAX
39F7:BD 80 C0 201 LDA PHASEOFF,X ;FLIP THE PHASE
39FA:A6 2B 202 LDX SLOTTEMP ;RESTORE X-REG
39FC:60 203 SEEKRTS RTS ;AND RETURN ; /sarcasm I don't know what we would do without you Captain Obvious!
001 SBTL '16-SECTOR MSWAIT'
002 **************************
003 * MSWAIT SUBROUTINE *
004 **************************
005 * *
006 * DELAYS A SPECIFIED *
007 * NUMBER OF 100 USEC *
008 * INTERVALS FOR MOTOR *
009 * ON TIMING. *
010 * *
011 * ---- ON ENTRY ---- *
012 * A-REG: HOLDS NUMBER *
013 * OF 100 USEC *
014 * INTERVALS TO *
015 * DELAY. *
016 * *
017 * ---- ON EXIT ----- *
018 * A-REG: HOLDS $00. *
019 * X-REG: HOLDS $00. *
020 * Y-REG: UNCHANGED. *
021 * CARRY: SET. *
022 * *
023 * MONTIMEL, MONTIMEH *
024 * ARE INCREMENTED ONCE *
025 * PER 100 USEC INTERVAL*
026 * FOR MOTON ON TIMING. *
027 * ---- ASSUMES ---- *
028 * 1 USEC CYCLE TIME *
029 **************************
39FD:00 00 00 030 DS 3,0 ;AVOID PAGE BOUNDARY CROSSING...; T0S3 @ $FC wastes 3 bytes
3A00:A2 11 031 MSWAIT LDX #$11 ; === T0S4 === *sigh* Typical bloated code ...
3A02:CA 032 MSW1 DEX DELAY 86 USEC. ; ... should just adjust algorithm timing instead!
3A03:D0 FD 033 BNE MSW1
3A05:E6 46 034 INC MONTIMEL
3A07:D0 02 035 BNE MSW2 ; DOUBLE-BYTE
3A09:E6 47 036 INC MONTIMEH INCREMENT.
3A0B:38 037 MSW2 SEC
3A0C:E9 01 038 SBC #$1 DONE 'N' INTERVALS?
3A0E:D0 F0 039 BNE MSWAIT (A-REG COUNTS)
3A10:60 040 RTS
041 AEC1 EQU * ;TELL RELOCATOR WHERE CORE ENDS
042 **************************
043 * PHASE ON-, OFF-TIME *
044 * TABLES IN 100-USEC *
045 * INTERVALS. (SEEK) *
046 **************************
3A11:01 30 28 047 ONTABLE DFB 1,$30,$28 ; See RDADSEK, Page 108, Line #TODO
3A14:24 20 1E 048 DFB $24,$20,$1E
3A17:1D 1C 1C 049 DFB $1D,$1C,$1C
3A1A:1C 1C 1C 050 DFB $1C,$1C,$1C
3A1D:70 2C 26 051 OFFTABLE DFB $70,$2C,$26 ; See RDADSEK Page 109, Line #183
3A20:22 1F 1E 052 DFB $22,$1F,$1E
3A23:1D 1C 1C 053 DFB $1D,$1C,$1C
3A26:1C 1C 1C 054 DFB $1C,$1C,$1C ; === Page 98 ===
055 SBTL '16-SECTOR NYBBLE TABLES'
056 ***************************
057 * *
058 * 6-BIT TO 7-BIT *
059 * NIBL CONVERSION TABLE *
060 * *
061 ***************************
062 * *
063 * CODES WITH MORE THAN *
064 * ONE PAIR OF ADJACENT *
065 * ZEROES OR WITH NO *
066 * ADJACENT ONES (EXCEPT *
067 * B7) ARE EXCLUDED. *
068 * *
069 * THIS TABLE MAY *NOT* *
070 * CROSS A PAGE BOUNDARY! *
071 * *
072 ***************************
3A29:96 97 9A 073 NIBL DFB $96,$97,$9A ; /sarcasm, Gee if only
3A2C:9B 9D 9E 074 DFB $9B,$9D,$9E ; there was a HEX pseudo-mnemonic
3A2F:9F A6 A7 075 DFB $9F,$A6,$A7 ; so we could group these in 4 bytes ...
3A32:AB AC AD 076 DFB $AB,$AC,$AD ; ... maybe one day. :)
3A35:AE AF B2 077 DFB $AE,$AF,$B2 ; NOTE: Also see NIBL and PD2
3A38:B3 B4 B5 078 DFB $B3,$B4,$B5
3A3B:B6 B7 B9 079 DFB $B6,$B7,$B9
3A3E:BA BB BC 080 DFB $BA,$BB,$BC
3A41:BD BE BF 081 DFB $BD,$BE,$BF
3A44:CB CD CE 082 DFB $CB,$CD,$CE
3A47:CF D3 D6 083 DFB $CF,$D3,$D6
3A4A:D7 D9 DA 084 DFB $D7,$D9,$DA
3A4D:DB DC DD 085 DFB $DB,$DC,$DD
3A50:DE DF E5 086 DFB $DE,$DF,$E5
3A53:E6 E7 E9 087 DFB $E6,$E7,$E9
3A56:EA EB EC 088 DFB $EA,$EB,$EC
3A59:ED EE EF 089 DFB $ED,$EE,$EF
3A5C:F2 F3 F4 090 DFB $F2,$F3,$F4
3A5F:F5 F6 F7 091 DFB $F5,$F6,$F7
3A62:F9 FA FB 092 DFB $F9,$FA,$FB
3A65:FC FD FE 093 DFB $FC,$FD,$FE
3A68:FF 094 DFB $FF
095 PAGE
096 ***************************
097 * 7-BIT TO 6-BIT *
098 * 'DENIBLIZE' TABL *
099 * (16-SECTOR FORMAT) *
100 * *
101 * VALID CODES *
102 * $96 TO $FF ONLY. *
103 * *
104 * *
105 * CODES WITH MORE THAN *
106 * ONE PAIR OF ADJACENT *
107 * ZEROES OR WITH NO *
108 * ADJACENT ONES (EXCEPT *
109 * BIT 7) ARE EXCLUDED. *
110 * *
111 * THIS TABLE *MUST* BE *
112 * ALIGNED AT THE END OF *
113 * A PAGE IN MEMORY!!! *
114 ***************************
115 XP EQU <* ;CURRENT PAGE ADDRESS
116 DNIBL EQU 256*XP ;DNIBL TABLE PAGE ; See READ4
117 PAGE ; === Page 99 ===
118 ***********************************************
119 *
120 * GHOST APPEND BUG PATCH BY
121 * BILL GRIMM
122 *
123 ***********************************************
124 PSC1 EQU * ;Tell relocater where to start
125 MOVEOF EQU * ; Called from DOSGO2A
3A69:AE 5F 2A 126 LDX CMDNO ; GET CMD NUMBER
3A6C:E0 1C 127 CPX #$1C ; APPEND COMMAND? ; magic number TODO
3A6E:F0 05 128 BEQ GOON ; YES, RETURN TO CALLING ROUTINE
3A70:A2 00 129 LDX #$00 ; NO, THEN CLEAR X ; Aye, Aye, Captain Obvious
3A72:8E 5D 36 130 STX EOFFLAG ; CLEAR EOF FLAG
3A75:60 131 GOON RTS
132 SKP 4
133 ***********************************************
134 *
135 * TURN Apple //e 80 COLUMN CARD
136 * OFF & INIT APPLE
137 *
138 ***********************************************
139 OFF80 EQU *
3A76:A9 FF 140 LDA #$FF
3A78:8D FB 04 141 STA $4FB ; CLEARS FUNNY 80 COL STUFF ; magic number TEXT screen hole TODO
3A7B:8D 0C C0 142 STA $C00C ; TURNS 80 COL OFF
3A7E:8D 0E C0 143 STA $C00E ; TURN OFF ALT CHAR SET ; /sarcasm If only we could define symbols ...
3A81:4C 2F FB 144 JMP $FB2F ; MONITOR INIT ROUTINE ; Oh wait! We already have MONINIT in BOOTLDR
; === DOS 3.3B 1983 ONLY === ; Called from GOBACK+5 = $3683
; Note: "Apple II DOS 3.3 C Source Code Listing" has the old DOS 3.3B TEMPY.pretty on Page 128
; DOS 3.3C shows this got relocated to $36B3 via the hex dump "DOS33C.OBJ" D/001B80: on Page 36
FIXIT2 EQU *
LDA CCBBYT ;3A84:AD BD 35
STA DCBCSB ;3A87:8D E6 35
STA DCBCRR ;3A8A:8D EA 35
TSX ;3A8D:BA
STX ENTSTK ;3A8E:8E 9B 33
JMP GOODIO ;3A91:4C 7F 33
; === DOS 3.3B 1983 ===
145 PAGE
146 PEC1 EQU * ;Tell relocater where to stop ; See CDETAB, RELOCTR, Page 115
147 PD1 EQU >*
148 PD2 EQU $96-PD1 ; $96 - $84 = $12
3A84:00 00 00 00 149 DS PD2,0 ;Must pad to $XX96 ; [.. *wastes* 18 bytes
3A88:00 00 00 00 ; .. No, no, no!
3A8C:00 00 00 00 ; .. Negative array index OFFSETS like the P6 PROM uses
3A90:00 00 00 00 ; ..
3A94:00 00 ; ..]
3A96:00 01 98 150 DFB $00,$01,$98 ; 96 97 -- *sigh* And the comment that this is the
3A99:99 02 03 151 DFB $99,$02,$03 ; -- 9A 9B 64 disk nibbles of 6&2 Read Table
3A9C:9C 04 05 152 DFB $9C,$04,$05 ; -- 9D 9E is where again? Comments people, comments!
3A9F:06 A0 A1 153 DFB $06,$A0,$A1 ; 9F -- -- Hey, after annotating 154 pages
3AA2:A2 A3 A4 154 DFB $A2,$A3,$A4 ; -- -- -- you would be grumpy too. :-)
3AA5:A5 07 08 155 DFB $A5,$07,$08 ; -- A6 A7
3AA8:A8 A9 AA 156 DFB $A8,$A9,$AA ; -- -- !! (!! Technically AA is a valid disk nibble)
3AAB:09 0A 0B 157 DFB $09,$0A,$0B ; AB AC AD but it reserved for a 3 byte header id
3AAE:0C 0D B0 158 DFB $0C,$0D,$B0 ; AE AF -- Typical DOS 3.3 B-L-O-A-T
3AB1:B1 0E 0F 159 DFB $B1,$0E,$0F ; -- B2 B3 One reserved byte D5 could be used for T/S header. HEAD = 8EAD i.e. D5 8E, or D5 8E AD
3AB4:10 11 12 160 DFB $10,$11,$12 ; B4 B5 B6 One reserved byte D5 could be used for Data header. DATA = DA1A i.e. D5 DA, or D5 DA 1A
3AB7:13 B8 14 161 DFB $13,$B8,$14 ; B7 -- B9 But since we have 66 valid disk nibbles reservering two for meta-data is OK.
3ABA:15 16 17 162 DFB $15,$16,$17 ; BA BB BC But we could pack more data on a track the more disk nibbles we use. i.e. 19 sectors/track.
3ABD:18 19 1A 163 DFB $18,$19,$1A ; BD BE BF
3AC0:C0 C1 C2 164 DFB $C0,$C1,$C2 ; -- -- -- [.. *wastes* 11 bytes (unused)
3AC3:C3 C4 C5 165 DFB $C3,$C4,$C5 ; -- -- -- .. /sarcasm But who cares, we have 48K right!?
3AC6:C6 C7 C8 166 DFB $C6,$C7,$C8 ; -- -- -- .. This is why DOS takes seconds longer to boot.
3AC9:C9 CA 1B 167 DFB $C9,$CA,$1B ; -- -- CB ..]
3ACC:CC 1C 1D 168 DFB $CC,$1C,$1D ; -- CD CE *sigh* This entire table can be compactly
3ACF:1E D0 D1 169 DFB $1E,$D0,$D1 ; CF -- -- represented with 8 lines instead of 36 lines
3AD2:D2 1F D4 170 DFB $D2,$1F,$D4 ; -- D3 -- If only we had a HEX pseudo-mnemonic ...
3AD5:D5 20 21 171 DFB $D5,$20,$21 ; @@ D6 D7 (@@ Technically D5 is valid but is reserved too)
3AD8:D8 22 23 172 DFB $D8,$22,$23 ; -- D9 DA x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
3ADB:24 25 26 173 DFB $24,$25,$26 ; DB DC DD 9x:-- -- -- -- -- -- 00 01 -- -- 02 03 -- 04 05 06
3ADE:27 28 E0 174 DFB $27,$28,$E0 ; DE DF -- Ax:-- -- -- -- -- -- 07 08 -- -- !! 09 0A 0B 0C 0D
3AE1:E1 E2 E3 175 DFB $E1,$E2,$E3 ; -- -- -- Bx:-- -- 0E 0F 10 11 12 13 -- 14 15 16 17 18 19 1A
3AE4:E4 29 2A 176 DFB $E4,$29,$2A ; -- E5 E6 Cx:-- -- -- -- -- -- -- -- -- -- -- 1B -- 1C 1D 1E
3AE7:2B E8 2C 177 DFB $2B,$E8,$2C ; E7 -- E9 Dx:-- -- -- 1F -- @@ 20 21 -- 22 23 24 25 26 27 28
3AEA:2D 2E 2F 178 DFB $2D,$2E,$2F ; EA EB EC Ex:-- -- -- -- -- 29 2A 2B -- 2C 2D 2E 2F 30 31 32
3AED:30 31 32 179 DFB $30,$31,$32 ; ED EE EF Fx:-- -- 33 34 35 36 37 38 -- 39 3A 3B 3C 3D 3E 3F
3AF0:F0 F1 33 180 DFB $F0,$F1,$33 ; -- -- F2 === Page 100 ===
3AF3:34 35 36 181 DFB $34,$35,$36 ; F3 F4 F5
3AF6:37 38 F8 182 DFB $37,$38,$F8 ; F6 F7 --
3AF9:39 3A 3B 183 DFB $39,$3A,$3B ; F9 FA FB
3AFC:3C 3D 3E 184 DFB $3C,$3D,$3E ; FC FD FE
3AFF:3F 185 DFB $3F ; FF
186 PAGE
187 ***************************
188 * *
189 * NYBBLE BUFFERS *
190 * *
191 * NBUF1 (256 BYTES) MUST *
192 * BE ALIGNED ON A PAGE *
193 * BOUNDARY. *
194 * *
195 * NBUF2 (86 BYTES) MUST * ; Incorrect: NBUF2 must _not_ cross
196 * BE ALIGNED ON A PAGE * ; a page boundary. Technically, it can be
197 * BOUNDARY. * ; anywhere *within* the page as long as the
198 * * ; code at WRITRTN, Line #>80 is fixed up.
199 *************************** ;
200 * ;
3B00:00 00 00 00 201 NBUF1 DS 256,0 ;NBUF1 ; === T0S5 === disk sector wasted with zeroes
3B04:00 00 00 00 ; *sigh* Let's waste an *entire* sector
3B08:00 00 00 00 ; with 342 disk nibbles of raw $96 nibbles
3B0C:00 00 00 00 ; PLUS the time decoding it
3B10:00 00 00 00 ; when _9 bytes_ would do
3B14:00 00 00 00 ; the job
3B18:00 00 00 00 ;
3B1C:00 00 00 00 ; LDA #0
3B20:00 00 00 00 ; TAY
3B24:00 00 00 00 ;.1 STA NBUF1,Y
3B28:00 00 00 00 ; INY
3B2C:00 00 00 00 ; BNE .1
3B30:00 00 00 00 ;
3B34:00 00 00 00 ; This data should at $3F00 ($BF00)
3B38:00 00 00 00
3B3C:00 00 00 00
3B40:00 00 00 00
3B44:00 00 00 00
3B48:00 00 00 00
3B4C:00 00 00 00
3B50:00 00 00 00
3B54:00 00 00 00
3B58:00 00 00 00
3B5C:00 00 00 00
3B60:00 00 00 00
3B64:00 00 00 00
3B68:00 00 00 00
3B6C:00 00 00 00
3B70:00 00 00 00
3B74:00 00 00 00
3B78:00 00 00 00
3B7C:00 00 00 00
3B80:00 00 00 00
3B84:00 00 00 00
3B88:00 00 00 00
3B8C:00 00 00 00
3B90:00 00 00 00
3B94:00 00 00 00
3B98:00 00 00 00
3B9C:00 00 00 00
3BA0:00 00 00 00
3BA4:00 00 00 00
3BA8:00 00 00 00
3BAC:00 00 00 00
3BB0:00 00 00 00
3BB4:00 00 00 00
3BB8:00 00 00 00
3BBC:00 00 00 00
3BC0:00 00 00 00
3BC4:00 00 00 00
3BC8:00 00 00 00
3BCC:00 00 00 00
3BD0:00 00 00 00
3BD4:00 00 00 00
3BD8:00 00 00 00
3BDC:00 00 00 00
3BE0:00 00 00 00
3BE4:00 00 00 00
3BE8:00 00 00 00
3BEC:00 00 00 00
3BF0:00 00 00 00
3BF4:00 00 00 00
3BF8:00 00 00 00
3BFC:00 00 00 00
3C00:00 00 00 00 202 NBUF2 DS 86,0 ;NBUF2 ; === T0S6 === disk sector wasted bytes
3C04:00 00 00 00 ; *sigh* more wasted disk space
3C08:00 00 00 00 ; pack code THEN data
3C0C:00 00 00 00 ; as interleaving it just
3C10:00 00 00 00 ; wastes memory
3C14:00 00 00 00
3C18:00 00 00 00
3C1C:00 00 00 00
3C20:00 00 00 00
3C24:00 00 00 00
3C28:00 00 00 00
3C2C:00 00 00 00
3C30:00 00 00 00
3C34:00 00 00 00
3C38:00 00 00 00
3C3C:00 00 00 00
3C40:00 00 00 00
3C44:00 00 00 00
3C48:00 00 00 00
3C4C:00 00 00 00
3C50:00 00 00 00
3C54:00 00
001 SBTL '16-SECTOR WRITE ADDRESS'
002 ********************************
003 * *
004 * WRITE ADR FIELD SUBROUTINE * ; Writes Disk Nibbles:
005 * (16-SECTOR FORMAT) * ; FF FF FF .. FF (Y sync bytes)
006 * WRITES SPECIFIED NUMBER OF * ; D5 AA 96
007 * 40-USEC (10-BIT) SELF-SYNC * ; VOL VOL 4&4
008 * NIBLS, ADR FIELDS 16-SECTOR * ; TRK TRK 4&4
009 * START MARKS ($D5,$AA,$96), * ; SEC SEC 4&4
010 * BODY (VOLUME, TRACK, SECTOR,* ; CRC CRC 4&4
011 * CHECKSUM), END FIELD MARKS, * ; DE EA EB
012 * AND THE WRITE TURN-OFF NIBL.*
013 * *
014 ********************************
015 * *
016 * ------- ON ENTRY ------- *
017 * *
018 * THE LOCATIONS VOLUME, TRK, * ; Technically NVOL not VOLUME
019 * AND NSECT MUST CONTAIN THE * ; See, programmers wrote out-of-date comments even back then! /s
020 * DESIRED VOLUME, TRACK, AND * ;
021 * SECTOR VALUES DESIRED. * ; NVOL @ $41 Volume
022 * * ; TRK @ $44 Track
023 * THE PROPER DRIVE MUST BE * ; NSECT @ $3F Sector
024 * ENABLED AND UP TO SPEED IN * ;
025 * READ MODE (Q7L, Q6L). * ; Not documented: AA
026 * * ;
027 * X-REG CONTAINS SLOTNUM * ; Zero-Page $3E *must* contain #$AA
028 * TIMES 16. * ; for 3 cycle timing. See Line #086
029 * *
030 * Y-REG CONTAINS NUMBER OF *
031 * SELF SYNC NIBLS DESIRED *
032 * MINUS 1. *
033 * (0 FOR 256 NIBLS) *
034 * *
035 ********************************
036 * *
037 * ------- CAUTION -------- *
038 * *
039 * 1 USEC CYCLE *
040 * *
041 ********************************
042 * *
043 * ------- CAUTION -------- *
044 * *
045 * MOST OF THIS CODE IS TIME *
046 * CRITICAL. OBSERVE ALL *
047 * 'NO PAGE CROSS!' WARNINGS *
048 * ON BRANCHES *
049 * *
050 ********************************
051 SWADR1 EQU * ;TELL RELOCATOR WHERE TO BEGIN
052 *******************************
3C56:38 053 WADR16 SEC ANTICIPATE WR PROT ERR.
3C57:BD 8D C0 054 LDA Q6H,X INTO 'WR PROT SENSE' MODE. ; === Page 135 ===
3C5A:BD 8E C0 055 LDA Q7L,X SENSE IT (NEG=PROTECTED)
3C5D:30 5E 056 BMI WADRTS ERR EXIT IF PROTECTED.
3C5F:A9 FF 057 LDA #$FF SELF-SYNC NIBL. ; 40 µ seconds to write any SYNC nibble
3C61:9D 8F C0 058 STA Q7H,X WRITE FRIST NIBL. ; = 0 [ 0]
3C64:DD 8C C0 059 CMP Q6L,X (4) BACK TO WRITE MODE. ; + 4 [ 4]
3C67:48 060 PHA (3) FOR DELAY ; + 3 [ 7]
3C68:68 061 PLA (4) ; + 4 [11]
3C69:20 C3 3C 062 WSYNC1 JSR WADRTS1 (12) FOR 40-USEC NIBLS. ; +12 [23] JSR=+6, <----------------+
3C6C:20 C3 3C 063 JSR WADRTS1 (12) ; +12 [35] RTS=+6 |
3C6F:9D 8D C0 064 STA Q6H,X (5) WRITE NIBL. ; + 5 [40] ========> 0 [ 0] |
3C72:DD 8C C0 065 CMP Q6L,X (4) (BACK TO WRITE MODE) ; + 4 [ 4] |
3C75:EA 066 NOP (2) FOR DELAY. ; + 2 [ 6] |
3C76:88 067 DEY (2) NEXT OF 'N' NIBLS. ; + 2 [ 8] |
3C77:D0 F0 068 BNE WSYNC1 (3) *** NO PAGE CROSS! *** ; + 2 [10] BEQ <== + 3 [11] --> BNE ^
; 32 µ seconds write DATA nibble
3C79:A9 D5 069 LDA #$D5 (2) ADR MARK 1. ; + 2 [12] magic number DISK_ADR_PROLOG_1 EQU #$D5
3C7B:20 D5 3C 070 JSR WNIBLB2 (15,9,6) WRITE IT. ; +24 [10] <-- JSR=6, WNIBLB2=9, WRNIBL=15
3C7E:A9 AA 071 LDA #$AA (2) ADR MARK 2. ; + 2 [12] magic number DISK_ADR_PROLOG_2 EQU #$AA
3C80:20 D5 3C 072 JSR WNIBLB2 (15,9,6) WRITE IT. ; +24 [10]
3C83:A9 96 073 LDA #$96 (2) 16-SECTOR ADR MARK 3. ; + 2 [10] magic number DISK_ADR_PROLOG_3 EQU #$96
3C85:20 D5 3C 074 JSR WNIBLB2 (15,9,6) WRITE IT. ; +24 [10]
3C88:A5 41 075 LDA NVOL (3) ; + 3 [13]
3C8A:20 C4 3C 076 JSR WBYTE (14,9,6) WRITE NVOL (ODD, THEN EVEN, BITS.) ; JSR=6
3C8D:A5 44 077 LDA TRK (3) WRITE TRACK NUMBER. ;
3C8F:20 C4 3C 078 JSR WBYTE (14,9,6) ODD, THEN EVEN, BITS) ;
3C92:A5 3F 079 LDA NSECT (3) WRITE SECTOR NUMBER. ;
3C94:20 C4 3C 080 JSR WBYTE (14,9,6) (ODD, THEN EVEN, BITS) ;
3C97:A5 41 081 LDA NVOL (3) ;
3C99:45 44 082 EOR TRK (3) FORM ADR FIELD CHECKSUM. ;
3C9B:45 3F 083 EOR NSECT (3) ;
3C9D:48 084 PHA (3) SAVE FOR EVEN BITS. ;
3C9E:4A 085 LSR A (2) ALIGHN ODD BITS. ; *spelling* "ALIGN" Poorly written assemblers explicitly need the implicit A register
3C9F:05 3E 086 ORA AA (3) SET CLOCK BITS. ; This is a shitty variable name: AA; call it WRITE_NIB_AA, see DSKFORM, Line #020,
087 * (PRECISE TIMING, 32 CYCLES PER NIBL)
3CA1:9D 8D C0 088 STA Q6H,X (5) WRITE CHECKSUM ODD BITS. ;
3CA4:BD 8C C0 089 LDA Q6L,X (4) BACK TO WRITE MODE. ;
3CA7:68 090 PLA (4) RECOVER FOR EVEN BITS. ;
3CA8:09 AA 091 ORA #$AA (2) SET CLOCK BITS. ;
3CAA:20 D4 3C 092 JSR WNIBLA (17,9,6) WRITE THEM. ;
3CAD:A9 DE 093 LDA #$DE (2) END MARK 1. ; magic number DISK_ADR_EPILOG_1 EQU #$DE
3CAF:20 D5 3C 094 JSR WNIBLB2 (15,9,6) WRITE IT. ;
3CB2:A9 AA 095 LDA #$AA (2) END MARK 2. ; magic number DISK_ADR_EPILOG_2 EQU #$AA
3CB4:20 D5 3C 096 JSR WNIBLB2 (15,9,6) WRITE IT. ;
3CB7:A9 EB 097 LDA #$EB (2) END MARK 3. ; magic number DISK_ADR_EPILOG_3 EQU #$EB
3CB9:20 D5 3C 098 JSR WNIBLB2 (15,9,6) 'WRITE TURN-OFF' ;
3CBC:18 099 CLC INDICATE NO WR PROT ERR.
3CBD:BD 8E C0 100 WADRTS LDA Q7L,X OUT OF WRITE MODE. ; TODO: used elsewhere?
3CC0:BD 8C C0 101 LDA Q6L,X TO READ MODE. ; These are shit function names -- they give no clue when they should be called!
3CC3:60 102 WADRTS1 RTS RETURN ; should be called WAIT_6
3CC4:48 103 WBYTE PHA (3) PRESERVE FOR EVEN BITS. ;+3 [22] should be called WRITE13_2NIB_22, JSR when cycles=13
3CC5:4A 104 LSR A (2) ALIGN ODD BITS. ;+2 [25]
3CC6:05 3E 105 ORA AA (3) SET CLOCK BITS. ;+3 [27]
3CC8:9D 8D C0 106 STA Q6H,X (5) WRITE NIBL. ;+5 [32] See: WRNIBL
3CCB:DD 8C C0 107 CMP Q6L,X (4) ;=4 [ 4]
3CCE:68 108 PLA (4) RECOVER FOR EVEN BITS. ;+4 [ 8]
3CCF:EA 109 NOP (2) ;+2 [10]
3CD0:EA 110 NOP (2) FOR DELAY. ;+2 [12]
3CD1:EA 111 NOP (2) ;+2 [14]
3CD2:09 AA 112 ORA #$AA (2) SET CLOCK BITS. ;+2 [16]
3CD4:EA 113 WNIBLA NOP (2) (17,9,6) ENTRY. ;+2 [18] Should be called WRITE12_1nib_18, JSR when cycles=12
3CD5:EA 114 WNIBLB2 NOP (2) (15,9,6) ENTRY. ;+2 [20] should be called WRITE14_1nib_20, JSR when cycles=14
3CD6:48 115 PHA (3) FOR ;+3 [23]
3CD7:68 116 PLA (4) DELAY. ;+4 [27] === Page 136 ===
3CD8:9D 8D C0 117 WRNIBL STA Q6H,X (5) WRITE NIBL. ;+5 [32] Should be called WRITE21_1nib_27, JSR when cycles=21
3CDB:DD 8C C0 118 CMP Q6L,X (4) ;=4 [ 4] -- WRNIBL unused, never referenced --
3CDE:60 119 RTS (6) RETURN ;+6 [10]
120 EWADR1 EQU * ;TELL RELOCTR WHERE TO STOP
121 XP2 EQU <*+255 ;H.O. ADDRESS NEXT PAGE ; Other page align macros BHERE1 use:
122 XP2H EQU 256*XP2 ;NOW AS 16-BITS ; DS $100-EWADR1
3CDF:00 123 DS XP2H-*,0 ;PAD OUT TO PAGE BOUNDARY.. ; *wastes* 33 bytes!
3CE0:00 00 00 00
3CE4:00 00 00 00
3CE8:00 00 00 00
3CEC:00 00 00 00
3CF0:00 00 00 00
3CF4:00 00 00 00
3CF8:00 00 00 00
3CFC:00 00 00 00
001 STBL '16-SECTOR RWTS'
002 ****************************
003 * DISK II *
004 * READ/WRITE TRACK-SECTOR * ; The famous RWTS
005 * * ; Technically it should be called RWSWT since it only supports:
006 * COPYRIGHT 1978 BY * ; Read Sector (RS)
007 * APPLE COMPUTER, INC. * ; Write Sector (WS)
008 * * ; Write Track (WT)
009 * ALL RIGHTS RESERVED *
010 * *
011 * R. WIGGINTON *
012 * *
013 * MODIFIED: 07/13/79 *
014 * R. AURICCHIO *
015 * ADDED WAIT-SEEK WHEN *
016 * POWERING-UP MOTOR. *
017 * *
018 * MODIFIED: 10/25/79 *
019 * R. AURICCHIO *
020 * ADDED DIAGMODE DISPLAYS *
021 * FOR ACTIVITY ANALYSIS. *
022 ****************************
023 ASC2 EQU * ;TELL RELOCTR WHERE RWTS BEGINS
024 *********************************
025 MOTOROFF EQU $C088
026 MOTORON EQU $C089
027 DRV1EN EQU $C08A
028 DRV2EN EQU $C08B
029 ******************************
030 * STATE MACHINE CONTROLS
031 * Q6 Q7 FUNCTION
032 * -- -- --------
033 * LO LO READ
034 * HI LO SENSE WRITE PROTECT
035 * LO HI WRITE
036 * HI HI WRITE LOAD
037 ******************************
038 DRV1TRK EQU $478 ; Text screen hole
039 DRV2TRK EQU $4F8 ; Text screen hole
040 IOBPL EQU $48 ;
041 IOBPH EQU $49 ;
042 SLOT EQU $5F8 ;HOLDS SLOT NUM USED ;
043 PTRSDEST EQU $3C ;
044 DEVCTBL EQU PTRSDEST ; $3C is pointer to Device Characteristics Table. See DCT
045 DRIVNO EQU $35 ; [0] Device Type -- never used --
046 MONTIME EQU $46 ; [1] Phases Per Track
047 SECT EQU CSSTV+1 ; $2D [2] Motor On Delay Low -- never used --
048 TRACK EQU CSSTV+2 ; $2E [3] Motor On Delay High
049 VOLUME EQU CSSTV+3 ; $2F
050 MAXSEEKS EQU 4 ;MAX FOR SEEKCNT ;
051 SEEKCNT EQU $4F8 ;# RESEEKS BEFORE RECALIBRATE ; Text screen hole, recycled with DRV2TRK
052 RETRYCNT EQU $578 ; Text screen hole
053 RECALCNT EQU $6F8 ;# RECALIBRATES -1 ; Text screen hole
054 PAGE ; === Page 117 ===
055 LST OFF
056 DO DIAGMODE
057 *
058 * DIAGMODE EQUATES...
059 *
060 SP EQU $A0 ;SPACE (INDICATOR OFF)
061 TD EQU 4 ;DISPL BETWEEN CHARS
062 TC1 EQU $1E ;^ - RWTS ACTIVE
063 TL1 EQU $07D0 ; VTAB 24: HTAB 1
064 TC2 EQU $0D ;M - MOTOR STARTUP
065 TL2 EQU TL1+TD
066 TC3 EQU $13 ;S - SEEK IN PROGRESS
067 TL3 EQU TL2+TD
068 TC4 EQU $01 ;A - READING ADDRESS
069 TL4 EQU TL3+TD
070 TC5 EQU $0C ;L - NOT DESIRED SECTOR (LATENCY)
071 TL5 EQU TL4+1
072 TC6 EQU $05 ;E - ADDRESS ERROR
073 TL6 EQU TL5+1
074 TC7 EQU $10 ;P - PRENIBBILIZING
075 TL7 EQU TL4+TD
076 TC8 EQU $17 ;W - WRITING
077 TL8 EQU TL7+TD
078 TC9 EQU $12 ;R - READING
079 TL9 EQU TL8+TD
080 TC10 EQU $05 ;E - READ ERROR
081 TL10 EQU TL9+TD
082 TC11 EQU $0F ;O - POSTNIBBLIZING
083 TL11 EQU TL10+TD
084 *
085 SCOUNT EQU $2FE ;SECTORS-ACCESSED COUNT
086 LCOUNT EQU $2FF ;LATENCY COUNT
087 TL12 EQU TL11+TD ;LATENCY POSITION
088 PAGE
089 FIN
090 LST ON
091 **************************
092 * *
093 * READ/WRITE A *
094 * TRACK AND SECTOR *
095 * *
096 **************************
097 * *
098 * ENTER WITH A & Y *
099 * REGISTERS POINTING TO *
100 * THE I/O CONTROL BLOCK *
101 * (THE 'IOB'). INSIDE *
102 * THE IOB: *
103 * *
104 * IBTYPE: IOB TYPE CODE *
105 * (SHOULD BE A 01) *
106 * *
107 * IBSLOT: CONTROLLER SLOT*
108 * NUMBER FOR THIS *
109 * ACCESS. *
110 * *
111 * IBDRVN: DRIVE NUMBER *
112 * FOR THIS ACCESS *
113 * *
114 * IBVOL: EXPECTED VOLUME *
115 * NUMBER. NOTE THAT *
116 * VOLUME 00 MATCHES *
117 * ANY VOLUME NUMBER * ; === Page 118 ===
118 * *
119 * IBTRK: TRACK TO USE *
120 * THIS ACCESS *
121 * *
122 * IBSECT: SECTOR NUMBER *
123 * TO USE THIS TIME *
124 * *
125 * IBDCTP: POINTER TO THE *
126 * DEVICE CHARACTER-* ; Really? You HAD to indent the line and force an artificial word break when it fits??
127 * ISTICS TABLE. *
128 * *
129 * IBBUFP: POINTER TO THE *
130 * PLACE THE DATA IS*
131 * OR SHOULD BE. *
132 * *
133 * IBDLEN: AMOUNT OF DATA *
134 * INBYTESTOBE *
135 * PROCESSED. *
136 * *
137 * IBCMD: COMMAND CODE: *
138 * 0-> NULL COMMAND * ; And this null command serves what purpose???
139 * 1-> READ SECTOR * ; RWTS_CMD_READ_SEC = 1
140 * 2-> WRITE SECTOR * ; RWTS_CMD_WRITE_SEC = 2
141 * 4-> FORMAT DISK * ; RWTS_CMD_FORMAT = 4
142 *
143 * IBSTAT: ERROR CODE: *
144 * 0-> NO ERROR *
145 * $10-> WRITE PROTECT *
146 * $20-> VOLUME ERROR *
147 * $40-> DRIVE ERROR *
148 * $80-> READ ERROR *
149 *
150 * IBSMOD: LOCATION TO *
151 * RETURN THE VOLUME*
152 * NUMBER ACTUALLY *
153 * FOUND. *
154 * *
155 * IOBPSN: PREVIOUS SLOT *
156 * NUMBER USED LAST * ; Why isn't the first word aligned with the colon???
157 * ACCESS. *
158 * *
159 * IOBPDN: PREVIOUS DRIVE *
160 * NUMBER USED LAST *
161 * ACCESS. *
162 * *
163 **************************
164 * *
165 * DEVICE CHARACTERISTICS *
166 * TABLE DESCRIPTION: *
167 * *
168 * DEVICE TYPE CODE * ; B7FB: [0] Device Type -- never used --
169 * (ZERO FOR DISK II) *
170 * *
171 * NUMBER OF PHASES PER * ; B7FC: [1] Device Phases Per Track, See MYSEEK
172 * TRACK (TWO FOR DISK II)*
173 * *
174 * MOTOR ON TIME IN 100 * ; B7FD: [2] Motor On Delay Low -- never used --
175 * MICROSECOND INTERVALS * ; B7FE: [3] Motor On Delay High -> MONTIME+1, See Line #250
176 * COMPLEMENTED. ($D8EF * ; Lies, only $D8 is used.
177 * FOR DISK II) *
178 * *
179 **************************
180 PAGE ; === Page 119 ===
3D00:84 48 181 RWTS STY IOBPL ;UPON ENTRY, A&Y POINT AT THE
3D02:85 49 182 STA IOBPH ;I/O CONTROL BLOCK (IOB)
183 LST OFF
184 DO DIAGMODE
185 LDY #TC1 ;SAY WE'RE ACTIVE
186 STY TL1
187 FIN
188 LST ON
3D04:A0 02 189 LDY #2 ;SET RECALIBRATE ; magic number RWTS_RECALIBRATE = $2
3D06:8C F8 06 190 STY RECALCNT ; COUNT ; Text screen hole!
3D09:A0 04 191 LDY #MAXSEEKS ;SET RESEEK
3D0B:8C F8 04 192 STY SEEKCNT ; COUNT ; Another text screen hole. WTF! 33 bytes above on page $3C / $BC!
3D0E:A0 01 193 LDY #1 ;GET SLOT # FOR THIS OPERATION ; magic number IOB_OFFSET_SLOT
3D10:B1 48 194 LDA (IOBPL),Y
3D12:AA 195 TAX
3D13:A0 0F 196 LDY #$0F ;DID HE CHANGE SLOTS? ; magic number IOB_OFFSET_PREV_SLOT
3D15:D1 48 197 CMP (IOBPL),Y
3D17:F0 1B 198 BEQ SAMESLOT ;IF HE DIDN'T, GOOD FOR HIM!
199 *
200 * NOW ARE USING A DIFFERENT SLOT.
201 * NOW WAIT FOR THIS DRIVE TO TURN OFF
202 * TO SENSE MOTOR NOT SPINNING, DATA FROM DISK MUST
203 * BE THE SAME FOR AT LEAST 96 MICROSECONDS
3D19:8A 204 TXA ;SAVE NEW SLOT #
3D1A:48 205 PHA
3D1B:B1 48 206 LDA (IOBPL),Y ;GET 'OLD SLOT NUMBER'
3D1D:AA 207 TAX
3D1E:68 208 PLA
3D1F:48 209 PHA ;PUT BACK ON STACK
3D20:91 48 210 STA (IOBPL),Y ;SAVE 'NEW SLOT NUMBER'
3D22:BD 8E C0 211 LDA Q7L,X ;GO INTO READ MODE
3D25:A0 08 212 STILLON LDY #$08 ;TO BE SURE, DATA MUST REMAIN
3D27:BD 8C C0 213 LDA Q6L,X ;STABLE FOR 96 MICROSECONDS
3D2A:DD 8C C0 214 NOTSURE CMP Q6L,X ;DATA STILL CHANGING?
3D2D:D0 F6 215 BNE STILLON ;IF SO, STILL SPINNING
3D2F:88 216 DEY
3D30:D0 F8 217 BNE NOTSURE ;STABLE LONG ENOUGH? IF NOT, LOOP
218 *
219 * PREVIOUS SLOT'S DRIVE NOW OFF...
220 *
3D32:68 221 PLA ;RESTORE NEW SLOT #
3D33:AA 222 TAX
223 *
224 * NOW CHECK IF THE MOTOR IS ON, THEN START IT
225 *
3D34:BD 8E C0 226 SAMESLOT LDA Q7L,X ;MAKE SURE IN READ MODE
3D37:BD 8C C0 227 LDA Q6L,X
3D3A:A0 08 228 LDY #8 ;WE MAY HAFTA CHECK SEVERAL TIMES TO BE SURE ; magic number RWTS_MIN_NIBBLES_DELTA = $8
229 CHKIFON EQU *
3D3C:BD 8C C0 230 LDA Q6L,X ;GET THE DATA
3D3F:48 231 PHA ;DELAY FOR DISK DATA TO CHANGE
3D40:68 232 PLA
3D41:48 233 PHA
3D42:68 234 PLA
3D43:8E F8 05 235 STA SLOT ; Text Screen Hole
3D46:DD 8C C0 236 CMP Q6L,X ;CHECK RUNNING HERE
3D49:D0 03 237 BNE ITISON ;=>IT'S ON...
3D4B:88 238 DEY ;MAYBE WE DIDN'T CATCH IT
3D4C:D0 EE 239 BNE CHKIFON ; SO WE'LL TRY AGAIN
240 *
241 ITISON EQU *
3D4E:08 242 PHP ;SAVE TEST RESULTS ; === Page 120 ===
3D4F:BD 89 C0 243 LDA MOTORON,X ;TURN ON MOTOR REGARDLESS
3D52:A0 06 244 LDY #6 ;MOVE OUT ALL POINTERS INTO ZPAGE ; magic number IOB_OFFSET_DCT
3D54:B1 48 245 PTRMOV LDA (IOBPL),Y ; [6] 37EE..37EF -> $ [0] 003C IOB_DCT
3D56:99 36 00 246 STA PTRSDEST-6,Y ; magic number IOB_OFFSET_DCT [8] 37F0..37F1 -> $ [2] 003D IOB_BUF
3D59:C8 247 INY
3D5A:C0 0A 248 CPY #$0A ;MOVED ALL POINTERS? ; magic number IOB_OFFSET_LEN
3D5C:D0 F6 249 BNE PTRMOV
3D5E:A0 03 250 LDY #3 ;SET UP THE ; magic number DCT_MOTOR+1
3D60:B1 3C 251 LDA (DEVCTBL),Y ; MOTOR-ON TIME ;
3D62:85 47 252 STA MONTIME+1 ; BUG: Motor On Time Low is never stored to MONTIME!
3D64:A0 02 253 LDY #2 ;NOW GET PARAMS ; magic number IOB_OFFSET_DRV_NUM
3D66:B1 48 254 LDA (IOBPL),Y ;DETERMINE DRIVE ONE OR TWO
3D68:A0 10 255 LDY #$10 ;SAME DRIVE USED BEFORE? ; magic number IOB_OFFSET_PREV_DRV
3D6A:D1 48 256 CMP (IOBPL),Y
3D6C:F0 06 257 BEQ OK ;IF SO, DON'T NECESSARILY WAIT FOR MOTOR
3D6E:91 48 258 STA (IOBPL),Y ;NOW USING THIS DRIVE
3D70:28 259 PLP ;TELL HIM MOTOR WAS OFF
3D71:A0 00 260 LDY #$00 ;SET ZERO FLAG ; 6502 doesn't have a CLZ or SEZ instruction
3D73:08 261 PHP
3D74:6A 262 OK ROR A ;BY GOING INTO THE CARRY
3D75:90 05 263 BCC SD1 ;SELECT DRIVE 2 !
3D77:BD 8A C0 264 LDA DRV1EN,X ;ASSUME DRIVE 1 TO HIT
3D7A:B0 03 265 BCS DRVSEL ;IF WRONG, ENABLE DRIVE 2 INSTEAD
3D7C:BD 8B C0 266 SD1 LDA DRV2EN,X
267 DRVSEL EQU *
3D7F:66 35 268 ROR DRIVNO ;SAVE SELECTED DRIVE
269 *
270 * DRIVE SELECTED. IF MOTORING-UP,
271 * WAIT BEFORE SEEKING...
272 *
3D81:28 273 PLP ;WAS THE MOTOR
3D82:08 274 PHP ; PREVIOUSLY OFF?
3D83:D0 0B 275 BNE NOWAIT ;=>NO, FORGET WAITING.
3D85:A0 07 276 LDY #7 ;YES, DELAY 150 MS
3D87:20 00 3A 277 SEEKW JSR MSWAIT
3D8A:88 278 DEY
3D8B:D0 FA 279 BNE SEEKW
3D8D:AE F8 05 280 LDX SLOT ;RESTORE SLOT NUMBER
281 *
282 NOWAIT EQU *
283 *
284 * SEEK TO DESIRED TRACK...
285 *
3D90:A0 04 286 LDY #4 ;SET TO IOBTRK ; magic number IOB_OFFSET_TRK
3D92:B1 48 287 LDA (IOBPL),Y ;GET DESIRED TRACK
3D94:20 5A 3E 288 JSR MYSEEK ;SEEK!
289 *
290 * SEE IF MOTOR WAS ALREADY SPINNING.
291 *
3D97:28 292 PLP
3D98:D0 11 293 BNE TRYTRK
294 *
295 * WAIT FOR MOTOR SPEED TO COME UP.
296 *
297 LST OFF
298 DO DIAGMODE
299 LDY #TC2
300 STY TL2
301 LDY #0
302 STY SCOUNT
303 STY LCOUNT
304 LDY #SP ;SHUT OFF THE ; === Page 121 ===
305 STY TL12 ; LATENCY INDICATOR
306 FIN
307 LST ON
3D9A:A4 47 308 LDY MONTIME+1 ;IF MOTORTIME IS POSITIVE,
3D9C:10 0D 309 BPL MOTORUP ; THEN SEEK WASTED ENUFF TIME FOR US
3D9E:A0 12 310 MOTOF LDY #$12 ;DELAY 100 USEC PER COUNT
3DA0:88 311 CONWAIT DEY
3DA1:D0 FD 312 BNE CONWAIT
3DA3:E6 46 313 INC MONTIME ; NOTE: MONTIME is never written to so this is a full 256 counter
3DA5:D0 F7 314 BNE MOTOF
3DA7:E6 47 315 INC MONTIME+1
3DA9:D0 F3 316 BNE MOTOF ;COUNT UP TO $0000
317 MOTORUP EQU *
318 LST OFF
319 DO DIAGMODE
320 LDY #SP ;SAY 'MOTOR RUNNING'
321 STY TL2
322 FIN
323 LST ON
001 *
002 * DISK IS NOW UP TO SPEED: READ IT!
003 * NOW CHECK: IF IT IS NOT THE FORMAT DISK COMMAND,
004 * LOCATE THE CORRECT SECTOR FOR THIS OPERATION.
005 *
006 TRYTRK EQU *
3DAB:A0 0C 007 LDY #$0C ; magic number IOB_OFFSET_CMD = $C
3DAD:B1 48 008 LDA (IOBPL),Y ;GET COMMAND CODE #
3DAF:F0 5A 009 BEQ GALLDONE ;IF NULL COMMAND, GO HOME TO BED. ;↓
3DB1:C9 04 010 CMP #$04 ;FORMAT THE DISK? ; magic number RWTS_CMD_FORMAT = $4 *sigh*
3DB3:F0 58 011 BEQ FORMDSK ;ALLRIGHT,ALLRIGHT, I WILL... ; If only the IBCMD commands were an enum instead of a dumb bitmask, see RWTS_CMD_*
3DB5:6A 012 ROR A ;SET CARRY=1 FOR READ, 0 FOR WRITE
3DB6:08 013 PHP ;AND SAVE THAT
3DB7:B0 03 014 BCS TRYTRK2 ;MUST PRENIBBLE FOR WRITE.
015 LST OFF
016 DO DIAGMOD
017 LDY #TC17 ;SAY 'PRENIBBLIZING'
018 STY TL7
019 FIN
020 LST ON
3DB9:20 00 38 021 JSR PRENIB16
022 LST OFF
023 DO DIAGMOD
024 LDY #SP ;PRENIB FINISHED
025 STY TL7
026 FIN
027 LST ON
3DBC:A0 30 028 TRYTRK2 LDY #$30 ;ONLY 48 RETRIES OF ANY KIND.
3DBE:8C 78 05 029 STY RETRYCNT
3DC1:AE F8 05 030 TRYADR LDX SLOT ;GET SLOT NUM INTO X-REG
031 LST OFF
032 DO DIAGMOD
033 LDA #TC4 ;SAY 'READING ADDRESS'
034 STA TL4
035 LDA #SP ;SAY 'NO ADDRESS ERROR' (YET)
036 STA TL6
037 FIN
038 LST ON
3DC4:20 44 39 039 JSR RDADR16 ;READ NEXT ADDRESS FIELD ; ^
040 LST OFF
041 DO DIAGMOD
042 LDA #SP ;ADDRESS-READ DONE
043 STA TL4
044 FIN
045 LST ON
3DC7:90 24 046 BCC RDRIGHT ;IF READ IT RIGHT, HURRAH! ; v
047 LST OFF
048 DO DIAGMOD
049 LDA #TC6 ;ADDRESS-READ DONE
050 STA TL4
051 FIN
052 LST ON
3DC9:CE 78 05 053 TRYADR2 DEC RETRYCNT ;ANOTHER MISTAEK!! ; *spelling* Oh, the **irony**
3DCC:10 F3 054 BPL TRYADR ; WELL, LET IT GO THIS TIME.. ; === page 123 ===
055 *
056 * RRRRRECALIBRATE !!!!
057 *
058 RECAL EQU *
3DCE:AD 78 04 059 LDA CURTRK
3DD1:48 060 PHA ;SAVE TRACK WE REALLY WANT ; /sarcasm Nice to read VNOTRK * 2 phases/track
3DD2:A9 60 061 LDA #$60 ;RECALIBRATE ALL OVER AGAIN! ; /sarcasm Yeah ... let's bang the user's drive head against
3DD4:20 95 3E 062 JSR SETTRK ;PRETEND TO BE ON TRACK 96 ; the case -- that will make it work and won't cause
3DD7:CE F8 06 063 DEC RECALCCNT ;ONCE TOO MANY?? ; any head alignment problems over time ... NOT!
3DDA:F0 28 064 BEQ DRVERR ;TRIED TO RECALIBRATE TOO MANY TIMES, ERROR! ; v
3DDC:A9 04 065 LDA #MAXSEEKS ;RESET THE
3DDE:8D F8 04 066 STA SEEKCNT ; SEEK COUNTER
3DE1:A9 00 067 LDA #$00
3DE3:20 5A 3E 068 JSR MYSEEK ;MOVE TO TRACK 00 ; v
3DE6:68 069 PLA
3DE7:20 5A 3E 070 RESEEK JSR MYSEEK ;GO TO CORRECT TRACK THIS TIME!
3DEA:4C BC 3D 071 JMP TRYTRK2 ;LOOP BACK, TRY AGAIN ON THIS TRACK
072 *
073 * HAVE NOW READ
074 * MAKE SURE THIS IS THE TRACK, SECTOR, AND VOLUME DESIRED.
075 *
3DED:A4 2E 076 RDRIGHT LDY TRACK ;ON THE RIGHT TRACK?
3DEF:CC 78 04 077 CPY CURTRK
3DF2:F0 1C 078 BEQ RTTRK ;IF SO, GOOD ;↓
079 * NO, DRIVE WAS ON A DIFFERENT TRACK. TRY
080 * RESEEKING/RECALIBRATING FROM THIS TRACK
3DF4:AD 78 04 081 LDA CURTRK ;PRESERVE DESTINATION TRACK
3DF7:48 082 PHA
3DF8:98 083 TYA
3DF9:20 95 3E 084 JSR SETTRK
3DFC:68 085 PLA
3DFD:CE F8 04 086 DEC SEKCNT ;SHOULD WE RESEEK?
3E00:D0 E5 087 BNE RESEEK ;=>YES, RESEEK ;↑ === T0S8 ===
3E02:F0 CA 088 BEQ RECAL ;=>NO, RECALIBRATE! ;↑
089 ****
3E04:68 090 DRVERR PLA ;REMOVE CURTRK
3E05:A9 40 091 LDA #IBDERR ;BAD DRIVE ERROR
3E07:28 092 JMPTO1 PLP
3E08:4C 48 3E 093 JMP HNDLERR
3E0B:F0 39 094 GALLDONE BEQ ALLDONE ;↓
3E0D:4C AF 3E 095 FORMDSK JMP DSKFORM ;=>GO TO IT! ;↓ WhyTF is FormatDisk in the middle here???
096 *
097 * DRIVE IS ON RIGHT TRACK, CHECK VOLUME MISMATCH
098 *
3E10:A0 03 099 RTTRK LDY #3 ;IS THE RIGHT DISK IN? ; magic number IOB_OFFSET_VOL = $03
3E12:B1 48 100 LDA (IOBPL),Y ;GET DESIRED VOLUM
3E14:48 101 PHA ;PRESERVE DESIRED VOLUME#
3E15:A5 2F 102 LDA VOLUME ;GET ACTUAL VOLUME HERE
3E17:A0 0E 103 LDY #$0E ;TELL OPSYS WHAT VOLUME WAS THERE ; magic number IOB_OFFSET_MOD = $E
3E19:91 48 104 STA (IOBPL),Y
3E1B:68 105 PLA ;GET DESIRED VOLUME BACK
3E1C:F0 08 106 BEQ CORRECTVOL ;DESIRED VOLUME 00 MATCHES ALL. ;↓
3E1E:C5 2F 107 CMP VOLUME
3E20:F0 04 108 BEQ CORRECTVOL ;YUP, IT WAS RIGHT! ;↓
3E22:A9 20 109 LDA #IBVMME ;HE SWITCHED DISCS!
3E24:D0 E1 110 BNE JMPTO1 ;ALWAYS TAKEN ;↑
111 CORRECTVOL EQU *
3E26:A0 05 112 LDY #5 ; magic number IOB_OFFSET_SECTOR = $5
3E28:B1 48 113 LDA (IOBPL),Y ; TO ALLOW FOR INTERLEAVE
3E2A:A8 114 TAY
3E2B:B9 B8 3F 115 LDA INTRLEAV,Y ;COMPUTE PHYSICAL SECTOR ; DOS Sector Interleave/Skew Mapping
3E2E:C5 2D 116 CMP SECT ;DID WE GET THE SECTOR? ; === Page 124 ===
117 LST OFF
118 DO DIAGMOD
119 BEQ GOTSECT ;=>WE FOUND IT!
120 LDA #TC5 ;SAY 'LATENCY'
121 STA TL5
122 LDA SCOUNT ;ARE WE WAITING FOR FIRST SECTOR?
123 BEQ NOLAT ;=>YES, LATENCY UNPREDICTABLE ANYWAY
124 INC LCOUNT ;NO, COUNT SECTORS MISSED
125 NOLAT EQU *
126 JMP TRYADR2 ;NOW..GET CORRECT SECTOR..
127 ELSE
128 LST ON
3E30:D0 97 129 BNE TRYADR2 ;NO, KEEP TRYING. ;↑
130 FIN
131 *
132 * HOORAY! WE GOT THE RIGHT SECTOR!
133 *
134 GOTSECT EQU *
135 LST OFF
136 DO DIAGMOD
137 LDA #SP ;SAY 'NO LATENCY'
138 STA TL5
139 INC SCOUNT ;BUMP 'SECTORS-ACCESSED' COUNT
140 FIN
141 LST ON
3E32:28 142 PLP
3E33:90 1C 143 BCC WRIT ;CARRY WAS SET FOR READ OPERATION. ;↓
144 LST OFF
145 DO DIAGMOD
146 LDA #TC9 ;SAY 'READING'
147 STA TL9
148 LDA #SP ;SAY 'NO READ ERROR' (YET)
149 STA TL10
150 FIN
151 LST ON
3E35:20 DC 38 152 JSR READ16 ;CLEARED FOR WRITE
153 LST OFF
154 DO DIAGMOD
155 LDA #SP ;READ FINISHED
156 STA TL9
157 FIN
158 LST ON
3E38:08 159 PHP ;SAVE STATUS OF READ OPERATION
160 LST OFF
161 DO DIAGMOD
162 BCC GOODREAD ;NO ERROR
163 LDA #TC10 ;SAY 'READ ERROR'
164 STA TL10
165 JMP TRYADR2 ;RETRY ON ERROR
166 *
167 GOODREAD EQU *
168 ELSE
169 LST ON
3E39:B0 8E 170 BCS TRYADR2 ;CARRY SET UPON RETURN IF BAD READ ;↑
171 FIN
3E3B:28 172 PLP ;CAREFUL OF STACK
3E3C:A2 00 173 LDX #0 ;SET TO POSTNIBLIZE
3E3E:86 26 174 STX T0 ; All 256 BYTES OF THE SECTOR
175 LST OFF
176 DO DIAGMOD
177 LDA #TC11 ;SAY 'POSTINIBBLIZING' ;POST_IN_NIBBLIZING
178 STA TL11
179 FIN ; === Page 125 ===
180 LST ON
3E40:20 C2 38 181 JSR POSTNB16 ;DECODE INTO REAL WORLD DATA
182 LST OFF
183 DO DIAGMOD
184 LDA #SP ;POSTNIB COMPLETED
185 STA TL11
186 FIN
187 LST ON
3E43:AE F8 05 188 LDX SLOT ;RESTORE SLOTNUM INTO X ; I never would have guessed ...
3E46:18 189 ALLDONE CLC
3E47:24 190 DFB $24 ;SKIP OVER NEXT BYTE WITH BIT OPCODE ; BIT $zp
3E48:38 191 HNDLERR SEC ;INDICATE AN ERROR
3E49:A0 0D 192 LDY #$0D ;GIVE HIM ERROR# ; magic number IOB_OFFSET_ERROR = $D
3E4B:91 48 193 STA (IOBPL),Y
3E4D:BD 88 C0 194 LDA MOTOROFF,X ; TURN IT OFF...
195 LST OFF
196 DO DIAGMOD
197 * AVERAGE LATENCY = LCOUNT/SCOUNT
198 LDA LCOUNT ; GET TOTAL LATENCY
199 LDY #0 ; CLEAR QUOTIENT
200 DIVIDE EQU *
201 CMP SCOUNT ; DONE?
202 BCC PRTLAT ; =>YES.PRINT IT
203 SBC SCOUNT ; REMOVE SCOUNT
204 INY ; INCREMENT QUOTIENT
205 BNE DIVIDE
206 *
207 PRTLAT TYA ; Print Latency
208 AND #$0F ; MAX LATENCY=15
209 ORA #$B0 ; MAKE ASCII ; NO, this is make Apple Text; ASCII = $00..$7F
210 CMP #$BA ; IS IT A-F
211 BCC PRTL2 ;=>NO
212 ADC #6 ;ADD 7 (INCLUDES CARRY)
213 PRTL2 STA TL12 ;STUFF LATENCY COUNT
214 LDA #SP ; SAY 'RWTS NOT ACTIVE'
215 STA TL1
216 FIN
217 LST ON
3E50:60 218 RTS
219 WRIT EQU *
220 LST OFF
221 DO DIAGMOD
222 LDA #TC8 ; SAY 'WRITING'
223 STA TL8
224 FIN
225 LST ON
3E51:20 2A 38 226 JSR WRITE16 ;WRITE NYBBLES NOW ; ^ WRITRTN, page 137
227 LST OFF
228 DO DIAGMOD
229 LDA #SP ;WRITE FINISHED
230 STA TL8
231 FIN
232 LST ON
3E54:90 F0 233 BCC ALLDONE ;IF NO ERRORS.
3E56:A9 10 234 LDA #IBWPER ;DISK IS WRITE PROTECTED!!
3E58:B0 EE 235 BCS HNDLERR ;ALWAYS TAKEN
236 *
237 * THIS IS THE 'SEEK' ROUTINE
238 * SEEKS TRACK 'N' IN SLOT #X/$10
239 * IF DRIVNO IS NEGATIVE, ON DRIVE 1
240 * IF DRIVNO IS POSITIVE, ON DRIVE 2
241 *
3E5A:48 242 MYSEEK PHA ; AND PRESERVE A-REGISTER ; === Page 126 === Uhm, OK, Captain Obvious
243 LST OFF
244 DO DIAGMOD
245 LDA #TC3 ;SAY 'SEEKING'
246 STA TL3
247 FIN
248 LST ON
3E5B:A0 01 249 LDY #$01 ;IS THIS A TWO-PHASE DISC? ; magic number DCT_OFFSET_TYPE = $1
3E5D:B1 3C 250 LDA (DEVCTBL),Y
3E5F:6A 251 ROR A ;GET # OF PHASES INTO CARRY
3E60:68 252 PLA
3E61:90 08 253 BCC MYSEEK2 ;IF ONE PHASE PER TRACK
3E63:0A 254 ASL A
3E64:20 6B 3E 255 JSR MYSEEK2
3E67:4E 78 04 256 LDA CURTRK ;DIVIDE BACK DOWN
257 LST OFF
258 DO DIAGMOD
259 LDA #SP
260 STA TL3 ;SEEK DONE
261 FIN
262 LST ON
3E6A:60 263 RTS
3E6B:85 2A 264 MYSEEK2 STA TRKN ;SAVE DESTINATION TRACK(*2) ;
3E6D:20 8E 3E 265 JSR XTOY ;SET Y=SLOT#
3E70:B9 78 04 266 LDA DRV1TRK,Y
3E73:24 35 267 BIT DRIVNO
3E75:30 03 268 BMI WASD0 ;IS MINUS, ON DRIVE ZERO
3E77:B9 F8 04 269 LDA DRV2TRK,Y
3E7A:8D 78 04 270 WASD0 STA CURTRK ;THIS IS WHERE I AM ; Going to resist cheap shot here
3E7D:A5 2A 271 LDA TRKN ;AND WHERE I'M GOING TO ; But I will point out crappy var names and better ones:
3E7F:24 35 272 BIT DRIVNO ;NOW UPDATE SLOT DEPENDENT ; SRC_TRK
3E81:30 05 273 BMI ISDRV1 ;LOCATIONS WITH TRACK ; DST_TRK
3E83:99 F8 04 274 STA DRV2TRK,Y ;INFORMATION
3E86:10 03 275 BPL GOSEEK ;ALWAYS TAKEN
3E88:99 78 04 276 ISDRV1 STA DRV1TRK,Y
3E8B:4C A0 39 277 GOSEEK JMP SEEK ;GO THERE!
3E8E:8A 278 XTOY TXA
3E8F:4A 279 LSR A
3E90:4A 280 LSR A
3E91:4A 281 LSR A
3E92:4A 282 LSR A
3E93:A8 283 TAY
3E94:60 284 RTS
285 *
286 * THIS SUBROUTINE SETS THE SLOT DEPENDENT TRACK
287 * LOCATION.
288 *
3E95:48 289 SETTRK PHA ;PRESERVE DESTINATION TRACK
3E96:A0 02 290 LDY #$02 ; magic number IOB_OFFSET_DRIVE = $2
3E98:B1 48 291 LDA (IOBPL),Y
3E9A:6A 292 ROR A ;GET DRIVE # INTO CARRY
3E9B:66 35 293 ROR DRIVNO ;INTO (DRIVNO)
3E9D:20 8E 3E 294 JSR XTOY ;SET UP Y-REG
3EA0:68 295 PLA
3EA1:0A 296 ASL A ;ASSUME TRACK IS HELD*2
3EA2:24 35 297 SETTRK2 BIT DRIVNO ; unused label
3EA4:30 05 298 BMI ONDRV1 ;IF ON DRIVE 1(1), DRIVNO MINUS
3EA6:99 F8 04 299 STA DRV2TRK,Y
3EA9:10 03 300 BPL SETRTS
3EAB:99 78 04 301 ONDRV1 STA DRV1TRK,Y
3EAE:60 302 SETRTS RTS
001 SBTL '16-SECTOR FORMATTER'
002 ****************************
003 * *
004 * FORMAT DISK AND RETURN *
005 * *
006 ****************************
007 *
008 * EQUATES FOR FORMATTER
009 *
010 NSYNC EQU $45 ;NUM GAP SELF-SYNC NIBLS ; No, not the 90's band
011 *
012 REP 40
013 DSKFORM EQU *
014 DO DIAGMOD ;ELIMINATE FMTR FROM DIAG ASSEMBLY
015 LST OFF
016 ELSE
3EAF:A0 03 017 LDY #3 ; magic number IOB_OFFSET_VOL = $3
3EB1:B1 48 018 LDA (IOBPL),Y VOLUME NUMBER IN IOB.
3EB3:85 41 019 STA NVOL FOR FORMATTER.
3EB5:A9 AA 020 LDA #$AA SET Z-PAG LOC TO $AA FOR ; *sigh* Because AA is so descriptive ... WTF does AA stand for to a new reader?!?!
3EB7:85 3E 021 STA AA TIME DEPENDENT REFERENCES. ; Call it WRITE_NIB_AA; see WADR16, Lines #086, #105
3EB9:A0 56 022 LDY #$56 ; magic number
3EBB:A9 00 023 LDA #0
3EBD:85 44 024 STA TRK TRACK NUMBER, 0 TO 34
3EBF:99 FF 3B 025 CLRNBUF2 STA NBUF2-1,Y CLEAR NBUFS TO WRITE
3EC2:88 026 DEY ZERO SECTORS
3EC3:D0 FA 027 BNE CLRNBUF2
3EC5:99 00 3B 028 CLRNBUF1 STA NBUF1,Y
3EC8:88 029 DEY
3EC9:D0 FA 030 BNE CLRNBUF1 ;
3ECB:A9 50 031 LDA #$50 ; magic number TODO FORMAT_LAST_TRACK EQU 40*2 ; *2 = 2 phases/track
3ECD:20 95 3E 032 JSR SETTRK FAKE LIKE ON TRACK 80.
3ED0:A9 28 033 LDA #$28 ; magic number TODO FORMAT_SECTOR_GAP EQU 40
3ED2:85 45 034 STA NSYNC BEGIN WITH 40 SELF-SYNC NIBLS.
3ED4:A5 44 035 FORMTRK LDA TRK
3ED6:20 5A 3E 036 JSR MYSEEK GOTO NEXT TRACK.
3ED9:20 0D 3F 037 JSR WTRACK16 WRITE AND VERIFY TRACK.
3EDC:A9 08 038 FORMERR1 LDA #8 'UNABLE TO FORMAT' ERR CODE. ; magic number TODO
3EDE:B0 24 039 BCS FORMERR CONTINUE IF NO ERROR.
3EE0:A9 30 040 LDA #$30 UP TO 48 SECTOR RETRIES ; *sigh* Why _this_ value? magic number TODO FORMAT_MAX_RETRY EQU 48
3EE2:8D 78 05 041 STA RETRYCNT TO FIND SECTOR 0. ; Also, why not in decimal??
3EE5:38 042 FINDS0 SEC ANTICIPATE 'UNABLE TO FORMAT'
3EE6:CE 78 05 043 DEC RETRYCNT DONE 48 RETRIES?
3EE9:F0 19 044 BEQ FORMERR IF SO, 'UNABLE TO FORMAT' ERR.
3EEB:20 44 39 045 JSR RDADR16 ;READ ADR FIELD. ; *sigh* Inconsistent comment meta character
3EEE:B0 F5 046 BCS FINDS0 RETRY IF ERR.
3EF0:A5 2D 047 LDA SECT CHECK SECTOR THAT WAS READ.
3EF2:D0 F1 048 BNE FINDS0 CONTINUE SEARCHING IF NOT SECT 0.
3EF4:20 DC 38 049 JSR READ16 ;NOW READ DATA FIELD. ; *sigh* Make up your mother falcon mind! Always use ; or not!
3EF7:B0 EC 050 BCS FINDS0 CONTINUE SEARCH IF ERR.
051 * (NOW POSITIONED PROPERLY FOR NEXT TRACK) ; Unknown if leading space after '*' should be 1 space, 1 tab, etc??
3EF9:E6 44 052 INC TRK INCREMENT TRACK NUMBER. ; /sarcasm Gee, George what does this do?
3EFB:A5 44 053 LDA TRK ; Code documents WHAT, Comments document WHY
3EFD:C9 23 054 CMP #$23 CONTINUE IF LESS THEN 35 ; === Page 83 === magic number DISK_MAX_TRACK or at least VNOTRK
3EFF:90 D3 055 BCC FORMTRK ; === T0S9 ===
3F01:18 056 CLC CLEAR CARRY TO INDICATE 'NO ERR';[.. JMP ALLDONE
3F02:90 05 057 BCC FORMDONE ELSE TURN OFF MOTOR AND RETURN ; ..
3F04:A0 0D 058 FORMERR LDY #$0D ; .. JMP HNDLERR magic number IOB_OFFSET_ERR = $D
3F06:91 48 059 STA (IOBPL),Y RETURN ERROR CODE. ; .. wastes remaining 6 bytes.
3F08:38 060 SEC SET CARRY TO INDICATE ERR. ; .. We could invert the return value,
3F09:BD 88 C0 061 FORMDONE LDA MOTOROFF,X ; TURN MOTOR OFF. ; .. but there is a better optimization
3F0C:60 062 RTS ; AND RETURN. ; .. using the two JMPs above to reach common code in RWTSTWO ]
063 PAGE
064 ******************************
065 * *
066 * WRITE TRACK SUBROUTINE *
067 * *
068 ******************************
3F0D:A9 00 069 WTRACK16 LDA #0
3F0F:85 3F 070 STA NSECT SECTOR NUMBER, 0 to 15.
3F11:A0 80 071 LDY #128 ;128 NIBS PRIOR SECTOR 0
3F13:D0 02 072 BNE WSECT0 ; TO INSURE NO BLANK SPOT BETW 15 & 0
3F15:A4 45 073 WSECT LDY NSYNC CURRENT NUM OF GAP SELF-SYNC NIBLS.
074 WSECT0 EQU *
3F17:20 56 3C 075 JSR WADR16 WRITE GAP AND ADR FIELD.
3F1A:B0 6B 076 BCS WEXIT2 ERR IF WRITE PROTECTED.
3F1C:20 2A 38 077 JSR WRITE16 ;WRITE SECTOR FROM NBUF1, NBUF2
3F1F:B0 66 078 BCS WEXIT2 ERR IF WRITE PROTECTED.
3F21:E6 3F 079 INC NSECT NEXT OF 16 SECTORS.
3F23:A5 3F 080 LDA NSECT
3F25:C9 10 081 CMP #$10 ; What's the point of VNOSEC in VTOC then?!?!
3F27:90 EC 082 BCC WSECT CONTINUE IF NOT DONE.
083 PAGE
084 *****************************
085 * *
086 * VERIFY ROUTINE *
087 * *
088 * VERIFIES THAT THE FIRST *
089 * SECTOR ENCOUNTERED IS *
090 * SECTOR 0, AND THAT ALL *
091 * 16 SECTORS ARE READABLE *
092 * WITH MINIMAL RETRIES. *
093 * (2 REVOLUTIONS MAXIMUM) *
094 * *
095 * IF FIRST SECTOR IS NOT *
096 * SECTOR 0 THEN THE *
097 * CURRENT NUMBER OF SELF- *
098 * SYNC NIBLS IS DECR'D BY *
099 * 1 (IF ALREADY LESS THAN *
100 * 16) OR BY 2. THEN SECTOR *
101 * 15 IS LOCATED SO AS TO *
102 * POSITION THE NEW TRACK *
103 * REWRITE. *
104 * *
105 * IF UNABLE TO READ ANY *
106 * SECTOR THEN THE ENTIRE *
107 * TRACK IS REWRITTEN. *
108 * *
109 * AFTER VERIFYING TRACK 0, *
110 * THE NUMBER OF SELF-SYNC *
111 * NIBLS, NSYNC, IS DECR'D *
112 * BY 2 (IF STILL 16 OR *
113 * GREATER). *
114 * *
115 *****************************
116 PAGE ; === Page 84 ===
3F29:A0 0F 117 VTRACK LDY #$F ; magic number TODO
3F2B:84 3F 118 STY NSECT SET 16 BYTES OF
3F2D:A9 30 119 LDA #$30 SECTOR FOUND TABLE
3F2F:8D 78 05 120 STA RETRYCNT TO $30 (MARK THEM). ; TEXT HOLE TODO XREF with other screen holes
3F32:99 A8 3F 121 CLRFOUND STA FOUND,Y
3F35:88 122 DEY
3F36:10 FA 123 BPl CLRFOUND
3F38:A4 45 124 LDY NSYNC
3F3A:20 87 3F 125 S0DELAY JSR WEXIT2
3F3D:20 87 3F 126 JSR WEXIT2 (12) EXPECTED TO INSURE
3F40:20 87 3F 127 JSR WEXIT2 (12) PROPER GAP PRIOR SECTOR 0.
3F43:48 128 PHA (3)
3F44:68 129 PLA (4)
3F45:EA 130 NOP (2)
3F46:88 131 DEY (2)
3F47:D0 F1 132 DEY S0DELAY (3)
3F49:20 44 39 133 JSR RDADR16 ;READ NEXT ADDRESS FIELD.
3F4C:B0 23 134 BCS S15LOC ERR, LOCATE SECT 15 AND REWRITE TRK.
3F4E:A5 2D 135 LDA SECT WAS IT SECTOR 0?
3F50:F0 15 136 BEQ VDATA YES, NOW VERIFY DATA FIELD.
3F52:A9 10 137 LDA #$10 ;↓ magic number TODO
3F54:C5 45 138 CMP NSYNC DECR NSYNC BY 1 IF LESS THAN
3F56:A5 45 139 LDA NSYNC 16, BY 2 IF NOT LESS.
3F58:E9 01 140 SBC #1
3F5A:85 45 141 STA NSYNC
3F5C:C9 05 142 CMP #5 IF LESS THAN 5, UNRECOVERABLE
3F5E:B0 11 143 BCS S15LOC ERR, ELSE REWRITE AFTER DATA FLD 15.
3F60:38 144 VERR SEC DRIVE EXTREMELY FAST OR
3F61:60 145 RTS OTHER SEVERE ERROR.
3F62:20 44 39 146 VSECT JSR RDADR16 ;READ AN ADDRESS FIELD.
3F65:B0 05 147 BCS VERR1 RETRY IF ERR. ;↓
3F67:20 DC 38 148 VDATA JSR READ16 ;READ DATA FIELD.
3F6A:90 1C 149 BCC SECTOK (GOOD) ;↓
3F6C:CE 78 05 150 VERR1 DEC RETRYCNT NEXT OF 48 SECTOR TRIES.
3F6F:D0 F1 151 BNE VSECT (KEEP TRYING) ;↑
3F71:20 44 39 152 S15LOC JSR RDADR16 ;READ ADDRESS FIELD. ;↑
3F74:B0 0B 153 BCS NOTS15 ERR, TRY UP TO 128 TIMES. ;↓
3F76:A5 2D 154 LDA SECT SECTOR THAT WAS READ.
3F78:C9 0F 155 CMP #$F SECTOR 15? ; magic number VERIFY_REREAD_LAST_SEC
3F7A:D0 05 156 BNE NOTS15 NO, CONTINUE SEARCHING. ;↓
3F7C:20 DC 38 157 JSR READ16 ;READ DATA FIELD. ; Why isn't this called READDATAHDR ???
3F7F:90 8C 158 BCC WRITE TRACK FROM HERE IF NO ERR. ;↑ Read 16 what? Oh, Read 16 Sector Data Field
3F81:CE 78 05 159 NOTS15 DEC RETRYCNT $FF TO $7F, 128 TRIES.
3F84:D0 EB 160 BNE S15LOC TRY FOR SECT 15 AGAIN. ;↑
3F86:38 161 SEC SET CARRY TO INDICATE VERIFY ERR.
3F87:60 162 WEXIT2 RTS AND RETURN TO FORMATTER.
3F88:A4 2D 163 SECTOK LDY SECT THIS IS SECTOR READ.
3F8A:B9 A8 3F 164 LDA FOUND,Y ALREADY FOUND?
3F8D:30 DD 165 BMI VERR1 YES, IGNORE IT.
3F8F:A9 FF 166 LDA #$FF ; magic number FLAG_SECTOR_FOUND = 1
3F91:99 A8 3F 167 STA FOUND,Y INDICATE THIS SECT NOW FOUND.
3F94:C6 3F 168 DEC NSECT FOUND 16 SECTORS?
3F96:10 CA 169 BPL VSECT NO, LOOK FOR NEXT.
3F98:A5 44 170 LDA TRK
3F9A:D0 0A 171 BNE WEXIT1 IF TRACK 0 AND NSYNC > 16 ;
3F9C:A5 45 172 LDA NSYNC (NUM GAP SYNC NIBLS)
3F9E:C9 10 173 CMP #$10 THEN SUBTRACT 2 FROM NSYNC
3FA0:90 E5 174 BCC WEXIT2 TO AVOID RETRIES ON LATER TRKS.
3FA2:C6 45 175 DEC NSYNC
3FA4:C6 45 176 DEC NSYNC
3FA6:18 177 WEXIT1 CLC INDICATE NO ERROR.
3FA7:60 178 RTS RETURN.
179 ****************************** ; === Page 85 ===
180 AEC2 EQU * ;TELL RELOCTR WHERE RWTS ENDS
181 ******************************
3FA8:00 00 00 00 182 FOUND DFB 0,0,0,0 'SECTOR FOUND' TABLE ;[.. wastes 16 bytes -- these are always cleared before used CLRFOUND, See: SECTOK
3FAC:00 00 00 00 183 DFB 0,0,0,0 ; .. TODO DOS 3.3 1980 has these as $FF
3FB0:00 00 00 00 184 DFB 0,0,0,0 ; ..
3FB4:00 00 00 00 185 DFB 0,0,0,0 ; ..]
186 FIN ; Macro started waaay back on Line #014, DSKFORM
187 LST ON
188 REP 40
189 * THIS TABLE IS USED TO TRANSLATE
190 * LOGICAL (REQUESTED) SECTOR NUMBER
191 * TO PHYSICAL SECTOR NUMBER. THE
192 * DISKETTE IS FORMATTED WITH ALL
193 * SECTORS IN MONOTONICALLY INCREASING ; MONOTONICALLY INCREASING ORDER
194 * ORDER. THE TRANSLATION WILL ALLOW ; Yup, math classes were just as boring back then too.
195 * TIME BETWEEN SECTORS FOR READS.
196 *
197 REP 40
198 *
199 * NOTE: THE CURRENT IMPLEMENTATION OF DOS
200 * USUALLY ACCESSES SECTORS IN DECREASING
201 * ORDER ON A TRACK. THUS WE WILL
202 * TRANSLATE IN REVERSE ORDER...
203 *
204 * THE INTERLEAVE IS THEN 9:1 ; TODO: Verify this is optimal for reading
205 * ; sectors in normal F,E,D,..,2,1,0 access pattern order
206 * NOTE: WE MAP LOGICAL SECTOR 0
207 * INTO PHYSICAL SECTOR 0 SO THAT
208 * WRITING OF BOOT DURING 'INIT'
209 * IS CORRECT FOR SECTOR ZERO.
210 *
211 INTRLEAV EQU * ; *sigh*
3FB8:00 0D 0B 09 212 DFB $00,$0D,$0B,$09 ; /sarcasm Here's a novel concept ...
3FBC:07 05 03 01 213 DFB $07,$05,$03,$01 ; How about *formatting* the sectors in the correct
3FC0:0E 0C 0A 08 214 DFB $0E,$0C,$0A,$08 ; order on the disk in the first place so we don't even
3FC4:06 04 02 0F 215 DFB $06,$04,$02,$0F ; need to waste memory with this table at all !
001 SBTL "DOS PATCHES"
002 ********************************
003 *
004 * DOS 3.2 PATCHES BY DICK HUSTON
005 *
006 ********************************
007 * AFTER THE FACT PATCHES
008 * CLRBYTE CALLED FROM DOS2 LABEL SOPTS +7 LINES
009 * CLRSTS1 CALLED FROM DOS3 LABEL ERROR +2 LINES
010 * ERROR9X CALLED FROM DOS5 LABEL ERROR9*
011 *
012 *
013 REP 40
014 *
015 * DOS 3.3 REVISION B PATCH
016 *
017 REP 40
018 *****************************
019 SDP1 EQU * ; Start Dos Patch
020 RCPATCH EQU * ; "Called" from BOOTLDR, Func DOSINT, Line 295
3FC8:20 93 FE 021 JSR SETVID
3FCB:AD 81 C0 022 LDA $C081 ; magic number If only ROMIN = $C081 for Language Card (LC)
3FCE:AD 81 C0 023 LDA $C081 ; magic number 1st read = read ROM, 2nd read = write enable LC Bank 2
3FD1:A9 00 024 LDA #0
3FD3:8D 00 E0 025 STA $E000 ; magic number *sigh* Forces Language Card to reload
026 DO DOS33B
3FD6:20 76 3A 027 JSR OFF80
3FD9:4C 44 37 028 JMP RCBACK ; wastes 2 bytes Why not RTS ???
029 ELSE
030 JMP RCBACK
031 DS 3,0
032 FIN
033 *****************************
3FDC:8D 63 2A 034 CLRBYTE STA TEMP1A ; Called from SOPTS, Page 18, Line 176
3FDF:8D 70 2A 035 STA CB ;SET TYPE PARAM DEFAUTL=0 ; *spelling* DEFAULT
3FE2:8D 71 2A 036 STA CB+1
3FE5:60 037 RTS
038 SKP 4
3FE6:20 5B 27 039 CLRSTS1 JSR CLRSTS ; TODO Clear ???
3FE9:8C B7 2A 040 STY RSTATE ;PREVENTS FOREVER 'FILE NOT FOUND'
3FEC:60 041 RTS ; IN APPLESOFT
042 *****************************
3FED:20 7E 2E 043 ERROR9X JSR RTNFCB
3FF0:AE 9B 33 044 LDX ENTSTK ;GET STACK
3FF3:9A 045 TXS ;MESSY MESSY MESSY
3FF4:20 16 23 046 JSR CLALL ;GO CLOSE EVERYBODY
3FF7:BA 047 TSX
3FF8:8E 9B 33 048 STX ENTSTK ;RESTORE SAVE STK
3FFB:A9 09 049 LDA #9 ; magic number LDA #CRENSA
3FFD:4C 85 33 050 JMP ERRORA ;AND BACK
051 *****************************
052 ENDP1 EQU *-1 ; END OF DOS PATCHES FOR RELOCTR
053 ENDOFDOS EQU *
054 DO ENDOFDOS-$4000 ; === Page 53 ===
055 FAIL 2,'DOS LENGTH NOT CORRECT'
056 FIN
AITSTL = ??? AP1 = ??? ASBRK1 = ??? ASBRK2 = ??? ASCNTU1 = ??? ASCNTU2 = ??? ASRSEQ1 = ??? ASRSEQ2 = ??? ASRUN1 = 24FC ASRUN2 = 2506 AA = ??? ADRTAB = 1C28 AEC2 = 3FA8 AEND = 2AC7 AIOB = 2AC1 ALC10S = 33A0 AS1VT = 1D6C AS2VT = 1D78 ASC1 = ??? ASEOP = ??? ASEOP2 = ??? ASEQ = 1D60 ASHM1 = 0073 ASHM2 = 006F ASIBSW = 2AB6 ASLMEM = 0067 ASONERR = ??? ASRNX = ??? ASSOP = ??? ASTART = 1D0C AVOLDR = 2AC5 AVTOC = 2AC3
BADIO = 30A1 BD2 = 30B2 BEGIN = 1B00 BFT1 = ??? BFT2 = BFT2 BFTIB = ??? BHERE5 = 36FF BI01 = 37A9 BLDFTB = ??? BOOTIO = 3793 BUMPER = 3671 BAIOB = 37E4 BGRPGC = 0800 BHERE1 = 36B3 BHERE4 = 36FD BOOTCNT = 0800 BOOTSL = 002E BREAK = 1D5A BRETRY = 005C BSECTR = 003D BSLOT = 002B BTEMP = 003E BUF = ???
CCBLDR = 1E5D CERTN = ??? CF3 = 2E72 CHIN0 = 1E95 CHIN1 = 1E9E CHIN2 = 1EA6 CHRIN = 1E81 CHROUT = 1EBD CL0 = 231B CL1 = 2320 CL2 = 2330 CLALL = 2316 CLC1 = ??? CLCFCB = 2E6A CLOSE = 22FC CLOSFILE = 365E CLRBYTE = ??? CLRCCB = ??? CLRFNA = 2097 CLRFNS = 2095 CLRFOUND = 3F32 CLRNBUF1 = 3EC5 CLRNBUF2 = 3EBF CLRPHASE = ??? CLRSTS = 275B CLRSTS1 = ??? CLX = 2306 CMDGO = ??? CMDGO1 = ??? CMDRTN = ??? CNF = 2000 CNF1 = 200B CORRECTVOL = 3E26 COS0 = 1EEB COS00 = 1EF3 COS01 = 1F00 COS01 = ??? COS1 = 1F12 COS1A = 1F15 COS2 = ??? COS2A = ??? COS3 = ??? COS3A = ??? COS3B = ??? COS4 = ??? COS4A = ??? COS5 = ??? COS6 = ??? COS7 = ??? CS2 = ??? CSERR = 2018 CA = 2A72 CB = 2A70 CCB = ??? CCBADR = 1D0E CCBBBA = ??? CCBBLN = ??? CCBBSA = ??? CCBBYT = ??? CCBBYT = ??? CCBBYT = ??? CCBBYT = ??? CCBDAT = ??? CCBDBP = ??? CCBDRV = ??? CCBFCB = ??? CCBFN1 = ??? CCBFUC = ??? CCBLEN = ??? CCBREQ = ??? CCBRQM = ??? CCBSBP = ??? CCBSLT = ??? CCBSM = ??? CCBSPR = ??? CCBSTA = ??? CCBVOL = ??? CCHAR = 2AB2 CD = 2A68 CDETAB = CDETAB CFCBAD = ??? CFCBDR = ??? CFCBSB = ??? CFTABA = 2A4F CHAIN = 1D56 CINA = 1D02 CL = 2A6C CMDETB = 1D1E CMDNO = 2A5F CMDNTB = 2884 CMDSTB = ??? CMDVT = 2AC9 CNFTBS = 2A57 CNUM = ??? CONT = 1D5E COUNT = ??? COUTA = 1D04 CR = 2A6E CS = 2A6A CSSTV = ??? CSUM = ??? CURCCB = 3399 CUROPT = 2A66 CURTRK = ??? CV = 2A66 CVDSEC = 3398 CVDTRK = 3397 CVTAB = 33A4
DBINIT = 1D84 DBRST = ??? DBVECT = 1E51 DCBIO = 3052 DCBIO1 = 3065 DCBIO2 = 3058 DCBSUP = ??? DENRTS = 2B1E DFVOL = ??? DG3 = 26C3 DI3 = ??? DISKERR = 37BF DISKIO = 37B5 DLDSUP = 37C2 DONTINC = ??? DOPEN = 2B28 DOSENT = 2B06 DOSGO = 26A8 DOSGO2A = 26BB DOSINT = 373B DOSLODR = 3700 DOSREL = 1B03 DR0 = 1B03 DR0A = 1B0B DR1 = 1B11 DR10 = 1C13 DR11 = 1C25 DR1A = 1B24 DR1B = 1B0D DR2 = 1B28 DR2A = 1B35 DR2B = 1B4C DR2C = 1B51 DR3 = ??? DR4 = ??? DR5 = ??? DR6 = ??? DR7 = ??? DR8 = ??? DR9 = ??? DRTNI = ??? DRTNO = ??? DRVERR = 3E04 DSKFORM = 3EAF DTB1 = 31C2 DTB2 = 31C6 DTBLN = 31B5 DCBABM = 35F2 DCBALS = 35F0 DCBATK = 35F1 DCBCDS = 35D4 DCBCDT = 35D3 DCBCMS = ??? DCBCRB = ??? DCBCRR = ??? DCBCRS = ??? DCBCSB = ??? DCBDFS = ??? DCBDMS = ??? DCBDNF = ??? DCBDRV = ??? DCBFDS = 35D2 DCBFDT = 35D1 DCBFUC = ??? DCBNSA = ??? DCBRCL = ??? DCBSDL = ??? DCBSEC = ??? DCBSLT = ??? DCBSPR = 35FB DCBTRK = ??? DCBVDI = ??? DCBVDR = ??? DCBVOL = 35F9 DCBVTN = 35FA DCBWRF = 35D5 DCT = 37FB DELTA = 1C7F DFNFB = 2A58 DFNFTS = 2AB1 DNIBL = ??? DOSLNG = 1C7E DPGCNT = 1C80 DRIVNO = 0035 DRV1TRK = 0478 DRV2TRK = 04F8
EAPND = 2298 EAS = ??? EAS0 = ??? EAS1 = ??? EAS2 = ??? EASAV = ??? EASL1 = 243B EBLD = ??? EBLD1 = ??? EBLD2 = ??? EBLD3 = ??? EBRUN = ??? EBSV = 2331 EBSV1 = 233D EC2 = 3397 ECAT = ??? ECHAIN = 24F0 ECLOSE = 22EA ECMD = ??? EDEL = 2263 EEXEC = ??? EIBL = 2450 EIBSV = ??? EIN = ??? EINIT = ??? EINITA = ??? EINT = ??? ELD1 = 2419 ELD2 = 2420 ELOAD = 2413 ELOAD0 = 2416 ELOCK = 2271 EMAXF = 2251 EMON = 2233 EMPR = 2702 EMPR1 = 26E1 ENFA = 26C8 ENM1 = ??? ENOMON = 233D EO1 = 22BC EO3 = 22C8 EO4 = 22CB EO5 = 22D2 EO6 = 22D8 EOFIN = 2CB8 EOPEN = 22A3 EPOS = ??? EPR = ??? ER10 = 2C6D EREAD = 251B EREN = 2281 ERNAS = 26E1 ERNU1 = 26D0 ERR2 = 2B1F ERR3A = 2C6A ERRNT = 26EF ERROR = 26D2 ERROR1 = ??? ERROR10 = 337B ERROR2 = ??? ERROR3 = ??? ERROR4 = ??? ERROR5 = ??? ERROR6 = ??? ERROR9 = 3377 ERROR9X = ??? ERRORA = 3385 ERRORB = 3385 ERRTN1 = 26FF ERUN = 24D1 ERUN0 = 24D9 ERUN1 = 24DC ESAVE = ??? ESYNTX = 26C4 ETYP = 26D0 EUNLK = ??? EVAR = 227D EWRITE = 2510 EX0 = ??? EX1 = ??? EX1A = ??? EX2 = ??? EXP1 = ??? EXP2 = ??? EAT1 = 1D56 EAT2 = ??? EC1 = 2884 EC3 = 37E0 EFTABA = 2AB4 EM1 = ??? EM10 = ??? EM11 = ??? EM12 = ??? EM13 = ??? EM14 = ??? EM15 = ??? EM2 = ??? EM3 = ??? EM4 = ??? EM5 = ??? EM6 = ??? EM7 = ??? EM8 = ??? EM9 = ??? EMDTB = ??? EMSG = ??? ENDOFDOS = ??? ENDP1 = ??? ENTSLT = 339F ENTSTK = 339B EOFFLAG = 365D ESTATE = 2AB3
F01 = ??? F01A = ??? F02 = 2B3D F02A = 2B61 F02B = 2B64 F03 = ??? FC1 = 2C1C FC2 = 2C37 FCLOSE = ??? FD2 = ??? FDEL = ??? FDS1 = ??? FDSUB = ??? FF1 = ??? FF2 = ??? FF3 = ??? FF4 = ??? FF4A = ??? FF5 = ??? FF6 = ??? FF7 = ??? FF8 = ??? FFMT = 2E8E FILSRC = 2764 FINDS0 = 3EE5 FIXIT = 36AC FIXIT2 = 36B3 FLOCK = 2CEF FLS1 = 276E FLS1A = 2773 FNDFIL = ??? FOPEN = 2B22 FORMDONE = 3F09 FORMDSK = 3E0D FORMERR = 3F04 FORMERR1 = 3EDC FORMTRK = 3ED4 FPOSTN = ??? FREAD = 2C58 FRESEC = ??? FRETRK = ??? FRNME = 2C3A FS1 = ??? FS2 = ??? FS3 = ??? FS4 = ??? FT1 = ??? FUNLCK = 2CF6 FVAR = ??? FWRITE = 2C70 FASB = 2AB8 FCB = 35D1 FCBDCB = 35D1 FDENT = ??? FDFRS = ??? FDLAST = ??? FDLSDL = ??? FDLSEC = ??? FDLTRK = ??? FDNSA = ??? FDSPAR = ??? FDUCDE = ??? FILDIR = ??? FN1ADR = 1D06 FN2ADR = 1D08 FNAME1 = 2A75 FNAME2 = ??? FOUND = 3FA8 FTAB = 1D00 FTTAB = 33A7
GALLDONE = 3E0B GETBYT = 2CA8 GETIN = 1EBA GETKEY = FD0C GETNUM = ??? GETSEC = ??? GN2 = ??? GN2A = ??? GN3 = ??? GN4 = ??? GN5 = ??? GNBC = ??? GNWSEC = 3134 GNXTC = ??? GNXTCR = ??? GOBACK = 367E GODOS = 240A GOGOOD = ??? GOINIT = ??? GOINT = ??? GOLOADER = 3639 GOODIO = 337F GOON = ??? GOSEEK = 3E8B GOTSECT = ??? GS0 = ??? GS1 = ??? GS1A = ??? GS2 = ??? GS3 = ??? GS4 = ??? GS5 = ??? GS6 = ??? GS7 = ??? GS8 = ??? GSS1 = ??? GO = 1D5C GRPGC = 36FF GRSPG = 36FE
HEXNUM = ??? HN0 = ??? HN1 = ??? HN2 = ??? HOME = FC58 HERE3L = 35FE HEREL = 0081
IAS1 = ??? IAS1A = ??? IAS2A = ??? IAS2B = ??? IBBRK = ??? IBCHN = ??? IBCONT = ??? IBGO = ??? IBRUN = 24E5 ICFD = ??? ICFD0 = ??? ICFD1 = ??? ICFD2 = ??? ICFD3 = ??? ICFD4 = ??? ICFDB = ??? ICFNLC = ??? IIB1 = ??? INCR1 = 3177 INCR2 = 318D INCRRB = 315B INCS2 = 31A1 INCSCB = 3194 INITA = ??? INITA1 = ??? INITA2 = ??? INITA3 = ??? INITAA = ??? INITB = ??? INITC = ??? INITD = ??? INITE = 1E2A INITF = 1E45 INITF1 = 1E4A INITG = 1E50 INITZ = 1E1D INPRT = FE8B INSDS2 = F88E IOBLDR = 1E64 IORTS = FF58 ISDRV1 = 3E88 IBASVT = 1D56 IBBUFP = 37F0 IBCMD = 37F4 IBDCTP = 37EE IBDLEN = 37F2 IBDRVN = 37EA IBHMEM = ??? IBLMEM = ??? IBPDRV = 37F8 IBPSLT = 37F7 IBSECT = 37ED IBSLOT = 37E9 IBSMOD = 37F6 IBSOP = ??? IBSOV = ??? IBSPAR = 37F9 IBSTAT = 37F5 IBTRK = 37EC IBTYPE = 37E8 IBVOL = 37EB IBVT = 1D62 IDX = ??? IFB = 1E51 IFBL = 1E81 IMBITS = 2A74 INOPTS = 2A65 INRLEAV = 3FB8 INSW = 0038 IOBPH = 0049 IOBPL = 0048 ISTATE = 2A51
JMPTO1 = 3E07
LCKGO = 2CFB LD1 = 24B1 LD1A = 24C2 LD1B = 24C4 LD1C = 24D0 LD2 = 247A LD3 = 2471 LDREGS = ??? LNB1 = 30C6 LNB2 = 30C9 LNB3 = 30DB LNB4 = 30ED LNB6 = 30F3 LNB7 = 3114 LNB7A = 310E LNB8 = 312C LNBCON = 3120 LOCNXB = 30B6 LOCSEC = ??? LS1 = ??? LS1A = ??? LS2 = ??? LAST = ??? LBUFD = 2A5D LBUFF = 0200 LENGTH = 002F LOADADDR = 36FD LOC1 = 0026
MAXTST = ??? MFERR = 26CC MFULL1 = 24AB MIB1 = 31B4 MIBDA = 31A2 MINTST = ??? MODECK = ??? MONBRK = FA59 MONINIT = FB2F MONRST = FF65 MOVEOF = ??? MSB1 = 2FEA MSW1 = ??? MSW2 = ??? MSWAIT = ??? MULT = FB63 MVCSW = ??? MVEFTA = ??? MVF1 = 2F12 MVFCBD = 2F0C MVFCBP = 2F08 MVFCBS = 2F10 MVFDBA = 2F4B MVN = ??? MVOSW = ??? MVSBA = 2FE4 MVSRTN = 2883 MVVDBA = 3045 MYSEEK = 3E5A MYSEEK2 = 3E6B MONMOD = 2A5E MONTIME = 0046 MONTIMEH = ??? MONTIMEL = ???
NBPER = ??? NOTFOUND = 366B NOTRUN = ??? NOTS15 = 3F81 NT1 = 2EAC NT2 = 2EB4 NT3 = 2EBA NT4 = 2ECC NT5 = 2ED2 NT6 = 2EE5 NT7 = 2EE8 NT8 = 2EFF NXTEXC = ??? NBUF1 = 3B00 NBUF2 = ??? NEPAGE = 1C7D NIBL = ??? NSECT = ??? NSPAGE = 1C7C NSYNC = ??? NVOL = ???
OCTD = ??? OFF80 = ??? ONDRV1 = 3EAB OPEN = 22AA ORIGIN = 1B00 ORTN = ??? ORTN1 = ??? OUT = ??? OUTPTR = ??? OFFTABLE = ??? ONTABLE = ??? OPT1L = ??? OPTAB1 = ??? OPTAB2 = ??? OPTAB3 = ??? OSTATE = 2A52 OUTSVT = 1D10 OUTSW = 0036
PB0 = 2CDE POST1 = 38C4 POST2 = 38C6 POSTNB16 = 38C2 PRCR = 2E2F PRCR1 = 2E41 PRCRIF = ??? PRENIB1 = 3804 PRENIB16 = 3800 PRENIB2 = 381E PRINT = FDED PRN1 = 2E44 PRN2 = 2E47 PRN3 = 2E60 PRNUM = 2E42 PRRTN = ??? PSC1 = ??? PUTBYT = 2CDA PD2 = 0012 PEC1 = 3A84 PHASEOFF = ??? PHASEON = ??? POINTA = 0026 PRIOR = ??? PROMPT = 0033 PTRSDEST = 003C PWCNST = 03F4
Q6H = ??? Q6L = ??? Q7H = ??? Q7L = ???
RBYTE = ??? RCBACK = 3744 RCPATCH = ??? RD0 = 2DB0 RD1 = 2DCA RD2 = 2DD1 RD2A = 2DE4 RD2B = 2DF0 RD2C = 2DF6 RD3 = 2E18 RD3A = 2E22 RDA1 = 394F RDA2 = 39F9 RDA3 = 3964 RDA4 = 3971 RDA5 = 3979 RDA6 = ??? RDA7 = ??? RDADR16 = 3944 RDAFLD = 396F RDASN1 = 3954 RDASYN = 3948 RDATA1 = ??? RDATA2 = ??? RDERR = ??? RDEXIT = ??? RDFDC = 2FC0 RDFDIR = 2F5E RDIR = ??? RDRIGHT = ??? RDSECT = 2FDC RDVC = 3027 RDVDGO = 302A RDVDIR = ??? RDVTOC = 2FF7 READ1 = ??? READ16 = ??? READ2 = ??? READ3 = ??? READ4 = ??? READ5 = ??? READ6 = ??? READ7 = ??? READ8 = ??? READNEXT = 361F RESEEK = ??? RETURN = 3386 RFDIO1 = 2FB5 RFDIO2 = 2FB7 RFDNL = 2F82 RFDNL1 = 2F8B RFDNXT = 2F74 RNXBLK = 2C96 RNXBYT = 2C8A RSPBLK = 2C93 RSPBYT = 2C87 RSYNC = ??? RSYNC1 = ??? RTNFCB = 2E7E RTTRK = 3E10 RVDA = 3020 RVDC = 3018 RVT = ??? RWP1 = 2531 RWP2 = 2534 RWP2A = 253D RWP3 = 2546 RWPOSN = 2526 RWPR = 254E RECALCNT = 06F8 REMDR = 007f REMDR3 = 0002 REPAGE = 1C7B RETRYCNT = 0578 RSPAGE = 1C7A RSTATE = 2AB7 RUN = 1D58
S0DELAY = 3F3A S15LOC = 3F71 SC0 = 1FD6 SC0A = 1FE5 SC1 = 1D84 SC1A = 1FF6 SC1X = 1FE8 SC2 = 2AFD SCNCMD = 1FCD SDP1 = ??? SECTOK = 3F88 SEEK = ??? SEEK2 = ??? SEEKEND = ??? SEEKRTS = ??? SERR1 = 2092 SERR2A = ??? SERR3A = ??? SETKBD = FE89 SETPHASE = ??? SETRTS = 3EAE SETTRK = 3E95 SETTRK2 = 3EA2 SETVID = FE93 SN1 = 2099 SN10 = 20A0 SN2 = 2043 SN2A = 2050 SN3 = 2054 SN4 = 2059 SN5 = 2061 SN6 = 2066 SN7 = 2078 SN8 = 207F SP1 = 20E8 SP2 = ??? SP3 = ??? SP4 = ??? SP5 = ??? SP6 = ??? SP7 = 2161 SP8 = 2164 STEP = ??? STEP2 = ??? SV1 = ??? SV1A = ??? SV2 = ??? SV3 = 23FF SVRB = 1EE2 SVREGS = 1ED1 SVRGSA = 1ED4 SWADR1 = 3C56 SWTR = ??? SWTST = ??? SYN1 = 2032 SYN1A = 2038 SYNTAX = 201B SAT1 = 1D00 SAT2 = 2AC1 SC3 = 365D SEEKCNT = 04F8 SLOT = 05F8 SLOTABS = ??? SLOTTEMP = ??? SLOTZ = ??? START = 1D00 SVA = 2A5C SVBL = 2A60 SVBLA = 1D0A SVCMD = 2A62 SVINS = 2A55 SVOUTS = 2A53 SVSTK = 2A59 SVX = 2A5A SVY = 2A5B
TR0 = ??? TR1 = ??? TRYADR = ??? TRYADR2 = ??? TRYTRK = ??? TRYTRK2 = ??? TSINIT = ??? TSNXT = ??? TSTEXC = ??? TSTFUC = ??? TSTOPN = ??? TSTRUN = ??? T0 = ??? TABLE = 084D TEMP1 = 339C TEMP1A = 2A63 TEMP2 = 339D TEMP2A = 2A64 TEMP3 = 339E TRK = ??? TRK0LDR = 3600 TRKCNT = ??? TRKN = ???
USERENT = 2AFD USRCR = 2B03
VAR1 = ??? VDATA = 3F67 VDINC = ??? VERR = 3F60 VERR1 = 3F6C VSECT = 3F62 VTIO = ??? VTRACK = 3F29 VALCA1 = ??? VALCA2 = ??? VALCA3 = ??? VALCA4 = ??? VDEND = ??? VDFILE = 34C6 VDFLEN = ??? VDIRSC = 33BD VDIRTK = 33BC VDLEN = ??? VDLSEC = 34BD VDLTRK = 34BC VDNF = 34BE VDOSRN = 33BE VDOST = 33BB VDSPAR = 34BF VDTCDE = 34BB VML = ??? VNOSEC = ??? VNOTRK = ??? VOLDIR = 34BB VOLMES = ??? VSECAL = ??? VSECLN = ??? VSPARE = ??? VTDMS = ??? VTOC = 33BB VVOLNO = ???
WADR16 = 3C56 WADRTS = 3CBD WADRTS1 = 3CC3 WASD0 = 3E7A WBOOT = 374A WBYTE = 3CC4 WDATA0 = ??? WDATA1 = ??? WDATA2 = ??? WEXIT = ??? WEXIT1 = 3FA6 WEXIT2 = 3F87 WNIBL = ??? WNIBL7 = ??? WNIBL9 = ??? WNIBLA = 3CD4 WNIBLB2 = 3CD5 WNXBLK = 2CCA WNXBYT = 2CBE WRFDGO = 2F3A WRFDIR = 2F34 WRGO = 2F23 WRIT = ??? WRITE16 = ??? WRNIBL = 3CD8 WRSECT = 2F1D WRVDIR = 3037 WRVTOC = 2FFB WSECT = 3F15 WSECT0 = 3F17 WSPBLK = 2CC7 WSPBYT = 2CBB WSYNC = ??? WSYNC1 = 3C69 WTRACK16 = 3F0D WVT = ??? WTEMP = ???
XTOY = 3E8E XP = ???
YESEOF = 26B7
ZPGFCB = 0042 ZPGWRK = 0040 ZRSET = 03F2
A
AITSTL = ??? AP1 = ??? ASBRK1 = ??? ASBRK2 = ??? ASCNTU1 = ??? ASCNTU2 = ??? ASRSEQ1 = ??? ASRSEQ2 = ??? ASRUN1 = 24FC ASRUN2 = 2506 AA = ??? ADRTAB = 1C28 AEC2 = 3FA8 AEND = 2AC7 AIOB = 2AC1 ALC10S = 33A0 AS1VT = 1D6C AS2VT = 1D78 ASC1 = ??? ASEOP = ??? ASEOP2 = ??? ASEQ = 1D60 ASHM1 = 0073 ASHM2 = 006F ASIBSW = 2AB6 ASLMEM = 0067 ASONERR = ??? ASRNX = ??? ASSOP = ??? ASTART = 1D0C AVOLDR = 2AC5 AVTOC = 2AC3B
BADIO = 30A1 BD2 = 30B2 BEGIN = 1B00 BFT1 = ??? BFT2 = BFT2 BFTIB = ??? BHERE5 = 36FF BI01 = 37A9 BLDFTB = ??? BOOTIO = 3793 BUMPER = 3671 BAIOB = 37E4 BGRPGC = 0800 BHERE1 = 36B3 BHERE4 = 36FD BOOTCNT = 0800 BOOTSL = 002E BREAK = 1D5A BRETRY = 005C BSECTR = 003D BSLOT = 002B BTEMP = 003E BUF = ???C
CCBLDR = 1E5D CERTN = ??? CF3 = 2E72 CHIN0 = 1E95 CHIN1 = 1E9E CHIN2 = 1EA6 CHRIN = 1E81 CHROUT = 1EBD CL0 = 231B CL1 = 2320 CL2 = 2330 CLALL = 2316 CLC1 = ??? CLCFCB = 2E6A CLOSE = 22FC CLOSFILE = 365E CLRBYTE = ??? CLRCCB = ??? CLRFNA = 2097 CLRFNS = 2095 CLRFOUND = 3F32 CLRNBUF1 = 3EC5 CLRNBUF2 = 3EBF CLRPHASE = ??? CLRSTS = 275B CLRSTS1 = ??? CLX = 2306 CMDGO = ??? CMDGO1 = ??? CMDRTN = ??? CNF = 2000 CNF1 = 200B CORRECTVOL = 3E26 COS0 = 1EEB COS00 = 1EF3 COS01 = 1F00 COS01 = ??? COS1 = 1F12 COS1A = 1F15 COS2 = ??? COS2A = ??? COS3 = ??? COS3A = ??? COS3B = ??? COS4 = ??? COS4A = ??? COS5 = ??? COS6 = ??? COS7 = ??? CS2 = ??? CSERR = 2018 CA = 2A72 CB = 2A70 CCB = ??? CCBADR = 1D0E CCBBBA = ??? CCBBLN = ??? CCBBSA = ??? CCBBYT = ??? CCBBYT = ??? CCBBYT = ??? CCBBYT = ??? CCBDAT = ??? CCBDBP = ??? CCBDRV = ??? CCBFCB = ??? CCBFN1 = ??? CCBFUC = ??? CCBLEN = ??? CCBREQ = ??? CCBRQM = ??? CCBSBP = ??? CCBSLT = ??? CCBSM = ??? CCBSPR = ??? CCBSTA = ??? CCBVOL = ??? CCHAR = 2AB2 CD = 2A68 CDETAB = CDETAB CFCBAD = ??? CFCBDR = ??? CFCBSB = ??? CFTABA = 2A4F CHAIN = 1D56 CINA = 1D02 CL = 2A6C CMDETB = 1D1E CMDNO = 2A5F CMDNTB = 2884 CMDSTB = ??? CMDVT = 2AC9 CNFTBS = 2A57 CNUM = ??? CONT = 1D5E COUNT = ??? COUTA = 1D04 CR = 2A6E CS = 2A6A CSSTV = ??? CSUM = ??? CURCCB = 3399 CUROPT = 2A66 CURTRK = ??? CV = 2A66 CVDSEC = 3398 CVDTRK = 3397 CVTAB = 33A4D
DBINIT = 1D84 DBRST = ??? DBVECT = 1E51 DCBIO = 3052 DCBIO1 = 3065 DCBIO2 = 3058 DCBSUP = ??? DENRTS = 2B1E DFVOL = ??? DG3 = 26C3 DI3 = ??? DISKERR = 37BF DISKIO = 37B5 DLDSUP = 37C2 DONTINC = ??? DOPEN = 2B28 DOSENT = 2B06 DOSGO = 26A8 DOSGO2A = 26BB DOSINT = 373B DOSLODR = 3700 DOSREL = 1B03 DR0 = 1B03 DR0A = 1B0B DR1 = 1B11 DR10 = 1C13 DR11 = 1C25 DR1A = 1B24 DR1B = 1B0D DR2 = 1B28 DR2A = 1B35 DR2B = 1B4C DR2C = 1B51 DR3 = ??? DR4 = ??? DR5 = ??? DR6 = ??? DR7 = ??? DR8 = ??? DR9 = ??? DRTNI = ??? DRTNO = ??? DRVERR = 3E04 DSKFORM = 3EAF DTB1 = 31C2 DTB2 = 31C6 DTBLN = 31B5 DCBABM = 35F2 DCBALS = 35F0 DCBATK = 35F1 DCBCDS = 35D4 DCBCDT = 35D3 DCBCMS = ??? DCBCRB = ??? DCBCRR = ??? DCBCRS = ??? DCBCSB = ??? DCBDFS = ??? DCBDMS = ??? DCBDNF = ??? DCBDRV = ??? DCBFDS = 35D2 DCBFDT = 35D1 DCBFUC = ??? DCBNSA = ??? DCBRCL = ??? DCBSDL = ??? DCBSEC = ??? DCBSLT = ??? DCBSPR = 35FB DCBTRK = ??? DCBVDI = ??? DCBVDR = ??? DCBVOL = 35F9 DCBVTN = 35FA DCBWRF = 35D5 DCT = 37FB DELTA = 1C7F DFNFB = 2A58 DFNFTS = 2AB1 DNIBL = ??? DOSLNG = 1C7E DPGCNT = 1C80 DRIVNO = 0035 DRV1TRK = 0478 DRV2TRK = 04F8E
EAPND = 2298 EAS = ??? EAS0 = ??? EAS1 = ??? EAS2 = ??? EASAV = ??? EASL1 = 243B EBLD = ??? EBLD1 = ??? EBLD2 = ??? EBLD3 = ??? EBRUN = ??? EBSV = 2331 EBSV1 = 233D EC2 = 3397 ECAT = ??? ECHAIN = 24F0 ECLOSE = 22EA ECMD = ??? EDEL = 2263 EEXEC = ??? EIBL = 2450 EIBSV = ??? EIN = ??? EINIT = ??? EINITA = ??? EINT = ??? ELD1 = 2419 ELD2 = 2420 ELOAD = 2413 ELOAD0 = 2416 ELOCK = 2271 EMAXF = 2251 EMON = 2233 EMPR = 2702 EMPR1 = 26E1 ENFA = 26C8 ENM1 = ??? ENOMON = 233D EO1 = 22BC EO3 = 22C8 EO4 = 22CB EO5 = 22D2 EO6 = 22D8 EOFIN = 2CB8 EOPEN = 22A3 EPOS = ??? EPR = ??? ER10 = 2C6D EREAD = 251B EREN = 2281 ERNAS = 26E1 ERNU1 = 26D0 ERR2 = 2B1F ERR3A = 2C6A ERRNT = 26EF ERROR = 26D2 ERROR1 = ??? ERROR10 = 337B ERROR2 = ??? ERROR3 = ??? ERROR4 = ??? ERROR5 = ??? ERROR6 = ??? ERROR9 = 3377 ERROR9X = ??? ERRORA = 3385 ERRORB = 3385 ERRTN1 = 26FF ERUN = 24D1 ERUN0 = 24D9 ERUN1 = 24DC ESAVE = ??? ESYNTX = 26C4 ETYP = 26D0 EUNLK = ??? EVAR = 227D EWRITE = 2510 EX0 = ??? EX1 = ??? EX1A = ??? EX2 = ??? EXP1 = ??? EXP2 = ??? EAT1 = 1D56 EAT2 = ??? EC1 = 2884 EC3 = 37E0 EFTABA = 2AB4 EM1 = ??? EM10 = ??? EM11 = ??? EM12 = ??? EM13 = ??? EM14 = ??? EM15 = ??? EM2 = ??? EM3 = ??? EM4 = ??? EM5 = ??? EM6 = ??? EM7 = ??? EM8 = ??? EM9 = ??? EMDTB = ??? EMSG = ??? ENDOFDOS = ??? ENDP1 = ??? ENTSLT = 339F ENTSTK = 339B EOFFLAG = 365D ESTATE = 2AB3F
F01 = ??? F01A = ??? F02 = 2B3D F02A = 2B61 F02B = 2B64 F03 = ??? FC1 = 2C1C FC2 = 2C37 FCLOSE = ??? FD2 = ??? FDEL = ??? FDS1 = ??? FDSUB = ??? FF1 = ??? FF2 = ??? FF3 = ??? FF4 = ??? FF4A = ??? FF5 = ??? FF6 = ??? FF7 = ??? FF8 = ??? FFMT = 2E8E FILSRC = 2764 FINDS0 = 3EE5 FIXIT = 36AC FIXIT2 = 36B3 FLOCK = 2CEF FLS1 = 276E FLS1A = 2773 FNDFIL = ??? FOPEN = 2B22 FORMDONE = 3F09 FORMDSK = 3E0D FORMERR = 3F04 FORMERR1 = 3EDC FORMTRK = 3ED4 FPOSTN = ??? FREAD = 2C58 FRESEC = ??? FRETRK = ??? FRNME = 2C3A FS1 = ??? FS2 = ??? FS3 = ??? FS4 = ??? FT1 = ??? FUNLCK = 2CF6 FVAR = ??? FWRITE = 2C70 FASB = 2AB8 FCB = 35D1 FCBDCB = 35D1 FDENT = ??? FDFRS = ??? FDLAST = ??? FDLSDL = ??? FDLSEC = ??? FDLTRK = ??? FDNSA = ??? FDSPAR = ??? FDUCDE = ??? FILDIR = ??? FN1ADR = 1D06 FN2ADR = 1D08 FNAME1 = 2A75 FNAME2 = ??? FOUND = 3FA8 FTAB = 1D00 FTTAB = 33A7G
GALLDONE = 3E0B GETBYT = 2CA8 GETIN = 1EBA GETKEY = FD0C GETNUM = ??? GETSEC = ??? GN2 = ??? GN2A = ??? GN3 = ??? GN4 = ??? GN5 = ??? GNBC = ??? GNWSEC = 3134 GNXTC = ??? GNXTCR = ??? GOBACK = 367E GODOS = 240A GOGOOD = ??? GOINIT = ??? GOINT = ??? GOLOADER = 3639 GOODIO = 337F GOON = ??? GOSEEK = 3E8B GOTSECT = ??? GS0 = ??? GS1 = ??? GS1A = ??? GS2 = ??? GS3 = ??? GS4 = ??? GS5 = ??? GS6 = ??? GS7 = ??? GS8 = ??? GSS1 = ??? GO = 1D5C GRPGC = 36FF GRSPG = 36FEH
HEXNUM = ??? HN0 = ??? HN1 = ??? HN2 = ??? HOME = FC58 HERE3L = 35FE HEREL = 0081I
IAS1 = ??? IAS1A = ??? IAS2A = ??? IAS2B = ??? IBBRK = ??? IBCHN = ??? IBCONT = ??? IBGO = ??? IBRUN = 24E5 ICFD = ??? ICFD0 = ??? ICFD1 = ??? ICFD2 = ??? ICFD3 = ??? ICFD4 = ??? ICFDB = ??? ICFNLC = ??? IIB1 = ??? INCR1 = 3177 INCR2 = 318D INCRRB = 315B INCS2 = 31A1 INCSCB = 3194 INITA = ??? INITA1 = ??? INITA2 = ??? INITA3 = ??? INITAA = ??? INITB = ??? INITC = ??? INITD = ??? INITE = 1E2A INITF = 1E45 INITF1 = 1E4A INITG = 1E50 INITZ = 1E1D INPRT = FE8B INSDS2 = F88E IOBLDR = 1E64 IORTS = FF58 ISDRV1 = 3E88 IBASVT = 1D56 IBBUFP = 37F0 IBCMD = 37F4 IBDCTP = 37EE IBDLEN = 37F2 IBDRVN = 37EA IBHMEM = ??? IBLMEM = ??? IBPDRV = 37F8 IBPSLT = 37F7 IBSECT = 37ED IBSLOT = 37E9 IBSMOD = 37F6 IBSOP = ??? IBSOV = ??? IBSPAR = 37F9 IBSTAT = 37F5 IBTRK = 37EC IBTYPE = 37E8 IBVOL = 37EB IBVT = 1D62 IDX = ??? IFB = 1E51 IFBL = 1E81 IMBITS = 2A74 INOPTS = 2A65 INRLEAV = 3FB8 INSW = 0038 IOBPH = 0049 IOBPL = 0048 ISTATE = 2A51J
JMPTO1 = 3E07K
L
LCKGO = 2CFB LD1 = 24B1 LD1A = 24C2 LD1B = 24C4 LD1C = 24D0 LD2 = 247A LD3 = 2471 LDREGS = ??? LNB1 = 30C6 LNB2 = 30C9 LNB3 = 30DB LNB4 = 30ED LNB6 = 30F3 LNB7 = 3114 LNB7A = 310E LNB8 = 312C LNBCON = 3120 LOCNXB = 30B6 LOCSEC = ??? LS1 = ??? LS1A = ??? LS2 = ??? LAST = ??? LBUFD = 2A5D LBUFF = 0200 LENGTH = 002F LOADADDR = 36FD LOC1 = 0026M
MAXTST = ??? MFERR = 26CC MFULL1 = 24AB MIB1 = 31B4 MIBDA = 31A2 MINTST = ??? MODECK = ??? MONBRK = FA59 MONINIT = FB2F MONRST = FF65 MOVEOF = ??? MSB1 = 2FEA MSW1 = ??? MSW2 = ??? MSWAIT = ??? MULT = FB63 MVCSW = ??? MVEFTA = ??? MVF1 = 2F12 MVFCBD = 2F0C MVFCBP = 2F08 MVFCBS = 2F10 MVFDBA = 2F4B MVN = ??? MVOSW = ??? MVSBA = 2FE4 MVSRTN = 2883 MVVDBA = 3045 MYSEEK = 3E5A MYSEEK2 = 3E6B MONMOD = 2A5E MONTIME = 0046 MONTIMEH = ??? MONTIMEL = ???N
NBPER = ??? NOTFOUND = 366B NOTRUN = ??? NOTS15 = 3F81 NT1 = 2EAC NT2 = 2EB4 NT3 = 2EBA NT4 = 2ECC NT5 = 2ED2 NT6 = 2EE5 NT7 = 2EE8 NT8 = 2EFF NXTEXC = ??? NBUF1 = 3B00 NBUF2 = ??? NEPAGE = 1C7D NIBL = ??? NSECT = ??? NSPAGE = 1C7C NSYNC = ??? NVOL = ???O
OCTD = ??? OFF80 = ??? ONDRV1 = 3EAB OPEN = 22AA ORIGIN = 1B00 ORTN = ??? ORTN1 = ??? OUT = ??? OUTPTR = ??? OFFTABLE = ??? ONTABLE = ??? OPT1L = ??? OPTAB1 = ??? OPTAB2 = ??? OPTAB3 = ??? OSTATE = 2A52 OUTSVT = 1D10 OUTSW = 0036P
PB0 = 2CDE POST1 = 38C4 POST2 = 38C6 POSTNB16 = 38C2 PRCR = 2E2F PRCR1 = 2E41 PRCRIF = ??? PRENIB1 = 3804 PRENIB16 = 3800 PRENIB2 = 381E PRINT = FDED PRN1 = 2E44 PRN2 = 2E47 PRN3 = 2E60 PRNUM = 2E42 PRRTN = ??? PSC1 = ??? PUTBYT = 2CDA PD2 = 0012 PEC1 = 3A84 PHASEOFF = ??? PHASEON = ??? POINTA = 0026 PRIOR = ??? PROMPT = 0033 PTRSDEST = 003C PWCNST = 03F4Q
Q6H = ??? Q6L = ??? Q7H = ??? Q7L = ???R
RBYTE = ??? RCBACK = 3744 RCPATCH = ??? RD0 = 2DB0 RD1 = 2DCA RD2 = 2DD1 RD2A = 2DE4 RD2B = 2DF0 RD2C = 2DF6 RD3 = 2E18 RD3A = 2E22 RDA1 = 394F RDA2 = 39F9 RDA3 = 3964 RDA4 = 3971 RDA5 = 3979 RDA6 = ??? RDA7 = ??? RDADR16 = 3944 RDAFLD = 396F RDASN1 = 3954 RDASYN = 3948 RDATA1 = ??? RDATA2 = ??? RDERR = ??? RDEXIT = ??? RDFDC = 2FC0 RDFDIR = 2F5E RDIR = ??? RDRIGHT = ??? RDSECT = 2FDC RDVC = 3027 RDVDGO = 302A RDVDIR = ??? RDVTOC = 2FF7 READ1 = ??? READ16 = ??? READ2 = ??? READ3 = ??? READ4 = ??? READ5 = ??? READ6 = ??? READ7 = ??? READ8 = ??? READNEXT = 361F RESEEK = ??? RETURN = 3386 RFDIO1 = 2FB5 RFDIO2 = 2FB7 RFDNL = 2F82 RFDNL1 = 2F8B RFDNXT = 2F74 RNXBLK = 2C96 RNXBYT = 2C8A RSPBLK = 2C93 RSPBYT = 2C87 RSYNC = ??? RSYNC1 = ??? RTNFCB = 2E7E RTTRK = 3E10 RVDA = 3020 RVDC = 3018 RVT = ??? RWP1 = 2531 RWP2 = 2534 RWP2A = 253D RWP3 = 2546 RWPOSN = 2526 RWPR = 254E RECALCNT = 06F8 REMDR = 007f REMDR3 = 0002 REPAGE = 1C7B RETRYCNT = 0578 RSPAGE = 1C7A RSTATE = 2AB7 RUN = 1D58S
S0DELAY = 3F3A S15LOC = 3F71 SC0 = 1FD6 SC0A = 1FE5 SC1 = 1D84 SC1A = 1FF6 SC1X = 1FE8 SC2 = 2AFD SCNCMD = 1FCD SDP1 = ??? SECTOK = 3F88 SEEK = ??? SEEK2 = ??? SEEKEND = ??? SEEKRTS = ??? SERR1 = 2092 SERR2A = ??? SERR3A = ??? SETKBD = FE89 SETPHASE = ??? SETRTS = 3EAE SETTRK = 3E95 SETTRK2 = 3EA2 SETVID = FE93 SN1 = 2099 SN10 = 20A0 SN2 = 2043 SN2A = 2050 SN3 = 2054 SN4 = 2059 SN5 = 2061 SN6 = 2066 SN7 = 2078 SN8 = 207F SP1 = 20E8 SP2 = ??? SP3 = ??? SP4 = ??? SP5 = ??? SP6 = ??? SP7 = 2161 SP8 = 2164 STEP = ??? STEP2 = ??? SV1 = ??? SV1A = ??? SV2 = ??? SV3 = 23FF SVRB = 1EE2 SVREGS = 1ED1 SVRGSA = 1ED4 SWADR1 = 3C56 SWTR = ??? SWTST = ??? SYN1 = 2032 SYN1A = 2038 SYNTAX = 201B SAT1 = 1D00 SAT2 = 2AC1 SC3 = 365D SEEKCNT = 04F8 SLOT = 05F8 SLOTABS = ??? SLOTTEMP = ??? SLOTZ = ??? START = 1D00 SVA = 2A5C SVBL = 2A60 SVBLA = 1D0A SVCMD = 2A62 SVINS = 2A55 SVOUTS = 2A53 SVSTK = 2A59 SVX = 2A5A SVY = 2A5BT
TR0 = ??? TR1 = ??? TRYADR = ??? TRYADR2 = ??? TRYTRK = ??? TRYTRK2 = ??? TSINIT = ??? TSNXT = ??? TSTEXC = ??? TSTFUC = ??? TSTOPN = ??? TSTRUN = ??? T0 = ??? TABLE = 084D TEMP1 = 339C TEMP1A = 2A63 TEMP2 = 339D TEMP2A = 2A64 TEMP3 = 339E TRK = ??? TRK0LDR = 3600 TRKCNT = ??? TRKN = ???U
USERENT = 2AFD USRCR = 2B03V
VAR1 = ??? VDATA = 3F67 VDINC = ??? VERR = 3F60 VERR1 = 3F6C VSECT = 3F62 VTIO = ??? VTRACK = 3F29 VALCA1 = ??? VALCA2 = ??? VALCA3 = ??? VALCA4 = ??? VDEND = ??? VDFILE = 34C6 VDFLEN = ??? VDIRSC = 33BD VDIRTK = 33BC VDLEN = ??? VDLSEC = 34BD VDLTRK = 34BC VDNF = 34BE VDOSRN = 33BE VDOST = 33BB VDSPAR = 34BF VDTCDE = 34BB VML = ??? VNOSEC = ??? VNOTRK = ??? VOLDIR = 34BB VOLMES = ??? VSECAL = ??? VSECLN = ??? VSPARE = ??? VTDMS = ??? VTOC = 33BB VVOLNO = ???W
WADR16 = 3C56 WADRTS = 3CBD WADRTS1 = 3CC3 WASD0 = 3E7A WBOOT = 374A WBYTE = 3CC4 WDATA0 = ??? WDATA1 = ??? WDATA2 = ??? WEXIT = ??? WEXIT1 = 3FA6 WEXIT2 = 3F87 WNIBL = ??? WNIBL7 = ??? WNIBL9 = ??? WNIBLA = 3CD4 WNIBLB2 = 3CD5 WNXBLK = 2CCA WNXBYT = 2CBE WRFDGO = 2F3A WRFDIR = 2F34 WRGO = 2F23 WRIT = ??? WRITE16 = ??? WRNIBL = 3CD8 WRSECT = 2F1D WRVDIR = 3037 WRVTOC = 2FFB WSECT = 3F15 WSECT0 = 3F17 WSPBLK = 2CC7 WSPBYT = 2CBB WSYNC = ??? WSYNC1 = 3C69 WTRACK16 = 3F0D WVT = ??? WTEMP = ???X
XTOY = 3E8E XP = ???Y
YESEOF = 26B7Z
ZPGFCB = 0042 ZPGWRK = 0040 ZRSET = 03F2
Â
| Total LOC (Lines of Code): | 6,442 |
| Number of Source assembly files: | 29 |
| Average LOC per source file: | 222 |
| Total Spelling mistakes: | 38 |
| Total Equates: | 130 |
| Total Functions: | 622 |
| Total Variables: | 333 |
| Total Functions referenced (*) | 580 |
| Total Variables referenced (*) | 333 |
| Total Magic Numbers: | 195 |
| Total Wasted bytes (run-time memory): | 751 |
| Total Wasted sectors: | 14 |
(*) Note: Includes commentary references to functions and variables.
Â
RELOCTR ; $1B00 .. $1C80, T0SA - T0SB DOSINIT ; $1C81 .. $1E80, T0SB - T0SD DOSHOOK ; $1E81 .. $1FCC, T0SD - T0SE CMDSCAN ; $1FCD .. $2192, T0SE - T1S0 XOPNCLS ; $2193 .. $2330, T1S0 - T1S2 XLODSAV ; $2331 .. $250F, T1S2 - T1S4 XMISCMD ; $2510 .. $26A7, T1S4 - T1S5 DOSGOER ; $26A8 .. $27D3, T1S5 - T1S6 BLDFTAB ; $27D4 .. $2883, T1S6 - T1S7 CMDTBLS ; $2884 .. $2A4E, T1S7 - T1S9 FDOSENT ; $2A4F .. $2B21, T1S9 - T1SA FOPCLRW ; $2B22 .. $2CEE, T1SA - T1SB FDELCAT ; $2CEF .. $2E8D, T1SB - T1SD FMTRWIO ; $2E8E .. $2FF6, T1SD - T1SE FLOCNXB ; $2FF7 .. $31C8, T1SE - T2S0 FLOCSEC ; $31C9 .. $3396, T2S0 - T2S2 FVCBUFS ; $3397 .. $35FD, T2S2 - T2S4 BOOTLDR ; $35FE .. $37FF, T0S0 - T0S1 COREQUS ; n/a PRENIBL ; $3800 .. $3829, T0S2 WRITRTN ; $382A .. $38C1, T0S2 POSTNRD ; $38C2 .. $3943, T0S2 - T0S3 RDADSEK ; $3944 .. $39FC, T0S3 MSWAITR ; $39FD .. $3C55, T0S3 - T0S6 WRITADR ; $3C56 .. $3CFF, T0S6 RWTSONE ; $3D00 .. $3DAA, T0S7 RWTSTWO ; $3DAB .. $3EAE, T0S7 - T0S8 FORMATR ; $3EAF .. $3FC7, T0S8 - T0S9 DOSPTCH ; $3FC8 .. $3FFF, T0S9

1B00:4C 84 1D A9 BF 85 41 A2 |L..)?.A"| T0SA, RELOCTR, $1B00 .. $1CFF, T0SA - T0SB 1B08:00 86 40 A0 00 A1 40 85 |..@ .!@.| 1B10:26 98 45 26 85 26 98 41 |&.E&.&.A| 1B18:40 81 40 C5 26 D0 05 C8 |@.@E&P.H| 1B20:D0 EF F0 04 C6 41 D0 E3 |Pop.FAPc| 1B28:A5 41 29 DF 85 43 86 42 |%A)_.C.B| 1B30:A1 42 48 85 26 98 45 26 |!BH.&.E&| 1B38:85 26 98 41 40 81 42 C5 |.&.A@.BE| 1B40:26 D0 09 C8 D0 EF A4 43 |&P.HPo$C| 1B48:68 4C 51 1B 68 81 42 A4 |hLQ.h.B$| 1B50:41 C8 8C 7D 1C 38 98 ED |AH.}.8.m| 1B58:7E 1C 8D 7C 1C 38 ED 7A |~..|.8mz| 1B60:1C F0 9D 8D 7F 1C AD 7A |.p....-z| 1B68:1C 8D 0D 1D A9 1D 8D 49 |....)..I| 1B70:37 A9 84 8D 48 37 A2 00 |7)..H7".| 1B78:86 40 BD 29 1C A8 BD 2A |.@=).(=*| 1B80:1C 85 41 4C 93 1B 18 B1 |..AL...1| 1B88:40 6D 7F 1C 91 40 C8 D0 |@m...@HP| 1B90:02 E6 41 C8 D0 02 E6 41 |.fAHP.fA| 1B98:A5 41 DD 2C 1C 90 E7 98 |%A],..g.| 1BA0:DD 2B 1C 90 E1 8A 18 69 |]+..a..i| 1BA8:04 AA EC 28 1C 90 CB A2 |.*l(..K"| 1BB0:00 8E 9C 33 BD 5A 1C 85 |...3=Z..| 1BB8:40 BD 5B 1C 85 41 A2 00 |@=[..A".| 1BC0:A1 40 20 8E F8 A4 2F C0 |!@ .x$/@| 1BC8:02 D0 11 B1 40 CD 7A 1C |.P.1@Mz.| 1BD0:90 0A CD 7B 1C B0 05 6D |..M{.0.m| 1BD8:7F 1C 91 40 38 A5 2F 65 |...@8%/e| 1BE0:40 85 40 A9 00 65 41 85 |@.@).eA.| 1BE8:41 AE 9C 33 DD 5D 1C 90 |A..3]]..| 1BF0:CD A5 40 DD 5C 1C 90 C6 |M%@]..F| 1BF8:8A 18 69 04 AA EC 59 1C |..i.*lY.| 1C00:90 AF A9 3F 85 41 AC 7D |./)?.A,}| T0SB 1C08:1C 88 84 43 A9 00 85 40 |...C)..@| 1C10:85 42 A8 B1 40 91 42 C8 |.B(1@.BH| 1C18:D0 F9 CE 80 1C F0 06 C6 |PyN..p.F| 1C20:41 C6 43 D0 EE 4C 54 1E |AFCPnLT.| 1C28:24 00 1D 56 1D 58 1D 5A |$..V.X.Z| 1C30:1D 64 1D 66 1D 6C 1D 70 |.d.f.l.p| 1C38:1D 78 1D 7C 1D 7E 1D 80 |.x.|.~..| 1C40:1D C1 2A FD 2A E4 37 E8 |.A*}*d7h| 1C48:37 EE 37 F0 37 00 00 00 |7n7p7...| 1C50:00 00 00 00 00 00 00 00 |........| 1C58:00 20 84 1D 84 28 FD 2A |. ...(}*| 1C60:97 33 5D 36 E0 37 56 3C |.3]6`7V<| 1C68:DF 3C 00 38 11 3A 69 3A |_<.8.:i:| 1C70:84 3A 00 3D A8 3F C8 3F |.:.=(?H?| 1C78:FF 3F 1D 40 00 00 23 00 |.?.@..#.| 1C80:23 FC FC FC FC FC FC FD |#||||||}| DOSINIT, $1C81 .. $1E80, T0SB - T0SD 1C88:FC FC FF FC FD FC FC FF |||.|}||.| 1C90:FF FC FE FD FE FD FD FE |.|~}~}}~| 1C98:FF FC FE FF FD FE FF FD |.|~.}~.}| 1CA0:FC FD FD FC FD FE FD FF ||}}|}~}.| 1CA8:FC FE FC FC FC FC FC FC ||~||||||| 1CB0:FD FC FC FE FC FD FC FC |}||~|}||| 1CB8:FF FC FC FE FD FC FD FF |.||~}|}.| 1CC0:FC FF FD FE FF FD FF FC ||.}~.}.|| 1CC8:FC FD FE FF FF FF FC FC ||}~...||| 1CD0:FF FF FC FE FD FC FD FD |..|~}|}}| 1CD8:FE FF FD FE FF FC FE FE |~.}~.|~~| 1CE0:FC FD FC FD FE FD FD FC ||}|}~}}|| 1CE8:FD FC FF FD FC FF FC FC |}|.}|.||| 1CF0:FE FD FC FC FD FC FE FC |~}||}|~|| 1CF8:FC FD FF FC FC FD FC FC ||}.||}||| 1D00:D3 1C 81 1E BD 1E 75 2A |S...=.u*| T0SC 1D08:93 2A 60 2A 00 1B BB 35 |.*`*..;5| 1D10:EA 1E 11 1F 22 1F 2E 1F |j..."...| 1D18:51 1F 60 1F 70 1F 4E 25 |Q.`.p.N%| 1D20:12 24 96 23 D0 24 EF 24 |.$.#P$o$| 1D28:62 22 70 22 74 22 E9 22 |b"p"t"i"| 1D30:1A 25 C5 25 0F 25 DC 25 |.%E%.%%| 1D38:A2 22 97 22 80 22 6D 25 |""."."m%| 1D40:32 22 3C 22 28 22 2D 22 |2"<"("-"| 1D48:50 22 79 25 9D 25 30 23 |P"y%.%0#| 1D50:5C 23 8D 23 7C 22 36 E8 |#.#|"6h| 1D58:E5 24 E3 E3 00 E0 03 E0 |e$cc.`.`| 1D60:00 00 36 E8 E5 24 E3 E3 |..6he$cc| 1D68:00 E0 03 E0 FC 24 FC 24 |.`.`|$|$| 1D70:65 D8 00 E0 3C D4 F2 D4 |eX.`06 25 06 25 67 10 84 1D |.%.%g...| 1D80:3C 0C F2 0C AD E9 37 4A |<.r.-i7J| 1D88:4A 4A 4A 8D 6A 2A AD EA |JJJ.j*-j| 1D90:37 8D 68 2A AD 00 E0 49 |7.h*-.`I| 1D98:20 D0 11 8D B6 2A A2 0A | P..6*".| 1DA0:BD 61 1D 9D 55 1D CA D0 |=a..U.JP| 1DA8:F7 4C BC 1D A9 40 8D B6 |wL<.)@.6| 1DB0:2A A2 0C BD 6B 1D 9D 55 |*".=k..U| 1DB8:1D CA D0 F7 38 B0 12 AD |.JPw80.-| 1DC0:B6 2A D0 04 A9 20 D0 05 |6*P.) P.| 1DC8:0A 10 05 A9 4C 20 B2 25 |...)L 2%| 1DD0:18 08 20 51 28 A9 00 8D |.. Q()..| 1DD8:5E 2A 8D 52 2A 28 6A 8D |^*.R*(j.| 1DE0:51 2A 30 03 6C 5E 1D 6C |Q*0.l^.l| 1DE8:5C 1D 0A 10 19 8D B6 2A |.....6*| 1DF0:A2 0C BD 77 1D 9D 55 1D |".=w..U.| 1DF8:CA D0 F7 A2 1D BD 93 2A |JPw".=.*| 1E00:9D 75 2A CA 10 F7 AD B1 |.u*J.w-1| T0SD 1E08:2A 8D 57 2A 20 D4 27 AD |*.W* T'-| 1E10:B3 2A F0 09 48 20 9D 26 |3*p.H .&| 1E18:68 A0 00 91 40 20 5B 27 |h ..@ ['| 1E20:AD 5F 2A D0 20 A2 2F BD |-_*P "/=| 1E28:51 1E 9D D0 03 CA 10 F7 |Q..P.J.w| 1E30:AD 53 1E 8D F3 03 49 A5 |-S..s.I%| 1E38:8D F4 03 AD 52 1E 8D F2 |.t.-R..r| 1E40:03 A9 06 D0 05 AD 62 2A |.).P.-b*| 1E48:F0 06 8D 5F 2A 4C 80 21 |p.._*L.!| 1E50:60 4C BF 1D 4C 84 1D 4C |`L?.L..L| 1E58:FD 2A 4C B5 37 AD 0F 1D |}*L57-..| 1E60:AC 0E 1D 60 AD C2 2A AC |,..`-B*,| 1E68:C1 2A 60 4C 51 28 EA EA |A*`LQ(jj| 1E70:4C 59 FA 4C 65 FF 4C 58 |LYzLe.LX| 1E78:FF 4C 65 FF 4C 65 FF 65 |.Le.Le.e| 1E80:FF 20 D1 1E AD 51 2A F0 |. Q.-Q*p| DOSHOOK, $1E81 - $1FCC, T0SD - T0SE 1E88:15 48 AD 5C 2A 91 28 68 |.H-*.(h| 1E90:30 03 4C 26 26 20 EA 1D |0.L&& j.| 1E98:A4 24 A9 60 91 28 AD B3 |$$)`.(-3| 1EA0:2A F0 03 20 82 26 A9 03 |*p. .&).| 1EA8:8D 52 2A 20 BA 1F 20 BA |.R* :. :| 1EB0:1E 8D 5C 2A 8E 5A 2A 4C |..*.Z*L| 1EB8:B3 1F 6C 38 00 20 D1 1E |3.l8. Q.| 1EC0:AD 52 2A 0A AA BD 11 1D |-R*.*=..| 1EC8:48 BD 10 1D 48 AD 5C 2A |H=..H-*| 1ED0:60 8D 5C 2A 8E 5A 2A 8C |`.*.Z*.| 1ED8:5B 2A BA E8 E8 8E 59 2A |[*:hh.Y*| 1EE0:A2 03 BD 53 2A 95 36 CA |".=S*.6J| 1EE8:10 F8 60 AE B7 2A F0 03 |.x`.7*p.| 1EF0:4C 78 1F AE 51 2A F0 08 |Lx..Q*p.| 1EF8:C9 BF F0 75 C5 33 F0 27 |I?puE3p'| 1F00:A2 02 8E 52 2A CD B2 2A |"..R*M2*| T0SE 1F08:D0 19 CA 8E 52 2A CA 8E |P.J.R*J.| 1F10:5D 2A AE 5D 2A 9D 00 02 |]*.]*...| 1F18:E8 8E 5D 2A C9 8D D0 75 |h.]*I.Pu| 1F20:4C CD 1F C9 8D D0 7D A2 |LM.I.P}"| 1F28:00 8E 52 2A 4C A4 1F A2 |..R*L$."| 1F30:00 8E 52 2A C9 8D F0 07 |..R*I.p.| 1F38:AD B3 2A F0 67 D0 5E 48 |-3*pgP^H| 1F40:38 AD B3 2A D0 03 20 5E |8-3*P. ^| 1F48:26 68 90 EC AE 5A 2A 4C |&h.l.Z*L| 1F50:15 1F C9 8D D0 05 A9 05 |..I.P.).| 1F58:8D 52 2A 20 0E 26 4C 99 |.R* .&L.| 1F60:1F CD B2 2A F0 85 C9 8A |.M2*p.I.| 1F68:F0 F1 A2 04 8E 52 2A D0 |pq"..R*P| 1F70:E1 A9 00 8D 52 2A F0 25 |a)..R*p%| 1F78:A9 00 8D B7 2A 20 51 28 |)..7* Q(| 1F80:4C DC 24 AD 00 02 CD B2 |L$-..M2| 1F88:2A F0 0A A9 8D 8D 00 02 |*p.)....| 1F90:A2 00 8E 5A 2A A9 40 D0 |"..Z*)@P| 1F98:06 A9 10 D0 02 A9 20 2D |.).P.) -| 1FA0:5E 2A F0 0F 20 BA 1F 20 |^*p. :. | 1FA8:C5 1F 8D 5C 2A 8C 5B 2A |E..*.[*| 1FB0:8E 5A 2A 20 51 28 AE 59 |.Z* Q(.Y| 1FB8:2A 9A AD 5C 2A AC 5B 2A |*.-*,[*| 1FC0:AE 5A 2A 38 60 6C 36 00 |.Z*8`l6.| 1FC8:A9 8D 4C C5 1F A0 FF 8C |).LE. ..| CMDSCAN, $1FCD .. $2192, T0SE - T1S0 1FD0:5F 2A C8 8C 62 2A EE 5F |_*H.b*n_| 1FD8:2A A2 00 08 BD 00 02 CD |*"..=..M| 1FE0:B2 2A D0 01 E8 8E 5D 2A |2*P.h.]*| 1FE8:20 A4 21 29 7F 59 84 28 | $!).Y.(| 1FF0:C8 0A F0 02 68 08 90 F0 |H.p.h..p| 1FF8:28 F0 20 B9 84 28 D0 D6 |(p 9.(PV| 2000:AD 00 02 CD B2 2A F0 03 |-..M2*p.| T0SF 2008:4C A4 1F AD 01 02 C9 8D |L$.-..I.| 2010:D0 06 20 5B 27 4C 95 1F |P. ['L..| 2018:4C C4 26 0E 5F 2A AC 5F |LD&._*,_| 2020:2A 20 5E 26 90 0C A9 02 |* ^&..).| 2028:39 09 29 F0 05 A9 0F 4C |9.)p.).L| 2030:D2 26 C0 06 D0 02 84 33 |R&@.P..3| 2038:A9 20 39 09 29 F0 61 20 |) 9.)pa | 2040:95 20 08 20 A4 21 F0 1E |. . $!p.| 2048:0A 90 05 30 03 4C 00 20 |...0.L. | 2050:6A 4C 59 20 20 93 21 F0 |jLY .!p| 2058:0D 99 75 2A C8 C0 3C 90 |..u*H@<.| 2060:F3 20 93 21 D0 FB 28 D0 |s .!P{(P| 2068:0F AC 5F 2A A9 10 39 09 |.,_*).9.| 2070:29 F0 0C A0 1E 08 D0 CB |)p. ..PK| 2078:AD 93 2A C9 A0 F0 13 AD |-.*I p.-| 2080:75 2A C9 A0 D0 4B AC 5F |u*I PK,_| 2088:2A A9 C0 39 09 29 F0 02 |*)@9.)p.| 2090:10 3F 4C 00 20 A0 3C A9 |.?L. <)| 2098:A0 99 74 2A 88 D0 FA 60 | .t*.Pz`| 20A0:8D 75 2A A9 0C 39 09 29 |.u*).9.)| 20A8:F0 27 20 B9 21 B0 1F A8 |p' 9!0.(| 20B0:D0 17 E0 11 B0 13 AC 5F |P.`.0.,_| 20B8:2A A9 08 39 09 29 F0 06 |*).9.)p.| 20C0:E0 08 B0 CE 90 0B 8A D0 |`.0N...P| 20C8:08 A9 02 4C D2 26 4C C4 |.).LR&LD| 20D0:26 A9 00 8D 65 2A 8D 74 |&)..e*.t| 20D8:2A 8D 66 2A 8D 6C 2A 8D |*.f*.l*.| 20E0:6D 2A 20 DC 3F AD 5D 2A |m* ?-]*| 20E8:20 A4 21 D0 1F C9 8D D0 | $!P.I.P| 20F0:F7 AE 5F 2A AD 65 2A 1D |w._*-e*.| 20F8:0A 29 5D 0A 29 D0 93 AE |.)].)P..| 2100:63 2A F0 76 8D 63 2A 8E |c*pv.c*.| T1S0 2108:5D 2A D0 DC A2 0A DD 40 |]*P\".]@| 2110:29 F0 05 CA D0 F8 F0 B6 |)p.JPxp6| 2118:BD 4A 29 30 47 0D 65 2A |=J)0G.e*| 2120:8D 65 2A CA 8E 64 2A 20 |.e*J.d* | 2128:B9 21 B0 A2 AD 64 2A 0A |9!0"-d*.| 2130:0A A8 A5 45 D0 09 A5 44 |.(%EP.%D| 2138:D9 55 29 90 8C A5 45 D9 |YU)..%EY| 2140:58 29 90 0B D0 83 A5 44 |X)..P.%D| 2148:D9 57 29 90 02 D0 F5 AD |YW)..Pu-| 2150:63 2A D0 94 98 4A A8 A5 |c*P..J(%| 2158:45 99 67 2A A5 44 99 66 |E.g*%D.f| 2160:2A 4C E8 20 48 A9 80 0D |*Lh H)..| 2168:65 2A 8D 65 2A 68 29 7F |e*.e*h).| 2170:0D 74 2A 8D 74 2A D0 E9 |.t*.t*Pi| 2178:F0 9C 20 80 21 4C 83 1F |p. .!L..| 2180:20 5B 27 20 AE 21 AD 5F | [' .!-_| 2188:2A AA BD 1F 1D 48 BD 1E |**=..H=.| 2190:1D 48 60 AE 5D 2A BD 00 |.H`.]*=.| XOPNCLS, $2193 .. $2330, T1S0 - T1S2 2198:02 C9 8D F0 06 E8 8E 5D |.I.p.h.]| 21A0:2A C9 AC 60 20 93 21 F0 |*I,` .!p| 21A8:FA C9 A0 F0 F7 60 A9 00 |zI pw`).| 21B0:A0 16 99 BA 35 88 D0 FA | ..:5.Pz| 21B8:60 A9 00 85 44 85 45 20 |`)..D.E | 21C0:A4 21 08 C9 A4 F0 3C 28 |$!.I$p<(| 21C8:4C CE 21 20 A4 21 D0 06 |LN! $!P.| 21D0:A6 44 A5 45 18 60 38 E9 |&D%E.`8i| 21D8:B0 30 21 C9 0A B0 1D 20 |00!I.0. | 21E0:FE 21 65 44 AA A9 00 65 |~!eD*).e| 21E8:45 A8 20 FE 21 20 FE 21 |E( ~! ~!| 21F0:8A 65 44 85 44 98 65 45 |.eD.D.eE| 21F8:85 45 90 CF 38 60 06 44 |.E.O8`.D| 2200:26 45 60 28 20 A4 21 F0 |&E`( $!p| T1S1 2208:C5 38 E9 B0 30 EE C9 0A |E8i00nI.| 2210:90 08 E9 07 30 E6 C9 10 |..i.0fI.| 2218:B0 E2 A2 04 20 FE 21 CA |0b". ~!J| 2220:D0 FA 05 44 85 44 4C 04 |Pz.D.DL.| 2228:22 A5 44 4C 95 FE A5 44 |"%DL.~%D| 2230:4C 8B FE AD 5E 2A 0D 74 |L.~-^*.t| 2238:2A 8D 5E 2A 60 2C 74 2A |*.^*`,t*| 2240:50 03 20 C8 1F A9 70 4D |P. H.)pM| 2248:74 2A 2D 5E 2A 8D 5E 2A |t*-^*.^*| 2250:60 A9 00 8D B3 2A A5 44 |`)..3*%D| 2258:48 20 16 23 68 8D 57 2A |H .#h.W*| 2260:4C D4 27 A9 05 20 AA 22 |LT'). *"| 2268:20 64 27 A0 00 98 91 40 | d' ...@| 2270:60 A9 07 D0 02 A9 08 20 |`).P.). | 2278:AA 22 4C EA 22 A9 0C D0 |*"Lj").P| 2280:F6 AD 08 1D 8D BD 35 AD |v-...=5-| 2288:09 1D 8D BE 35 A9 09 8D |...>5)..| 2290:63 2A 20 C8 22 4C EA 22 |c* H"Lj"| 2298:20 A3 22 20 8C 26 D0 FB | #" .&P{| 22A0:4C 71 36 A9 00 4C D5 23 |Lq6).LU#| 22A8:A9 01 8D 63 2A AD 6C 2A |)..c*-l*| 22B0:D0 0A AD 6D 2A D0 05 A9 |P.-m*P.)| 22B8:01 8D 6C 2A AD 6C 2A 8D |..l*-l*.| 22C0:BD 35 AD 6D 2A 8D BE 35 |=5-m*.>5| 22C8:20 EA 22 A5 45 D0 03 4C | j"%EP.L| 22D0:C8 26 85 41 A5 44 85 40 |H&.A%D.@| 22D8:20 43 27 20 4E 27 20 1A | C' N' .| 22E0:27 AD 63 2A 8D BB 35 4C |'-c*.;5L| 22E8:A8 26 AD 75 2A C9 A0 F0 |(&-u*I p| 22F0:25 20 64 27 B0 3A 20 FC |% d'0: || 22F8:22 4C EA 22 20 AF 27 D0 |"Lj" /'P| 2300:05 A9 00 8D B3 2A A0 00 |.)..3* .| T1S2 2308:98 91 40 20 4E 27 A9 02 |..@ N').| 2310:8D BB 35 4C A8 26 20 92 |.;5L(& .| 2318:27 D0 05 20 9A 27 F0 10 |'P. .'p.| 2320:20 AF 27 F0 F6 20 AA 27 | /'pv *'| 2328:F0 F1 20 FC 22 4C 16 23 |pq |"L.#| 2330:60 A9 09 2D 65 2A C9 09 |`).-e*I.| XLODSAV, $2331 .. $250F, T1S2 - T1S4 2338:F0 03 4C 00 20 A9 04 20 |p.L. ). | 2340:D5 23 AD 73 2A AC 72 2A |U#-s*,r*| 2348:20 E0 23 AD 6D 2A AC 6C | `#-m*,l| 2350:2A 20 E0 23 AD 73 2A AC |* `#-s*,| 2358:72 2A 4C FF 23 20 A8 22 |r*L.# ("| 2360:A9 7F 2D C2 35 C9 04 F0 |).-B5I.p| 2368:03 4C D0 26 A9 04 20 D5 |.LP&). U| 2370:23 20 7A 24 AA AD 65 2A |# z$*-e*| 2378:29 01 D0 06 8E 72 2A 8C |).P..r*.| 2380:73 2A 20 7A 24 AE 72 2A |s* z$.r*| 2388:AC 73 2A 4C 71 24 20 5D |,s*Lq$ ]| 2390:23 20 51 28 6C 72 2A AD |# Q(lr*-| 2398:B6 2A F0 20 A5 D6 10 03 |6*p %V..| 23A0:4C CC 26 A9 02 20 D5 23 |LL&). U#| 23A8:38 A5 AF E5 67 A8 A5 B0 |8%/eg(%0| 23B0:E5 68 20 E0 23 A5 68 A4 |eh `#%h$| 23B8:67 4C FF 23 A9 01 20 D5 |gL.#). U| 23C0:23 38 A5 4C E5 CA A8 A5 |#8%LeJ(%| 23C8:4D E5 CB 20 E0 23 A5 CB |MeK `#%K| 23D0:A4 CA 4C FF 23 8D C2 35 |$JL.#.B5| 23D8:48 20 A8 22 68 4C C4 27 |H ("hLD'| 23E0:8C C1 35 8C C3 35 8D C2 |.A5.C5.B| 23E8:35 A9 04 8D BB 35 A9 01 |5)..;5).| 23F0:8D BC 35 20 A8 26 AD C2 |.<5 (&-B| 23F8:35 8D C3 35 4C A8 26 8C |5.C5L(&.| 2400:C3 35 8D C4 35 A9 02 4C |C5.D5).L| T1S3 2408:86 36 20 A8 26 4C EA 22 |.6 (&Lj"| 2410:4C D0 26 20 16 23 20 A8 |LP& .# (| 2418:22 A9 23 2D C2 35 F0 F0 |")#-B5pp| 2420:8D C2 35 AD B6 2A F0 28 |.B5-6*p(| 2428:A9 02 20 B1 24 20 7A 24 |). 1$ z$| 2430:18 65 67 AA 98 65 68 C5 |.eg*.ehE| 2438:74 B0 70 85 B0 85 6A 86 |t0p.0.j.| 2440:AF 86 69 A6 67 A4 68 20 |/.i&g$h | 2448:71 24 20 51 28 6C 60 1D |q$ Q(l`.| 2450:A9 01 20 B1 24 20 7A 24 |). 1$ z$| 2458:38 A5 4C ED 60 2A AA A5 |8%Lm`**%| 2460:4D ED 61 2A 90 45 A8 C4 |Mma*.E(D| 2468:4B 90 40 F0 3E 84 CB 86 |K.@p>.K.| 2470:CA 8E C3 35 8C C4 35 4C |J.C5.D5L| 2478:0A 24 AD 0A 1D 8D C3 35 |.$-...C5| 2480:AD 0B 1D 8D C4 35 A9 00 |-...D5).| 2488:8D C2 35 A9 02 8D C1 35 |.B5)..A5| 2490:A9 03 8D BB 35 A9 02 8D |)..;5)..| 2498:BC 35 20 A8 26 AD 61 2A |<5 (&-a*| 24A0:8D C2 35 A8 AD 60 2A 8D |.B5(-`*.| 24A8:C1 35 60 20 EA 22 4C CC |A5` j"LL| 24B0:26 CD C2 35 F0 1A AE 5F |&MB5p.._| 24B8:2A 8E 62 2A 4A F0 03 4C |*.b*Jp.L| 24C0:9E 25 A2 1D BD 75 2A 9D |.%".=u*.| 24C8:93 2A CA 10 F7 4C 7A 25 |.*J.wLz%| 24D0:60 AD B6 2A F0 03 8D B7 |`-6*p..7| 24D8:2A 20 13 24 20 C8 1F 20 |* .$ H. | 24E0:51 28 6C 58 1D A5 4A 85 |Q(lX.%J.| 24E8:CC A5 4B 85 CD 6C 56 1D |L%K.MlV.| 24F0:20 16 24 20 C8 1F 20 51 | .$ H. Q| 24F8:28 6C 56 1D 20 65 D6 85 |(lV. eV.| 2500:33 85 D8 4C D2 D7 20 65 |3.XLRW e| T1S4 2508:0E 85 33 85 D8 4C D4 0F |..3.XLT.| 2510:20 26 25 A9 05 8D 52 2A | &%)..R*| XMISCMD, $2510 .. $26A7, T1S4 - T1S5 2518:4C 83 1F 20 26 25 A9 01 |L.. &%).| 2520:8D 51 2A 4C 83 1F 20 64 |.Q*L.. d| 2528:27 90 06 20 A3 22 4C 34 |'.. #"L4| 2530:25 20 4E 27 AD 65 2A 29 |% N'-e*)| 2538:06 F0 13 A2 03 BD 6E 2A |.p.".=n*| 2540:9D BD 35 CA 10 F7 A9 0A |.=5J.w).| 2548:8D BB 35 20 A8 26 60 A9 |.;5 (&`)| 2550:40 2D 65 2A F0 05 AD 66 |@-e*p.-f| 2558:2A D0 05 A9 FE 8D 66 2A |*P.)~.f*| 2560:AD 0D 1D 8D BC 35 A9 0B |-...<5).| 2568:20 AA 22 4C 97 23 A9 06 | *"L.#).| 2570:20 AA 22 AD BF 35 8D 66 | *"-?5.f| 2578:2A 60 A9 4C 20 B2 25 F0 |*`)L 2%p| 2580:2E A9 00 8D B6 2A A0 1E |.)..6* .| 2588:20 97 20 A2 09 BD B7 2A | . ".=7*| 2590:9D 74 2A CA D0 F7 A9 C0 |.t*JPw)@| 2598:8D 51 2A 4C D1 24 A9 20 |.Q*LQ$) | 25A0:20 B2 25 F0 05 A9 01 4C | 2%p.).L| 25A8:D2 26 A9 00 8D B7 2A 4C |R&)..7*L| 25B0:84 1D CD 00 E0 F0 0E 8D |..M.`p..| 25B8:80 C0 CD 00 E0 F0 06 8D |.@M.`p..| 25C0:81 C0 CD 00 E0 60 20 A3 |.@M.`` #| 25C8:22 AD 4F 2A 8D B4 2A AD |"-O*.4*-| 25D0:50 2A 8D B5 2A AD 75 2A |P*.5*-u*| 25D8:8D B3 2A D0 0E 20 64 27 |.3*P. d'| 25E0:90 06 20 A3 22 4C EB 25 |.. #"Lk%| 25E8:20 4E 27 AD 65 2A 29 04 | N'-e*).| 25F0:F0 1B AD 6E 2A D0 08 AE |p.-n*P..| 25F8:6F 2A F0 11 CE 6F 2A CE |o*p.No*N| 2600:6E 2A 20 8C 26 F0 38 C9 |n* .&p8I| T1S5 2608:8D D0 F7 F0 E5 60 20 5E |.Pwpe` ^| 2610:26 B0 66 AD 5C 2A 8D C3 |&0f-*.C| 2618:35 A9 04 8D BB 35 A9 01 |5)..;5).| 2620:8D BC 35 4C A8 26 20 5E |.<5L(& ^| 2628:26 B0 4E A9 06 8D 52 2A |&0N)..R*| 2630:20 8C 26 D0 0F 20 FC 22 | .&P. |"| 2638:A9 03 CD 52 2A F0 CE A9 |).MR*pN)| 2640:05 4C D2 26 C9 E0 90 02 |.LR&I`..| 2648:29 7F 8D 5C 2A AE 5A 2A |)..*.Z*| 2650:F0 09 CA BD 00 02 09 80 |p.J=....| 2658:9D 00 02 4C B3 1F 48 AD |...L3.H-| 2660:B6 2A F0 0E A6 76 E8 F0 |6*p.&vhp| 2668:0D A6 33 E0 DD F0 07 68 |.&3`]p.h| 2670:18 60 A5 D9 30 F9 68 38 |.`%Y0yh8| 2678:60 20 FC 22 20 5B 27 4C |` |" ['L| 2680:B3 1F 20 9D 26 20 4E 27 |3. .& N'| 2688:A9 03 D0 A1 A9 03 8D BB |).P!)..;| 2690:35 A9 01 8D BC 35 20 A8 |5)..<5 (| 2698:26 AD C3 35 60 AD B5 2A |&-C5`-5*| 26A0:85 41 AD B4 2A 85 40 60 |.A-4*.@`| 26A8:20 06 2B 90 16 AD C5 35 | .+..-E5| DOSGOER, $26A8 .. $27D3, T1S5 - T1S6 26B0:C9 05 F0 03 4C 5E 36 4C |I.p.L^6L| 26B8:92 36 EA 20 69 3A A2 00 |.6j i:".| 26C0:8E C3 35 60 A9 0B D0 0A |.C5`).P.| 26C8:A9 0C D0 06 A9 0E D0 02 |).P.).P.| 26D0:A9 0D 8D 5C 2A 20 E6 3F |)..* f?| 26D8:AD B6 2A F0 04 A5 D8 30 |-6*p.%X0| 26E0:0E A2 00 20 02 27 AE 5C |.". .'.| 26E8:2A 20 02 27 20 C8 1F 20 |* .' H. | 26F0:51 28 20 5E 26 AE 5C 2A |Q( ^&.*| 26F8:A9 03 B0 03 6C 5A 1D 6C |).0.lZ.l| 2700:5E 1D BD 3F 2A AA 8E 63 |^.=?**.c| T1S6 2708:2A BD 71 29 48 09 80 20 |*=q)H.. | 2710:C5 1F AE 63 2A E8 68 10 |E..c*hh.| 2718:ED 60 AD 66 2A 8D BF 35 |m`-f*.?5| 2720:AD 68 2A 8D C0 35 AD 6A |-h*.@5-j| 2728:2A 8D C1 35 AD 06 1D 8D |*.A5-...| 2730:C3 35 AD 07 1D 8D C4 35 |C5-...D5| 2738:A5 40 8D 4F 2A A5 41 8D |%@.O*%A.| 2740:50 2A 60 A0 1D B9 75 2A |P*` .9u*| 2748:91 40 88 10 F8 60 A0 1E |.@..x` .| 2750:B1 40 99 A9 35 C8 C0 26 |1@.)5H@&| 2758:D0 F6 60 A0 00 8C 51 2A |Pv` ..Q*| 2760:8C 52 2A 60 A9 00 85 45 |.R*`)..E| 2768:20 92 27 4C 73 27 20 9A | .'Ls' .| 2770:27 F0 1D 20 AA 27 D0 0A |'p. *'P.| 2778:A5 40 85 44 A5 41 85 45 |%@.D%A.E| 2780:D0 EC A0 1D B1 40 D9 75 |Pl .1@Yu| 2788:2A D0 E3 88 10 F6 18 60 |*Pc..v.`| 2790:38 60 AD 00 1D AE 01 1D |8`-.....| 2798:D0 0A A0 25 B1 40 F0 09 |P. %1@p.| 27A0:AA 88 B1 40 86 41 85 40 |*.1@.A.@| 27A8:8A 60 A0 00 B1 40 60 AD |.` .1@`-| 27B0:B3 2A F0 0E AD B4 2A C5 |3*p.-4*E| 27B8:40 D0 08 AD B5 2A C5 41 |@P.-5*EA| 27C0:F0 01 CA 60 4D C2 35 F0 |p.J`MB5p| 27C8:0A 29 7F F0 06 20 EA 22 |.).p. j"| 27D0:4C D0 26 60 38 AD 00 1D |LP&`8-..| BLDFTAB, $27D4 .. $2883, T1S6 - T1S7 27D8:85 40 AD 01 1D 85 41 AD |.@-...A-| 27E0:57 2A 8D 63 2A A0 00 98 |W*.c* ..| 27E8:91 40 A0 1E 38 A5 40 E9 |.@ .8%@i| 27F0:2D 91 40 48 A5 41 E9 00 |-.@H%Ai.| 27F8:C8 91 40 AA CA 68 48 C8 |H.@*JhHH| 2800:91 40 8A C8 91 40 AA CA |.@.H.@*J| T1S7 2808:68 48 C8 91 40 C8 8A 91 |hHH.@H..| 2810:40 CE 63 2A F0 17 AA 68 |@Nc*p.*h| 2818:38 E9 26 C8 91 40 48 8A |8i&H.@H.| 2820:E9 00 C8 91 40 85 41 68 |i.H.@.Ah| 2828:85 40 4C E5 27 48 A9 00 |.@Le'H).| 2830:C8 91 40 C8 91 40 AD B6 |H.@H.@-6| 2838:2A F0 0B 68 85 74 85 70 |*p.h.t.p| 2840:68 85 73 85 6F 60 68 85 |h.s.o`h.| 2848:4D 85 CB 68 85 4C 85 CA |M.Kh.L.J| 2850:60 A5 39 CD 03 1D F0 12 |`%9M..p.| 2858:8D 56 2A A5 38 8D 55 2A |.V*%8.U*| 2860:AD 02 1D 85 38 AD 03 1D |-...8-..| 2868:85 39 A5 37 CD 05 1D F0 |.9%7M..p| 2870:12 8D 54 2A A5 36 8D 53 |..T*%6.S| 2878:2A AD 04 1D 85 36 AD 05 |*-...6-.| 2880:1D 85 37 60 49 4E 49 D4 |..7`INIT| CMDTBLS, $2884 .. $2A4E, T1S7 - T1S9 2888:4C 4F 41 C4 53 41 56 C5 |LOADSAVE| 2890:52 55 CE 43 48 41 49 CE |RUNCHAIN| 2898:44 45 4C 45 54 C5 4C 4F |DELETELO| 28A0:43 CB 55 4E 4C 4F 43 CB |CKUNLOCK| 28A8:43 4C 4F 53 C5 52 45 41 |CLOSEREA| 28B0:C4 45 58 45 C3 57 52 49 |DEXECWRI| 28B8:54 C5 50 4F 53 49 54 49 |TEPOSITI| 28C0:4F CE 4F 50 45 CE 41 50 |ONOPENAP| 28C8:50 45 4E C4 52 45 4E 41 |PENDRENA| 28D0:4D C5 43 41 54 41 4C 4F |MECATALO| 28D8:C7 4D 4F CE 4E 4F 4D 4F |GMONNOMO| 28E0:CE 50 52 A3 49 4E A3 4D |NPR#IN#M| 28E8:41 58 46 49 4C 45 D3 46 |AXFILESF| 28F0:D0 49 4E D4 42 53 41 56 |PINTBSAV| 28F8:C5 42 4C 4F 41 C4 42 52 |EBLOADBR| 2900:55 CE 56 45 52 49 46 D9 |UNVERIFY| T1S8 2908:00 21 70 A0 70 A1 70 A0 |.!p p!p | 2910:70 20 70 20 70 20 70 20 |p p p p | 2918:70 60 00 22 06 20 74 22 |p`.". t"| 2920:06 22 04 23 78 22 70 30 |.".#x"p0| 2928:70 40 70 40 80 40 80 08 |p@p@.@..| 2930:00 08 00 04 00 40 70 40 |.....@p@| 2938:00 21 79 20 71 20 71 20 |.!y q q | 2940:70 D6 C4 D3 CC D2 C2 C1 |pVDSLRBA| 2948:C3 C9 CF 40 20 10 08 04 |CIO@ ...| 2950:02 01 C0 A0 90 00 00 FE |..@ ...~| 2958:00 01 00 02 00 01 00 07 |........| 2960:00 01 00 FF 7F 00 00 FF |........| 2968:7F 00 00 FF 7F 00 00 FF |........| 2970:FF 0D 07 8D 4C 41 4E 47 |....LANG| 2978:55 41 47 45 20 4E 4F 54 |UAGE NOT| 2980:20 41 56 41 49 4C 41 42 | AVAILAB| 2988:4C C5 52 41 4E 47 45 20 |LERANGE | 2990:45 52 52 4F D2 57 52 49 |ERRORWRI| 2998:54 45 20 50 52 4F 54 45 |TE PROTE| 29A0:43 54 45 C4 45 4E 44 20 |CTEDEND | 29A8:4F 46 20 44 41 54 C1 46 |OF DATAF| 29B0:49 4C 45 20 4E 4F 54 20 |ILE NOT | 29B8:46 4F 55 4E C4 56 4F 4C |FOUNDVOL| 29C0:55 4D 45 20 4D 49 53 4D |UME MISM| 29C8:41 54 43 C8 49 2F 4F 20 |ATCHI/O | 29D0:45 52 52 4F D2 44 49 53 |ERRORDIS| 29D8:4B 20 46 55 4C CC 46 49 |K FULLFI| 29E0:4C 45 20 4C 4F 43 4B 45 |LE LOCKE| 29E8:C4 53 59 4E 54 41 58 20 |DSYNTAX | 29F0:45 52 52 4F D2 4E 4F 20 |ERRORNO | 29F8:42 55 46 46 45 52 53 20 |BUFFERS | 2A00:41 56 41 49 4C 41 42 4C |AVAILABL| T1S9 2A08:C5 46 49 4C 45 20 54 59 |EFILE TY| 2A10:50 45 20 4D 49 53 4D 41 |PE MISMA| 2A18:54 43 C8 50 52 4F 47 52 |TCHPROGR| 2A20:41 4D 20 54 4F 4F 20 4C |AM TOO L| 2A28:41 52 47 C5 4E 4F 54 20 |ARGENOT | 2A30:44 49 52 45 43 54 20 43 |DIRECT C| 2A38:4F 4D 4D 41 4E C4 8D 00 |OMMAND..| 2A40:03 19 19 24 33 3E 4C 5B |...$3>L[| 2A48:64 6D 78 84 98 AA BB 00 |dmx..*;.| FDOSENT, $2A4F .. $2B21, T1S9 - T1SA 2A50:00 00 00 00 00 00 00 00 |........| 2A58:03 00 00 00 00 00 00 00 |........| 2A60:00 00 00 00 00 00 00 00 |........| 2A68:00 00 00 00 01 00 00 00 |........| 2A70:00 00 00 00 00 C8 C5 CC |.....HEL| 2A78:CC CF A0 A0 A0 A0 A0 A0 |LO | 2A80:A0 A0 A0 A0 A0 A0 A0 A0 | | 2A88:A0 A0 A0 A0 A0 A0 A0 A0 | | 2A90:A0 A0 A0 A0 A0 A0 A0 A0 | | 2A98:A0 A0 A0 A0 A0 A0 A0 A0 | | 2AA0:A0 A0 A0 A0 A0 A0 A0 A0 | | 2AA8:A0 A0 A0 A0 A0 A0 A0 A0 | | 2AB0:A0 03 84 00 00 00 00 00 | .......| 2AB8:C1 D0 D0 CC C5 D3 CF C6 |APPLESOF| 2AC0:D4 E8 37 BB 33 BB 34 00 |Th7;3;4.| 2AC8:40 7E 33 21 2B 05 2C 57 |@~3!+.,W| 2AD0:2C 6F 2C 2A 2D 97 2D EE |,o,*-.-n| 2AD8:2C F5 2C 39 2C 11 2D 8D |,u,9,.-.| 2AE0:2E 17 2D 7E 33 7E 33 89 |..-~3~3.| 2AE8:2C 95 2C 86 2C 92 2C 7E |,.,.,.,~| 2AF0:33 7E 33 BD 2C C9 2C BA |3~3=,I,:| 2AF8:2C C6 2C 7E 33 E0 00 F0 |,F,~3`.p| 2B00:02 A2 02 8E 5F 2A BA 8E |.".._*:.| T1SA 2B08:9B 33 20 6A 2E AD BB 35 |.3 j.-;5| 2B10:C9 0D B0 0B 0A AA BD CA |I.0..*=J| 2B18:2A 48 BD C9 2A 48 60 4C |*H=I*H`L| 2B20:63 33 20 28 2B 4C 7F 33 |c3 (+L.3| FOPCLRW, $2B22 .. $2CEE, T1SA - T1SB 2B28:20 DC 2B A9 01 8D E3 35 | +)..c5| 2B30:AE BE 35 AD BD 35 D0 05 |.>5-=5P.| 2B38:E0 00 D0 01 E8 8D E8 35 |`.P.h.h5| 2B40:8E E9 35 20 C9 31 90 5E |.i5 I1.^| 2B48:8E 9C 33 AE 5F 2A BD 09 |..3._*=.| 2B50:29 AE 9C 33 4A B0 0D AD |)..3J0.-| 2B58:51 2A C9 C0 D0 03 4C 5F |Q*I@P.L_| 2B60:33 4C 73 33 A9 00 9D E8 |3Ls3)..h| 2B68:34 A9 01 9D E7 34 8E 9C |4)..g4..| 2B70:33 20 44 32 AE 9C 33 9D |3 D2..3.| 2B78:C7 34 8D D2 35 8D D4 35 |G4.R5.T5| 2B80:AD F1 35 9D C6 34 8D D1 |-q5.F4.Q| 2B88:35 8D D3 35 AD C2 35 9D |5.S5-B5.| 2B90:C8 34 20 37 30 20 0C 2F |H4 70 ./| 2B98:20 D6 37 20 3A 2F AE 9C | V7 :/..| 2BA0:33 A9 06 8D C5 35 BD C6 |3)..E5=F| 2BA8:34 8D D1 35 BD C7 34 8D |4.Q5=G4.| 2BB0:D2 35 BD C8 34 8D C2 35 |R5=H4.B5| 2BB8:8D F6 35 BD E7 34 8D EE |.v5=g4.n| 2BC0:35 BD E8 34 8D EF 35 8E |5=h4.o5.| 2BC8:D9 35 A9 FF 8D E0 35 8D |Y5)..`5.| 2BD0:E1 35 AD E2 33 8D DA 35 |a5-b3.Z5| 2BD8:18 4C 5E 2F A9 00 AA 9D |.L^/).*.| 2BE0:D1 35 E8 E0 2D D0 F8 AD |Q5h`-Px-| 2BE8:BF 35 49 FF 8D F9 35 AD |?5I..y5-| 2BF0:C0 35 8D F8 35 AD C1 35 |@5.x5-A5| 2BF8:0A 0A 0A 0A AA 8E F7 35 |....*.w5| 2C00:A9 11 8D FA 35 60 20 1D |)..z5` .| T1SB 2C08:2F 20 34 2F 20 C3 32 A9 |/ 4/ C2)| 2C10:02 2D D5 35 F0 21 20 F7 |.-U5p! w| 2C18:2F A9 00 18 20 11 30 38 |/).. .08| 2C20:CE D8 35 D0 F7 AE D9 35 |NX5Pw.Y5| 2C28:AD EE 35 9D E7 34 AD EF |-n5.g4-o| 2C30:35 9D E8 34 20 37 30 4C |5.h4 70L| 2C38:7F 33 20 28 2B AD F6 35 |.3 (+-v5| 2C40:30 2B AD BD 35 85 42 AD |0+-=5.B-| 2C48:BE 35 85 43 AE 9C 33 20 |>5.C..3 | 2C50:1C 32 20 37 30 4C 7F 33 |.2 70L.3| 2C58:AD BC 35 C9 05 B0 0B 0A |-<5I.0..| 2C60:AA BD E6 2A 48 BD E5 2A |*=f*H=e*| 2C68:48 60 4C 67 33 4C 7B 33 |H`Lg3L{3| 2C70:AD F6 35 30 F8 AD BC 35 |-v50x-<5| 2C78:C9 05 B0 EE 0A AA BD F2 |I.0n.*=r| 2C80:2A 48 BD F1 2A 48 60 20 |*H=q*H` | 2C88:00 33 20 A8 2C 8D C3 35 |.3 (,.C5| 2C90:4C 7F 33 20 00 33 20 B5 |L.3 .3 5| 2C98:31 20 A8 2C 48 20 A2 31 |1 (,H "1| 2CA0:A0 00 68 91 42 4C 96 2C | .h.BL.,| 2CA8:20 B6 30 B0 0B B1 42 48 | 600.1BH| 2CB0:20 5B 31 20 94 31 68 60 | [1 .1h`| 2CB8:4C 6F 33 20 00 33 AD C3 |Lo3 .3-C| 2CC0:35 20 DA 2C 4C 7F 33 20 |5 Z,L.3 | 2CC8:00 33 20 A2 31 A0 00 B1 |.3 "1 .1| 2CD0:42 20 DA 2C 20 B5 31 4C |B Z, 51L| 2CD8:CA 2C 48 20 B6 30 68 91 |J,H 60h.| 2CE0:42 A9 40 0D D5 35 8D D5 |B)@.U5.U| 2CE8:35 20 5B 31 4C 94 31 A9 |5 [1L.1)| FDELCAT, $2CEF .. $2E8D, T1SB - T1SD 2CF0:80 8D 9E 33 D0 05 A9 00 |...3P.).| 2CF8:8D 9E 33 20 28 2B AE 9C |..3 (+..| 2D00:33 BD C8 34 29 7F 0D 9E |3=H4)...| T1SC 2D08:33 9D C8 34 20 37 30 4C |3.H4 70L| 2D10:7F 33 20 00 33 4C 7F 33 |.3 .3L.3| 2D18:20 28 2B 20 B6 30 B0 EF | (+ 600o| 2D20:EE E4 35 D0 F6 EE E5 35 |nd5Pvne5| 2D28:4C 1B 2D 20 28 2B AE 9C |L.- (+..| 2D30:33 BD C8 34 10 03 4C 7B |3=H4..L{| 2D38:33 AE 9C 33 BD C6 34 8D |3..3=F4.| 2D40:D1 35 9D E6 34 A9 FF 9D |Q5.f4)..| 2D48:C6 34 BC C7 34 8C D2 35 |F420 37 30 18 20 5E 2F B0 | 70. ^/0| 2D58:2A 20 0C 2F A0 0C 8C 9C |* ./ ...| 2D60:33 B1 42 30 0B F0 09 48 |31B0.p.H| 2D68:C8 B1 42 A8 68 20 89 2D |H1B(h .-| 2D70:AC 9C 33 C8 C8 D0 E7 AD |,.3HHPg-| 2D78:D3 35 AC D4 35 20 89 2D |S5,T5 .-| 2D80:38 B0 D1 20 FB 2F 4C 7F |80Q {/L.| 2D88:33 38 20 DD 32 A9 00 A2 |38 ]2)."| 2D90:05 9D F0 35 CA 10 FA 60 |..p5J.z`| 2D98:20 DC 2B A9 FF 8D F9 35 | +)..y5| 2DA0:20 F7 2F A9 16 8D 9D 33 | w/)...3| 2DA8:20 2F 2E 20 2F 2E A2 0B | /. /.".| 2DB0:BD AF 33 20 ED FD CA 10 |=/3 m}J.| 2DB8:F7 86 45 AD F6 37 85 44 |w.E-v7.D| 2DC0:20 42 2E 20 2F 2E 20 2F | B. /. /| 2DC8:2E 18 20 11 30 B0 5D A2 |.. .00]"| 2DD0:00 8E 9C 33 BD C6 34 F0 |...3=F4p| 2DD8:53 30 4A A0 A0 BD C8 34 |S0J =H4| 2DE0:10 02 A0 AA 98 20 ED FD |.. *. m}| 2DE8:BD C8 34 29 7F A0 07 0A |=H4). ..| 2DF0:0A B0 03 88 D0 FA B9 A7 |.0..Pz9'| 2DF8:33 20 ED FD A9 A0 20 ED |3 m}) m| 2E00:FD BD E7 34 85 44 BD E8 |}=g4.D=h| T1SD 2E08:34 85 45 20 42 2E A9 A0 |4.E B.) | 2E10:20 ED FD E8 E8 E8 A0 1D | m}hhh .| 2E18:BD C6 34 20 ED FD E8 88 |=F4 m}h.| 2E20:10 F6 20 2F 2E 20 30 32 |.v /. 02| 2E28:90 A7 B0 9E 4C 7F 33 A9 |.'0.L.3)| 2E30:8D 20 ED FD CE 9D 33 D0 |. m}N.3P| 2E38:08 20 0C FD A9 15 8D 9D |. .})...| 2E40:33 60 A0 02 A9 00 48 A5 |3` .).H%| 2E48:44 D9 A4 33 90 12 F9 A4 |DY$3..y$| 2E50:33 85 44 A5 45 E9 00 85 |3.D%Ei..| 2E58:45 68 69 00 48 4C 47 2E |Ehi.HLG.| 2E60:68 09 B0 20 ED FD 88 10 |h.0 m}..| 2E68:DB 60 20 08 2F A0 00 8C |[` ./ ..| 2E70:C5 35 B1 42 99 D1 35 C8 |E51B.Q5H| 2E78:C0 2D D0 F6 18 60 20 08 |@-Pv.` .| 2E80:2F A0 00 B9 D1 35 91 42 |/ .9Q5.B| 2E88:C8 C0 2D D0 F6 60 20 DC |H@-Pv` | FMTRWIO, $2E8E .. $2FF6, T1SD - T1SE 2E90:2B A9 04 20 58 30 AD F9 |+). X0-y| 2E98:35 49 FF 8D C1 33 A9 11 |5I..A3).| 2EA0:8D EB 33 A9 01 8D EC 33 |.k3)..l3| 2EA8:A2 38 A9 00 9D BB 33 E8 |"8)..;3h| 2EB0:D0 FA A2 0C E0 8C F0 14 |Pz".`.p.| 2EB8:A0 03 B9 A0 33 9D F3 33 | .9 3.s3| 2EC0:E8 88 10 F6 E0 44 D0 EC |h..v`DPl| 2EC8:A2 48 D0 E8 20 FB 2F A2 |"HPh {/"| 2ED0:00 8A 9D BB 34 E8 D0 FA |...;4hPz| 2ED8:20 45 30 A9 11 AC F0 33 | E0).,p3| 2EE0:88 88 8D EC 37 8D BC 34 |...l7.<4| 2EE8:8C BD 34 C8 8C ED 37 A9 |.=4H.m7)| 2EF0:02 20 58 30 AC BD 34 88 |. X0,=4.| 2EF8:30 05 D0 EC 98 F0 E6 20 |0.Pl.pf | 2F00:C2 37 20 4A 37 4C 7F 33 |B7 J7L.3| T1SE 2F08:A2 00 F0 06 A2 02 D0 02 |".p.".P.| 2F10:A2 04 BD C7 35 85 42 BD |".=G5.B=| 2F18:C8 35 85 43 60 2C D5 35 |H5.C`,U5| 2F20:70 01 60 20 E4 2F A9 02 |p.` d/).| 2F28:20 52 30 A9 BF 2D D5 35 | R0)?-U5| 2F30:8D D5 35 60 AD D5 35 30 |.U5`-U50| 2F38:01 60 20 4B 2F A9 02 20 |.` K/). | 2F40:52 30 A9 7F 2D D5 35 8D |R0).-U5.| 2F48:D5 35 60 AD C9 35 8D F0 |U5`-I5.p| 2F50:37 AD CA 35 8D F1 37 AE |7-J5.q7.| 2F58:D3 35 AC D4 35 60 08 20 |S5,T5`. | 2F60:34 2F 20 4B 2F 20 0C 2F |4/ K/ ./| 2F68:28 B0 09 AE D1 35 AC D2 |(0..Q5,R| 2F70:35 4C B5 2F A0 01 B1 42 |5L5/ .1B| 2F78:F0 08 AA C8 B1 42 A8 4C |p.*H1B(L| 2F80:B5 2F AD BB 35 C9 04 F0 |5/-;5I.p| 2F88:02 38 60 20 44 32 A0 02 |.8` D2 .| 2F90:91 42 48 88 AD F1 35 91 |.BH.-q5.| 2F98:42 48 20 3A 2F 20 D6 37 |BH :/ V7| 2FA0:A0 05 AD DE 35 91 42 C8 | .-^5.BH| 2FA8:AD DF 35 91 42 68 AA 68 |-_5.Bh*h| 2FB0:A8 A9 02 D0 02 A9 01 8E |().P.)..| 2FB8:D3 35 8C D4 35 20 52 30 |S5.T5 R0| 2FC0:A0 05 B1 42 8D DC 35 18 | .1B.5.| 2FC8:6D DA 35 8D DE 35 C8 B1 |mZ5.^5H1| 2FD0:42 8D DD 35 6D DB 35 8D |B.]5m[5.| 2FD8:DF 35 18 60 20 E4 2F A9 |_5.` d/)| 2FE0:01 4C 52 30 AC CB 35 AD |.LR0,K5-| 2FE8:CC 35 8C F0 37 8D F1 37 |L5.p7.q7| 2FF0:AE D6 35 AC D7 35 60 A9 |.V5,W5`)| FLOCNXB, T1SE - T2S0, $2FF7 .. $31C8 2FF8:01 D0 02 A9 02 AC C3 2A |.P.).,C*| 3000:8C F0 37 AC C4 2A 8C F1 |.p7,D*.q| T1SF 3008:37 AE FA 35 A0 00 4C 52 |7.z5 .LR| 3010:30 08 20 45 30 28 B0 08 |0. E0(0.| 3018:AC BD 33 AE BC 33 D0 0A |,=3.<3P.| 3020:AE BC 34 D0 02 38 60 AC |.<4P.8`,| 3028:BD 34 8E 97 33 8C 98 33 |=4..3..3| 3030:A9 01 20 52 30 18 60 20 |). R0.` | 3038:45 30 AE 97 33 AC 98 33 |E0..3,.3| 3040:A9 02 4C 52 30 AD C5 2A |).LR0-E*| 3048:8D F0 37 AD C6 2A 8D F1 |.p7-F*.q| 3050:37 60 8E EC 37 8C ED 37 |7`.l7.m7| 3058:8D F4 37 C9 02 D0 06 0D |.t7I.P..| 3060:D5 35 8D D5 35 AD F9 35 |U5.U5-y5| 3068:49 FF 8D EB 37 AD F7 35 |I..k7-w5| 3070:8D E9 37 AD F8 35 8D EA |.i7-x5.j| 3078:37 AD E2 35 8D F2 37 AD |7-b5.r7-| 3080:E3 35 8D F3 37 A9 01 8D |c5.s7)..| 3088:E8 37 AC C1 2A AD C2 2A |h7,A*-B*| 3090:20 B5 37 AD F6 37 8D BF | 57-v7.?| 3098:35 A9 FF 8D EB 37 B0 01 |5)..k70.| 30A0:60 AD F5 37 A0 07 C9 20 |`-u7 .I | 30A8:F0 08 A0 04 C9 10 F0 02 |p. .I.p.| 30B0:A0 08 98 4C 85 33 AD E4 | ..L.3-d| 30B8:35 CD E0 35 D0 08 AD E5 |5M`5P.-e| 30C0:35 CD E1 35 F0 66 20 1D |5Ma5pf .| 30C8:2F AD E5 35 CD DD 35 90 |/-e5M]5.| 30D0:1C D0 08 AD E4 35 CD DC |.P.-d5M| 30D8:35 90 12 AD E5 35 CD DF |5..-e5M_| 30E0:35 90 10 D0 08 AD E4 35 |5..P.-d5| 30E8:CD DE 35 90 06 20 5E 2F |M^5.. ^/| 30F0:90 D7 60 38 AD E4 35 ED |.W`8-d5m| 30F8:DC 35 0A 69 0C A8 20 0C |5.i.( .| 3100:2F B1 42 D0 0F AD BB 35 |/1BP.-;5| T2S0 3108:C9 04 F0 02 38 60 20 34 |I.p.8` 4| 3110:31 4C 20 31 8D D6 35 C8 |1L 1.V5H| 3118:B1 42 8D D7 35 20 DC 2F |1B.W5 /| 3120:AD E4 35 8D E0 35 AD E5 |-d5.`5-e| 3128:35 8D E1 35 20 10 2F AC |5.a5 ./,| 3130:E6 35 18 60 8C 9D 33 20 |f5.`..3 | 3138:44 32 AC 9D 33 C8 91 42 |D2,.3H.B| 3140:8D D7 35 88 AD F1 35 91 |.W5.-q5.| 3148:42 8D D6 35 20 10 2F 20 |B.V5 ./ | 3150:D6 37 A9 C0 0D D5 35 8D |V7)@.U5.| 3158:D5 35 60 AE EA 35 8E BD |U5`.j5.=| 3160:35 AE EB 35 8E BE 35 AE |5.k5.>5.| 3168:EC 35 AC ED 35 8E BF 35 |l5,m5.?5| 3170:8C C0 35 E8 D0 01 C8 CC |.@5hP.HL| 3178:E9 35 D0 11 EC E8 35 D0 |i5P.lh5P| 3180:0C A2 00 A0 00 EE EA 35 |.". .nj5| 3188:D0 03 EE EB 35 8E EC 35 |P.nk5.l5| 3190:8C ED 35 60 EE E6 35 D0 |.m5`nf5P| 3198:08 EE E4 35 D0 03 EE E5 |.nd5P.ne| 31A0:35 60 AC C3 35 AE C4 35 |5`,C5.D5| 31A8:84 42 86 43 EE C3 35 D0 |.B.CnC5P| 31B0:03 EE C4 35 60 AC C1 35 |.nD5`,A5| 31B8:D0 08 AE C2 35 F0 07 CE |P..B5p.N| 31C0:C2 35 CE C1 35 60 4C 7F |B5NA5`L.| 31C8:33 20 F7 2F AD C3 35 85 |3 w/-C5.| FLOCSEC, T2S0 - T2S2, $31C9 .. $3396 ($B1C9 .. $B396) 31D0:42 AD C4 35 85 43 A9 01 |B-D5.C).| 31D8:8D 9D 33 A9 00 8D D8 35 |..3)..X5| 31E0:18 EE D8 35 20 11 30 B0 |.nX5 .00| 31E8:51 A2 00 8E 9C 33 BD C6 |Q"...3=F| 31F0:34 F0 1F 30 22 A0 00 E8 |4p.0" .h| 31F8:E8 E8 B1 42 DD C6 34 D0 |hh1B]F4P| 3200:0A C8 C0 1E D0 F3 AE 9C |.H@.Ps..| T2S1 3208:33 18 60 20 30 32 90 DB |3.` 02.[| 3210:B0 CF AC 9D 33 D0 C1 AC |0O,.3PA,| 3218:9D 33 D0 EF A0 00 E8 E8 |.3Po .hh| 3220:E8 B1 42 9D C6 34 C8 C0 |h1B.F4H@| 3228:1E D0 F5 AE 9C 33 38 60 |.Pu..38`| 3230:18 AD 9C 33 69 23 AA E0 |.-.3i#*`| 3238:F5 60 A9 00 AC 9D 33 D0 |u`).,.3P| 3240:97 4C 77 33 AD F1 35 F0 |.Lw3-q5p| 3248:21 CE F0 35 30 17 18 A2 |!Np50.."| 3250:04 3E F1 35 CA D0 FA 90 |.>q5JPz.| 3258:F0 EE EE 35 D0 03 EE EF |pnn5P.no| 3260:35 AD F0 35 60 A9 00 8D |5-p5`)..| 3268:F1 35 A9 00 8D 9E 33 20 |q5)...3 | 3270:F7 2F 18 AD EB 33 6D EC |w/.-k3ml| 3278:33 F0 09 CD EF 33 90 14 |3p.Mo3..| 3280:A9 FF D0 0A AD 9E 33 D0 |).P.-.3P| 3288:37 A9 01 8D 9E 33 8D EC |7)...3.l| 3290:33 18 69 11 8D EB 33 8D |3.i..k3.| 3298:F1 35 A8 0A 0A A8 A2 04 |q5(..(".| 32A0:18 B9 F6 33 9D F1 35 F0 |.9v3.q5p| 32A8:06 38 A9 00 99 F6 33 88 |.8)..v3.| 32B0:CA D0 EE 90 BD 20 FB 2F |JPn.= {/| 32B8:AD F0 33 8D F0 35 D0 89 |-p3.p5P.| 32C0:4C 77 33 AD F1 35 D0 01 |Lw3-q5P.| 32C8:60 48 20 F7 2F AC F0 35 |`H w/,p5| 32D0:68 18 20 DD 32 A9 00 8D |h. ]2)..| 32D8:F1 35 4C FB 2F A2 FC 7E |q5L{/"|~| 32E0:F6 34 E8 D0 FA C8 CC F0 |v4hPzHLp| 32E8:33 D0 F2 0A 0A A8 F0 0F |3Pr..(p.| 32F0:A2 04 BD F1 35 19 F6 33 |".=q5.v3| 32F8:99 F6 33 88 CA D0 F3 60 |.v3.JPs`| 3300:AD BD 35 8D E6 35 8D EA |-=5.f5.j| T2S2 3308:35 AD BE 35 8D E4 35 8D |5->5.d5.| 3310:EB 35 A9 00 8D E5 35 A0 |k5)..e5 | 3318:10 AA AD E6 35 4A B0 03 |.*-f5J0.| 3320:8A 90 0E 18 AD E5 35 6D |....-e5m| 3328:E8 35 8D E5 35 8A 6D E9 |h5.e5.mi| 3330:35 6A 6E E5 35 6E E4 35 |5jne5nd5| 3338:6E E6 35 88 D0 DB 18 AD |nf5.P[.-| 3340:BF 35 8D EC 35 6D E6 35 |?5.l5mf5| 3348:8D E6 35 AD C0 35 8D ED |.f5-@5.m| 3350:35 6D E4 35 8D E4 35 90 |5md5.d5.| 3358:03 EE E5 35 60 00 00 A9 |.ne5`..)| 3360:01 D0 22 A9 02 D0 1E A9 |.P").P.)| 3368:03 D0 1A A9 04 D0 16 A9 |.P.).P.)| 3370:05 D0 12 A9 06 D0 0E 4C |.P.).P.L| 3378:ED 3F EA A9 0A D0 06 AD |m?j).P.-| 3380:C5 35 18 90 01 38 08 8D |E5...8..| 3388:C5 35 A9 00 85 48 20 7E |E5)..H ~| 3390:2E 28 AE 9B 33 9A 60 00 |.(..3.`.| FVCBUFS, T2S2 - T2S4, $3397 .. $35FD ($B397 .. $B5FD) 3398:00 00 00 00 00 00 00 00 |........| 33A0:00 00 FF FF 01 0A 64 D4 |......dT| 33A8:C9 C1 C2 D3 D2 C1 C2 A0 |IABSRAB | 33B0:C5 CD D5 CC CF D6 A0 CB |EMULOV K| 33B8:D3 C9 C4 04 11 0F 04 00 |SID.....| 33C0:00 FE FC FD FF FC FF FC |.~|}.|.|| 33C8:FC FE FF FC FD FF FE FF ||~.|}.~.| 33D0:FD FE FF FD FD FD FF FE |}~.}}}.~| 33D8:FD FF FC FF FF FD FD FC |}.|..}}|| 33E0:FE FE 7A FE FD FF FD FE |~~z~}.}~| 33E8:FE FF FC 11 01 00 00 23 |~.|....#| 33F0:10 00 01 FF FC FC FD FC |....||}|| 33F8:FE FC FC FD FD FE FC FC |~||}}~||| 3400:FF FC FC FD FC FD FD FC |.||}|}}|| T2S3 3408:FF FE FC FC FC FC FE FE |.~||||~~| 3410:FC FD FC FC FC FE FC FD ||}|||~|}| 3418:FC FC FE FC FC FC FE FC |||~|||~|| 3420:FC FF FC FC FC FC FD FD ||.||||}}| 3428:FC FF FF FC FE FD FE FD ||..|~}~}| 3430:FE FC FF FC FE FF FD FC |~|.|~.}|| 3438:FF FC FC FC FD FE FD FE |.|||}~}~| 3440:FC FC FC FF FE FC FC FD ||||.~||}| 3448:FC FD FF FC FC FC FC FE ||}.||||~| 3450:FD FC FD FC FC FC FD FC |}|}|||}|| 3458:FD FF FC FE FD FC FC FD |}.|~}||}| 3460:FC FC FC FC FC FC FF FF |||||||..| 3468:FE FC FF FC FD FF FE FF |~|.|}.~.| 3470:FE FE FC FC FD FC FC FC |~~||}|||| 3478:FE FE FE FD FE FD FC FE |~~~}~}|~| 3480:FD FD FC FC FE FE FC FC |}}||~~||| 3488:FD FC FC FE FC FC FD FC |}||~||}|| 3490:FE FE FC FD FC FC FC FC |~~|}||||| 3498:FC FD FD FC FE FD FC FC ||}}|~}||| 34A0:FE FC FC FC FC FC FE FC |~|||||~|| 34A8:FD FD FC FF FD FC FE FE |}}|.}|~~| 34B0:FC FD FD FE FF FD FE FF ||}}~.}~.| 34B8:FE FF FC 02 FC FD FC FC |~.|.|}||| ↠entire sector wasted for unreferenced 1 byte @ $(34)BB !! 34C0:FC FE FE FE FD FE FF FE ||~~~}~.~| 34C8:FC FC FC FC FC FE FC FD ||||||~|}| 34D0:FC FC FF FD FC FE FC FC |||.}|~||| 34D8:FD FE FE FF FC FE FF FD |}~~.|~.}| 34E0:FF FE FC FC FE FE FD FF |.~||~~}.| 34E8:FE FF FF FD FC FE FF FC |~..}|~.|| 34F0:FE FD FE FC FE FC FF FE |~}~|~|.~| 34F8:FE FE FC FD FD FE FF FC |~~|}}~.|| 3500:FC FC FC FC FC FE FC FD ||||||~|}| T2S4 3508:FD FC FF FD FC FE FE FC |}|.}|~~|| 3510:FE FD FC FF FF FC FC FE |~}|..||~| 3518:FE FD FE FD FE FE FC FC |~}~}~~||| 3520:FE FD FD FC FE FD FC FC |~}}|~}||| 3528:FE FC FC FE FC FC FD FC |~||~||}|| 3530:FD FD FC FF FD FC FE FD |}}|.}|~}| 3538:FC FD FF FC FE FC FC FC ||}.|~|||| 3540:FC FC FC FD FC FC FE FC ||||}||~|| 3548:FD FC FC FF FC FC FE FD |}||.||~}| 3550:FC FD FF FC FF FD FE FF ||}.|.}~.| 3558:FD FF FE FC FD FF FF FF |}.~|}...| 3560:FC FC FE FC FC FF FF FC |||~||..|| 3568:FC FD FC FE FC FC FC FC ||}|~||||| 3570:FC FE FC FC FD FD FC FC ||~||}}||| 3578:FE FC FD FC FC FE FE FC |~|}||~~|| 3580:FC FC FC FC FF FC FC FC |||||.|||| 3588:FC FD FD FC FF FC FC FE ||}}|.||~| 3590:FF FC FD FF FC FF FD FE |.|}.|.}~| 3598:FF FD FD FD FF FE FD FF |.}}}.~}.| 35A0:FC FF FD FD FD FC FE FC ||.}}}|~|| 35A8:FC FF FE FC FC FE FC FC ||.~||~||| 35B0:FE FC FD FD FC FF FD FC |~|}}|.}|| 35B8:FE FC FC FF FF FC FC FD |~||..||}| 35C0:FC FE FE FE FC FF FC FF ||~~~|.|.| 35C8:FC FF FF FE FC FE FC FD ||..~|~|}| 35D0:FF FF FD FD FE FC FC FC |..}}~|||| 35D8:FC FC FE FD FD FF FE FC |||~}}.~|| 35E0:FE FC FC FC FF FC FC FE |~|||.||~| 35E8:FE FC FE FC FC FC FF FC |~|~|||.|| 35F0:FC FC FE FC FC FF FD FE |||~||.}~| 35F8:FC FC FD FC FC FF FD FC |||}||.}|| BOOTLDR, $35FE .. $37FF, T0S0 - T0S1 3600:01 A5 27 C9 09 D0 18 A5 |.%'I.P.%| T0S0 3608:2B 4A 4A 4A 4A 09 C0 85 |+JJJJ.@.| 3610:3F A9 5C 85 3E 18 AD FE |?).>.-~| 3618:08 6D FF 08 8D FE 08 AE |.m...~..| 3620:FF 08 30 15 BD 4D 08 85 |..0.=M..| 3628:3D CE FF 08 AD FE 08 85 |=N..-~..| 3630:27 CE FE 08 A6 2B 6C 3E |'N~.&+l>| 3638:00 EE FE 08 EE FE 08 20 |.n~.n~. | 3640:89 FE 20 93 FE 20 2F FB |.~ .~ /{| 3648:A6 2B 6C FD 08 00 0D 0B |&+l}....| 3650:09 07 05 03 01 0E 0C 0A |........| 3658:08 06 04 02 0F 00 20 64 |...... d| 3660:27 B0 08 A9 00 A8 8D 5D |'0.).(.]| 3668:36 91 40 AD C5 35 4C D2 |6.@-E5LR| 3670:26 AD 5D 36 F0 08 EE BD |&-]6p.n=| 3678:35 D0 03 EE BE 35 A9 00 |5P.n>5).| 3680:8D 5D 36 4C B3 36 8D BC |.]6L36.<| 3688:35 20 A8 26 20 EA 22 4C |5 (& j"L| 3690:7D 22 A0 13 B1 42 D0 14 |}" .1BP.| 3698:C8 C0 17 D0 F7 A0 19 B1 |H@.Pw .1| 36A0:42 99 A4 35 C8 C0 1D D0 |B.$5H@.P| 36A8:F6 4C BB 26 A2 FF 8E 5D |vL;&"..]| 36B0:36 D0 F6 AD BD 35 8D E6 |6Pv-=5.f| 36B8:35 8D EA 35 AD BE 35 8D |5.j5->5.| 36C0:E7 35 8D EB 35 8D E4 35 |g5.k5.d5| 36C8:BA 8E 9B 33 4C 7F 33 00 |:..3L.3.| 36D0:00 00 00 00 00 00 00 00 |........| 36D8:00 00 00 00 00 00 00 00 |........| 36E0:00 00 00 00 00 00 00 00 |........| 36E8:00 00 00 00 00 00 00 00 |........| 36F0:00 00 00 00 00 00 00 00 |........| 36F8:00 00 00 00 00 00 36 09 |......6.| 3700:8E E9 37 8E F7 37 A9 01 |.i7.w7).| T0S1 3708:8D F8 37 8D EA 37 AD E0 |.x7.j7-`| 3710:37 8D E1 37 A9 02 8D EC |7.a7)..l| 3718:37 A9 04 8D ED 37 AC E7 |7)..m7,g| 3720:37 88 8C F1 37 A9 01 8D |7..q7)..| 3728:F4 37 8A 4A 4A 4A 4A AA |t7.JJJJ*| 3730:A9 00 9D F8 04 9D 78 04 |)..x..x.| 3738:20 93 37 A2 FF 9A 8E EB | .7"...k| 3740:37 4C C8 3F 20 89 FE 4C |7LH? .~L| 3748:03 1B AD E7 37 38 ED F1 |..-g78mq| 3750:37 8D E1 37 AD E7 37 8D |7.a7-g7.| 3758:F1 37 CE F1 37 A9 02 8D |q7Nq7)..| 3760:EC 37 A9 04 8D ED 37 A9 |l7)..m7)| 3768:02 8D F4 37 20 93 37 AD |..t7 .7-| 3770:E7 37 8D FE 36 18 69 09 |g7.~6.i.| 3778:8D F1 37 A9 0A 8D E1 37 |.q7)..a7| 3780:38 E9 01 8D FF 36 8D ED |8i...6.m| 3788:37 20 93 37 60 00 00 00 |7 .7`...| 3790:00 00 00 AD E5 37 AC E4 |...-e7,d| 3798:37 20 B5 37 AC ED 37 88 |7 57,m7.| 37A0:10 07 A0 0F EA EA CE EC |.. .jjNl| 37A8:37 8C ED 37 CE F1 37 CE |7.m7Nq7N| 37B0:E1 37 D0 DF 60 08 78 20 |a7P_`.x | 37B8:00 3D B0 03 28 18 60 28 |.=0.(.`(| 37C0:38 60 AD BC 35 8D F1 37 |8`-<5.q7| 37C8:A9 00 8D F0 37 AD F9 35 |)..p7-y5| 37D0:49 FF 8D EB 37 60 A9 00 |I..k7`).| 37D8:A8 91 42 C8 D0 FB 60 00 |(.BHP{`.| 37E0:1B 00 0A 1B E8 37 00 36 |....h7.6| 37E8:01 60 01 00 00 00 FB 37 |.`....{7| 37F0:00 00 00 01 00 00 00 60 |.......`| 37F8:01 00 00 00 01 EF D8 00 |.....oX.| 3800:A2 00 A0 02 88 B1 3E 4A |". ..1>J| T0S2, PRENIBL, $3800 .. $3829, T0S2 3808:3E 00 3C 4A 3E 00 3C 99 |>..<.| 3810:00 3B E8 E0 56 90 ED A2 |.;h`V.m"| 3818:00 98 D0 E8 A2 55 BD 00 |..Ph"U=.| 3820:3C 29 3F 9D 00 3C CA 10 |<)?..F5 60 38 86 27 8E 78 06 |u`8.'.x.| WRITRTN, $382A .. $38C1, T0S2 3830:BD 8D C0 BD 8E C0 30 7C |=.@=.@0|| 3838:AD 00 3C 85 26 A9 FF 9D |-.<.&)..| 3840:8F C0 1D 8C C0 48 68 EA |.@..@Hhj| 3848:A0 04 48 68 20 B9 38 88 | .Hh 98.| 3850:D0 F8 A9 D5 20 B8 38 A9 |Px)U 88)| 3858:AA 20 B8 38 A9 AD 20 B8 |* 88)- 8| 3860:38 98 A0 56 D0 03 B9 00 |8. VP.9.| 3868:3C 59 FF 3B AA BD 29 3A |A6 27 9D 8D C0 BD 8C C0 |&'..@=.@| 3878:88 D0 EB A5 26 EA 59 00 |.Pk%&jY.| 3880:3B AA BD 29 3A AE 78 06 |;*=):.x.| 3888:9D 8D C0 BD 8C C0 B9 00 |..@=.@9.| 3890:3B C8 D0 EA AA BD 29 3A |;HPj*=):| 3898:A6 27 20 BB 38 A9 DE 20 |&' ;8)^ | 38A0:B8 38 A9 AA 20 B8 38 A9 |88)* 88)| 38A8:EB 20 B8 38 A9 FF 20 B8 |k 88). 8| 38B0:38 BD 8E C0 BD 8C C0 60 |8=.@=.@`| 38B8:18 48 68 9D 8D C0 1D 8C |.Hh..@..| 38C0:C0 60 A0 00 A2 56 CA 30 |@` ."VJ0| POSTNRD, $38C2 .. $3943, T0S2 - T0S3 38C8:FB B9 00 3B 5E 00 3C 2A |{9.;^.<*| 38D0:5E 00 3C 2A 91 3E C8 C4 |^.<*.>HD| 38D8:26 D0 EB 60 A0 20 88 F0 |&Pk` .p| 38E0:61 BD 8C C0 10 FB 49 D5 |a=.@.{IU| 38E8:D0 F4 EA BD 8C C0 10 FB |Ptj=.@.{| 38F0:C9 AA D0 F2 A0 56 BD 8C |I*Pr V=.| 38F8:C0 10 FB C9 AD D0 E7 A9 |@.{I-Pg)| 3900:00 88 84 26 BC 8C C0 10 |...&<.@.| T0S3 3908:FB 59 00 3A A4 26 99 00 |{Y.:$&..| 3910:3C D0 EE 84 26 BC 8C C0 |10 FB 59 00 3A A4 26 99 |.{Y.:$&.| 3920:00 3B C8 D0 EE BC 8C C0 |.;HPn<.@| 3928:10 FB D9 00 3A D0 13 BD |.{Y.:P.=| 3930:8C C0 10 FB C9 DE D0 0A |.@.{I^P.| 3938:EA BD 8C C0 10 FB C9 AA |j=.@.{I*| 3940:F0 5C 38 60 A0 FC 84 26 |p8` |.&| RDADSEK, $3944 .. $39FC, T0S3 3948:C8 D0 04 E6 26 F0 F3 BD |HP.f&ps=| 3950:8C C0 10 FB C9 D5 D0 F0 |.@.{IUPp| 3958:EA BD 8C C0 10 FB C9 AA |j=.@.{I*| 3960:D0 F2 A0 03 BD 8C C0 10 |Pr .=.@.| 3968:FB C9 96 D0 E7 A9 00 85 |{I.Pg)..| 3970:27 BD 8C C0 10 FB 2A 85 |'=.@.{*.| 3978:26 BD 8C C0 10 FB 25 26 |&=.@.{%&| 3980:99 2C 00 45 27 88 10 E7 |.,.E'..g| 3988:A8 D0 B7 BD 8C C0 10 FB |(P7=.@.{| 3990:C9 DE D0 AE EA BD 8C C0 |I^P.j=.@| 3998:10 FB C9 AA D0 A4 18 60 |.{I*P$.`| 39A0:86 2B 85 2A CD 78 04 F0 |.+.*Mx.p| 39A8:53 A9 00 85 26 AD 78 04 |S)..&-x.| 39B0:85 27 38 E5 2A F0 33 B0 |.'8e*p30| 39B8:07 49 FF EE 78 04 90 05 |.I.nx...| 39C0:69 FE CE 78 04 C5 26 90 |i~Nx.E&.| 39C8:02 A5 26 C9 0C B0 01 A8 |.%&I.0.(| 39D0:38 20 EE 39 B9 11 3A 20 |8 n99.: | 39D8:00 3A A5 27 18 20 F1 39 |.:%'. q9| 39E0:B9 1D 3A 20 00 3A E6 26 |9.: .:f&| 39E8:D0 C3 20 00 3A 18 AD 78 |PC .:.-x| 39F0:04 29 03 2A 05 2B AA BD |.).*.+*=| 39F8:80 C0 A6 2B 60 00 00 00 |.@&+`...| MSWAITR, $39FD .. $3C55, T0S3 - T0S6 3A00:A2 11 CA D0 FD E6 46 D0 |".JP}fFP| T0S4 3A08:02 E6 47 38 E9 01 D0 F0 |.fG8i.Pp| 3A10:60 01 30 28 24 20 1E 1D |`.0($ ..| 3A18:1C 1C 1C 1C 1C 70 2C 26 |.....p,&| 3A20:22 1F 1E 1D 1C 1C 1C 1C |".......| 3A28:1C 96 97 9A 9B 9D 9E 9F |........| 3A30:A6 A7 AB AC AD AE AF B2 |&'+,-./2| 3A38:B3 B4 B5 B6 B7 B9 BA BB |345679:;| 3A40:BC BD BE BF CB CD CE CF |<=>?KMNO| 3A48:D3 D6 D7 D9 DA DB DC DD |SVWYZ[]| 3A50:DE DF E5 E6 E7 E9 EA EB |^_efgijk| 3A58:EC ED EE EF F2 F3 F4 F5 |lmnorstu| 3A60:F6 F7 F9 FA FB FC FD FE |vwyz{|}~| 3A68:FF AE 5F 2A E0 1C F0 05 |.._*`.p.| 3A70:A2 00 8E 5D 36 60 A9 FF |"..]6`).| 3A78:8D FB 04 8D 0C C0 8D 0E |.{...@..| 3A80:C0 4C 2F FB 00 00 00 00 |@L/{....| 3A88:00 00 00 00 00 00 00 00 |........| 3A90:00 00 00 00 00 00 00 01 |........| 3A98:98 99 02 03 9C 04 05 06 |........| 3AA0:A0 A1 A2 A3 A4 A5 07 08 | !"#$%..| 3AA8:A8 A9 AA 09 0A 0B 0C 0D |()*.....| 3AB0:B0 B1 0E 0F 10 11 12 13 |01......| 3AB8:B8 14 15 16 17 18 19 1A |8.......| 3AC0:C0 C1 C2 C3 C4 C5 C6 C7 |@ABCDEFG| 3AC8:C8 C9 CA 1B CC 1C 1D 1E |HIJ.L...| 3AD0:D0 D1 D2 1F D4 D5 20 21 |PQR.TU !| 3AD8:D8 22 23 24 25 26 27 28 |X"#$%&'(| 3AE0:E0 E1 E2 E3 E4 29 2A 2B |`abcd)*+| 3AE8:E8 2C 2D 2E 2F 30 31 32 |h,-./012| 3AF0:F0 F1 33 34 35 36 37 38 |pq345678| 3AF8:F8 39 3A 3B 3C 3D 3E 3F |x9:;<=>?| 3B00:00 00 00 00 00 00 00 00 |........| T0S5 3B08:00 00 00 00 00 00 00 00 |........| 3B10:00 00 00 00 00 00 00 00 |........| 3B18:00 00 00 00 00 00 00 00 |........| 3B20:00 00 00 00 00 00 00 00 |........| 3B28:00 00 00 00 00 00 00 00 |........| 3B30:00 00 00 00 00 00 00 00 |........| 3B38:00 00 00 00 00 00 00 00 |........| 3B40:00 00 00 00 00 00 00 00 |........| 3B48:00 00 00 00 00 00 00 00 |........| 3B50:00 00 00 00 00 00 00 00 |........| 3B58:00 00 00 00 00 00 00 00 |........| 3B60:00 00 00 00 00 00 00 00 |........| 3B68:00 00 00 00 00 00 00 00 |........| 3B70:00 00 00 00 00 00 00 00 |........| 3B78:00 00 00 00 00 00 00 00 |........| 3B80:00 00 00 00 00 00 00 00 |........| 3B88:00 00 00 00 00 00 00 00 |........| 3B90:00 00 00 00 00 00 00 00 |........| 3B98:00 00 00 00 00 00 00 00 |........| 3BA0:00 00 00 00 00 00 00 00 |........| 3BA8:00 00 00 00 00 00 00 00 |........| 3BB0:00 00 00 00 00 00 00 00 |........| 3BB8:00 00 00 00 00 00 00 00 |........| 3BC0:00 00 00 00 00 00 00 00 |........| 3BC8:00 00 00 00 00 00 00 00 |........| 3BD0:00 00 00 00 00 00 00 00 |........| 3BD8:00 00 00 00 00 00 00 00 |........| 3BE0:00 00 00 00 00 00 00 00 |........| 3BE8:00 00 00 00 00 00 00 00 |........| 3BF0:00 00 00 00 00 00 00 00 |........| 3BF8:00 00 00 00 00 00 00 00 |........| 3C00:00 00 00 00 00 00 00 00 |........| T0S6 3C08:00 00 00 00 00 00 00 00 |........| 3C10:00 00 00 00 00 00 00 00 |........| 3C18:00 00 00 00 00 00 00 00 |........| 3C20:00 00 00 00 00 00 00 00 |........| 3C28:00 00 00 00 00 00 00 00 |........| 3C30:00 00 00 00 00 00 00 00 |........| 3C38:00 00 00 00 00 00 00 00 |........| 3C40:00 00 00 00 00 00 00 00 |........| 3C48:00 00 00 00 00 00 00 00 |........| 3C50:00 00 00 00 00 00 38 BD |......8=| WRITADR, $3C56 .. $3CFF, T0S6 3C58:8D C0 BD 8E C0 30 5E A9 |.@=.@0^)| 3C60:FF 9D 8F C0 DD 8C C0 48 |...@].@H| 3C68:68 20 C3 3C 20 C3 3C 9D |h C< C<.| 3C70:8D C0 DD 8C C0 EA 88 D0 |.@].@j.P| 3C78:F0 A9 D5 20 D5 3C A9 AA |p)U U<)*| 3C80:20 D5 3C A9 96 20 D5 3C | U<). U<| 3C88:A5 41 20 C4 3C A5 44 20 |%A D<%D | 3C90:C4 3C A5 3F 20 C4 3C A5 |D<%? D<%| 3C98:41 45 44 45 3F 48 4A 05 |AEDE?HJ.| 3CA0:3E 9D 8D C0 BD 8C C0 68 |>..@=.@h| 3CA8:09 AA 20 D4 3C A9 DE 20 |.* T<)^ | 3CB0:D5 3C A9 AA 20 D5 3C A9 |U<)* U<)| 3CB8:EB 20 D5 3C 18 BD 8E C0 |k U<.=.@| 3CC0:BD 8C C0 60 48 4A 05 3E |=.@`HJ.>| 3CC8:9D 8D C0 DD 8C C0 68 EA |..@].@hj| 3CD0:EA EA 09 AA EA EA 48 68 |jj.*jjHh| 3CD8:9D 8D C0 DD 8C C0 60 00 |..@].@`.| 3CE0:00 00 00 00 00 00 00 00 |........| 3CE8:00 00 00 00 00 00 00 00 |........| 3CF0:00 00 00 00 00 00 00 00 |........| 3CF8:00 00 00 00 00 00 00 00 |........| 3D00:84 48 85 49 A0 02 8C F8 |.H.I ..x| T0S7, RWTSONE, $3D00 .. $3DAA, T0S7 3D08:06 A0 04 8C F8 04 A0 01 |. ..x. .| 3D10:B1 48 AA A0 0F D1 48 F0 |1H* .QHp| 3D18:1B 8A 48 B1 48 AA 68 48 |..H1H*hH| 3D20:91 48 BD 8E C0 A0 08 BD |.H=.@ .=| 3D28:8C C0 DD 8C C0 D0 F6 88 |.@].@Pv.| 3D30:D0 F8 68 AA BD 8E C0 BD |Pxh*=.@=| 3D38:8C C0 A0 08 BD 8C C0 48 |.@ .=.@H| 3D40:68 48 68 8E F8 05 DD 8C |hHh.x.].| 3D48:C0 D0 03 88 D0 EE 08 BD |@P..Pn.=| 3D50:89 C0 A0 06 B1 48 99 36 |.@ .1H.6| 3D58:00 C8 C0 0A D0 F6 A0 03 |.H@.Pv .| 3D60:B1 3C 85 47 A0 02 B1 48 |1<.G .1H| 3D68:A0 10 D1 48 F0 06 91 48 | .QHp..H| 3D70:28 A0 00 08 6A 90 05 BD |( ..j..=| 3D78:8A C0 B0 03 BD 8B C0 66 |.@0.=.@f| 3D80:35 28 08 D0 0B A0 07 20 |5(.P. . | 3D88:00 3A 88 D0 FA AE F8 05 |.:.Pz.x.| 3D90:A0 04 B1 48 20 5A 3E 28 | .1H Z>(| 3D98:D0 11 A4 47 10 0D A0 12 |P.$G.. .| 3DA0:88 D0 FD E6 46 D0 F7 E6 |.P}fFPwf| 3DA8:47 D0 F3 A0 0C B1 48 F0 |GPs .1Hp| RWTSTWO, T0S7 - T0S8, $3DAB .. $3EAE ($BDAB .. $BEAE) 3DB0:5A C9 04 F0 58 6A 08 B0 |ZI.pXj.0| 3DB8:03 20 00 38 A0 30 8C 78 |. .8 0.x| 3DC0:05 AE F8 05 20 44 39 90 |..x. D9.| 3DC8:24 CE 78 05 10 F3 AD 78 |$Nx..s-x| 3DD0:04 48 A9 60 20 95 3E CE |.H)` .>N| 3DD8:F8 06 F0 28 A9 04 8D F8 |x.p()..x| 3DE0:04 A9 00 20 5A 3E 68 20 |.). Z>h | 3DE8:5A 3E 4C BC 3D A4 2E CC |Z>L<=$.L| 3DF0:78 04 F0 1C AD 78 04 48 |x.p.-x.H| 3DF8:98 20 95 3E 68 CE F8 04 |. .>hNx.| 3E00:D0 E5 F0 CA 68 A9 40 28 |PepJh)@(| T0S8 3E08:4C 48 3E F0 39 4C AF 3E |LH>p9L/>| 3E10:A0 03 B1 48 48 A5 2F A0 | .1HH%/ | 3E18:0E 91 48 68 F0 08 C5 2F |..Hhp.E/| 3E20:F0 04 A9 20 D0 E1 A0 05 |p.) Pa .| 3E28:B1 48 A8 B9 B8 3F C5 2D |1H(98?E-| 3E30:D0 97 28 90 1C 20 DC 38 |P.(.. 8| 3E38:08 B0 8E 28 A2 00 86 26 |.0.("..&| 3E40:20 C2 38 AE F8 05 18 24 | B8.x..$| 3E48:38 A0 0D 91 48 BD 88 C0 |8 ..H=.@| 3E50:60 20 2A 38 90 F0 A9 10 |` *8.p).| 3E58:B0 EE 48 A0 01 B1 3C 6A |0nH .168 90 08 0A 20 6B 3E 4E |h... k>N| 3E68:78 04 60 85 2A 20 8E 3E |x.`.* .>| 3E70:B9 78 04 24 35 30 03 B9 |9x.$50.9| 3E78:F8 04 8D 78 04 A5 2A 24 |x..x.%*$| 3E80:35 30 05 99 F8 04 10 03 |50..x...| 3E88:99 78 04 4C A0 39 8A 4A |.x.L 9.J| 3E90:4A 4A 4A A8 60 48 A0 02 |JJJ(`H .| 3E98:B1 48 6A 66 35 20 8E 3E |1Hjf5 .>| 3EA0:68 0A 24 35 30 05 99 F8 |h.$50..x| 3EA8:04 10 03 99 78 04 60 A0 |....x.` | FORMATR, T0S8 - T0S9, $3EAF .. $3FC7 ($BEAF .. $BFC7) 3EB0:03 B1 48 85 41 A9 AA 85 |.1H.A)*.| 3EB8:3E A0 56 A9 00 85 44 99 |> V)..D.| 3EC0:FF 3B 88 D0 FA 99 00 3B |.;.Pz..;| 3EC8:88 D0 FA A9 50 20 95 3E |.Pz)P .>| 3ED0:A9 28 85 45 A5 44 20 5A |)(.E%D Z| 3ED8:3E 20 0D 3F A9 08 B0 24 |> .?).0$| 3EE0:A9 30 8D 78 05 38 CE 78 |)0.x.8Nx| 3EE8:05 F0 19 20 44 39 B0 F5 |.p. D90u| 3EF0:A5 2D D0 F1 20 DC 38 B0 |%-Pq 80| 3EF8:EC E6 44 A5 44 C9 23 90 |lfD%DI#.| 3F00:D3 18 90 05 A0 0D 91 48 |S... ..H| T0S9 3F08:38 BD 88 C0 60 A9 00 85 |8=.@`)..| 3F10:3F A0 80 D0 02 A4 45 20 |? .P.$E | 3F18:56 3C B0 6B 20 2A 38 B0 |V<0k *80| 3F20:66 E6 3F A5 3F C9 10 90 |ff?%?I..| 3F28:EC A0 0F 84 3F A9 30 8D |l ..?)0.| 3F30:78 05 99 A8 3F 88 10 FA |x..(?..z| 3F38:A4 45 20 87 3F 20 87 3F |$E .? .?| 3F40:20 87 3F 48 68 EA 88 D0 | .?Hhj.P| 3F48:F1 20 44 39 B0 23 A5 2D |q D90#%-| 3F50:F0 15 A9 10 C5 45 A5 45 |p.).EE%E| 3F58:E9 01 85 45 C9 05 B0 11 |i..EI.0.| 3F60:38 60 20 44 39 B0 05 20 |8` D90. | 3F68:DC 38 90 1C CE 78 05 D0 |8..Nx.P| 3F70:F1 20 44 39 B0 0B A5 2D |q D90.%-| 3F78:C9 0F D0 05 20 DC 38 90 |I.P. 8.| 3F80:8C CE 78 05 D0 EB 38 60 |.Nx.Pk8`| 3F88:A4 2D B9 A8 3F 30 DD A9 |$-9(?0])| 3F90:FF 99 A8 3F C6 3F 10 CA |..(?F?.J| 3F98:A5 44 D0 0A A5 45 C9 10 |%DP.%EI.| 3FA0:90 E5 C6 45 C6 45 18 60 |.eFEFE.`| 3FA8:00 00 00 00 00 00 00 00 |........| 3FB0:00 00 00 00 00 00 00 00 |........| 3FB8:00 0D 0B 09 07 05 03 01 |........| 3FC0:0E 0C 0A 08 06 04 02 0F |........| 3FC8:20 93 FE AD 81 C0 AD 81 | .~-.@-.| DOSPTCH, T0S9, $3FC8 .. $3FFF ($BFC8 .. $BFFF) 3FD0:C0 A9 00 8D 00 E0 20 76 |@)...` v| 3FD8:3A 4C 44 37 8D 63 2A 8D |:LD7.c*.| 3FE0:70 2A 8D 71 2A 60 20 5B |p*.q*` [| 3FE8:27 8C B7 2A 60 20 7E 2E |'.7*` ~.| 3FF0:AE 9B 33 9A 20 16 23 BA |..3. .#:| 3FF8:8E 9B 33 A9 09 4C 85 33 |..3).L.3|
There are several locations where memory and disk space are wasted.
Â
I've annotated *wastes* locations in the listing where memory is wasted.
Â
| T/S | Range | File | Func/Var | Line | Bytes | Description |
|---|---|---|---|---|---|---|
| T0S0 | $36B3..$36FD | BOOTLDR | n/a | 75 | Padding for boot sector | |
| T0S1 | $37FF | BOOTLDR | n/a | 1 | Unused slack at end | |
| T0S3 | $FD..$FF | MSWAITR | n/a | 3 | Line #30 page align MSWAIT | |
| T0S6 | $00..$55 | MSWAITR | NBUF2 | 86 | While we need run-time memory for NBUF2 there is NO need to waste disk space. Data should always either BEFORE or AFTER code -- never interleaved. |
|
| T0S9 | $3FDA .. $3FDB | DOSPTCH | RCPATCH | 028 | 2 | JMP RCBACK instead of RTS |
| T0SA | $1B49 .. $1B49 | RELOCTR | DR2A | 153 | 1 | ZPGFCB can never point to page 0. We can switch the order: From: LDY ZPGFCB+1 PLA JMP DR2C To: PLA LDY ZPGFCB+1 BNE DR2C |
| T0SB | $1B7D .. $1B7D | RELOCTR | DR3 | 181 | 1 | Useless TAY when LDY would suffice From: LDA ADRTAB+1,X TAY To: LDY ADRTAB+1,X |
| T0SB | $1B83 .. $1B83 | RELOCTR | DR3 | 184 | 1 | Start Address (+2) in ADRTAB is never on page 0; Change (absolute) JMP to (relative) BNE: From: LDA ADRTAB+2,X STA ZPGWRK+1 JMP DR5 To: LDA ADRTAB+2,X STA ZPGWRK+1 BNE DR5 |
| T0SB | $1C12 .. $1C12 | RELOCTR | DR9 | 273 | 1 | Useless TAY when LDY and STY would suffice From: LDA #0 STA ZPGWRK STA ZPGFCB TAY To: LDY #0 STY ZPGWRK STY ZPGFCB |
| T0SB | $1C4D .. $1C58 | RELOCTR | ADRTAB | 306 | 11 | Unreferenced data after ADRTAB |
| T0SB | $1C81 .. $1CFF | DOSINIT | START | 003 | 127 | Padding so START is aligned on a new memory page Technically, only 82 bytes. See note at address. |
| T0SC | $1D78 .. $1D83 | DOSINIT | AS2VT | 103 | 10 | Dead data: Applesoft in RAM vector table |
| T2S2 | $33BB .. $33BB | FVCBUFS | 023 | 1 | Unused sector type 4 = VTOC | |
| T2S2 | $33A0 .. $33A3 | FVCBUFS | ALC10S | 4 | 32 sectors/track allocation bitmap mask | |
| T2S2 | $33BF .. $33BF | FVCBUFS | n/a | 1 | VTOC spare shenanigans | |
| T2S2 | $33C0 .. $33C0 | FVCBUFS | n/a | 1 | VTOC spare shenanigans | |
| T2S2 | $33C2 .. $33E1 | FVCBUFS | n/a | 32 | VTOC spare shenanigans | |
| T2S2 | $33E3 .. $33EA | FVCBUFS | n/a | 8 | VTOC spare shenanigans | |
| T2S2 | $33ED .. $33ED | FVCBUFS | VALCA3 | 1 | VTOC Track Allocation byte 3 | |
| T2S2 | $33EE .. $33EE | FVCBUFS | VALCA4 | 1 | VTOC Track Allocation byte 4 | |
| T2S2 | $33F3 .. $ | |
? | |||
| T2S2 | $3497 .. $34BA | FVCBUFS | n/a | 40 | VTOC tracks 41 - 50 sector bitmaps | |
| T2S2 | $34BB .. $34BB | FVCBUFS | VDTCDE | 1 | CAT Unused sector type 2 = CATALOG | |
| T0SC | DOSINIT | Wastes 12 bytes for Applesoft/Integer Func Pointers -- IBASVT | ||||
| Total | --- | --- | --- | 160 |
Â
There are two types of data that reside in both memory and on disk:
Â
There is no need store the uninitialized ones on disk IF they are placed after code. (Note: This may cause slightly more code, say copying a block of data that has both initialized and uninitialized parts, since the initialized and uninitialized data will no longer be contiguous. Usually uninitialized data are "large", say > 16 bytes, such as an array or buffer.) Even the EDASM manual states on Page 45 (my emphasis added):
This means that if you accidently enter a DS with an expression that comes up with a value of, say 48K bytes, you will suddenly get a very large output file. The expression is most often used as a relatively small constant, for small data areas, since large buffers and work areas should not be part of an object program, (unless of course you have disk space burning a hole in your diskette).
Apparently the authors of DOS 3.3 never got the memo -- see the section Wasted Sectors below.
For example, DOS does dumb shit like this: Interleaving code and data bloating the program stored on disk.
Example 1:
ORG $2000
WRK EQU $40
COUT EQU $FDED
PRNTYX EQU $F940
; --- begin code ---
MAIN EQU * ;=12 $2000
JSR FUNC1 ; +3
JSR FUNC2 ; +3
LDY #>END ; +2 hi byte of addr
LDX #*
REMDR EQU 256-HEREL ; pad to end of page
ORG *+REMDR
; $2100
BUF1 DS 256,0 ;+256 initialized
FNAME EQU * ; $2200
FNAME1 ASC "HELLO_________________________" ; +30 filename
FNAME1LEN EQU *-FNAME
FUNC1 EQU * ;=14 $221E
LDX #0 ; +2
PUTCHAR
LDA FNAME,X ; +3
JSR COUT ; +3
INX ; +1
CPX #FNAME1LEN ; +2
BNE PUTCHAR ; +2
RTS ; +1
FCB EQU * ;=4 $222C
FCB_SLOT DS 1 ; +1
FCB_DRIVE DS 1 ; +1
FCB_TRACK DS 1 ; +1
FCB_SECTOR DS 1 ; +1
FCB_LEN EQU *-FCB ;
FUNC2 EQU * ;=7 $2230
LDA #6 ; +2
STA FCB_SLOT ; +3
RTS ; +1
VTOC EQU * ; $2236 uninitialized
ORG VTOC+256 ;+256
END EQU * ;=822 $2336 bytes on disk
Which takes up a whopping total of 822 bytes ($336) in memory or (822 + 255)/256) = 4 sectors on disk!
Instead if we grouped all the code first, followed by all initialized data, and then all uninitialized data at the end "pre-allocating" them we will use significantly less disk space.
The only thing left to do is to add short "zero uninitialized data" stub at the beginning of our programs.
Example 2:
ORG $2000
WRK EQU $40
COUT EQU $FDED
PRNTYX EQU $F940
; --- begin zero uninitialized data (similiar to init bss) ---
; Zero memory from DATA_START .. DATA_END
; in 2 stages:
;
; DATA_START .. page of DATA_END
; page of DATA_END .. DATA_END
;
; +---------------+-------------+
; | 00 .. 00 | 00 .. 00 |
; +---------------+-------------|
; ^ ^ ^
; DATA_START DataEndPage DATA_END
; $2100 $2400 $2403
;
INIT ;=33 $2000
LDY #
LDX #>DATA_START ; +2 hi byte of addr: ca65, merlin; EDASM #<
STY WRK+0 ; +2
STX WRK+1 ; +2
LDA #0 ; +2
CHECK_PAGE
LDX WRK+1 ; +2
CPX #>DATA_END ; +2 hi byte of addr
BCS CHECK_PART ; +2 src >= end ?
CLEAR_PAGE
STA (WRK),Y ; +2
INY ; +1
BNE CLEAR_PAGE ; +2
INC WRK+1 ; +2
BNE CHECK_PAGE ; +2
; Zero from start of memory page of DATA_END .. DATA_END
CHECK_PART
LDX #
CLEAR_PART
STA (WRK),Y ; +2
INY ; +1
DEX ; +1
BNE CLEAR_PART ; +2
; --- end clear stub --- ;Sub-Total 33 bytes header code
; --- begin code ---
MAIN EQU * ;=12 $2021
JSR FUNC1 ; +3
JSR FUNC2 ; +3
LDY #>END ; +2 hi byte of addr
LDX #*
REMDR EQU 256-HEREL ; pad to end of page
ORG *+REMDR
; === begin data === Uninitialized data
DATA_START EQU *
BUF1 EQU * ; $2100
ORG *+256
VTOC EQU * ; $2200
ORG *+256
DATA_END EQU * ; $2300
; === end data ===
In contradistinction to the previous example, our new code plus initialized data only takes up 100 bytes ($64) in memory; This is only 1 sector on disk even though it uses the same Total run-time memory data bytes as Example 1 !
Â
| Track/Sector | File | Description |
|---|---|---|
| T0S5 | MSWAITR | Wastes 256 bytes for NBUF1 - entire sector is zero! |
| T0SB | DOSINIT | Wastes 127 bytes for padding to page align START DOS Vectors |
| T2S3 | FCVBUFS | Wastes 255 bytes for VTOC and an unused single byte of the start of the CATALOG ($02) @ $BB ! |
| T2S4 | FCVBUFS | Wastes 256 bytes for CATALOG remaining bytes since it spans two sectors |
| T2S5 - T2SF | n/a | Rest of Track 2 is reserved. See: HNTDAFS #4 and TODO |
Total sectors wasted: 14 !
Â
Why is DOS 3.3 so slow loading files when faster DOS's such as DiversiDOS, Pronto DOS, FastDOS, are able to load significantly faster?
When DOS has finished reading the raw disk nibbles into a buffer, it must "decode" the 342 nibbles into 256 bytes. Then it must copy the sector back to the caller's address space. This doesn't leave a whole lot of time. While there is sector interleaving DOS to help alleviate the lack of time this it isn't enough due to excessing buffering. DOS has significant overhead where it copies data from/to 3 buffers. TODO: citation In modern terminology this is known as buffer bloat.
Let's trace the BLOAD command to see what happens.
First, prepare a new blank disk that we'll use for testing.
Â
NEW
1 ? CHR$(4);"CATALOG"
2 END
3 HGR
4 FOR C=0 TO 7
5 HCOLOR=C:X=C*14:Z=(C+1)*14-1
6 FOR Y=0 TO 16:HPLOT X,Y TO Z,Y:NEXT
7 NEXT
INIT HELLO
RUN 3
BSAVE TEST,A$2000,L$1FF8
We've created a binary graphics file on track $13, sector $F .. track $14, sector $0. (Remember, DOS start at sector $F and works "down" sector $0.)
Here is the corresponding Track / Sector usage:
T13S0 $2EFC .. $2FFB
T13S1 $2DFC .. $2EFB
T13S2 $2CFC .. $2DFB
T13S3 $2BFC .. $2CFB
T13S4 $2AFC .. $2BFB
T13S5 $29FC .. $2AFB
T13S6 $28FC .. $29FB
T13S7 $27FC .. $28FB
T13S8 $26FC .. $27FB
T13S9 $25FC .. $26FB
T13SA $24FC .. $25FB
T13SB $23FC .. $24FB
T13SC $22FC .. $23FB
T13SD $21FC .. $22FB
T13SE $20FC .. $21FB
T13SE $2000 .. $20FB
T13SF Array of sectors for file TEST
T14S0 $3EFB .. $3FF7
T14S1 $3DFB .. $3EFB
T14S2 $3CFB .. $3DFB
T14S3 $3BFB .. $3CFB
T14S4 $3AFB .. $3BFB
T14S5 $39FB .. $3AFB
T14S6 $38FB .. $39FB
T14S7 $37FB .. $38FB
T14S8 $36FC .. $37FB
T14S9 $35FC .. $36FB
T14SA $34FC .. $35FB
T14SB $33FC .. $34FB
T14SC $32FC .. $33FB
T14SD $31FC .. $32FB
T14SE $30FC .. $31FB
T14SF $2FFC .. $30FB
And the corresponding Track / Sector disk map
T00000000000000001111111111111111222
T0123456789ABCDEF0123456789ABCDEF012
0.DDD..............V.BB..............
1.DDD..............C.BB..............
2.DDD..............C.BB..............
3.DDD..............C.BB..............
4.DDD..............C.BB..............
5.DD...............C.BB..............
6.DD...............C.BB..............
7.DD...............C.BB..............
8.DD...............C.BB..............
9.DD...............C.BB..............
A.DD...............C.BB..............
B.DD...............C.BB..............
C.DD...............C.BB..............
D.DD...............C.BB..............
E.DD...............CABB..............
F.DD...............CabB..............
T00000000000000001111111111111111222
T0123456789ABCDEF0123456789ABCDEF012
Legend:
a = Track/Sector List: HELLO
A = Applesoft program: HELLO
b = Track/Sector list of: TEST
B = Binary graphics file: TEST
C = Catalog
D = DOS 3.3 Boot
V = VTOC (Volume Table of Contents -- Free/Used sectors bitmap)
A special Thank-You to:
Apple ][ Forever!