30-04-2017  (2282 lectures) Categoria: Apple

RWTS - DOS 3.3C - Apple II

Apple DOS 3.3C Source Code (Unified HTML and Annotated Version)

0.0 Table of Contents

 

1.0 Introduction


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!

 

  • Syntax Highlighting
    • Linking all functions (blue) -- clicking on them will scroll to their declaration,
    • Linking all variables (green) -- clicking on them will scroll to their declaration,
    • All numbers (orange),
    • Inactive macro sections (gray)
    • Options for color or monochrome syntax highlighting
  • Line numbers,
  • Memory address and instruction opcodes,
  • Cleaned up sloppy vertical alignment (such as (#) clock cycles),
  • Unindented macro sections,
  • Snarky annotation commentary column,
  • Entire source code is a single continuous page.

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.

dumb How NOT to Design a File System, or
How NOT to Design an Operating System
wastes # bytes wasted due to bad architecture or inefficient code
disk Unitialized data, wasted sector
magic number Hard-Coded constant that the reader is assumed to know what it means
TODO Unanswered question(s)
CODE Code snippet
unused Unused code or reference
Misc.
MACRO Conditional code

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!

2.0 Assembly Source Code Listing



=== DOS33C - Master Source File, Page 39 ===

                    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


=== RELOCTR - Relocate DOS to high (48K) memory, Page 110, T0SA-T0SB, $1B00 .. $1C80 (n/a) ===

                    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


=== DOSINIT - Command Tables and Interpreter, Page 48, T0SB - T0SD, $9C81 .. $9E80 ===

                    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


=== DOSHOOK - Input / Output Vector, Pages 44 - 47, T0SD - T0SE, $9E81 .. $9FCC ===

                    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


=== CMDSCAN - Scan for commands, Page 16, T0SE - T1S0, $9FCD .. $A192 ===

                    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


=== XOPNCLS - Execute Open / Close, Pages 150 - 154, T1S0 - T1S2, $A193 .. $A330 ===

                    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


=== XLODSAV - Execute Load / Save, Pages 140 - 144, T1S2 - T1S4, $A331 .. $A50F ===

                    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


=== XMISCMD - Execute misc. commands, Pages 145 - 149, T1S4 - T1S5, $A510 .. $A6A7 ===

                    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


=== DOSGOER - Print Error message, Pages 40 - 43, T1S5 - T1S6, $A6A8 .. $A7D3 ===

                    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


=== BLDFTAB - Build File Tables, Page 4, T1S6 @ $D4 - T1S7 @ $83, $A7D4 .. $A883 ===

                    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


=== CMDTBLS - Commands, Page 21, T1S7 - T1S9, $A884 .. $AA4E ===

                    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


=== FDOSENT - External Entry Point, Pages 60 - 62, T1S9 @ $4F - T1SA @ $21, $2A4F .. $2B21 ===

                    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


=== FOPCLRW - Open; Close; Rename; Read, Page 77, T1SA - T1SB, $2B22 ($AB22) ===

                    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


=== FDELCAT - Delete, Catalog, Page 55, T1SB @ $EF - T1SD, $2CEF .. $2E8D ($ACEF .. $AE8D) ===

                    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


=== FMTRWIO - Execute Format Request, Page 73, T1SD - T1SE, $AE8E .. $AFF6 ===

                    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


=== FLOCNXB - Locate Next Byte, Page 63, T1SE - T2S0, $AFF7 .. $B1C8 ===

                    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


=== FLOCSEC - Locate Sector, Page 68, T2S0 - T2S2, $B1C9 .. $B396 ===

                    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 *


=== FVCBUFS - File Volume Catalog Buffers, Page 86, T2S2 @ $97 - T2S4 @ $FD, $B397 .. $B5FD ===

"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 ;


=== BOOTLDR - Boot loader, Page 8, T0S0 - T0S1, $B5FE .. $B7FF ===

                    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


=== COREQUS - Core Equates, Page 24, n/a, $n/a ===

                    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


=== PRENIBL - Prenibblize sector data for writing, Page 104, T0S2, $B800 .. $B829 ===

                    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


=== WRITRTN - Write Routine, Page 137, T0S2, $B82A .. $B8C1 ===

                    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


=== POSTNRD - Post Nibbilize Read, Page 101, T0S2 @ $C2 - T0S3 @ $43, $B8C2 .. $B943 ===

                    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.


=== RDADSEK - Read Disk Address; Seek, Page 106, T0S3 @ $44, $B944 .. $B9FC ===

                    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!


=== MSWAITR - Microsecond wait routine, Page 97, T0S3 @ $FD - T0S6 @ $55, $B9FD .. $BC55 ===

                    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


=== WRITADR - Write Address, Page 134, T0S6 @ $56, $BC56 .. $BCFF ===

                    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


=== RWTSONE - Read Write Track Sector - Part 1, Page 116, T0S7, $BD00 .. $BDAA ===

                    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


=== RWTSTWO - Read Write Track Sector - Part 2, Page 122, T0S7 - T0S8, $BDAB .. $BEAE ===

                    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


=== FORMATR - Format Disk, Page 82 - 85, T0S8 @ $AF.. T0S9 @ $C7, $BEAF .. $BFC7 ===

                    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 !


=== DOSPTCH - Revision B Patches, Page 52, T0S9 @ $C8, $BFC8 .. $BFFF ===

                    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


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      = 2AC3

B

    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      = 33A4

D

    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

E

    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

F

    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

G

    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

H

    HEXNUM     = ???
    HN0        = ???
    HN1        = ???
    HN2        = ???
    HOME       = FC58
    HERE3L     = 35FE
    HEREL      = 0081

I

    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

J

    JMPTO1     = 3E07

K

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       = 0026

M

    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      = 0036

P

    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

Q

    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        = 1D58

S

    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

T

    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      = 2B03

V

    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     = 26B7

Z

    ZPGFCB     = 0042
    ZPGWRK     = 0040
    ZRSET      = 03F2

3.2 Symbols (Address)

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      = 2AC3

B

    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      = 33A4

D

    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

E

    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     = ???
    ER