\ Disassembly of Opus EDOS 0.4 patched by EDOSPAT 4.60 (W) \ Greg Cook, 20/Feb/2009 \ Created with Watford DIS-ASM 1.20 \ Notes all done except Tube host code \ for which a commentary by J.G.Harston can be found at: \ http://mdfs.net/Software/Tube/BBC/Host.lst \ Comments beginning with capital letters are entry points \Paged ROM header 8000 4C B5 80 JMP &80B5 L.. \Language entry (RTS) 8003 4C 3D 80 JMP &803D L=. \Service entry 8006 82 ??? . \rom type: service only 8007 26 57 ROL &57 &W \copyright pointer 8009 4F ??? O \version byte and title 800A 50 55 BVC &8061 PU 800C 53 ??? S 800D 20 45 44 JSR &4445 ED 8010 4F ??? O 8011 53 ??? S 8012 20 00 30 JSR &3000 .0 \version string 8015 2E 34 30 ROL &3034 .40 8018 20 28 32 JSR &3228 (2 801B 30 20 BMI &803D 0 801D 46 65 LSR &65 Fe 801F 62 ??? b 8020 20 32 30 JSR &3032 20 8023 30 39 BMI &805E 09 8025 29 00 AND #&00 00000000 \copyright string 8027 28 PLP ( \(C) validated by MOS prior 8028 43 ??? C \to accepting ROM 8029 29 31 AND #&31 00110001 802B 39 38 34 AND &3438,Y 984 802E 20 41 6C JSR &6C41 Al 8031 61 6E ADC (&6E,X) an 8033 20 57 69 JSR &6957 Wi 8036 6C 6C 69 JMP (&696C) lli 8039 61 6D ADC (&6D,X) am 803B 73 ??? s 803C 00 BRK . \Paged ROM service 803D 20 03 B7 JSR &B703 .. \ROM service. call monitor 8040 C9 01 CMP #&01 00000001 \request absolute workspace 8042 F0 29 BEQ &806D .) 8044 C9 02 CMP #&02 00000010 \request private workspace 8046 F0 2C BEQ &8074 ., 8048 C9 03 CMP #&03 00000011 \boot 804A F0 45 BEQ &8091 .E 804C C9 04 CMP #&04 00000100 \unrecognised OSCLI 804E F0 47 BEQ &8097 .G 8050 C9 08 CMP #&08 00001000 \unrecognised OSWORD 8052 F0 49 BEQ &809D .I 8054 C9 09 CMP #&09 00001001 \*HELP 8056 F0 4B BEQ &80A3 .K 8058 C9 0A CMP #&0A 00001010 \claim absolute workspace 805A F0 4D BEQ &80A9 .M 805C C9 0F CMP #&0F 00001111 \vectors claimed 805E F0 49 BEQ &80A9 .I 8060 C9 12 CMP #&12 00010010 \initialise filing system 8062 F0 48 BEQ &80AC .H 8064 C9 FE CMP #&FE 11111110 \tube post initialisation 8066 F0 4E BEQ &80B6 .N 8068 C9 FF CMP #&FF 11111111 \tube main initialisation 806A F0 54 BEQ &80C0 .T 806C 60 RTS ` 806D C0 16 CPY #&16 00010110 \Request absolute workspace 806F B0 02 BCS &8073 .. \we need 8 pages 0E..15 incl. 8071 A0 16 LDY #&16 00010110 8073 60 RTS ` 8074 48 PHA H \Request private workspace 8075 98 TYA . \save our page number in the 8076 9D F0 0D STA &0DF0,X ... \OS ROM table 8079 85 A9 STA &A9 .. \and in high byte of pointer 807B 18 CLC . \claim one page 807C 69 01 ADC #&01 00000001 807E A8 TAY . 807F 68 PLA h \restore ROM call number 8080 20 00 92 JSR &9200 .. \save AXY 8083 AD 8D 02 LDA &028D ... \get last reset type 8086 F0 08 BEQ &8090 .. \if not 0 soft break 8088 A0 00 LDY #&00 00000000 \then low byte of pointer =0 808A 84 A8 STY &A8 .. \clear workspace flag in 808C A0 0D LDY #&0D 00001101 \byte &D of private page 808E 91 A8 STA (&A8),Y .. \marking it uninitialised. 8090 60 RTS ` 8091 20 C6 80 JSR &80C6 .. \Boot. test boot key 8094 B0 1A BCS &80B0 .. \if okay boot the disc 8096 60 RTS ` 8097 20 03 81 JSR &8103 .. \Unrecognised OSCLI. scan it 809A B0 17 BCS &80B3 .. \if we ran it break out 809C 60 RTS ` 809D 20 00 BA JSR &BA00 .. \Unrecognised OSWORD. compare 80A0 B0 11 BCS &80B3 .. \with our codes && break out 80A2 60 RTS ` 80A3 20 06 81 JSR &8106 .. \*HELP. search our topics 80A6 B0 0B BCS &80B3 .. \if specific to us break out 80A8 60 RTS ` 80A9 4C 06 96 JMP &9606 L.. \Wksp claim/vectors changed. 80AC C0 04 CPY #&04 00000100 \Initialise FS. our FS ID = 4 80AE D0 05 BNE &80B5 .. 80B0 20 03 96 JSR &9603 .. 80B3 A9 00 LDA #&00 00000000 \Break out of ROM call chain. 80B5 60 RTS ` 80B6 C0 00 CPY #&00 00000000 \Post-initialise Tube. 80B8 F0 FB BEQ &80B5 .. \edos ignores if Y=0 80BA 20 03 A0 JSR &A003 .. \otherwise it does post-init 80BD A9 00 LDA #&00 00000000 \and consumes the call. 80BF 60 RTS ` 80C0 20 00 A0 JSR &A000 .. \Initialise Tube. 80C3 A9 00 LDA #&00 00000000 \edos consumes this call 80C5 60 RTS ` 80C6 20 00 92 JSR &9200 .. \Test boot key 80C9 A9 7A LDA #&7A 01111010 \scan keyboard from code &10 80CB 20 F4 FF JSR &FFF4 .. 80CE 8A TXA . 80CF 30 09 BMI &80DA 0. \if no keypress C=1, allow boot 80D1 C9 32 CMP #&32 00110010 \if key is not "D" disallow boot 80D3 D0 07 BNE &80DC .. 80D5 A9 78 LDA #&78 01111000 \else register keypress for 2KR 80D7 20 F4 FF JSR &FFF4 .. 80DA 38 SEC 8 \return C=1 allow boot 80DB 60 RTS ` 80DC 18 CLC . \return C=0 disallow boot 80DD 60 RTS ` \Keyword recognition and help subsystem 8100 4C 0C 81 JMP &810C L.. \OSFSC 3 8103 4C 1A 81 JMP &811A L.. \OSCLI 8106 4C 13 81 JMP &8113 L.. \*HELP 8109 4C 70 81 JMP &8170 Lp. \Print syntax for command 810C 20 00 92 JSR &9200 .. \OSFSC 3. scan DFS commands 810F A2 2C LDX #&2C 00101100 8111 D0 0C BNE &811F .. 8113 20 00 92 JSR &9200 .. \*HELP. scans help keywords 8116 A2 E0 LDX #&E0 11100000 8118 D0 05 BNE &811F .. 811A 20 00 92 JSR &9200 .. \OSCLI. scans UTILS commands 811D A2 00 LDX #&00 00000000 811F 20 C2 FF JSR &FFC2 .. \Scan. call GSINIT on keyword 8122 8A TXA . \x=table offset. save X 8123 48 PHA H 8124 98 TYA . \save GSINIT offset in Y 8125 48 PHA H 8126 BD 1B 82 LDA &821B,X ... \get character from table 8129 F0 41 BEQ &816C .A \if NUL then exit C=0 812B 30 1F BMI &814C 0. \if terminator test completeness 812D 51 F2 EOR (&F2),Y Q. \else compare with command char 812F 29 DF AND #&DF 11011111 \make test case insensitive 8131 D0 04 BNE &8137 .. \if unequal test if abbreviated 8133 E8 INX . \else increment table offset 8134 C8 INY . \increment command offset 8135 D0 EF BNE &8126 .. \and loop. 8137 E8 INX . \search tbl for next terminator 8138 BD 1B 82 LDA &821B,X ... 813B 10 FA BPL &8137 .. 813D B1 F2 LDA (&F2),Y .. \get char where search stopped 813F C8 INY . \increment command offset 8140 C9 2E CMP #&2E 00101110 \was it a dot? 8142 F0 14 BEQ &8158 .. \if so accept the abbreviation 8144 68 PLA h \else restore command offset 8145 A8 TAY . \to start 8146 68 PLA h \discard old table offset 8147 E8 INX . \increment table offset by 3 to 8148 E8 INX . \skip syntax and action address 8149 E8 INX . 814A D0 D6 BNE &8122 .. \and compare with next keyword. 814C B1 F2 LDA (&F2),Y .. \get character after command 814E 29 DF AND #&DF 11011111 \convert to uppercase 8150 C9 41 CMP #&41 01000001 \is it less than "A"? 8152 90 04 BCC &8158 .. \then accept the command 8154 C9 5B CMP #&5B 01011011 \is it less than "Z"? 8156 90 EC BCC &8144 .. \then table entry was too short! 8158 BD 1C 82 LDA &821C,X ... \else accept command. 815B 85 A8 STA &A8 .. \get action address 815D BD 1D 82 LDA &821D,X ... \store in temp pointer 8160 85 A9 STA &A9 .. 8162 18 CLC . 8163 20 C2 FF JSR &FFC2 .. \call GSINIT on command tail 8166 68 PLA h \discard old GSINIT offset 8167 68 PLA h \get tbl offset of this command 8168 AA TAX . \place in X 8169 6C A8 00 JMP (&00A8) l.. \and jump to the action address. 816C 68 PLA h \command not found. 816D 68 PLA h \discard offsets 816E 18 CLC . \offer command to lower ROMs 816F 60 RTS ` \exit 8170 20 18 90 JSR &9018 .. \Print syntax for command 8173 08 PHP . \X=offset to help entry 8174 DC ??? . \error 220, "Syntax" 8175 53 ??? S 8176 79 6E 74 ADC &746E,Y ynt 8179 61 78 ADC (&78,X) ax 817B 3A ??? : 817C 00 BRK . 817D 20 F1 81 JSR &81F1 .. \print help entry 8180 20 09 90 JSR &9009 .. \display error (never returns) 8183 A9 02 LDA #&02 00000010 \*HELP 8185 A2 E3 LDX #&E3 11100011 \one column.point to keywd table 8187 20 94 81 JSR &8194 .. \print help keywords 818A 18 CLC . \pass call to lower ROMs 818B 60 RTS ` \exit 818C A2 2C LDX #&2C 00101100 \*HELP DFS 818E D0 02 BNE &8192 .. \point to DFS table 8190 A2 00 LDX #&00 00000000 \*HELP UTILS 8192 A9 01 LDA #&01 00000001 \Print help table, two columns: 8194 85 AA STA &AA .. \Print help table. 8196 20 C8 83 JSR &83C8 .. \print newline then EDOS banner 8199 20 F1 81 JSR &81F1 .. \print help entry 819C E8 INX . \skip syntax and action address 819D E8 INX . 819E E8 INX . 819F BD 18 82 LDA &8218,X ... \search keyword just printed 81A2 10 FA BPL &819E .. \until terminator found 81A4 BD 1B 82 LDA &821B,X ... \test first char of next keyword 81A7 F0 16 BEQ &81BF .. \if NUL print newline and exit 81A9 A5 AA LDA &AA .. \else toggle b0 of column flag 81AB 49 01 EOR #&01 00000001 81AD 85 AA STA &AA .. 81AF F0 06 BEQ &81B7 .. \if any bit is set 81B1 20 09 90 JSR &9009 .. \print newline 81B4 4C 99 81 JMP &8199 L.. \and loop 81B7 A9 28 LDA #&28 00101000 \else tab to column 40 81B9 20 06 90 JSR &9006 .. 81BC 4C 99 81 JMP &8199 L.. \and loop. 81BF 20 09 90 JSR &9009 .. \print newline 81C2 38 SEC 8 \break out of ROM call 81C3 60 RTS ` \exit 81C4 20 C8 83 JSR &83C8 .. \*HELP EDOS 81C7 20 18 90 JSR &9018 .. \print newline then EDOS banner 81CA 02 ??? . \EDOSPAT version number 81CB 45 44 EOR &44 ED \target controller 81CD 4F ??? O \and EDOSPAT author 81CE 53 ??? S 81CF 50 41 BVC &8212 PA 81D1 54 ??? T 81D2 20 34 2E JSR &2E34 4. 81D5 36 30 ROL &30,X 60 81D7 20 28 57 JSR &5728 (W 81DA 29 20 AND #&20 00100000 81DC 4F ??? O 81DD 70 75 BVS &8254 pu 81DF 73 ??? s 81E0 20 32 37 JSR &3732 27 81E3 39 31 20 AND &2031,Y 91 81E6 20 3A 47 JSR &473A :G 81E9 2E 43 6F ROL &6F43 .Co 81EC 6F ??? o 81ED 6B ??? k 81EE 00 BRK . 81EF 38 SEC 8 81F0 60 RTS ` 81F1 20 00 92 JSR &9200 .. \Print help entry, X=offset. 81F4 A9 02 LDA #&02 00000010 \tab to column 2 or more 81F6 20 06 90 JSR &9006 .. \returning current POS in A 81F9 48 PHA H \save POS 81FA BD 1B 82 LDA &821B,X ... \get character from table 81FD 30 06 BMI &8205 0. \if not the terminator 81FF 20 00 90 JSR &9000 .. \print the character 8202 E8 INX . \advance offset 8203 D0 F5 BNE &81FA .. \and loop 8205 29 7F AND #&7F 01111111 \else mask terminator 8207 AA TAX . \to get offset of syntax 8208 68 PLA h \get back POS 8209 18 CLC . \add 9 820A 69 09 ADC #&09 00001001 820C 20 06 90 JSR &9006 .. \tab to 9 places after command 820F BD 14 83 LDA &8314,X ... \get character from syntax 8212 F0 06 BEQ &821A .. \if NUL then exit 8214 20 00 90 JSR &9000 .. \else print the character 8217 E8 INX . \advance offset 8218 D0 F5 BNE &820F .. \and loop. 821A 60 RTS ` 821B 42 ??? B \Table of UTILS commands 821C 55 49 EOR &49,X UI \*BUILD. Command name 821E 4C 44 BA JMP &BA44 LD. \Syntax fsp (b7 set) 8221 00 BRK . \Action address &8400 8222 84 44 STY &44 .D \*DISC I, &8403 8224 49 53 EOR #&53 01010011 8226 43 ??? C 8227 B8 CLV . 8228 03 ??? . 8229 84 44 STY &44 .D \*DISK I, &8403 822B 49 53 EOR #&53 01010011 822D 4B ??? K 822E B8 CLV . 822F 03 ??? . 8230 84 44 STY &44 .D \*DUMP fsp, &8406 8232 55 4D EOR &4D,X UM 8234 50 BA BVC &81F0 P. 8236 06 84 ASL &84 .. 8238 4C 49 53 JMP &5349 LIS \*LIST fsp, &8409 823B 54 ??? T 823C BA TSX . 823D 09 84 ORA #&84 10000100 823F 54 ??? T \*TYPE fsp, &840C 8240 59 50 45 EOR &4550,Y YPE 8243 BA TSX . 8244 0C ??? . 8245 84 00 STY &00 .. 8247 41 43 EOR (&43,X) AC \Table of DFS commands 8249 43 ??? C \*ACCESS fsp L, &8600 824A 45 53 EOR &53 ES 824C 53 ??? S 824D 80 ??? . 824E 00 BRK . 824F 86 42 STX &42 .B \*BACKUP drv drv, &8A00 8251 41 43 EOR (&43,X) AC 8253 4B ??? K 8254 55 50 EOR &50,X UP 8256 88 DEY . 8257 00 BRK . 8258 8A TXA . 8259 43 ??? C \*CATGEN vol ..., &A903 825A 41 54 EOR (&54,X) AT 825C 47 ??? G 825D 45 4E EOR &4E EN 825F E1 03 SBC (&03,X) .. 8261 A9 43 LDA #&43 01000011 \*COMPACT vol, &8A03 8263 4F ??? O 8264 4D 50 41 EOR &4150 MPA 8267 43 ??? C 8268 54 ??? T 8269 9B ??? . 826A 03 ??? . 826B 8A TXA . 826C 43 ??? C \*COPY vol vol afsp, &8A06 826D 4F ??? O 826E 50 59 BVC &82C9 PY 8270 9F ??? . 8271 06 8A ASL &8A .. 8273 44 ??? D \*DELETE fsp, &8606 8274 45 4C EOR &4C EL 8276 45 54 EOR &54 ET 8278 45 BA EOR &BA E. 827A 06 86 ASL &86 .. 827C 44 ??? D \*DESTROY afsp, &8609 827D 45 53 EOR &53 ES 827F 54 ??? T 8280 52 ??? R 8281 4F ??? O 8282 59 B3 09 EOR &09B3,Y Y.. 8285 86 44 STX &44 .D \*DIR dir, &860C 8287 49 52 EOR #&52 01010010 8289 BE 0C 86 LDX &860C,Y ... 828C 44 ??? D \*DRIVE vol, &8627 828D 52 ??? R 828E 49 56 EOR #&56 01010110 8290 45 9B EOR &9B E. 8292 27 ??? ' 8293 86 45 STX &45 .E \*ENABLE, &8A09 8295 4E 41 42 LSR &4241 NAB 8298 4C 45 B7 JMP &B745 LE. 829B 09 8A ORA #&8A 10001010 829D 46 43 LSR &43 FC \*FCOPY fsp name, &8A12 829F 4F ??? O 82A0 50 59 BVC &82FB PY 82A2 C2 ??? . 82A3 12 ??? . 82A4 8A TXA . 82A5 46 4F LSR &4F FO \*FORMAT drv ..., &A900 82A7 52 ??? R 82A8 4D 41 54 EOR &5441 MAT 82AB F5 00 SBC &00,X .. 82AD A9 49 LDA #&49 01001001 \*INFO afsp, &8612 82AF 4E 46 4F LSR &4F46 NFO 82B2 B3 ??? . 82B3 12 ??? . 82B4 86 4C STX &4C .L \*LIB dir, &8615 82B6 49 42 EOR #&42 01000010 82B8 BE 15 86 LDX &8615,Y ... 82BB 4C 4F 43 JMP &434F LOC \*LOCK afsp, &8621 82BE 4B ??? K 82BF B3 ??? . 82C0 21 86 AND (&86,X) !. 82C2 52 ??? R \*RENAME fsp name, &8618 82C3 45 4E EOR &4E EN 82C5 41 4D EOR (&4D,X) AM 82C7 45 C2 EOR &C2 E. 82C9 18 CLC . 82CA 86 53 STX &53 .S \*SCOPY vol vol afsp, &8A0F 82CC 43 ??? C 82CD 4F ??? O 82CE 50 59 BVC &8329 PY 82D0 9F ??? . 82D1 0F ??? . 82D2 8A TXA . 82D3 54 ??? T \*TITLE title, &861B 82D4 49 54 EOR #&54 01010100 82D6 4C 45 DB JMP &DB45 LE. 82D9 1B ??? . 82DA 86 55 STX &55 .U \*UNLOCK afsp, &8624 82DC 4E 4C 4F LSR &4F4C NLO 82DF 43 ??? C 82E0 4B ??? K 82E1 B3 ??? . 82E2 24 86 BIT &86 $. 82E4 56 45 LSR &45,X VE \*VERIFY drv, &A906 82E6 52 ??? R 82E7 49 46 EOR #&46 01000110 82E9 59 F1 06 EOR &06F1,Y Y.. 82EC A9 56 LDA #&56 01010110 \*VOL vol, &8627 82EE 4F ??? O 82EF 4C 9B 27 JMP &279B L.' 82F2 86 57 STX &57 .W \*WIPE afsp, &861E 82F4 49 50 EOR #&50 01010000 82F6 45 B3 EOR &B3 E. 82F8 1E 86 00 ASL &0086,X ... \Help keywords 82FB B7 ??? . \*HELP, &83DA 82FC DA ??? . 82FD 83 ??? . 82FE 45 44 EOR &44 ED \*HELP EDOS, &81C4 8300 4F ??? O 8301 53 ??? S 8302 B7 ??? . 8303 C4 81 CPY &81 .. 8305 44 ??? D \*HELP DFS, &818C 8306 46 53 LSR &53 FS 8308 B7 ??? . 8309 8C 81 55 STY &5581 ..U \*HELP UTILS, &8190 830C 54 ??? T 830D 49 4C EOR #&4C 01001100 830F 53 ??? S 8310 B7 ??? . 8311 90 81 BCC &8294 .. 8313 00 BRK . 8314 61 66 ADC (&66,X) af \Syntax particles 8316 73 ??? s \afsp L 8317 70 20 BVS &8339 p 8319 20 4C 00 JSR &004C L. 831C 73 ??? s \src drv dest drv 831D 72 ??? r 831E 63 ??? c 831F 20 64 72 JSR &7264 dr 8322 76 20 ROR &20,X v 8324 20 20 64 JSR &6420 d 8327 65 73 ADC &73 es 8329 74 ??? t 832A 20 64 72 JSR &7264 dr 832D 76 00 ROR &00,X v. 832F 76 6F ROR &6F,X vo \vol 8331 6C 00 73 JMP (&7300) l.s \src vol dest vol afsp 8334 72 ??? r 8335 63 ??? c 8336 20 76 6F JSR &6F76 vo 8339 6C 20 20 JMP (&2020) l 833C 20 64 65 JSR &6564 de 833F 73 ??? s 8340 74 ??? t 8341 20 76 6F JSR &6F76 vo 8344 6C 20 20 JMP (&2020) l 8347 61 66 ADC (&66,X) af 8349 73 ??? s 834A 70 00 BVS &834C p. \(empty syntax) 834C 49 00 EOR #&00 00000000 \I 834E 66 73 ROR &73 fs \fsp 8350 70 00 BVS &8352 p. 8352 64 ??? d \dir 8353 69 72 ADC #&72 01110010 8355 00 BRK . 8356 6F ??? o \old fsp new entry name 8357 6C 64 20 JMP (&2064) ld 835A 66 73 ROR &73 fs 835C 70 20 BVS &837E p 835E 20 20 6E JSR &6E20 n 8361 65 77 ADC &77 ew 8363 20 65 6E JSR &6E65 en 8366 74 ??? t 8367 72 ??? r 8368 79 20 6E ADC &6E20,Y y n 836B 61 6D ADC (&6D,X) am 836D 65 00 ADC &00 e. 836F 74 ??? t \title 8370 69 74 ADC #&74 01110100 8372 6C 65 00 JMP (&0065) le. 8375 64 ??? d \drv vol specs 8376 72 ??? r 8377 76 20 ROR &20,X v 8379 20 20 76 JSR &7620 v 837C 6F ??? o 837D 6C 20 73 JMP (&7320) l s 8380 70 65 BVS &83E7 pe 8382 63 ??? c 8383 73 ??? s 8384 00 BRK . 8385 64 ??? d \drv 8386 72 ??? r 8387 76 00 ROR &00,X v. 8389 64 ??? d \drv S D 40 80 40-80 Oo 838A 72 ??? r 838B 76 20 ROR &20,X v 838D 20 53 20 JSR &2053 S 8390 20 44 20 JSR &2044 D 8393 20 34 30 JSR &3034 40 8396 20 20 38 JSR &3820 8 8399 30 20 BMI &83BB 0 839B 20 34 30 JSR &3034 40 839E 2D 38 30 AND &3038 -80 83A1 20 20 4F JSR &4F20 O 83A4 6F ??? o 83A5 00 BRK . \EDOSPAT extensions, block 1 83C8 20 09 90 JSR &9009 .. \Print newline then EDOS banner 83CB 4C 00 96 JMP &9600 L.. 83CE 20 00 96 JSR &9600 .. \Print EDOS banner then newline 83D1 4C 09 90 JMP &9009 L.. 83D4 B9 00 01 LDA &0100,Y ... \Get character from *DUMP row 83D7 C9 7F CMP #&7F 01111111 \exit C=1 if DEL or higher. 83D9 60 RTS ` 83DA 18 CLC . \*HELP with empty keyword: 83DB 20 C2 FF JSR &FFC2 .. \call GSINIT on current position 83DE F0 0F BEQ &83EF .. \if end-of-string then scan kywd 83E0 C9 2E CMP #&2E 00101110 \else test if first char is dot 83E2 D0 09 BNE &83ED .. \if not then ignore call, else: 83E4 20 C4 81 JSR &81C4 .. \*HELP . 83E7 20 8C 81 JSR &818C .. \do *HELP EDOS, *HELP DFS 83EA 20 90 81 JSR &8190 .. \do *HELP UTILS 83ED 18 CLC . \and pass *HELP . to lower ROMs. 83EE 60 RTS ` 83EF 98 TYA . \scan for end of keyword: 83F0 F0 0B BEQ &83FD .. \if start-of-string then *HELP 83F2 88 DEY . \else step back one character 83F3 B1 F2 LDA (&F2),Y .. \fetch it 83F5 C9 20 CMP #&20 00100000 \if space then keep scanning 83F7 F0 F6 BEQ &83EF .. 83F9 C9 22 CMP #&22 00100010 \if double quotes 83FB F0 F0 BEQ &83ED .. \then ignore the call 83FD 4C 83 81 JMP &8183 L.. \if anything else then *HELP \Utilities 8400 4C 0F 84 JMP &840F L.. \*BUILD 8403 4C 71 84 JMP &8471 Lq. \*DISC, *DISK 8406 4C 82 84 JMP &8482 L.. \*DUMP 8409 4C F4 84 JMP &84F4 L.. \*LIST 840C 4C 1F 85 JMP &851F L.. \*TYPE 840F A9 80 LDA #&80 10000000 \*BUILD 8411 20 3B 85 JSR &853B ;. \open file for writing 8414 20 67 84 JSR &8467 g. \flush all open files 8417 20 73 85 JSR &8573 s. \increment line number 841A 20 8B 85 JSR &858B .. \print line number 841D 20 44 84 JSR &8444 D. \input line 8420 A6 AA LDX &AA .. \get low byte of pointer 8422 E4 AF CPX &AF .. \compare with line length 8424 F0 0B BEQ &8431 .. \if equal input next line 8426 A2 00 LDX #&00 00000000 \else get char at pointer 8428 A1 AA LDA (&AA,X) .. 842A 20 D4 FF JSR &FFD4 .. \call OSBPUT 842D E6 AA INC &AA .. \advance pointer 842F D0 EF BNE &8420 .. \loop until end of buffer 8431 24 FF BIT &FF $. \test escape flag 8433 10 E2 BPL &8417 .. \if clear input next line 8435 98 TYA . \else save file handle 8436 48 PHA H 8437 A9 7E LDA #&7E 01111110 \acknowledge Escape 8439 20 F4 FF JSR &FFF4 .. 843C 68 PLA h \restore file handle 843D A8 TAY . 843E 20 E7 FF JSR &FFE7 .. \print newline 8441 4C 6C 85 JMP &856C Ll. \close file and exit. 8444 20 00 92 JSR &9200 .. \Input line 8447 88 DEY . \Y=handle, point to previous 8448 C0 11 CPY #&11 00010001 \buffer. If buffer was &11 844A B0 02 BCS &844E .. \or less, point to next 844C C8 INY . \buffer. 844D C8 INY . 844E 84 AB STY &AB .. \store high byte of pointer 8450 A0 FF LDY #&FF 11111111 8452 84 AC STY &AC .. \maximum line length = 255 8454 84 AE STY &AE .. \maximum ASCII value = 255 8456 C8 INY . \set Y=0 8457 84 AA STY &AA .. \clear low byte of pointer 8459 84 AD STY &AD .. \minimum ASCII value = 0 845B 98 TYA . \set A=0 845C A2 AA LDX #&AA 10101010 \point XY to parameter block 845E 20 F1 FF JSR &FFF1 .. \call OSWORD to input line 8461 B0 01 BCS &8464 .. \if user did not Escape 8463 C8 INY . \add 1 for the CR character 8464 84 AF STY &AF .. \return length of line in &AF 8466 60 RTS ` 8467 20 00 92 JSR &9200 .. \Flush all open files 846A A9 FF LDA #&FF 11111111 846C A0 00 LDY #&00 00000000 846E 4C DA FF JMP &FFDA L.. 8471 20 C5 FF JSR &FFC5 .. \*DISC, *DISK 8474 A0 01 LDY #&01 00000001 \call GSREAD for next char 8476 B0 05 BCS &847D .. \if EOS init EDOS, Y=1 no boot 8478 C9 49 CMP #&49 01001001 \else is character "I"? 847A D0 01 BNE &847D .. \if not init EDOS, Y=1 no boot 847C 88 DEY . \else Y=0 to boot default drive 847D 20 03 96 JSR &9603 .. \initialise EDOS 8480 38 SEC 8 \C=1, exit and break ROM call 8481 60 RTS ` 8482 20 39 85 JSR &8539 9. \*DUMP 8485 AE 55 03 LDX &0355 .U. \open file, get current MODE 8488 BD EC 84 LDA &84EC,X ... \get ASCII column tab for MODE 848B 85 AA STA &AA .. \store in temp 848D BD E4 84 LDA &84E4,X ... \get bytes per row for MODE 8490 85 AF STA &AF .. \store in temp 8492 20 93 85 JSR &8593 .. \BGET byte 8495 B0 27 BCS &84BE .' \if EOF close file 8497 20 8A 85 JSR &858A .. \else print file offset+space 849A 20 79 85 JSR &8579 y. \add bytes/row to file offset 849D A6 AF LDX &AF .. \X=bytes per row 849F 24 AA BIT &AA $. \if b7 of tab clear 84A1 30 03 BMI &84A6 0. 84A3 20 03 90 JSR &9003 .. \then print space. 84A6 38 SEC 8 \permit leading zero 84A7 20 0F 90 JSR &900F .. \print hex byte 84AA 9D 00 01 STA &0100,X ... \store byte for ASCII column 84AD CA DEX . \decrement column counter 84AE D0 06 BNE &84B6 .. \if no more columns 84B0 20 C1 84 JSR &84C1 .. \print ASCII column 84B3 4C 92 84 JMP &8492 L.. \and loop for next row. 84B6 20 93 85 JSR &8593 .. \else BGET next byte 84B9 90 E4 BCC &849F .. \if no EOF print it and loop 84BB 20 C1 84 JSR &84C1 .. \else flush ASCII column 84BE 4C 6C 85 JMP &856C Ll. \close file and exit. 84C1 20 00 92 JSR &9200 .. \Print ASCII column 84C4 A5 AA LDA &AA .. \X=no.chars not to print 84C6 29 7F AND #&7F 01111111 \mask print-space bit off tab 84C8 20 06 90 JSR &9006 .. \tab to screen column 84CB A4 AF LDY &AF .. \Y=bytes per row 84CD 20 D4 83 JSR &83D4 .. \get byte from stack page 84D0 B0 04 BCS &84D6 .. \if >=&7F print a dot 84D2 C9 20 CMP #&20 00100000 \else if >=&20 print character 84D4 B0 02 BCS &84D8 .. 84D6 A9 2E LDA #&2E 00101110 \else print a dot 84D8 20 00 90 JSR &9000 .. 84DB 88 DEY . \decrement byte pointer 84DC E8 INX . \increment bytes not to print 84DD E4 AF CPX &AF .. \if result <> bytes per column 84DF D0 EC BNE &84CD .. \then loop for next character 84E1 4C E7 FF JMP &FFE7 L.. \else print newline and exit. 84E4 10 08 BPL &84EE .. \*DUMP bytes/row in MODEs [0..7] 84E6 04 ??? . 84E7 10 08 BPL &84F1 .. 84E9 04 ??? . 84EA 08 PHP . 84EB 08 PHP . 84EC 37 ??? 7 \*DUMP ASCII tab in MODEs [0..7] 84ED 1F ??? . 84EE 8E 37 1F STX &1F37 .7. 84F1 8E 1F 1F STX &1F1F ... 84F4 20 39 85 JSR &8539 9. \*LIST 84F7 20 93 85 JSR &8593 .. \open file, BGET char 84FA B0 70 BCS &856C .p \if EOF close file 84FC 20 73 85 JSR &8573 s. \else increment line number 84FF 20 8B 85 JSR &858B .. \print line number 8502 20 E3 FF JSR &FFE3 .. \call OSASCI to print char 8505 C9 0D CMP #&0D 00001101 \was it CR? 8507 F0 EE BEQ &84F7 .. \if so start next line 8509 C9 0A CMP #&0A 00001010 \was it LF? 850B F0 07 BEQ &8514 .. \if so BGET+OSWRCH next char 850D 20 93 85 JSR &8593 .. \else BGET next character 8510 B0 5A BCS &856C .Z \if EOF close file 8512 90 EE BCC &8502 .. \else print char and loop. 8514 20 93 85 JSR &8593 .. \test Escape and BGET char 8517 B0 53 BCS &856C .S \if EOF close file 8519 20 EE FF JSR &FFEE .. \else call OSWRCH to print 851C 4C 05 85 JMP &8505 L.. \interpret char and loop. 851F 20 39 85 JSR &8539 9. \*TYPE 8522 20 93 85 JSR &8593 .. \open file, BGET char 8525 B0 45 BCS &856C .E \if EOF close file 8527 20 E3 FF JSR &FFE3 .. \else print char with OSASCI 852A C9 0A CMP #&0A 00001010 \was it LF? 852C D0 F4 BNE &8522 .. \if not loop for next char 852E 20 93 85 JSR &8593 .. \else BGET next char 8531 B0 39 BCS &856C .9 \if EOF close file 8533 20 EE FF JSR &FFEE .. \else call OSWRCH to print 8536 4C 2A 85 JMP &852A L*. \interpret char and loop. 8539 A9 40 LDA #&40 01000000 \Open file for reading 853B 20 00 92 JSR &9200 .. \Open file 853E 48 PHA H \save A 853F 98 TYA . \GSREAD pointer (&F2),Y 8540 18 CLC . \points to filename. 8541 65 F2 ADC &F2 e. \calculate XY = &F2,3 + Y 8543 AA TAX . \X = Y + &F2 8544 A9 00 LDA #&00 00000000 \A = 0 8546 85 A8 STA &A8 .. \as side effect line no.=0 8548 85 A9 STA &A9 .. \Y = 0 + &F3 + carry 854A 65 F3 ADC &F3 e. 854C A8 TAY . 854D 68 PLA h \restore A file open mode 854E 20 CE FF JSR &FFCE .. \call OSFIND to open file 8551 BA TSX . \return handle in Y 8552 9D 03 01 STA &0103,X ... 8555 AA TAX . \if handle = 0 8556 D0 1A BNE &8572 .. 8558 20 18 90 JSR &9018 .. \give "File not found" error. 855B 0A ASL A . 855C D6 46 DEC &46,X .F 855E 69 6C ADC #&6C 01101100 8560 65 20 ADC &20 e 8562 6E 6F 74 ROR &746F not 8565 20 66 6F JSR &6F66 fo 8568 75 6E ADC &6E,X un 856A 64 ??? d 856B 00 BRK . 856C A9 00 LDA #&00 00000000 \Close file 856E 20 CE FF JSR &FFCE .. \break unrecognised OSCLI 8571 38 SEC 8 \ROM call and exit 8572 60 RTS ` 8573 48 PHA H \Increment line number 8574 F8 SED . 8575 A9 01 LDA #&01 00000001 8577 D0 03 BNE &857C .. 8579 48 PHA H \Add bytes/row to file offset 857A A5 AF LDA &AF .. 857C 18 CLC . 857D 65 A8 ADC &A8 e. 857F 85 A8 STA &A8 .. 8581 A9 00 LDA #&00 00000000 8583 65 A9 ADC &A9 e. 8585 85 A9 STA &A9 .. 8587 D8 CLD . 8588 68 PLA h 8589 60 RTS ` 858A 38 SEC 8 \Print offset w/leading zeroes 858B 20 15 90 JSR &9015 .. \Print BCD line no at &00A8 858E A8 TAY . 858F 00 BRK . 8590 4C 03 90 JMP &9003 L.. \print space and exit 8593 24 FF BIT &FF $. \Test Escape and BGET 8595 30 DA BMI &8571 0. 8597 4C D7 FF JMP &FFD7 L.. \'Light' DFS commands 8600 4C 2A 86 JMP &862A L*. \*ACCESS 8603 4C 74 86 JMP &8674 Lt. \*CAT 8606 4C BC 87 JMP &87BC L.. \*DELETE 8609 4C CD 87 JMP &87CD L.. \*DESTROY 860C 4C 0E 88 JMP &880E L.. \*DIR 860F 4C 28 88 JMP &8828 L(. \Was *DRIVE 8612 4C 42 88 JMP &8842 LB. \*INFO 8615 4C 35 88 JMP &8835 L5. \*LIB 8618 4C 54 88 JMP &8854 LT. \*RENAME 861B 4C 91 88 JMP &8891 L.. \*TITLE 861E 4C B9 88 JMP &88B9 L.. \*WIPE 8621 4C 3E 86 JMP &863E L>. \*LOCK 8624 4C 4C 86 JMP &864C LL. \*UNLOCK 8627 4C 1B 88 JMP &881B L.. \*VOL, *DRIVE 862A 20 15 93 JSR &9315 .. \*ACCESS 862D 20 C5 FF JSR &FFC5 .. \get afsp, call GSREAD 8630 B0 1D BCS &864F .. \if end of string unlock file 8632 C9 4C CMP #&4C 01001100 \else is character "L"? 8634 D0 05 BNE &863B .. \if not print syntax and exit 8636 20 C5 FF JSR &FFC5 .. \call GSREAD for next char 8639 B0 06 BCS &8641 .. \if end of string lock file 863B 4C 09 81 JMP &8109 L.. \else print syntax and exit 863E 20 15 93 JSR &9315 .. \*LOCK 8641 20 6A 86 JSR &866A j. \select file, dir in A 8644 09 80 ORA #&80 10000000 \set attribute bit 8646 20 5A 86 JSR &865A Z. \update file, select next 8649 90 F9 BCC &8644 .. \loop until no more files 864B 60 RTS ` 864C 20 15 93 JSR &9315 .. \*UNLOCK 864F 20 6A 86 JSR &866A j. \select file, dir in A 8652 29 7F AND #&7F 01111111 \clear attribute bit 8654 20 5A 86 JSR &865A Z. \update file, select next 8657 90 F9 BCC &8652 .. \loop until no more files 8659 60 RTS ` 865A 8D 47 10 STA &1047 .G. \Update file entry 865D 20 06 A6 JSR &A606 .. \store dir, pack catalogue entry 8660 20 0F A5 JSR &A50F .. \find next match of afsp 8663 90 08 BCC &866D .. \if more matches select next 8665 20 03 9B JSR &9B03 .. \else write catalogue 8668 38 SEC 8 \set carry and exit 8669 60 RTS ` 866A 20 83 89 JSR &8983 .. \Select file from afsp 866D 20 03 A6 JSR &A603 .. \?, unpack catalogue entry 8670 AD 47 10 LDA &1047 .G. \return directory and attribute 8673 60 RTS ` 8674 20 06 93 JSR &9306 .. \*CAT 8677 20 0C 9B JSR &9B0C .. \get drv/vol spec, softmount 867A 20 6E 89 JSR &896E n. \reset column COUNT = 0 867D 20 18 90 JSR &9018 .. \print "Defs" 8680 00 BRK . 8681 44 ??? D 8682 65 66 ADC &66 ef 8684 73 ??? s 8685 00 BRK . 8686 A2 00 LDX #&00 00000000 \x=0 for default path 8688 20 E9 88 JSR &88E9 .. \print " :"+path 868B A9 2E LDA #&2E 00101110 \start with a dot 868D 20 00 90 JSR &9000 .. \print character in A 8690 BD 00 10 LDA &1000,X ... \get character of def filename 8693 E8 INX . \increment index 8694 E0 08 CPX #&08 00001000 \have we loaded 7 characters? 8696 D0 F5 BNE &868D .. \if not then loop 8698 20 73 89 JSR &8973 s. \else tab to next 20-column 869B 20 18 90 JSR &9018 .. \print "Lib" 869E 00 BRK . 869F 4C 69 62 JMP &6269 Lib 86A2 00 BRK . 86A3 A2 03 LDX #&03 00000011 \x=3 for library path 86A5 20 E9 88 JSR &88E9 .. \print " :"+path 86A8 20 73 89 JSR &8973 s. \tab to next 20-column 86AB A5 C9 LDA &C9 .. \get immediate (*CAT) drive 86AD 20 18 90 JSR &9018 .. \print "Drive "+number 86B0 C0 44 CPY #&44 01000100 86B2 72 ??? r 86B3 69 76 ADC #&76 01110110 86B5 65 20 ADC &20 e 86B7 00 BRK . 86B8 AA TAX . \drive number to X register 86B9 BD F8 0F LDA &0FF8,X ... \get track stepping status 86BC D0 09 BNE &86C7 .. \if enabled skip forward 86BE BD F4 0F LDA &0FF4,X ... \else get no. tracks 86C1 20 04 89 JSR &8904 .. \print "n tracks" 86C4 4C D3 86 JMP &86D3 L.. \skip forward. 86C7 20 18 90 JSR &9018 .. \print " 40-80" 86CA 00 BRK . 86CB 20 20 34 JSR &3420 4 86CE 30 2D BMI &86FD 0- 86D0 38 SEC 8 86D1 30 00 BMI &86D3 0. 86D3 20 73 89 JSR &8973 s. \tab to next 20-column 86D6 BD F0 0F LDA &0FF0,X ... \get density flag 86D9 4A LSR A J \divide by 8 (SD=1 DD=2) 86DA 4A LSR A J 86DB 4A LSR A J 86DC 20 18 90 JSR &9018 .. \print "Density "+number 86DF 80 ??? . 86E0 44 ??? D 86E1 65 6E ADC &6E en 86E3 73 ??? s 86E4 69 74 ADC #&74 01110100 86E6 79 20 00 ADC &0020,Y y . 86E9 BD FC 0F LDA &0FFC,X ... \get number of volumes 86EC F0 32 BEQ &8720 .2 \if DFS skip volume list 86EE 20 03 90 JSR &9003 .. \else print a space 86F1 A0 41 LDY #&41 01000001 \start with "A" 86F3 B9 EF 0F LDA &0FEF,Y ... \get no. tracks in 1030..7 86F6 F0 04 BEQ &86FC .. \if none volume not present 86F8 98 TYA . \else print volume letter 86F9 20 00 90 JSR &9000 .. 86FC C8 INY . \increment volume letter 86FD C0 49 CPY #&49 01001001 \is it before "I"? 86FF D0 F2 BNE &86F3 .. \if so loop. 8701 A4 C8 LDY &C8 .. \get immediate (*CAT) volume 8703 D0 18 BNE &871D .. \if undefined then 8705 20 6B 89 JSR &896B k. \cat all vols: print newline 8708 A0 41 LDY #&41 01000001 \set immediate volume = "A" 870A 84 C8 STY &C8 .. 870C B9 EF 0F LDA &0FEF,Y ... \get no. tracks in volume 870F F0 06 BEQ &8717 .. \if volume is present 8711 20 00 9B JSR &9B00 .. \then read volume catalogue 8714 20 23 87 JSR &8723 #. \and list its contents. 8717 C8 INY . \increment volume letter 8718 C0 49 CPY #&49 01001001 \if now less than "I" 871A D0 EE BNE &870A .. \then loop over volumes 871C 60 RTS ` \else exit. 871D 20 09 9B JSR &9B09 .. \load volume catalogue 8720 20 6B 89 JSR &896B k. \print newline, reset count 8723 20 00 92 JSR &9200 .. \save AXY 8726 20 6B 89 JSR &896B k. \print newline, reset count 8729 A2 00 LDX #&00 00000000 \print first 8 characters 872B BD 00 0E LDA &0E00,X ... \of title in sector 0 872E 20 00 90 JSR &9000 .. 8731 E8 INX . 8732 E0 08 CPX #&08 00001000 8734 D0 F5 BNE &872B .. 8736 A2 00 LDX #&00 00000000 \print last 4 characters 8738 BD 00 0F LDA &0F00,X ... \of title in sector 1 873B 20 00 90 JSR &9000 .. 873E E8 INX . 873F E0 04 CPX #&04 00000100 8741 D0 F5 BNE &8738 .. 8743 AD 04 0F LDA &0F04 ... \get cycle number 8746 20 18 90 JSR &9018 .. \print " ("+hex byte 8749 40 RTI @ 874A 20 28 00 JSR &0028 (. 874D A9 29 LDA #&29 00101001 \print ")" 874F 20 00 90 JSR &9000 .. 8752 A6 C9 LDX &C9 .. \x=*CAT drive number 8754 BD FC 0F LDA &0FFC,X ... \get number of volumes 8757 F0 18 BEQ &8771 .. \if not a DFS disc 8759 20 73 89 JSR &8973 s. \then tab to next 20-column 875C 20 73 89 JSR &8973 s. \and again 875F A4 C8 LDY &C8 .. \get *CAT volume letter 8761 98 TYA . 8762 20 18 90 JSR &9018 .. \print "Vol " +letter 8765 C0 56 CPY #&56 01010110 8767 6F ??? o 8768 6C 20 00 JMP (&0020) l . 876B B9 EF 0F LDA &0FEF,Y ... \get number of tracks in volume 876E 20 04 89 JSR &8904 .. \print "n tracks" 8771 20 73 89 JSR &8973 s. \tab to next 20-field 8774 20 1B A6 JSR &A61B .. \get free space on volume 8777 20 09 A4 JSR &A409 .. \print decimal word 877A 20 18 90 JSR &9018 .. \print "free/" 877D 00 BRK . 877E 66 72 ROR &72 fr 8780 65 65 ADC &65 ee 8782 2F ??? / 8783 00 BRK . 8784 AD 06 0F LDA &0F06 ... \get sectors on volume high 8787 29 07 AND #&07 00000111 \mask all but low 3 bits 8789 8D 61 10 STA &1061 .a. \store in accumulator high 878C AD 07 0F LDA &0F07 ... \get sectors on volume low 878F 8D 60 10 STA &1060 .`. \store accumulator low 8792 20 09 A4 JSR &A409 .. \print decimal word 8795 20 03 90 JSR &9003 .. \print space 8798 20 09 96 JSR &9609 .. \get boot option, X=offset 879B A9 20 LDA #&20 00100000 \start with a space 879D 20 00 90 JSR &9000 .. \print character in A 87A0 BD 0C 96 LDA &960C,X ... \get char of boot opt string 87A3 E8 INX . \increment X 87A4 C9 20 CMP #&20 00100000 \was the character space? 87A6 D0 F5 BNE &879D .. \if not then loop 87A8 20 6B 89 JSR &896B k. \else print newline 87AB AD 07 10 LDA &1007 ... \get default directory 87AE 85 C7 STA &C7 .. \store immediate directory 87B0 A9 00 LDA #&00 00000000 \set A=0 87B2 20 18 89 JSR &8918 .. \list files in immed dir 87B5 A9 80 LDA #&80 10000000 \set A=&80 87B7 20 18 89 JSR &8918 .. \list files in all (other) dirs 87BA 38 SEC 8 \breakout ROM call and exit 87BB 60 RTS ` 87BC 20 12 93 JSR &9312 .. \*DELETE 87BF 20 83 89 JSR &8983 .. \get fsp, cat &check f.exists 87C2 20 21 A5 JSR &A521 !. \check file not locked 87C5 20 00 A6 JSR &A600 .. \delete catalogue entry 87C8 20 03 9B JSR &9B03 .. \write catalogue 87CB 38 SEC 8 \breakout ROM call and exit. 87CC 60 RTS ` 87CD 20 15 93 JSR &9315 .. \*DESTROY 87D0 20 00 9B JSR &9B00 .. \get afsp, load catalogue 87D3 20 12 A5 JSR &A512 .. \find unlocked file in cat 87D6 B0 34 BCS &880C .4 \if not found exit silently 87D8 20 6E 89 JSR &896E n. \else reset column count 87DB 20 03 A6 JSR &A603 .. \unpack fields from catalogue 87DE 20 03 A4 JSR &A403 .. \print directory and filename 87E1 20 00 A6 JSR &A600 .. \delete catalogue entry 87E4 20 18 A5 JSR &A518 .. \find next unlocked match 87E7 B0 06 BCS &87EF .. \if found 87E9 20 73 89 JSR &8973 s. \then tab to next 20-column 87EC 4C DB 87 JMP &87DB L.. \and loop 87EF 20 18 90 JSR &9018 .. \else ask 87F2 11 44 ORA (&44),Y .D \"Destroy these files?" 87F4 65 73 ADC &73 es \(*ENABLE won't bypass it) 87F6 74 ??? t 87F7 72 ??? r 87F8 6F ??? o 87F9 79 20 74 ADC &7420,Y y t 87FC 68 PLA h 87FD 65 73 ADC &73 es 87FF 65 20 ADC &20 e 8801 66 69 ROR &69 fi 8803 6C 65 73 JMP (&7365) les 8806 00 BRK . 8807 D0 03 BNE &880C .. \if user answers yes 8809 20 03 9B JSR &9B03 .. \then write catalogue. 880C 38 SEC 8 \breakout ROM call and exit. 880D 60 RTS ` 880E 20 09 93 JSR &9309 .. \*DIR 8811 20 06 92 JSR &9206 .. \get path spec 8814 C7 ??? . \copy immediate path 8815 00 BRK . \to default path 8816 07 ??? . \(dir, volume and drive) 8817 10 03 BPL &881C .. 8819 38 SEC 8 \breakout ROM call and exit. 881A 60 RTS ` 881B 20 03 93 JSR &9303 .. \*VOL, *DRIVE 881E 20 06 92 JSR &9206 .. \get volume spec (no colon) 8821 C8 INY . \copy immediate vol+drive 8822 00 BRK . \to default path 8823 08 PHP . 8824 10 02 BPL &8828 .. 8826 38 SEC 8 \breakout ROM call and exit. 8827 60 RTS ` 8828 20 00 93 JSR &9300 .. \Was *DRIVE 882B 20 06 92 JSR &9206 .. \get drive number 882E C9 00 CMP #&00 00000000 \copy immediate drive 8830 09 10 ORA #&10 00010000 \to default path 8832 01 38 ORA (&38,X) .8 \breakout ROM call and exit. 8834 60 RTS ` 8835 20 09 93 JSR &9309 .. \*LIB 8838 20 06 92 JSR &9206 .. \get path spec 883B C7 ??? . \copy immediate path 883C 00 BRK . \to library path 883D 0A ASL A . \(dir, volume and drive) 883E 10 03 BPL &8843 .. 8840 38 SEC 8 \breakout ROM call and exit. 8841 60 RTS ` 8842 20 80 89 JSR &8980 .. \*INFO 8845 20 03 A6 JSR &A603 .. \get afsp, exist!, unpack cat 8848 20 06 A4 JSR &A406 .. \print *INFO line 884B 20 09 90 JSR &9009 .. \print newline 884E 20 0F A5 JSR &A50F .. \find next match of afsp 8851 90 F2 BCC &8845 .. \loop, else breakout and exit. 8853 60 RTS ` 8854 98 TYA . \*RENAME 8855 48 PHA H \save command line pointer 8856 20 12 93 JSR &9312 .. \get file spec 8859 20 0F 93 JSR &930F .. \get entry name 885C 68 PLA h \(to check syntax) 885D A8 TAY . \restore command line pointer 885E 20 12 93 JSR &9312 .. \get file spec 8861 20 83 89 JSR &8983 .. \check file exists 8864 20 21 A5 JSR &A521 !. \check file not locked 8867 A5 CC LDA &CC .. \get pointer to cat entry 8869 48 PHA H \save it 886A 20 0F 93 JSR &930F .. \get new entry name 886D 20 09 A5 JSR &A509 .. \try to find it in cat 8870 B0 11 BCS &8883 .. \if present 8872 20 18 90 JSR &9018 .. \then "File exists" error 8875 0A ASL A . 8876 C4 46 CPY &46 .F 8878 69 6C ADC #&6C 01101100 887A 65 20 ADC &20 e 887C 65 78 ADC &78 ex 887E 69 73 ADC #&73 01110011 8880 74 ??? t 8881 73 ??? s 8882 00 BRK . 8883 68 PLA h \else restore cat pointer 8884 AA TAX . 8885 20 09 92 JSR &9209 .. \copy immediate filename 8888 C0 00 CPY #&00 00000000 \into catalogue at index X+8 888A 08 PHP . 888B 0E 08 02 ASL &0208 ... 888E 4C B4 88 JMP &88B4 L.. \jump to write cat and exit. 8891 20 06 92 JSR &9206 .. \*TITLE 8894 00 BRK . \copy default path to immed 8895 10 C0 BPL &8857 .. 8897 00 BRK . 8898 0A ASL A . 8899 20 00 9B JSR &9B00 .. \load catalogue 889C A2 00 LDX #&00 00000000 \clear index register 889E 20 1E 93 JSR &931E .. \get character of string 88A1 9D 00 0E STA &0E00,X ... \store in first part of title 88A4 E8 INX . \increment index register 88A5 E0 08 CPX #&08 00001000 \is it now 8 or more? 88A7 D0 F5 BNE &889E .. \if not loop 88A9 20 1E 93 JSR &931E .. \else get character of string 88AC 9D F8 0E STA &0EF8,X ... \store in last part of title 88AF E8 INX . \increment index register 88B0 E0 0C CPX #&0C 00001100 \is it 12 or more? 88B2 D0 F5 BNE &88A9 .. \if not loop 88B4 20 03 9B JSR &9B03 .. \else write catalogue 88B7 38 SEC 8 \breakout ROM call and exit. 88B8 60 RTS ` 88B9 20 80 89 JSR &8980 .. \*WIPE 88BC 20 03 A6 JSR &A603 .. \get afsp, exist!, unpack cat 88BF 20 03 A4 JSR &A403 .. \print directory and filename 88C2 AD 47 10 LDA &1047 .G. \get attribute bit 88C5 10 06 BPL &88CD .. \if locked 88C7 20 09 90 JSR &9009 .. \then print newline 88CA 4C E3 88 JMP &88E3 L.. \and loop to next file 88CD 20 18 90 JSR &9018 .. \ask " : delete?" 88D0 10 20 BPL &88F2 . 88D2 3A ??? : 88D3 20 64 65 JSR &6564 de 88D6 6C 65 74 JMP (&7465) let 88D9 65 00 ADC &00 e. 88DB D0 06 BNE &88E3 .. \if user answers no then loop 88DD 20 00 A6 JSR &A600 .. \else delete entry 88E0 20 03 9B JSR &9B03 .. \and write catalogue. 88E3 20 0F A5 JSR &A50F .. \find next match of afsp 88E6 90 D4 BCC &88BC .. \and loop else breakout +exit. 88E8 60 RTS ` 88E9 BD 09 10 LDA &1009,X ... \Print " :"+path 88EC 20 18 90 JSR &9018 .. \x=0 default path 88EF C0 20 CPY #&20 00100000 \x=3 library path 88F1 3A ??? : \get drive, print " :"+drive 88F2 00 BRK . 88F3 BD 08 10 LDA &1008,X ... \get volume letter 88F6 20 00 90 JSR &9000 .. \print character in A 88F9 A9 2E LDA #&2E 00101110 \set A=dot 88FB 20 00 90 JSR &9000 .. \print character in A 88FE BD 07 10 LDA &1007,X ... \print directory and exit. 8901 4C 00 90 JMP &9000 L.. 8904 20 18 90 JSR &9018 .. \Print " n tracks" 8907 80 ??? . \where number is in A 8908 20 20 00 JSR &0020 . \start with " "+number 890B 20 18 90 JSR &9018 .. \print " tracks" and exit. 890E 00 BRK . 890F 20 74 72 JSR &7274 tr 8912 61 63 ADC (&63,X) ac 8914 6B ??? k 8915 73 ??? s 8916 00 BRK . 8917 60 RTS ` 8918 85 A8 STA &A8 .. \List files in dir 891A 20 89 89 JSR &8989 .. \A=0 immed dir, A=&80 all dirs 891D B0 60 BCS &897F .` \select first file in cat para 891F 20 6B 89 JSR &896B k. \if none exit else print newline 8922 A6 CC LDX &CC .. \set X = catalogue pointer 8924 86 A9 STX &A9 .. \store in temp 8926 20 09 92 JSR &9209 .. \copy catalogue entry 8929 08 PHP . \to immediate name and directory 892A 0E C0 00 ASL &00C0 ... 892D 08 PHP . 892E 20 20 8F JSR &8F20 . \select next file in cat para 8931 89 ??? . 8932 B0 07 BCS &893B .. \if no more files then break out 8934 20 1B A5 JSR &A51B .. \else compare immed - cat entry 8937 90 F6 BCC &892F .. \if cat entry > immed then loop 8939 B0 E7 BCS &8922 .. \else loop to set new 'minimum'. 893B 20 06 92 JSR &9206 .. \copy immediate filename and dir 893E C0 00 CPY #&00 00000000 \to catalogue workspace 8940 40 RTI @ 8941 10 08 BPL &894B .. 8943 20 03 90 JSR &9003 .. \print space 8946 24 A8 BIT &A8 $. \test directory flag 8948 30 0C BMI &8956 0. \if current dir only 894A 20 03 90 JSR &9003 .. \then print two spaces 894D 20 03 90 JSR &9003 .. \to replace directory and dot 8950 20 00 A4 JSR &A400 .. \print filename 8953 4C 59 89 JMP &8959 LY. \and jump forward 8956 20 03 A4 JSR &A403 .. \else print dir and filename. 8959 A6 A9 LDX &A9 .. \get temp value 895B 86 CC STX &CC .. \restore to catalogue pointer 895D 20 00 A6 JSR &A600 .. \delete catalogue entry 8960 20 89 89 JSR &8989 .. \select first file in cat para 8963 B0 06 BCS &896B .. \if no more print nl and exit 8965 20 73 89 JSR &8973 s. \else tab to next 20-column 8968 4C 22 89 JMP &8922 L". \&loopfor next file in cat para. 896B 20 09 90 JSR &9009 .. \Print newline +reset: 896E 48 PHA H \Reset column COUNT = 0 896F A9 00 LDA #&00 00000000 8971 F0 09 BEQ &897C .. 8973 48 PHA H \Tab to next 20-column 8974 A5 AA LDA &AA .. 8976 18 CLC . 8977 69 14 ADC #&14 00010100 8979 20 06 90 JSR &9006 .. 897C 85 AA STA &AA .. 897E 68 PLA h 897F 60 RTS ` 8980 20 15 93 JSR &9315 .. \get afsp 8983 20 00 9B JSR &9B00 .. \load catalogue 8986 4C 0C A5 JMP &A50C L.. \and check file exists. 8989 20 00 A5 JSR &A500 .. \Select first file in cat para 898C 4C 92 89 JMP &8992 L.. \select 1st file and jump 898F 20 06 A5 JSR &A506 .. \Select next file in cat para 8992 B0 0A BCS &899E .. \if no more files then exit C=1 8994 24 A8 BIT &A8 $. \else test directory flag 8996 30 05 BMI &899D 0. \if b7=1 then exit C=0 8998 20 1E A5 JSR &A51E .. \else compare directory letters 899B D0 F2 BNE &898F .. \if mismatch then loop 899D 18 CLC . \else exit C=0 899E 60 RTS ` \'Medium' DFS commands 8A00 4C 15 8A JMP &8A15 L.. \*BACKUP 8A03 4C D3 8A JMP &8AD3 L.. \*COMPACT 8A06 4C 64 8B JMP &8B64 Ld. \*COPY 8A09 4C E7 8B JMP &8BE7 L.. \*ENABLE 8A0C 4C FA 8C JMP &8CFA L.. \Ask user for confirmation 8A0F 4C 77 8B JMP &8B77 Lw. \*SCOPY 8A12 4C A5 8B JMP &8BA5 L.. \*FCOPY 8A15 20 00 93 JSR &9300 .. \*BACKUP 8A18 A5 C9 LDA &C9 .. \get drive spec 8A1A 8D 70 10 STA &1070 .p. \store source drive in workspace 8A1D 20 00 93 JSR &9300 .. \get drive spec 8A20 A5 C9 LDA &C9 .. 8A22 8D 71 10 STA &1071 .q. \store dest drive in workspace 8A25 A9 00 LDA #&00 00000000 \clear source volume 8A27 8D 72 10 STA &1072 .r. 8A2A 8D 73 10 STA &1073 .s. \and target volume 8A2D AD 70 10 LDA &1070 .p. \print "Copying from drive " 8A30 20 18 90 JSR &9018 .. \+source drive 8A33 C0 43 CPY #&43 01000011 8A35 6F ??? o 8A36 70 79 BVS &8AB1 py 8A38 69 6E ADC #&6E 01101110 8A3A 67 ??? g 8A3B 20 66 72 JSR &7266 fr 8A3E 6F ??? o 8A3F 6D 20 64 ADC &6420 m d 8A42 72 ??? r 8A43 69 76 ADC #&76 01110110 8A45 65 20 ADC &20 e 8A47 00 BRK . 8A48 AD 71 10 LDA &1071 .q. 8A4B 20 18 90 JSR &9018 .. \print " to drive "+target+nl 8A4E C2 ??? . 8A4F 20 74 6F JSR &6F74 to 8A52 20 64 72 JSR &7264 dr 8A55 69 76 ADC #&76 01110110 8A57 65 20 ADC &20 e 8A59 00 BRK . 8A5A 20 77 8D JSR &8D77 w. \initialise and load source disc 8A5D 20 FF 8B JSR &8BFF .. \set up prompt flag 8A60 AE 70 10 LDX &1070 .p. \get source drive for use later 8A63 BD F4 0F LDA &0FF4,X ... \get no. tracks on source drive 8A66 8D 81 10 STA &1081 ... \store temp 8A69 BD F0 0F LDA &0FF0,X ... \get density of source drive 8A6C 48 PHA H \push density 8A6D 20 B7 8D JSR &8DB7 .. \swap source and target discs 8A70 20 91 8D JSR &8D91 .. \ensure catalogue loaded 8A73 AE 71 10 LDX &1071 .q. \get target drive for use later 8A76 68 PLA h \pop source density 8A77 DD F0 0F CMP &0FF0,X ... \compare with target density 8A7A D0 3F BNE &8ABB .? \if unequal "Incompatible discs" 8A7C AD 81 10 LDA &1081 ... \else get source tracks 8A7F DD F4 0F CMP &0FF4,X ... \compare with target tracks 8A82 D0 37 BNE &8ABB .7 \if unequal "Incompatible discs" 8A84 A9 00 LDA #&00 00000000 \else clear src sectors-to-go 8A86 8D 76 10 STA &1076 .v. 8A89 8D 78 10 STA &1078 .x. 8A8C 8D 79 10 STA &1079 .y. \and high byte of target stg. 8A8F BD F0 0F LDA &0FF0,X ... \get target sectors per track 8A92 18 CLC . 8A93 6D 76 10 ADC &1076 mv. \increase stg counts by this 8A96 8D 76 10 STA &1076 .v. 8A99 8D 77 10 STA &1077 .w. 8A9C 90 06 BCC &8AA4 .. \carry out to high bytes 8A9E EE 78 10 INC &1078 .x. 8AA1 EE 79 10 INC &1079 .y. 8AA4 CE 81 10 DEC &1081 ... \loop until all tracks done. 8AA7 D0 E6 BNE &8A8F .. 8AA9 AD 71 10 LDA &1071 .q. \get target drive 8AAC 09 80 ORA #&80 10000000 \set top bit 8AAE 20 0C 8A JSR &8A0C .. \confirm wipe of disc and memory 8AB1 90 06 BCC &8AB9 .. \if No then exit 8AB3 20 58 8E JSR &8E58 X. \else copy the disc 8AB6 20 58 8E JSR &8E58 X. \and make sure it is all done. 8AB9 38 SEC 8 \break out of ROM call and exit 8ABA 60 RTS ` 8ABB 20 18 90 JSR &9018 .. \Error "Incompatible discs" 8ABE 0A ASL A . 8ABF D3 ??? . 8AC0 49 6E EOR #&6E 01101110 8AC2 63 ??? c 8AC3 6F ??? o 8AC4 6D 70 61 ADC &6170 mpa 8AC7 74 ??? t 8AC8 69 62 ADC #&62 01100010 8ACA 6C 65 20 JMP (&2065) le 8ACD 64 ??? d 8ACE 69 73 ADC #&73 01110011 8AD0 63 ??? c 8AD1 73 ??? s 8AD2 00 BRK . 8AD3 20 EE 8B JSR &8BEE .. \*COMPACT 8AD6 20 F3 8B JSR &8BF3 .. \get and store volume spec 8AD9 20 77 8D JSR &8D77 w. \store it as 'target' volume too 8ADC A9 80 LDA #&80 10000000 \initialise & load source disc 8ADE 8D 80 10 STA &1080 ... \set flag for single disc oper'n 8AE1 A2 00 LDX #&00 00000000 \set &106B,C = &0001 8AE3 8E 6C 10 STX &106C .l. \to search for one free sector 8AE6 E8 INX . 8AE7 8E 6B 10 STX &106B .k. 8AEA 20 0C A6 JSR &A60C .. \find a free space in volume 8AED B0 5B BCS &8B4A .[ \(not at end!) if not found quit 8AEF 20 06 A5 JSR &A506 .. \else select next (a) file 8AF2 B0 56 BCS &8B4A .V \if no file found finish 8AF4 AD 70 10 LDA &1070 .p. \else get source drive 8AF7 20 18 90 JSR &9018 .. \print "Compacting vol "+n 8AFA C0 43 CPY #&43 01000011 8AFC 6F ??? o 8AFD 6D 70 61 ADC &6170 mpa 8B00 63 ??? c 8B01 74 ??? t 8B02 69 6E ADC #&6E 01101110 8B04 67 ??? g 8B05 20 76 6F JSR &6F76 vo 8B08 6C 20 00 JMP (&0020) l . 8B0B AD 72 10 LDA &1072 .r. \get source volume letter 8B0E 20 00 90 JSR &9000 .. \print it 8B11 20 09 90 JSR &9009 .. \print newline 8B14 A9 80 LDA #&80 10000000 \this routine wipes memory only 8B16 20 0C 8A JSR &8A0C .. \ask user for confirmation 8B19 90 2F BCC &8B4A ./ \if not given then finish 8B1B 20 03 A6 JSR &A603 .. \else unpack fields from cat 8B1E 20 CE 8E JSR &8ECE .. \copy entry from cat 1 to 2 8B21 20 00 A6 JSR &A600 .. \delete catalogue entry 8B24 20 2A 8F JSR &8F2A *. \set copy range = entry range 8B27 20 5B 8E JSR &8E5B [. \copy file 8B2A 98 TYA . \if a write is now due 8B2B D0 0D BNE &8B3A .. \then flush buffer &test if done 8B2D A6 CC LDX &CC .. \else get catalogue pointer 8B2F 20 06 A5 JSR &A506 .. \select next 'source' file 8B32 90 E7 BCC &8B1B .. \and loop if one is found 8B34 20 B7 8D JSR &8DB7 .. \else 'swap discs' 8B37 4C 27 8B JMP &8B27 L'. \and loop back to tidy up. 8B3A E4 AB CPX &AB .. \if all files have been saved 8B3C F0 09 BEQ &8B47 .. \then finish 8B3E 20 F0 8E JSR &8EF0 .. \else unpack cat 2 entry 8B41 20 45 8F JSR &8F45 E. \create catalogue entry +*INFO 8B44 4C 24 8B JMP &8B24 L$. \& loop back to save this file. 8B47 20 03 9B JSR &9B03 .. \Finish *COMPACT.write catalogue 8B4A 20 1B A6 JSR &A61B .. \get free space on volume 8B4D 20 09 A4 JSR &A409 .. \print decimal word 8B50 20 18 90 JSR &9018 .. \print " free sectors"+newline 8B53 02 ??? . 8B54 20 66 72 JSR &7266 fr 8B57 65 65 ADC &65 ee 8B59 20 73 65 JSR &6573 se 8B5C 63 ??? c 8B5D 74 ??? t 8B5E 6F ??? o 8B5F 72 ??? r 8B60 73 ??? s 8B61 00 BRK . 8B62 38 SEC 8 \and exit C=1. 8B63 60 RTS ` 8B64 20 DC 8C JSR &8CDC .. \*COPY 8B67 90 3A BCC &8BA3 .: \process args, if user aborts 8B69 20 03 A6 JSR &A603 .. \then exit else unpack fields 8B6C 20 49 8C JSR &8C49 I. \copy cat 1 to 2 and copy file 8B6F 20 0F A5 JSR &A50F .. \find next match of afsp 8B72 90 F5 BCC &8B69 .. \and loop if one is found 8B74 4C 5B 8C JMP &8C5B L[. \else flush copy buffer &exit. 8B77 20 DC 8C JSR &8CDC .. \*SCOPY 8B7A 90 27 BCC &8BA3 .' \process args, if user aborts 8B7C 20 03 A6 JSR &A603 .. \then exit else unpack fields 8B7F 20 03 A4 JSR &A403 .. \print directory and filename 8B82 20 18 90 JSR &9018 .. \ask " : copy?" 8B85 10 20 BPL &8BA7 . 8B87 3A ??? : 8B88 20 63 6F JSR &6F63 co 8B8B 70 79 BVS &8C06 py 8B8D 00 BRK . 8B8E D0 0E BNE &8B9E .. \if user answers yes, then: 8B90 20 49 8C JSR &8C49 I. \copy cat 1 to 2 and copy file 8B93 20 5B 8C JSR &8C5B [. \flush copy buffer 8B96 20 B7 8D JSR &8DB7 .. \swap discs (to reselect source) 8B99 20 91 8D JSR &8D91 .. \ensure catalogue loaded 8B9C 86 CC STX &CC .. \save catalogue pointer 8B9E 20 0F A5 JSR &A50F .. \find next match of afsp 8BA1 90 D9 BCC &8B7C .. \and loop if one is found 8BA3 38 SEC 8 \else exit C=1. 8BA4 60 RTS ` 8BA5 20 12 93 JSR &9312 .. \*FCOPY 8BA8 A2 00 LDX #&00 00000000 \get source file spec 8BAA 20 F3 8B JSR &8BF3 .. \store source vol for copier 8BAD 20 06 92 JSR &9206 .. \copy immediate filename+dir 8BB0 C0 00 CPY #&00 00000000 \to catalogue block 1 8BB2 40 RTI @ \(source filename) 8BB3 10 08 BPL &8BBD .. 8BB5 20 12 93 JSR &9312 .. \get target file spec 8BB8 20 F3 8B JSR &8BF3 .. \store target vol for copier 8BBB 20 06 92 JSR &9206 .. \copy immediate filename+dir 8BBE C0 00 CPY #&00 00000000 \to catalogue block 2 8BC0 58 CLI X \(target filename) 8BC1 10 08 BPL &8BCB .. 8BC3 20 06 92 JSR &9206 .. \copy catalogue block 1 8BC6 40 RTI @ \back to immediate filename+dir 8BC7 10 C0 BPL &8B89 .. \(source filename) 8BC9 00 BRK . 8BCA 08 PHP . 8BCB 20 98 8C JSR &8C98 .. \init copy, find source file 8BCE 20 F8 8C JSR &8CF8 .. \ask to overwrite memory 8BD1 90 D0 BCC &8BA3 .. \if refused exit C=1 8BD3 20 03 A6 JSR &A603 .. \else unpack fields from cat 8BD6 A6 CC LDX &CC .. \get catalogue pointer in X 8BD8 20 09 92 JSR &9209 .. \copy target filename+dir 8BDB 58 CLI X \to catalogue entry 8BDC 10 08 BPL &8BE6 .. \temporarily renaming the file 8BDE 0E 08 02 ASL &0208 ... 8BE1 20 49 8C JSR &8C49 I. \copy cat to cat2 and copy file 8BE4 4C 5B 8C JMP &8C5B L[. \flush copy buffer &exit. 8BE7 A9 02 LDA #&02 00000010 \*ENABLE 8BE9 8D 0F 10 STA &100F ... \set enabled flag b1=1 8BEC 38 SEC 8 \break out of ROM call 8BED 60 RTS ` \and exit 8BEE A2 00 LDX #&00 00000000 \Get and store source vol spec: 8BF0 20 03 93 JSR &9303 .. \Get and store dest vol spec 8BF3 A5 C8 LDA &C8 .. \get volume letter of spec 8BF5 9D 72 10 STA &1072,X .r. \store it in source/dest info 8BF8 A5 C9 LDA &C9 .. \get drive letter of spec 8BFA 9D 70 10 STA &1070,X .p. \store it in source/dest info 8BFD E8 INX . \move pointer from src to dest. 8BFE 60 RTS ` 8BFF AD 72 10 LDA &1072 .r. \Set up prompt flag 8C02 CD 73 10 CMP &1073 .s. \compare src and target volumes 8C05 D0 08 BNE &8C0F .. \if equal, then: 8C07 AD 70 10 LDA &1070 .p. \compare src and target drives 8C0A CD 71 10 CMP &1071 .q. \if equal,discs must be distinct 8C0D F0 34 BEQ &8C43 .4 \so jump to set prompt bit 8C0F AD 70 10 LDA &1070 .p. \else get source drive 8C12 4D 71 10 EOR &1071 Mq. \XOR target drive 8C15 29 01 AND #&01 00000001 \A=1 iff different units 8C17 D0 2F BNE &8C48 ./ \if so then exit 8C19 20 18 90 JSR &9018 .. \else ask 8C1C 10 41 BPL &8C5F .A \"Are source and target 8C1E 72 ??? r \the same disc?" 8C1F 65 20 ADC &20 e 8C21 73 ??? s 8C22 6F ??? o 8C23 75 72 ADC &72,X ur 8C25 63 ??? c 8C26 65 20 ADC &20 e 8C28 61 6E ADC (&6E,X) an 8C2A 64 ??? d 8C2B 20 74 61 JSR &6174 ta 8C2E 72 ??? r 8C2F 67 ??? g 8C30 65 74 ADC &74 et 8C32 20 74 68 JSR &6874 th 8C35 65 20 ADC &20 e 8C37 73 ??? s 8C38 61 6D ADC (&6D,X) am 8C3A 65 20 ADC &20 e 8C3C 64 ??? d 8C3D 69 73 ADC #&73 01110011 8C3F 63 ??? c 8C40 00 BRK . 8C41 F0 05 BEQ &8C48 .. \if Yes then exit 8C43 A9 40 LDA #&40 01000000 \else set prompt flag. 8C45 8D 80 10 STA &1080 ... \exit 8C48 60 RTS ` 8C49 20 CE 8E JSR &8ECE .. \copy entry from cat 1 to 2: \Copy file. Fulfils the entry now in catalogue block 2. \On entry if Y=0 then the file's contents are read from the source \disc into the data buffer. \If Y=1 then the file's contents are written from the data buffer \on to the target disc, and the rest of the copy buffer is flushed. 8C4C 20 2A 8F JSR &8F2A *. \Copy file 8C4F 20 5B 8E JSR &8E5B [. \set copy range = entry range 8C52 98 TYA . \read/write range to buffer 8C53 D0 09 BNE &8C5E .. \if write now due, flush else: 8C55 20 91 8D JSR &8D91 .. \ensure catalogue loaded 8C58 86 CC STX &CC .. \save catalogue ptr and exit. 8C5A 60 RTS ` 8C5B 20 58 8E JSR &8E58 X. \write(?) range, then: 8C5E E4 AB CPX &AB .. \Flush copy buffer. if empty 8C60 F0 31 BEQ &8C93 .1 \then flush cat 1 and exit C=1 8C62 20 F0 8E JSR &8EF0 .. \else unpack cat 2 entry 8C65 20 91 8D JSR &8D91 .. \ensure catalogue loaded 8C68 20 06 92 JSR &9206 .. \copy immediate filename+dir 8C6B C0 00 CPY #&00 00000000 \to catalogue block 1 8C6D 40 RTI @ \which has attribs from cat 2 8C6E 10 08 BPL &8C78 .. \(save filename being read) 8C70 20 06 92 JSR &9206 .. \copy catalogue block 2 8C73 58 CLI X \to immediate filename+dir 8C74 10 C0 BPL &8C36 .. \(target file name) 8C76 00 BRK . 8C77 08 PHP . 8C78 20 09 A5 JSR &A509 .. \find file in catalogue 8C7B B0 06 BCS &8C83 .. \if not found skip, else: 8C7D 20 21 A5 JSR &A521 !. \check file not locked 8C80 20 00 A6 JSR &A600 .. \delete catalogue entry 8C83 20 06 92 JSR &9206 .. \copy catalogue block 1 8C86 40 RTI @ \to immediate filename+dir 8C87 10 C0 BPL &8C49 .. \(restore filename being read) 8C89 00 BRK . 8C8A 08 PHP . 8C8B 20 45 8F JSR &8F45 E. \create cat entry +*INFO 8C8E E6 A8 INC &A8 .. \mark catalogue page as dirty 8C90 4C 4C 8C JMP &8C4C LL. \and go back to Copy file! 8C93 20 A7 8D JSR &8DA7 .. \Flush catalogue, exit C=1 8C96 38 SEC 8 8C97 60 RTS ` 8C98 20 77 8D JSR &8D77 w. \Initialise copy 8C9B 20 0C A5 JSR &A50C .. \init+cat, check file exists 8C9E AD 06 0F LDA &0F06 ... \get top 3 bits of disc size 8CA1 8D 81 10 STA &1081 ... \(+boot option), store 1081 8CA4 AD 70 10 LDA &1070 .p. \get source drive 8CA7 20 18 90 JSR &9018 .. \print "Copying from vol "+n 8CAA C0 43 CPY #&43 01000011 8CAC 6F ??? o 8CAD 70 79 BVS &8D28 py 8CAF 69 6E ADC #&6E 01101110 8CB1 67 ??? g 8CB2 20 66 72 JSR &7266 fr 8CB5 6F ??? o 8CB6 6D 20 76 ADC &7620 m v 8CB9 6F ??? o 8CBA 6C 20 00 JMP (&0020) l . 8CBD AD 72 10 LDA &1072 .r. \get source vol letter 8CC0 20 00 90 JSR &9000 .. \print it 8CC3 AD 71 10 LDA &1071 .q. \get target drive 8CC6 20 18 90 JSR &9018 .. \print " to vol "+n 8CC9 C0 20 CPY #&20 00100000 8CCB 74 ??? t 8CCC 6F ??? o 8CCD 20 76 6F JSR &6F76 vo 8CD0 6C 20 00 JMP (&0020) l . 8CD3 AD 73 10 LDA &1073 .s. \get target volume 8CD6 20 00 90 JSR &9000 .. \print it 8CD9 4C 09 90 JMP &9009 L.. \print newline and exit. 8CDC 20 EE 8B JSR &8BEE .. \Process *COPY, *SCOPY arguments 8CDF 20 F0 8B JSR &8BF0 .. \get &store src & dest vol specs 8CE2 20 15 93 JSR &9315 .. \get ambiguous file spec 8CE5 20 98 8C JSR &8C98 .. \initialise copy 8CE8 20 FF 8B JSR &8BFF .. \set up prompt flag 8CEB 2C 80 10 BIT &1080 ,.. \copy prompt bit of flag to b0 8CEE 50 08 BVC &8CF8 P. 8CF0 A9 01 LDA #&01 00000001 8CF2 0D 80 10 ORA &1080 ... 8CF5 8D 80 10 STA &1080 ... 8CF8 A9 80 LDA #&80 10000000 \Ask to overwrite memory only: 8CFA 0A ASL A . \Ask user for confirmation 8CFB 90 1A BCC &8D17 .. \if b0=1 caller will wipe memory 8CFD 2C 7A 02 BIT &027A ,z. \so test Tube presence 8D00 30 15 BMI &8D17 0. \if present I/O is free to wipe 8D02 20 53 8D JSR &8D53 S. \else ensure *ENABLEd or warn 8D05 B0 4A BCS &8D51 .J \if *ENABLED exit C=1 8D07 20 18 90 JSR &9018 .. \complete warning of memory loss 8D0A 02 ??? . 8D0B 75 73 ADC &73,X us 8D0D 65 72 ADC &72 er 8D0F 20 6D 65 JSR &656D me 8D12 6D 6F 72 ADC &726F mor 8D15 79 00 4A ADC &4A00,Y y.J \if b1=1 caller will wipe disc 8D18 F0 18 BEQ &8D32 .. \drive number in b2..3,now b0..1 8D1A 20 53 8D JSR &8D53 S. \ensure *ENABLED or warn 8D1D B0 32 BCS &8D51 .2 \if *ENABLED exit C=1 8D1F 20 18 90 JSR &9018 .. \finish warning of disc erasure 8D22 C2 ??? . 8D23 64 ??? d 8D24 69 73 ADC #&73 01110011 8D26 63 ??? c 8D27 20 69 6E JSR &6E69 in 8D2A 20 64 72 JSR &7264 dr 8D2D 69 76 ADC #&76 01110110 8D2F 65 20 ADC &20 e 8D31 00 BRK . 8D32 20 18 90 JSR &9018 .. \Ask if user wants to proceed 8D35 15 44 ORA &44,X .D \(yes/no) 8D37 6F ??? o 8D38 20 79 6F JSR &6F79 yo 8D3B 75 20 ADC &20,X u 8D3D 77 ??? w 8D3E 61 6E ADC (&6E,X) an 8D40 74 ??? t 8D41 20 74 6F JSR &6F74 to 8D44 20 70 72 JSR &7270 pr 8D47 6F ??? o 8D48 63 ??? c 8D49 65 65 ADC &65 ee 8D4B 64 ??? d 8D4C 00 BRK . 8D4D F0 02 BEQ &8D51 .. \Z=yes, if so exit C=1 8D4F 18 CLC . \else exit C=0. 8D50 60 RTS ` 8D51 38 SEC 8 \exit C=1 8D52 60 RTS ` 8D53 4E 0F 10 LSR &100F N.. \Print warning 8D56 B0 1E BCS &8D76 .. \return C=*ENABLEd 8D58 20 18 90 JSR &9018 .. \if not *ENABLEd 8D5B 01 57 ORA (&57,X) .W \begin warning message. 8D5D 41 52 EOR (&52,X) AR 8D5F 4E 49 4E LSR &4E49 NIN 8D62 47 ??? G 8D63 3A ??? : 8D64 20 77 69 JSR &6977 wi 8D67 6C 6C 20 JMP (&206C) ll 8D6A 6F ??? o 8D6B 76 65 ROR &65,X ve 8D6D 72 ??? r 8D6E 77 ??? w 8D6F 72 ??? r 8D70 69 74 ADC #&74 01110100 8D72 65 20 ADC &20 e 8D74 00 BRK . 8D75 18 CLC . 8D76 60 RTS ` 8D77 A9 00 LDA #&00 00000000 \Initialise and load source disc 8D79 A8 TAY . \clear A,Y 8D7A 85 AB STA &AB .. \and &AB 8D7C A2 0B LDX #&0B 00001011 \and &1076..81 8D7E 9D 76 10 STA &1076,X .v. 8D81 CA DEX . 8D82 10 FA BPL &8D7E .. 8D84 A9 13 LDA #&13 00010011 \=8271 read cmd for source drive 8D86 8D 74 10 STA &1074 .t. 8D89 A9 0B LDA #&0B 00001011 \=write command for target 8D8B 8D 75 10 STA &1075 .u. 8D8E 20 C7 8D JSR &8DC7 .. \ask for disc, then: 8D91 48 PHA H \Ensure catalogue loaded 8D92 A5 A8 LDA &A8 .. \get catalogue flag 8D94 D0 0F BNE &8DA5 .. \if catalogue empty 8D96 A5 C8 LDA &C8 .. \then get immediate volume; 8D98 F0 06 BEQ &8DA0 .. \if <>NUL 8D9A 20 00 9B JSR &9B00 .. \then load volume catalogue 8D9D 4C A3 8D JMP &8DA3 L.. \else 8DA0 20 0C 9B JSR &9B0C .. \softmount disc. 8DA3 E6 A8 INC &A8 .. \flag = 1, catalogue clean 8DA5 68 PLA h \restore A and exit. 8DA6 60 RTS ` 8DA7 48 PHA H \Flush catalogue 8DA8 A5 A8 LDA &A8 .. \save A, get page flag 8DAA C9 02 CMP #&02 00000010 \if page is empty or clean 8DAC 90 07 BCC &8DB5 .. \then exit 8DAE 20 03 9B JSR &9B03 .. \else write catalogue 8DB1 A9 01 LDA #&01 00000001 \and mark page as clean. 8DB3 85 A8 STA &A8 .. 8DB5 68 PLA h \restore A and exit. 8DB6 60 RTS ` 8DB7 20 A7 8D JSR &8DA7 .. \Swap source and target discs 8DBA 48 PHA H \flush catalogue, save A 8DBB 8A TXA . 8DBC 99 7E 10 STA &107E,Y .~. \store current drive in temp 8DBF 98 TYA . \toggle source/target drive 8DC0 49 01 EOR #&01 00000001 8DC2 A8 TAY . 8DC3 BE 7E 10 LDX &107E,Y .~. \load other drive no. into X 8DC6 68 PLA h \restore A, then: 8DC7 20 00 92 JSR &9200 .. \Ask for disc 8DCA 2C 80 10 BIT &1080 ,.. \test flag 8DCD 50 3C BVC &8E0B P< \if prompt bit clear then skip 8DCF C0 00 CPY #&00 00000000 \else test Y 8DD1 D0 11 BNE &8DE4 .. \if Y>0 then ask for target 8DD3 20 18 90 JSR &9018 .. \else ask for source 8DD6 00 BRK . \print "Is source" 8DD7 49 73 EOR #&73 01110011 8DD9 20 73 6F JSR &6F73 so 8DDC 75 72 ADC &72,X ur 8DDE 63 ??? c 8DDF 65 00 ADC &00 e. 8DE1 4C F2 8D JMP &8DF2 L.. \and jump. 8DE4 20 18 90 JSR &9018 .. \print "Is target" 8DE7 00 BRK . 8DE8 49 73 EOR #&73 01110011 8DEA 20 74 61 JSR &6174 ta 8DED 72 ??? r 8DEE 67 ??? g 8DEF 65 74 ADC &74 et 8DF1 00 BRK . 8DF2 B9 70 10 LDA &1070,Y .p. \get source or target drv no. 8DF5 20 18 90 JSR &9018 .. \ask " disc in drive "+n+"?" 8DF8 D0 20 BNE &8E1A . 8DFA 64 ??? d 8DFB 69 73 ADC #&73 01110011 8DFD 63 ??? c 8DFE 20 69 6E JSR &6E69 in 8E01 20 64 72 JSR &7264 dr 8E04 69 76 ADC #&76 01110110 8E06 65 20 ADC &20 e 8E08 00 BRK . 8E09 D0 C4 BNE &8DCF .. \if No then loop and ask again! 8E0B 2C 80 10 BIT &1080 ,.. \else test flag 8E0E 30 04 BMI &8E14 0. \if b7 clear 8E10 A2 00 LDX #&00 00000000 \then mark catalogue empty. 8E12 86 A8 STX &A8 .. 8E14 B9 72 10 LDA &1072,Y .r. \get source/target volume 8E17 85 C8 STA &C8 .. \store immediate volume 8E19 B9 70 10 LDA &1070,Y .p. \get source/target drive 8E1C 85 C9 STA &C9 .. \store immediate drive 8E1E A9 83 LDA #&83 10000011 \call OSBYTE 8E20 20 F4 FF JSR &FFF4 .. \to get OSHWM (High Water Mark) 8E23 86 A9 STX &A9 .. \store in &A9,&AA 8E25 84 AA STY &AA .. \pointer to catalogue 8E27 C8 INY . \increase by two pages 8E28 C8 INY . 8E29 84 AC STY &AC .. \store in &AB(=00),&AC; 8E2B A9 84 LDA #&84 10000100 \pointer to buffer. 8E2D 20 F4 FF JSR &FFF4 .. \call OSBYTE to get HIMEM 8E30 98 TYA . \subtract start of buffer 8E31 38 SEC 8 8E32 E5 AC SBC &AC .. 8E34 90 0E BCC &8E44 .. \if HIMEM <= buffer 8E36 F0 0C BEQ &8E44 .. \then error "No free memory" 8E38 85 AD STA &AD .. \else store buffer size 8E3A AD 80 10 LDA &1080 ... \test flag 8E3D 4A LSR A J \if bit 1 set 8E3E 90 03 BCC &8E43 .. 8E40 20 91 8D JSR &8D91 .. \then ensure catalogue loaded 8E43 60 RTS ` \and exit. 8E44 20 18 90 JSR &9018 .. \error "No free memory" 8E47 0A ASL A . 8E48 D4 ??? . 8E49 4E 6F 20 LSR &206F No 8E4C 66 72 ROR &72 fr 8E4E 65 65 ADC &65 ee 8E50 20 6D 65 JSR &656D me 8E53 6D 6F 72 ADC &726F mor 8E56 79 00 20 ADC &2000,Y y. \Copy data between discs 8E59 B7 ??? . \JSR &8DB7 swap discs &flsh cat: 8E5A 8D B9 76 STA &76B9 ..v \LDA &1076,Y test src stg count 8E5D 10 19 BPL &8E78 .. \ORA &1078,Y OR low & high bytes 8E5F 78 SEI x 8E60 10 D0 BPL &8E32 .. \BNE &8E64 if =0 8E62 01 60 ORA (&60,X) .` \RTS then exit 8E64 A5 AC LDA &AC .. \else set O7F address 8E66 8D 12 10 STA &1012 ... \to address of data buffer 8E69 A9 00 LDA #&00 00000000 8E6B 8D 11 10 STA &1011 ... 8E6E A9 FF LDA #&FF 11111111 8E70 8D 13 10 STA &1013 ... 8E73 8D 14 10 STA &1014 ... 8E76 B9 74 10 LDA &1074,Y .t. \set command = Read for src disc 8E79 8D 16 10 STA &1016 ... \or Write for target disc 8E7C A5 AD LDA &AD .. \if buffer size = 0 8E7E F0 D8 BEQ &8E58 .. \then swap discs and start again 8E80 20 86 8E JSR &8E86 .. \else do disc transfer <= bufsiz 8E83 4C 5B 8E JMP &8E5B L[. \and start again. 8E86 20 00 92 JSR &9200 .. \Do disc transfer.A=sector count 8E89 BE 78 10 LDX &1078,Y .x. \if source stg <256 then 8E8C D0 08 BNE &8E96 .. 8E8E D9 76 10 CMP &1076,Y .v. \A = max(A, source stg). 8E91 90 03 BCC &8E96 .. 8E93 B9 76 10 LDA &1076,Y .v. 8E96 85 AE STA &AE .. \save sector count 8E98 84 AF STY &AF .. \save source/target in temp 8E9A BE 7A 10 LDX &107A,Y .z. \get low byte of start sector 8E9D B9 7C 10 LDA &107C,Y .|. \get high byte 8EA0 A8 TAY . \set XY = start sector 8EA1 A5 AE LDA &AE .. \get sector count in A 8EA3 20 06 9B JSR &9B06 .. \do LBA transfer 8EA6 98 TYA . \XY = last+1 sector 8EA7 A4 AF LDY &AF .. \restore Y=source or target 8EA9 99 7C 10 STA &107C,Y .|. \store high byte 8EAC 8A TXA . \store low byte 8EAD 99 7A 10 STA &107A,Y .z. 8EB0 B9 76 10 LDA &1076,Y .v. \subtract sector count from 8EB3 38 SEC 8 \source sectors-to-go 8EB4 E5 AE SBC &AE .. \first low byte 8EB6 99 76 10 STA &1076,Y .v. 8EB9 B9 78 10 LDA &1078,Y .x. \then borrow from high byte 8EBC E9 00 SBC #&00 00000000 8EBE 99 78 10 STA &1078,Y .x. 8EC1 AD 12 10 LDA &1012 ... \number of last+1 page 8EC4 85 AC STA &AC .. \store start of data buffer 8EC6 A5 AD LDA &AD .. \subtract sector count 8EC8 38 SEC 8 \from buffer size 8EC9 E5 AE SBC &AE .. 8ECB 85 AD STA &AD .. \exit. 8ECD 60 RTS ` 8ECE A6 CC LDX &CC .. \Copy entry from cat 1 to 2 8ED0 20 00 92 JSR &9200 .. \cat ptr to X then save AXY 8ED3 A4 AB LDY &AB .. \?&AB = offset in cat 2 8ED5 98 TYA . \put into A and Y 8ED6 18 CLC . \add 8 to A 8ED7 69 08 ADC #&08 00001000 8ED9 85 AB STA &AB .. \store as loop limit 8EDB BD 08 0E LDA &0E08,X ... \copy name part of cat entry 8EDE 91 A9 STA (&A9),Y .. \to catalogue buffer 8EE0 E6 AA INC &AA .. \point to next page up 8EE2 BD 08 0F LDA &0F08,X ... \copy attributes of cat entry 8EE5 91 A9 STA (&A9),Y .. \to catalogue buffer 8EE7 C6 AA DEC &AA .. \point to original page 8EE9 E8 INX . \increment offsets 8EEA C8 INY . 8EEB C4 AB CPY &AB .. \compare with loop limit 8EED D0 EC BNE &8EDB .. \if equal exit else loop. 8EEF 60 RTS ` 8EF0 20 00 92 JSR &9200 .. \Unpack catalogue 2 entry 8EF3 8A TXA . \x = offset in catalogue 2 8EF4 A8 TAY . \copy it to Y 8EF5 A2 00 LDX #&00 00000000 \then set X = 0 8EF7 B1 A9 LDA (&A9),Y .. \copy cat entry in buffer 2 8EF9 9D 40 10 STA &1040,X .@. \to packed area in cat block 1 8EFC E6 AA INC &AA .. 8EFE B1 A9 LDA (&A9),Y .. 8F00 9D 48 10 STA &1048,X .H. 8F03 C6 AA DEC &AA .. 8F05 E8 INX . 8F06 C8 INY . 8F07 E0 08 CPX #&08 00001000 8F09 D0 EC BNE &8EF7 .. 8F0B AD 06 0F LDA &0F06 ... \get cat 1 volume size high bits 8F0E 48 PHA H \save 8F0F AD 81 10 LDA &1081 ... \put cat 2's size in its place 8F12 8D 06 0F STA &0F06 ... \(to select 18/19 bit fields): 8F15 20 12 A6 JSR &A612 .. \unpack cat fields from wkspace 8F18 68 PLA h \and restore cat 1's size. 8F19 8D 06 0F STA &0F06 ... 8F1C 20 06 92 JSR &9206 .. \copy cat block 1 to block 2 8F1F 40 RTI @ 8F20 10 58 BPL &8F7A .X 8F22 10 18 BPL &8F3C .. 8F24 BA TSX . \return new offset in X 8F25 98 TYA . 8F26 9D 04 01 STA &0104,X ... \and exit. 8F29 60 RTS ` 8F2A 48 PHA H \Set copy range = entry range 8F2B AD 53 10 LDA &1053 .S. \get sector count low byte 8F2E 99 76 10 STA &1076,Y .v. \store sectors-to-go low byte 8F31 AD 54 10 LDA &1054 .T. \same with high byte 8F34 99 78 10 STA &1078,Y .x. \Y=0 selects source Y=1 target 8F37 AD 51 10 LDA &1051 .Q. \absolute start sector low 8F3A 99 7A 10 STA &107A,Y .z. \(LBA) 8F3D AD 52 10 LDA &1052 .R. \absolute start sector high 8F40 99 7C 10 STA &107C,Y .|. 8F43 68 PLA h \restore A and exit. 8F44 60 RTS ` 8F45 20 09 A6 JSR &A609 .. \Create catalogue entry 8F48 20 06 A4 JSR &A406 .. \print *INFO line 8F4B 4C 09 90 JMP &9009 L.. \print newline and exit \Console output subsystem 9000 4C 1B 90 JMP &901B L.. \Print character in A 9003 4C 54 90 JMP &9054 LT. \Print space 9006 4C 5C 90 JMP &905C L\. \Tab to column in A 9009 4C 7E 90 JMP &907E L~. \Display error message/newline 900C 4C D7 90 JMP &90D7 L.. \Print hex nibble 900F 4C CC 90 JMP &90CC L.. \Print hex byte 9012 4C F0 90 JMP &90F0 L.. \Print decimal byte 9015 4C B1 90 JMP &90B1 L.. \Print hex word absolute 9018 4C 19 91 JMP &9119 L.. \Print string immediate 901B 20 00 92 JSR &9200 .. \Print character in A 901E A4 F4 LDY &F4 .. 9020 B9 A1 02 LDA &02A1,Y ... \Get ROM type byte 9023 29 08 AND #&08 00001000 \if b3=1 then error message 9025 D0 1E BNE &9045 .. \so add the character to it 9027 AD 7C 02 LDA &027C .|. \else get *FX3 setting 902A 29 10 AND #&10 00010000 \is *SPOOL output disabled? 902C D0 10 BNE &903E .. \if so print the character 902E AD 7C 02 LDA &027C .|. \else disable *SPOOL output 9031 09 10 ORA #&10 00010000 9033 8D 7C 02 STA &027C .|. 9036 B9 A1 02 LDA &02A1,Y ... \and set b2=1 in ROM type byte 9039 09 04 ORA #&04 00000100 \indicating it had been enabled. 903B 99 A1 02 STA &02A1,Y ... 903E BA TSX . \get value in A on entry 903F BD 05 01 LDA &0105,X ... \print it with OSWRCH and exit. 9042 4C EE FF JMP &FFEE L.. 9045 BA TSX . \add character to error message: 9046 BD 05 01 LDA &0105,X ... \get value of A on entry 9049 AC 00 01 LDY &0100 ... \get offset to end of error 904C 99 00 01 STA &0100,Y ... \store character at end 904F C8 INY . \increment offset 9050 8C 00 01 STY &0100 ... \store it and exit. 9053 60 RTS ` 9054 48 PHA H \Print space 9055 A9 20 LDA #&20 00100000 9057 20 1B 90 JSR &901B .. 905A 68 PLA h 905B 60 RTS ` 905C 20 00 92 JSR &9200 .. \Tab to column in A 905F A4 F4 LDY &F4 .. \get ROM type byte 9061 B9 A1 02 LDA &02A1,Y ... 9064 29 08 AND #&08 00001000 \is b3=1, error msg in progress? 9066 30 EC BMI &9054 0. \if so print one space and exit 9068 20 54 90 JSR &9054 T. \else print a space 906B A9 86 LDA #&86 10000110 \get cursor position 906D 20 F4 FF JSR &FFF4 .. 9070 8A TXA . \if cursor in column 0 9071 F0 06 BEQ &9079 .. \then return A=0 9073 BA TSX . \else compare column number 9074 DD 05 01 CMP &0105,X ... \with value of A on entry 9077 90 EF BCC &9068 .. \if less print more spaces 9079 BA TSX . \else return A=X coordinate 907A 9D 05 01 STA &0105,X ... \of cursor 907D 60 RTS ` 907E 20 00 92 JSR &9200 .. \Display error message/newline 9081 A4 F4 LDY &F4 .. \get ROM type byte 9083 B9 A1 02 LDA &02A1,Y ... \clear b2..3 9086 48 PHA H 9087 29 F3 AND #&F3 11110011 9089 99 A1 02 STA &02A1,Y ... 908C 68 PLA h \if b3 was 1 908D 48 PHA H 908E 29 08 AND #&08 00001000 9090 D0 11 BNE &90A3 .. \do a BRK error message in stack 9092 20 E7 FF JSR &FFE7 .. \else print a newline 9095 68 PLA h 9096 29 04 AND #&04 00000100 \if b2 was 1 enable *SPOOL 9098 F0 08 BEQ &90A2 .. 909A AD 7C 02 LDA &027C .|. 909D 29 EF AND #&EF 11101111 909F 8D 7C 02 STA &027C .|. 90A2 60 RTS ` \and exit. 90A3 AC 00 01 LDY &0100 ... \error message.get length of err 90A6 A9 00 LDA #&00 00000000 \set NUL error message terminatr 90A8 99 00 01 STA &0100,Y ... 90AB 8D 00 01 STA &0100 ... \and BRK instruction over length 90AE 4C 00 01 JMP &0100 L.. \call BRK. 90B1 20 00 92 JSR &9200 .. \Print hex word absolute 90B4 20 03 92 JSR &9203 .. \address follows caller's JSR 90B7 85 B2 STA &B2 .. \store address in pointer 90B9 20 03 92 JSR &9203 .. 90BC 85 B3 STA &B3 .. 90BE BA TSX . \get status register on entry 90BF BD 06 01 LDA &0106,X ... 90C2 48 PHA H \C=print leading zeroes 90C3 28 PLP ( 90C4 A0 01 LDY #&01 00000001 \offset to top byte of word 90C6 20 CA 90 JSR &90CA .. \fetch high byte and print 90C9 88 DEY . \point to bottom byte 90CA B1 B2 LDA (&B2),Y .. \fetch it and fall through: 90CC 48 PHA H \Print hex byte 90CD 08 PHP . \upper nibble first 90CE 4A LSR A J 90CF 4A LSR A J 90D0 4A LSR A J 90D1 4A LSR A J 90D2 28 PLP ( 90D3 20 D7 90 JSR &90D7 .. 90D6 68 PLA h \then lower. Fall through: 90D7 48 PHA H \Print hex nibble 90D8 29 0F AND #&0F 00001111 \on entry C=print leading zeroes 90DA F0 01 BEQ &90DD .. \on exit C=a nonzero was printed 90DC 38 SEC 8 90DD 08 PHP . 90DE 09 20 ORA #&20 00100000 90E0 90 08 BCC &90EA .. 90E2 09 30 ORA #&30 00110000 90E4 C9 3A CMP #&3A 00111010 90E6 90 02 BCC &90EA .. 90E8 69 06 ADC #&06 00000110 90EA 20 1B 90 JSR &901B .. 90ED 28 PLP ( 90EE 68 PLA h 90EF 60 RTS ` 90F0 20 00 92 JSR &9200 .. \Print decimal byte 90F3 18 CLC . \C=0, suppress leading zeroes 90F4 A0 02 LDY #&02 00000010 \start with the hundreds 90F6 08 PHP . \digit loop, save C 90F7 A2 00 LDX #&00 00000000 \set quotient = 0 90F9 D9 16 91 CMP &9116,Y ... \subtract loop 90FC 90 07 BCC &9105 .. \if A>=placevalue 90FE E8 INX . \then increment quotient 90FF 38 SEC 8 \and subtract placevalue 9100 F9 16 91 SBC &9116,Y ... \from A 9103 D0 F4 BNE &90F9 .. \if A>0 subtract again 9105 28 PLP ( \else restore C 9106 48 PHA H \save remnant 9107 8A TXA . 9108 D0 02 BNE &910C .. \if quotient>0 then print it 910A 90 03 BCC &910F .. \if a leading zero skip it 910C 20 D7 90 JSR &90D7 .. \else print it 910F 68 PLA h \restore remnant 9110 88 DEY . \point to lower placevalue 9111 D0 E3 BNE &90F6 .. \if not units then loop 9113 38 SEC 8 \else units. set carry 9114 4C D7 90 JMP &90D7 L.. \to print unit even if 0. exit. 9117 0A ASL A . \placevalue 10 9118 64 ??? d \placevalue 100 9119 20 00 92 JSR &9200 .. \Print string immediate 911C 20 03 92 JSR &9203 .. \fetch immediate microcode byte 911F 48 PHA H \save it 9120 29 08 AND #&08 00001000 \if b3=1 9122 F0 0F BEQ &9133 .. 9124 A9 01 LDA #&01 00000001 \then bottom of stack page =1 9126 8D 00 01 STA &0100 ... 9129 A4 F4 LDY &F4 .. \get our ROM socket number 912B B9 A1 02 LDA &02A1,Y ... \get ROM type byte +flags 912E 09 08 ORA #&08 00001000 \set b3=1 9130 99 A1 02 STA &02A1,Y ... \store it back. 9133 68 PLA h \restore microcode byte 9134 A8 TAY . \copy to Y 9135 4A LSR A J \shift b0 into carry 9136 90 0A BCC &9142 .. \if b0=1 9138 A9 0A LDA #&0A 00001010 \then prepend a newline. 913A 20 1B 90 JSR &901B .. 913D A9 0D LDA #&0D 00001101 913F 20 1B 90 JSR &901B .. 9142 20 03 92 JSR &9203 .. \fetch immediate character 9145 F0 06 BEQ &914D .. \if =NUL break out of loop 9147 20 1B 90 JSR &901B .. \else print the character 914A 4C 42 91 JMP &9142 LB. \and loop. 914D BA TSX . \get A on entry 914E BD 05 01 LDA &0105,X ... 9151 C0 80 CPY #&80 10000000 \if microcode b7=1 9153 90 10 BCC &9165 .. 9155 C0 C0 CPY #&C0 11000000 \then if b6=1 9157 90 06 BCC &915F .. 9159 20 1B 90 JSR &901B .. \then 11.. print char in A. 915C 4C 6C 91 JMP &916C Ll. 915F 20 F0 90 JSR &90F0 .. \else 10.. print decimal in A. 9162 4C 6C 91 JMP &916C Ll. 9165 C0 40 CPY #&40 01000000 \else if b6=1 9167 90 03 BCC &916C .. 9169 20 CC 90 JSR &90CC .. \then 01.. print hex in A. 916C 98 TYA . \restore microcode byte 916D 29 02 AND #&02 00000010 \if b1=1 916F F0 03 BEQ &9174 .. 9171 20 7E 90 JSR &907E ~. \then display newline/error msg. 9174 98 TYA . \restore microcode byte 9175 29 04 AND #&04 00000100 \if b2=1 9177 F0 05 BEQ &917E .. 9179 A9 07 LDA #&07 00000111 \then send BEL to make a beep. 917B 20 1B 90 JSR &901B .. 917E 98 TYA . \restore microcode byte 917F 29 10 AND #&10 00010000 \if b4=1 9181 F0 45 BEQ &91C8 .E 9183 20 18 90 JSR &9018 .. \then re-enter! to print "? " 9186 00 BRK . 9187 3F ??? ? 9188 20 00 A2 JSR &A200 .. \call *FX 15,1 918B 01 A9 ORA (&A9,X) .. \to clear input buffer 918D 0F ??? . 918E 20 F4 FF JSR &FFF4 .. 9191 20 E0 FF JSR &FFE0 .. \call OSRDCH to GET character 9194 90 0C BCC &91A2 .. \if ESCAPE pressed 9196 20 18 90 JSR &9018 .. \then re-enter 9199 0A ASL A . \to print "Escape" error 919A 11 45 ORA (&45),Y .E 919C 73 ??? s 919D 63 ??? c 919E 61 70 ADC (&70,X) ap 91A0 65 00 ADC &00 e. 91A2 C9 59 CMP #&59 01011001 \is it "Y"? 91A4 F0 16 BEQ &91BC .. \then register Yes 91A6 C9 79 CMP #&79 01111001 \is it "y"? 91A8 F0 12 BEQ &91BC .. \then register Yes 91AA C9 4E CMP #&4E 01001110 \is it "N"? 91AC F0 04 BEQ &91B2 .. \then register No 91AE C9 6E CMP #&6E 01101110 \is it "n"? 91B0 D0 DF BNE &9191 .. \if not get another keypress. 91B2 20 18 90 JSR &9018 .. \else print "no" 91B5 02 ??? . \(A=&4E or &6E) 91B6 6E 6F 00 ROR &006F no. 91B9 C9 FF CMP #&FF 11111111 \return Z=0, C=0. 91BB 60 RTS ` 91BC 20 18 90 JSR &9018 .. \print "yes" 91BF 02 ??? . 91C0 79 65 73 ADC &7365,Y yes 91C3 00 BRK . 91C4 A9 00 LDA #&00 00000000 \return Z=1, C=1. 91C6 C9 00 CMP #&00 00000000 91C8 60 RTS ` \Macroassembly and miscellaneous 9200 4C 12 92 JMP &9212 L.. \Save AXY 9203 4C 47 92 JMP &9247 LG. \Get byte immediate 9206 4C 68 92 JMP &9268 Lh. \Copy memory absolute 9209 4C 6F 92 JMP &926F Lo. \Copy memory absolute indexed 920C 6C 1E 02 JMP (&021E) l.. \Issue Filing System Call 920F 4C 0F 92 JMP &920F L.. \Halt \Save AXY, to be restored when the calling routine exits. \At that point the status register will be passed back to the \superroutine as in a normal RTS. \On return to the caller the stack will contain (right to left): \&2E, &92, Y, X, A, P, return address(-1) low, return address(-1) high, \superroutine address(-1) low, superroutine address(-1) high \i.e. &0101,S = &2E; &0105,S = A. 9212 08 PHP . \Save AXY 9213 48 PHA H \actually we now save P, A, X, Y 9214 8A TXA . 9215 48 PHA H 9216 98 TYA . 9217 48 PHA H 9218 A9 92 LDA #&92 10010010 \Push the address (less one) 921A 48 PHA H \of the restore routine 921B A9 2E LDA #&2E 00101110 \at &922F 921D 48 PHA H 921E A0 06 LDY #&06 00000110 \set loop counter to 6: 9220 BA TSX . \get current stack pointer 9221 BD 08 01 LDA &0108,X ... \peek at the 8th value down 9224 48 PHA H \push it on top, and loop x6. 9225 88 DEY . \(duplicates return address 9226 D0 F8 BNE &9220 .. \and PAXY) 9228 68 PLA h \pop Y, X, A 9229 A8 TAY . 922A 68 PLA h 922B AA TAX . 922C 68 PLA h 922D 28 PLP ( \pop P and return to caller. 922E 60 RTS ` \Restore AXY. Invoked by the caller of "Save AXY" when it reaches \an RTS. \After the PHP the stack contains (right to left): \new P, old Y, X, A, P, return address(-1) low, return address(-1) high, \superroutine address(-1) low, superroutine address(-1) high \i.e. &0101,S = new P. 922F 08 PHP . \Restore AXY 9230 BA TSX . \push status register on entry 9231 BD 01 01 LDA &0101,X ... \peek its value into A 9234 9D 05 01 STA &0105,X ... \overwrite old status 9237 9D 06 01 STA &0106,X ... \and "Save AXY" return address 923A 9D 07 01 STA &0107,X ... 923D 68 PLA h \discard status on entry 923E 68 PLA h \pop Y, X, A 923F A8 TAY . 9240 68 PLA h 9241 AA TAX . 9242 68 PLA h 9243 28 PLP ( \pop three copies of status 9244 28 PLP ( 9245 28 PLP ( \and return to superroutine 9246 60 RTS ` \Get byte immediate. The caller has already called "Save AXY", \and before that the superroutine called the caller with JSR. \After this JSR instruction is a number of bytes for the subroutine \to process. This routine fetches the next byte for the subroutine \and advances the return address back to the superroutine. \During the TSX at &924A the stack contains (right to left): \&2E, &92, caller Y, X, A, P, \&49, &92, caller return address(-1) low, high, \&2E, &92, superroutine Y, X, A, P, \caller "save AXY" return address(-1) low, high, \superroutine return address(-1) low, high \therefore &0113..4,S = address of the immediate operand, less one. 9247 20 00 92 JSR &9200 .. \Get byte immediate 924A BA TSX . \save caller's AXY 924B 18 CLC . \get stack pointer 924C BD 13 01 LDA &0113,X ... \add 1 to superroutine 924F 69 01 ADC #&01 00000001 \return address 9251 9D 13 01 STA &0113,X ... \save result back on stack 9254 85 B0 STA &B0 .. \and as a pointer 9256 BD 14 01 LDA &0114,X ... \complete the addition 9259 69 00 ADC #&00 00000000 \on the high byte 925B 9D 14 01 STA &0114,X ... \save back on stack 925E 85 B1 STA &B1 .. \store high byte of pointer 9260 A0 00 LDY #&00 00000000 \clear index register 9262 B1 B0 LDA (&B0),Y .. \get byte at new pointer 9264 9D 05 01 STA &0105,X ... \return in A on exit. 9267 60 RTS ` \Copy memory absolute \The JSR instruction calling this routine is followed by: \2 bytes From address, 2 bytes To address, 1 byte length. \Copying proceeds upwards in memory. 9268 20 00 92 JSR &9200 .. \Copy memory absolute 926B A0 05 LDY #&05 00000101 \5 argument bytes 926D D0 05 BNE &9274 .. \and jump always \Copy memory absolute indexed \Arguments as for "Copy memory absolute", except there is a sixth byte: \bits 4 to 7 of this byte control indexing of the From address, \bits 0 and 1 control indexing of the To address. \When the field is all zeroes the relevant address is used as is; \otherwise one of the following values is added to the given address \to form an effective address where the transfer will start. \Bits Value to be added \0000 or 00 Zero \0001 or 01 Y on entry \0010 or 10 X on entry \0011 or 11 A on entry \0100 &71 \0101 &92 \0110 caller return address(-1) low byte \0111 caller return address(-1) high byte \1xxx undefined 926F 20 00 92 JSR &9200 .. \Copy memory absolute indexed 9272 A0 06 LDY #&06 00000110 \6 argument bytes 9274 A2 00 LDX #&00 00000000 \clear offset 9276 86 B7 STX &B7 .. \default to no indexing 9278 20 03 92 JSR &9203 .. \fetch operand byte 927B 95 B2 STA &B2,X .. \store in workspace 927D E8 INX . \increment offset 927E 88 DEY . \decrement counter 927F D0 F7 BNE &9278 .. \loop while more argument bytes 9281 A5 B7 LDA &B7 .. \get indexing argument 9283 4A LSR A J \move bits 7..4 to 3..0 9284 4A LSR A J 9285 4A LSR A J 9286 4A LSR A J 9287 20 AD 92 JSR &92AD .. \fetch relevant index value 928A 65 B2 ADC &B2 e. \add to From address 928C 85 B2 STA &B2 .. \store back in workspace 928E 90 02 BCC &9292 .. \if carry out occurs 9290 E6 B3 INC &B3 .. \then increment high byte. 9292 A5 B7 LDA &B7 .. \get indexing argument 9294 29 03 AND #&03 00000011 \mask off From bits 9296 20 AD 92 JSR &92AD .. \interpret To bits 9299 65 B4 ADC &B4 e. \add relevant index to To addres 929B 85 B4 STA &B4 .. \store back in workspace 929D 90 02 BCC &92A1 .. \if carry out occurs 929F E6 B5 INC &B5 .. \then increment high byte. 92A1 A0 00 LDY #&00 00000000 \clear offset 92A3 B1 B2 LDA (&B2),Y .. \fetch byte from From area 92A5 91 B4 STA (&B4),Y .. \store in To area 92A7 C8 INY . \increment offset 92A8 C4 B6 CPY &B6 .. \have we copied all bytes? 92AA 90 F7 BCC &92A3 .. \if not then loop 92AC 60 RTS ` \else exit. 92AD A8 TAY . \Interpret index bits. 92AE F0 08 BEQ &92B8 .. \if none set then return zero 92B0 BA TSX . \else put stack pointer in X 92B1 E8 INX . \add Y to X without using memory 92B2 88 DEY . 92B3 D0 FC BNE &92B1 .. 92B5 BD 04 01 LDA &0104,X ... \peek one of the saved registers 92B8 18 CLC . \clear carry for add and exit. 92B9 60 RTS ` \Parsing and validation 9300 4C 21 93 JMP &9321 L!. \Get drive spec 9303 4C 4A 93 JMP &934A LJ. \Get volume spec 9306 4C 34 93 JMP &9334 L4. \Get ambiguous volume spec 9309 4C 5B 93 JMP &935B L[. \Get path spec 930C 4C 53 93 JMP &9353 LS. \Get ambiguous path spec 930F 4C 77 93 JMP &9377 Lw. \Get entry (dir+file) name 9312 4C 96 93 JMP &9396 L.. \Get file spec 9315 4C 8E 93 JMP &938E L.. \Get ambiguous file spec 9318 4C 2B 94 JMP &942B L+. \Get multiple drive spec 931B 4C 53 94 JMP &9453 LS. \X=6, check volume letter 931E 4C 5E 94 JMP &945E L^. \Get space padded string char 9321 20 00 92 JSR &9200 .. \Get drive spec 9324 20 06 92 JSR &9206 .. \0, :1, :2, 3, (nothing) 9327 09 10 ORA #&10 00010000 \copy default to immediate drive 9329 C9 00 CMP #&00 00000000 932B 01 A2 ORA (&A2,X) .. \LDX #&00 as it's a "drive" spec 932D 00 BRK . 932E 20 6F 94 JSR &946F o. \get drive spec pt2 and finish. 9331 4C CF 93 JMP &93CF L.. 9334 20 00 92 JSR &9200 .. \Get ambiguous volume spec 9337 20 98 94 JSR &9498 .. \0, :2, :1A, 3H, 1* etc. 933A B0 0B BCS &9347 .. \get volume spec pt2 933C C9 2A CMP #&2A 00101010 \if EOWord finish else compare 933E D0 07 BNE &9347 .. \if this char <> "*" then finish 9340 A9 00 LDA #&00 00000000 \else immed vol = NUL ambiguous 9342 85 C8 STA &C8 .. 9344 20 C5 FF JSR &FFC5 .. \call GSREAD and finish. 9347 4C CF 93 JMP &93CF L.. 934A 20 00 92 JSR &9200 .. \Get volume spec 934D 20 98 94 JSR &9498 .. \0A,:2B etc. get vol pt2 &finish 9350 4C CF 93 JMP &93CF L.. 9353 20 00 92 JSR &9200 .. \Get ambiguous path spec 9356 A9 01 LDA #&01 00000001 \*, :0.*, :3A.*, etc. & as below 9358 4C 60 93 JMP &9360 L`. 935B 20 00 92 JSR &9200 .. \Get path spec 935E A9 00 LDA #&00 00000000 \$, D, :0, :3.M, :2B.$, 9360 85 CE STA &CE .. \:1A etc. 9362 20 06 92 JSR &9206 .. \copy default path to immediate 9365 07 ??? . 9366 10 C7 BPL &932F .. 9368 00 BRK . 9369 03 ??? . 936A A2 0D LDX #&0D 00001101 \this is a "directory" spec 936C 20 AB 94 JSR &94AB .. \get volume part of path spec 936F B0 03 BCS &9374 .. \if end-of-word then exit C=1. 9371 20 F0 94 JSR &94F0 .. \get directory letter & finish. 9374 4C CF 93 JMP &93CF L.. 9377 20 00 92 JSR &9200 .. \Get entry (dir+file) name 937A A9 00 LDA #&00 00000000 \PROG, $.!BOOT, M.DTX 937C 85 CE STA &CE .. \ambiguous specs not allowed 937E 20 06 92 JSR &9206 .. \copy default to immediate 9381 00 BRK . \filename + directory 9382 10 C0 BPL &9344 .. 9384 00 BRK . 9385 08 PHP . 9386 A2 17 LDX #&17 00010111 \this is an "entry" spec 9388 20 47 95 JSR &9547 G. \set up and jump into file spec 938B 4C AA 93 JMP &93AA L.. 938E 20 00 92 JSR &9200 .. \Get ambiguous file spec 9391 A9 01 LDA #&01 00000001 \INTRO, #####P, :2A.*.*, 9393 4C 9B 93 JMP &939B L.. \(nothing) 9396 20 00 92 JSR &9200 .. \Get file spec 9399 A9 00 LDA #&00 00000000 \KEYBD, B.DOTTY, :3.!BOOT, 939B 85 CE STA &CE .. \:2.$.LUNARLA, :A.DEBUG, 939D 20 06 92 JSR &9206 .. \:A.M.DEMO, :1G.DATA12, 93A0 00 BRK . \:0A.$.MENU, (nothing) 93A1 10 C0 BPL &9363 .. \store ambiguous flag 93A3 00 BRK . \copy default to immediate 93A4 0A ASL A . \filename and full path 93A5 A2 1D LDX #&1D 00011101 \this is a "file" spec 93A7 20 AB 94 JSR &94AB .. \get volume part of path spec 93AA B0 23 BCS &93CF .# \if end-of-word then exit C=1 93AC 20 1B 95 JSR &951B .. \else peek next char (AY presvd) 93AF D0 0C BNE &93BD .. \if it was <>".", get filename 93B1 20 F0 94 JSR &94F0 .. \else get directory letter 93B4 C9 2E CMP #&2E 00101110 \compare current char with "." 93B6 D0 1F BNE &93D7 .. \if unequal then "Bad spec" err 93B8 20 C5 FF JSR &FFC5 .. \else call GSREAD 93BB B0 12 BCS &93CF .. \if end-of-word then finish 93BD 20 FA 94 JSR &94FA .. \else get filename proper 93C0 90 0D BCC &93CF .. \if invalid then finish, else: 93C2 A5 CE LDA &CE .. \Accept filename 93C4 30 08 BMI &93CE 0. \if this spec is unambiguous 93C6 20 06 92 JSR &9206 .. \then copy immediate filename 93C9 C0 00 CPY #&00 00000000 \to default filename. 93CB 00 BRK . 93CC 10 07 BPL &93D5 .. 93CE 38 SEC 8 \C=1 for success, fall through: 93CF 90 06 BCC &93D7 .. \Finish parsing. 93D1 BA TSX . \if carry flag is set 93D2 98 TYA . \then return Y to caller 93D3 9D 03 01 STA &0103,X ... \and exit, else: 93D6 60 RTS ` 93D7 20 18 90 JSR &9018 .. \Give bad spec error 93DA 08 PHP . \start error "Bad " 93DB CC 42 61 CPY &6142 .Ba 93DE 64 ??? d 93DF 20 00 A5 JSR &A500 .. \LDA &CE if unambiguous spec 93E2 CE F0 0F DEC &0FF0 ... \BEQ &93F4 then skip 93E5 20 18 90 JSR &9018 .. \else add "ambiguous " 93E8 00 BRK . 93E9 61 6D ADC (&6D,X) am 93EB 62 ??? b 93EC 69 67 ADC #&67 01100111 93EE 75 6F ADC &6F,X uo 93F0 75 73 ADC &73,X us 93F2 20 00 BD JSR &BD00 .. \LDA &9409,X 93F5 09 94 ORA #&94 10010100 \append type of spec 93F7 F0 06 BEQ &93FF .. \to error. if NUL, finish 93F9 20 00 90 JSR &9000 .. \else 'print' character 93FC E8 INX . \increment offset and loop. 93FD D0 F5 BNE &93F4 .. 93FF 20 18 90 JSR &9018 .. \finish error with " spec". 9402 02 ??? . 9403 20 73 70 JSR &7073 sp 9406 65 63 ADC &63 ec 9408 00 BRK . 9409 64 ??? d \spec types: &00,"drive" 940A 72 ??? r 940B 69 76 ADC #&76 01110110 940D 65 00 ADC &00 e. 940F 76 6F ROR &6F,X vo \&06,"volume" 9411 6C 75 6D JMP (&6D75) lum 9414 65 00 ADC &00 e. 9416 64 ??? d \&0D,"directory" 9417 69 72 ADC #&72 01110010 9419 65 63 ADC &63 ec 941B 74 ??? t 941C 6F ??? o 941D 72 ??? r 941E 79 00 65 ADC &6500,Y y.e \&17,"entry" 9421 6E 74 72 ROR &7274 ntr 9424 79 00 66 ADC &6600,Y y.f \&1D,"file" 9427 69 6C ADC #&6C 01101100 9429 65 00 ADC &00 e. 942B 20 00 92 JSR &9200 .. \Get multiple drive spec 942E A2 00 LDX #&00 00000000 \(nothing), 0, :2, :1 2, 1 :3 9430 20 47 95 JSR &9547 G. \call GSINIT C=0 then GSREAD 9433 B0 1B BCS &9450 .. \if end-of-word then finish 9435 C9 3A CMP #&3A 00111010 \else compare this char with ":" 9437 D0 06 BNE &943F .. \if unequal try it as drive no. 9439 20 7C 94 JSR &947C |. \else get drive character 943C 4C 47 94 JMP &9447 LG. \and loop if EOW else bad spec. 943F 20 8A 94 JSR &948A .. \validate and store drive number 9442 90 08 BCC &944C .. \if invalid return in A 9444 20 C5 FF JSR &FFC5 .. \else call GSREAD 9447 B0 E7 BCS &9430 .. \if end-of-word then loop 9449 4C D7 93 JMP &93D7 L.. \else give "Bad spec" error. 944C BA TSX . \Return A to caller 944D 9D 05 01 STA &0105,X ... \and finish parsing. 9450 4C D1 93 JMP &93D1 L.. 9453 20 00 92 JSR &9200 .. \X=6, check volume letter 9456 A2 06 LDX #&06 00000110 \this is a "volume" spec 9458 20 D8 94 JSR &94D8 .. \validate volume letter 945B 4C CF 93 JMP &93CF L.. \or error if invalid. 945E 24 E4 BIT &E4 $. \Get space padded string char 9460 70 09 BVS &946B p. \if b6 of MOS workspace flag set 9462 20 C5 FF JSR &FFC5 .. \(volatile?) then exit else GSRD 9465 90 07 BCC &946E .. \if not EOS return character C=0 9467 66 E4 ROR &E4 f. \else set b6 of workspace flag 9469 66 E4 ROR &E4 f. 946B A9 20 LDA #&20 00100000 \return a space 946D 38 SEC 8 \and exit C=1 (end-of-string) 946E 60 RTS ` 946F A9 00 LDA #&00 00000000 \Get drive spec pt2 9471 85 CE STA &CE .. \ambiguous spec not allowed 9473 20 47 95 JSR &9547 G. \call GSINIT C=0 then GSREAD 9476 B0 11 BCS &9489 .. \if end-of-word then exit C=1 9478 C9 3A CMP #&3A 00111010 \else compare with ":" 947A D0 05 BNE &9481 .. \if unequal try as drive number 947C 20 C5 FF JSR &FFC5 .. \else call GSREAD 947F B0 08 BCS &9489 .. \if end-of-word exit C=1, else: 9481 20 8A 94 JSR &948A .. \Get drive character 9484 90 03 BCC &9489 .. \test&store, if invalid exit C=0 9486 20 C5 FF JSR &FFC5 .. \else call GSREAD and exit. 9489 60 RTS ` 948A C9 30 CMP #&30 00110000 \Validate and store drive number 948C 90 08 BCC &9496 .. \if less than ASCII "0" 948E C9 34 CMP #&34 00110100 \or greater than "3" 9490 B0 04 BCS &9496 .. \then exit C=0 9492 85 C9 STA &C9 .. \else store immediate drive 9494 38 SEC 8 \and exit C=1. 9495 60 RTS ` 9496 18 CLC . 9497 60 RTS ` 9498 20 06 92 JSR &9206 .. \Get volume spec pt2 949B 08 PHP . \copy default to immediate 949C 10 C8 BPL &9466 .. \volume letter and drive number 949E 00 BRK . 949F 02 ??? . 94A0 A2 06 LDX #&06 00000110 \this is a "volume" spec 94A2 20 6F 94 JSR &946F o. \get drive spec pt2 94A5 B0 03 BCS &94AA .. \if end-of-word exit C=1 94A7 20 CF 94 JSR &94CF .. \else get volume letter & exit. 94AA 60 RTS ` 94AB 20 47 95 JSR &9547 G. \Get volume part of path spec 94AE B0 1E BCS &94CE .. \call GSINIT C=0 then GSREAD 94B0 C9 3A CMP #&3A 00111010 \if EOW exit C=1 else compare 94B2 D0 19 BNE &94CD .. \if this char <> ":" exit C=0 94B4 20 C5 FF JSR &FFC5 .. \else call GSREAD 94B7 B0 15 BCS &94CE .. \if end-of-word exit C=1 94B9 20 81 94 JSR &9481 .. \else get drive character 94BC B0 10 BCS &94CE .. \if end-of-word exit C=1 94BE 20 CF 94 JSR &94CF .. \else get volume letter 94C1 B0 0B BCS &94CE .. \if end-of-word exit C=1 94C3 C9 2E CMP #&2E 00101110 \else compare this char to "." 94C5 F0 03 BEQ &94CA .. \if equal call GSREAD and exit 94C7 4C D7 93 JMP &93D7 L.. \else give "Bad spec" error. 94CA 4C C5 FF JMP &FFC5 L.. 94CD 18 CLC . 94CE 60 RTS ` 94CF 20 D8 94 JSR &94D8 .. \Get volume letter 94D2 90 03 BCC &94D7 .. \test&store, if invalid exit C=0 94D4 20 C5 FF JSR &FFC5 .. \else call GSREAD and exit. 94D7 60 RTS ` 94D8 C9 41 CMP #&41 01000001 \Validate & store volume letter 94DA 90 12 BCC &94EE .. \if less than "A" exit C=0 94DC C9 49 CMP #&49 01001001 \else if "H" or less 94DE 90 0A BCC &94EA .. \then store and exit C=1 94E0 C9 61 CMP #&61 01100001 \else if less than "a" 94E2 90 0A BCC &94EE .. \then exit C=0 94E4 C9 69 CMP #&69 01101001 \else if greater than "i" 94E6 B0 06 BCS &94EE .. \then exit C=0 94E8 29 DF AND #&DF 11011111 \else convert to uppercase 94EA 85 C8 STA &C8 .. \store immediate volume 94EC 38 SEC 8 \and exit C=1. 94ED 60 RTS ` 94EE 18 CLC . 94EF 60 RTS ` 94F0 20 24 95 JSR &9524 $. \Get directory letter 94F3 90 D2 BCC &94C7 .. \test spec char, error if bad 94F5 85 C7 STA &C7 .. \else store immediate directory 94F7 4C C5 FF JMP &FFC5 L.. \call GSREAD and exit. 94FA 20 00 92 JSR &9200 .. \Get filename proper 94FD A2 00 LDX #&00 00000000 \x is now just an offset 94FF 20 24 95 JSR &9524 $. \test spec character 9502 90 14 BCC &9518 .. \if invalid return Y, exit C=0 9504 95 C0 STA &C0,X .. \else store immediate filename 9506 E8 INX . \increment offset 9507 E0 07 CPX #&07 00000111 \have we taken 7 characters? 9509 F0 0A BEQ &9515 .. \if so get pad char and finish 950B C9 2A CMP #&2A 00101010 \else compare this char with "*" 950D F0 03 BEQ &9512 .. \if unequal, then: 950F 20 1E 93 JSR &931E .. \get space padded character. 9512 4C FF 94 JMP &94FF L.. \now loop for more characters. 9515 20 1E 93 JSR &931E .. \get space padded character 9518 4C D1 93 JMP &93D1 L.. \return Y to caller and exit. 951B 20 00 92 JSR &9200 .. \Peek next char and compare "." 951E 20 1E 93 JSR &931E .. \preserve AXY, get padded char 9521 C9 2E CMP #&2E 00101110 \and return Z=1 iff equals "." 9523 60 RTS ` 9524 C9 3A CMP #&3A 00111010 \Test spec character 9526 F0 19 BEQ &9541 .. \is it ":" 9528 C9 2E CMP #&2E 00101110 \or "." ? 952A F0 15 BEQ &9541 .. \if so exit C=0 952C C9 2A CMP #&2A 00101010 \else is it a "*" ? 952E F0 04 BEQ &9534 .. \then go flag ambiguous 9530 C9 23 CMP #&23 00100011 \else is it a "#" ? 9532 D0 0A BNE &953E .. \if anything else exit C=1 9534 48 PHA H \else save character 9535 A5 CE LDA &CE .. \if ambiguous specs not allowed 9537 F0 07 BEQ &9540 .. \then exit C=0 9539 A9 FF LDA #&FF 11111111 \else flag = &FF 953B 85 CE STA &CE .. \as this spec is ambiguous 953D 68 PLA h \and exit C=1. 953E 38 SEC 8 953F 60 RTS ` 9540 68 PLA h 9541 18 CLC . 9542 60 RTS ` 9543 18 CLC . \Call GSINIT with C=0. 9544 4C C2 FF JMP &FFC2 L.. 9547 20 43 95 JSR &9543 C. \Call GSINIT C=0 then GSREAD. 954A 4C C5 FF JMP &FFC5 L.. \EDOS setup 9600 4C 1E 96 JMP &961E L.. \Print EDOS banner 9603 4C 3C 96 JMP &963C L<. \Initialise EDOS 9606 4C 12 97 JMP &9712 L.. \Save workspace to private page 9609 4C 2A 97 JMP &972A L*. \Get boot option 960C 4F ??? O \boot commands/descriptions 0..3 960D 46 46 LSR &46 FF \OFF, LOAD, RUN, EXEC 960F 20 4C 4F JSR &4F4C LO 9612 41 44 EOR (&44,X) AD 9614 20 52 55 JSR &5552 RU 9617 4E 20 45 LSR &4520 N E 961A 58 CLI X 961B 45 43 EOR &43 EC 961D 20 20 00 JSR &0020 . \Print EDOS banner 9620 92 ??? . 9621 A2 00 LDX #&00 00000000 \set character offset=0 (soon 1) 9623 20 2F 96 JSR &962F /. \print "OPUS EDOS " 9626 49 00 EOR #&00 00000000 9628 EA NOP . 9629 20 2F 96 JSR &962F /. \print version string 962C 4C 09 90 JMP &9009 L.. \print newline and exit. 962F E8 INX . \Print title string. inc offset 9630 BD 08 80 LDA &8008,X ... \get character from ROM title 9633 F0 06 BEQ &963B .. \if zero then exit 9635 20 00 90 JSR &9000 .. \else print character 9638 4C 2F 96 JMP &962F L/. \and repeat 963B 60 RTS ` 963C 20 00 92 JSR &9200 .. \Initialise EDOS 963F A9 06 LDA #&06 00000110 \issue OSFSC 6 to notify current 9641 20 0C 92 JSR &920C .. \FS. 9644 A9 A8 LDA #&A8 10101000 \call OSBYTE &A8, X=0, Y=&FF 9646 20 EB 9A JSR &9AEB .. \to get address of extended 9649 86 AA STX &AA .. \vector table 964B 84 AB STY &AB .. \store word in zero page 964D EA NOP . 964E A2 00 LDX #&00 00000000 \set X=0 offset in preset table 9650 A0 1B LDY #&1B 00011011 \set Y=&1B offset in EVT 9652 20 DA 96 JSR &96DA .. \copy two bytes from ROM to EVT 9655 20 DA 96 JSR &96DA .. 9658 A5 F4 LDA &F4 .. \add our ROM number to the table 965A 91 AA STA (&AA),Y .. 965C C8 INY . 965D E0 0E CPX #&0E 00001110 \have we copied 7 vectors? 965F D0 F1 BNE &9652 .. \if not loop 9661 A2 0F LDX #&0F 00001111 \issue ROM service call &F, 9663 A9 8F LDA #&8F 10001111 \vectors have been changed 9665 20 F4 FF JSR &FFF4 .. 9668 A2 0A LDX #&0A 00001010 \issue ROM service call &A, 966A A9 8F LDA #&8F 10001111 \claiming absolute workspace 966C 20 F4 FF JSR &FFF4 .. 966F 20 3A 97 JSR &973A :. \test flag in private page 9672 C9 EF CMP #&EF 11101111 \=&EF workspace stowed? 9674 F0 13 BEQ &9689 .. \if so go and unstow 9676 20 CE 83 JSR &83CE .. \else print EDOS banner+newline 9679 A0 00 LDY #&00 00000000 \store meta-default path and lib 967B B9 04 97 LDA &9704,Y ... \in private page, clear rest of 967E C0 0E CPY #&0E 00001110 \page 9680 90 02 BCC &9684 .. 9682 A9 00 LDA #&00 00000000 9684 91 A8 STA (&A8),Y .. 9686 C8 INY . 9687 D0 F2 BNE &967B .. 9689 A0 0D LDY #&0D 00001101 \store &BE, workspace unstowed 968B A9 BE LDA #&BE 10111110 \in flag in private page 968D 91 A8 STA (&A8),Y .. 968F A0 00 LDY #&00 00000000 \copy private page to absolute 9691 B1 A8 LDA (&A8),Y .. \workspace 9693 99 00 10 STA &1000,Y ... 9696 C8 INY . 9697 D0 F8 BNE &9691 .. 9699 20 06 92 JSR &9206 .. \copy default path to zero page 969C 00 BRK . 969D 10 C0 BPL &965F .. 969F 00 BRK . 96A0 0A ASL A . 96A1 A9 36 LDA #&36 00110110 \&36 = EDOS pseudo-command 96A3 8D 16 10 STA &1016 ... \2791 Force Interrupt 96A6 20 12 9B JSR &9B12 .. \issue plain OSWORD &7F 96A9 BA TSX . \get value of Y on entry 96AA BD 03 01 LDA &0103,X ... 96AD D0 20 BNE &96CF . \if Y=0 exit with C=1, break out 96AF 20 00 9B JSR &9B00 .. \else softmount & load cat 96B2 20 09 96 JSR &9609 .. \get boot option 96B5 F0 18 BEQ &96CF .. \if boot is OFF, exit C=1 96B7 20 09 92 JSR &9209 .. \else copy boot command fr &960C 96BA 0C ??? . \to string workspace at &1058 96BB 96 58 STX &58,Y .X \4 bytes, X indexed source 96BD 10 04 BPL &96C3 .. 96BF 20 20 06 JSR &0620 . \copy filename " $.!boot"+cr 96C2 92 ??? . \to &105C, 9 bytes 96C3 D1 96 CMP (&96),Y .. 96C5 5C ??? \ 96C6 10 09 BPL &96D1 .. 96C8 A2 58 LDX #&58 01011000 \call OSCLI on command string 96CA A0 10 LDY #&10 00010000 96CC 20 F7 FF JSR &FFF7 .. 96CF 38 SEC 8 \set C=1 to breakout of ROM call 96D0 60 RTS ` \and exit 96D1 20 24 2E JSR &2E24 $. \"$.!boot" name of boot file 96D4 21 62 AND (&62,X) !b 96D6 6F ??? o 96D7 6F ??? o 96D8 74 ??? t 96D9 0D BD E8 ORA &E8BD ... \LDA &96E8,X get preset vector 96DC 96 9D STX &9D,Y .. \STA &0212,X store in vector tbl 96DE 12 ??? . \pointing to extended vector 96DF 02 ??? . \handler 96E0 BD F6 96 LDA &96F6,X ... \get extended vector preset 96E3 91 AA STA (&AA),Y .. \store in extended vector table 96E5 E8 INX . \increment pair offset 96E6 C8 INY . \increment triplet offset 96E7 60 RTS ` \exit 96E8 1B ??? . \Vectors to extended vector 96E9 FF ??? . \handlers, 7 pairs [0..13] 96EA 1E FF 21 ASL &21FF,X ..! \&FF1B, &FF1E, &FF21, ...&FF2D. 96ED FF ??? . 96EE 24 FF BIT &FF $. 96F0 27 ??? ' 96F1 FF ??? . 96F2 2A ROL A * 96F3 FF ??? . 96F4 2D FF 00 AND &00FF -.. \&B000, FILEV for OSFILE 96F7 B0 03 BCS &96FC .. \&B003, ARGSV for OSARGS 96F9 B0 00 BCS &96FB .. \&B400, BGETV for OSBGET 96FB B4 03 LDY &03,X .. \&B403, BPUTV for OSBPUT 96FD B4 06 LDY &06,X .. \&B406, GBPBV for OSGBPB 96FF B4 06 LDY &06,X .. \&B006, FINDV for OSFIND 9701 B0 09 BCS &970C .. \&B009, FSCV for OSFILE 9703 B0 20 BCS &9725 . \meta-default filename and path 9705 20 20 20 JSR &2020 9708 20 20 20 JSR &2020 970B 24 41 BIT &41 $A 970D 30 24 BMI &9733 0$ \default library 970F 41 30 EOR (&30,X) A0 \flag BE = we own absolute wksp. 9711 BE 20 00 LDX &0020,Y . . \Save workspace to private page 9714 92 ??? . \when abs wksp claim or vecs chg 9715 20 D6 9A JSR &9AD6 .. \if wksp is ours flsh all files. 9718 D0 0F BNE &9729 .. \if not ours, then exit 971A A9 EF LDA #&EF 11101111 \else set abs page flag = &EF 971C 8D 0D 10 STA &100D ... \meaning workspace stowed 971F A0 00 LDY #&00 00000000 \and copy wkspace to private pg. 9721 B9 00 10 LDA &1000,Y ... \load one byte from abs page 9724 91 A8 STA (&A8),Y .. \store in private page 9726 C8 INY . \increment offset 9727 D0 F8 BNE &9721 .. \loop until whole page done 9729 60 RTS ` \exit 972A AD 06 0F LDA &0F06 ... \Get boot option 972D 29 30 AND #&30 00110000 \extract boot option 972F 4A LSR A J \shift right twice 9730 4A LSR A J \A=0,4,8 or 12 9731 AA TAX . \copy to X 9732 E0 08 CPX #&08 00001000 \if X>=8, increment X 9734 90 01 BCC &9737 .. 9736 E8 INX . \now X=0,4,9 or 13 9737 4A LSR A J \shift A right twice more 9738 4A LSR A J \return A=0 to 3, X=string ptr 9739 60 RTS ` 973A A4 F4 LDY &F4 .. \Test if private page available 973C B9 F0 0D LDA &0DF0,Y ... \get private page no.for our rom 973F 85 A9 STA &A9 .. \set high byte of pointer 9741 A9 00 LDA #&00 00000000 \clear low byte of pointer 9743 85 A8 STA &A8 .. 9745 A0 0D LDY #&0D 00001101 \load byte &D of private page 9747 B1 A8 LDA (&A8),Y .. \through the pointer 9749 C9 BE CMP #&BE 10111110 \compare with value &BE 974B 60 RTS ` \return Z=page available \Channel operations 9800 4C 24 98 JMP &9824 L$. \Initialise for open file 9803 4C 4E 98 JMP &984E LN. \Init & check file open 9806 4C AC 98 JMP &98AC L.. \Check file not open (mutex) 9809 4C 73 98 JMP &9873 Ls. \Get unused file handle 980C 4C 9E 98 JMP &989E L.. \Check file open &return pointer 980F 4C 0C 99 JMP &990C L.. \Flush open file 9812 4C 20 99 JMP &9920 L . \Transfer file buffer to LBA 9815 4C 49 99 JMP &9949 LI. \Close or flush open file 9818 4C 6B 99 JMP &996B Lk. \Close or flush all files 981B 4C 84 99 JMP &9984 L.. \Check volume not changed 981E 4C C7 99 JMP &99C7 L.. \Open a file 9821 4C 2E 9A JMP &9A2E L.. \Print disc/volume error message 9824 86 CB STX &CB .. \Initialise for open file 9826 A0 00 LDY #&00 00000000 \set pointer to buffer 9828 84 CA STY &CA .. 982A E0 11 CPX #&11 00010001 \validate file handle 982C 90 10 BCC &983E .. 982E E0 16 CPX #&16 00010110 9830 B0 0C BCS &983E .. 9832 BC 28 98 LDY &9828,X .(. \point Y to file workspace 9835 B9 88 10 LDA &1088,Y ... \put file flag byte in A 9838 60 RTS ` 9839 00 BRK . \table to start of workspace 983A 18 CLC . \for channels &11..15 983B 30 48 BMI &9885 0H 983D 60 RTS ` 983E 20 64 98 JSR &9864 d. \print "Channel n" 9841 20 18 90 JSR &9018 .. \print " invalid" 9844 02 ??? . 9845 20 69 6E JSR &6E69 in 9848 76 61 ROR &61,X va 984A 6C 69 64 JMP (&6469) lid 984D 00 BRK . 984E 20 00 98 JSR &9800 .. \Initialise for open file 9851 D0 E5 BNE &9838 .. \if file closed 9853 20 64 98 JSR &9864 d. \print "Channel n" 9856 20 18 90 JSR &9018 .. \print " not open" 9859 02 ??? . 985A 20 6E 6F JSR &6F6E no 985D 74 ??? t 985E 20 6F 70 JSR &706F op 9861 65 6E ADC &6E en 9863 00 BRK . 9864 8A TXA . 9865 20 18 90 JSR &9018 .. 9868 88 DEY . 9869 DE 43 68 DEC &6843,X .Ch 986C 61 6E ADC (&6E,X) an 986E 6E 65 6C ROR &6C65 nel 9871 20 00 48 JSR &4800 .H \Get unused file handle 9874 A2 11 LDX #&11 00010001 \start with lowest handle &11 9876 20 00 98 JSR &9800 .. \initialise for this handle 9879 F0 21 BEQ &989C .! \if handle unused exit 987B E8 INX . \else increment handle number 987C E0 16 CPX #&16 00010110 \have we run out of handles? 987E D0 F6 BNE &9876 .. \if not try next handle 9880 20 18 90 JSR &9018 .. \else give error 9883 0A ASL A . \"Too many open channels" 9884 C0 54 CPY #&54 01010100 9886 6F ??? o 9887 6F ??? o 9888 20 6D 61 JSR &616D ma 988B 6E 79 20 ROR &2079 ny 988E 6F ??? o 988F 70 65 BVS &98F6 pe 9891 6E 20 63 ROR &6320 n c 9894 68 PLA h 9895 61 6E ADC (&6E,X) an 9897 6E 65 6C ROR &6C65 nel 989A 73 ??? s 989B 00 BRK . 989C 68 PLA h \return unused handle in X 989D 60 RTS ` 989E 20 00 92 JSR &9200 .. \Initialise & check file open 98A1 98 TYA . \copy handle to X 98A2 AA TAX . 98A3 20 03 98 JSR &9803 .. \initialise & check file open 98A6 BA TSX . \return workspace pointer in Y 98A7 98 TYA . 98A8 9D 03 01 STA &0103,X ... 98AB 60 RTS ` 98AC 20 00 92 JSR &9200 .. \Check file not open (mutex) 98AF A2 11 LDX #&11 00010001 \start with lowest handle &11 98B1 20 00 98 JSR &9800 .. \initialise for this handle 98B4 F0 41 BEQ &98F7 .A \no match if handle is unused 98B6 BA TSX . \get A on entry. b7=we want to 98B7 1D 05 01 ORA &0105,X ... \open for writing.if request and 98BA 10 3B BPL &98F7 .; \handle both read only,no match. 98BC A2 08 LDX #&08 00001000 \else 8 characters to compare 98BE 86 B9 STX &B9 .. \store a counter 98C0 A6 CC LDX &CC .. \point X to filename in cat 98C2 BD 08 0E LDA &0E08,X ... \get character of file/dir name 98C5 20 FF 98 JSR &98FF .. \convert to upper case 98C8 85 B8 STA &B8 .. \store in temp location 98CA B9 8A 10 LDA &108A,Y ... \get filename char 4 this handle 98CD 20 FF 98 JSR &98FF .. \convert to upper case 98D0 C5 B8 CMP &B8 .. \compare with catalogue char 98D2 D0 23 BNE &98F7 .# \no match if unequal 98D4 E8 INX . \else increment catalogue ptr 98D5 C8 INY . \and handle pointer 98D6 C6 B9 DEC &B9 .. \one less char to compare 98D8 D0 E8 BNE &98C2 .. \loop if more characters 98DA A5 C8 LDA &C8 .. \else get volume of subject file 98DC D9 8A 10 CMP &108A,Y ... \compare with volume of handle 98DF D0 16 BNE &98F7 .. \no match if unequal 98E1 A5 C9 LDA &C9 .. \else get drive of subject file 98E3 D9 8B 10 CMP &108B,Y ... \compare with drive of handle 98E6 D0 0F BNE &98F7 .. \no match if unequal 98E8 20 18 90 JSR &9018 .. \else a match,"File open" error. 98EB 0A ASL A . 98EC C2 ??? . 98ED 46 69 LSR &69 Fi 98EF 6C 65 20 JMP (&2065) le 98F2 6F ??? o 98F3 70 65 BVS &995A pe 98F5 6E 00 A6 ROR &A600 n.. \put handle number back in X 98F8 CB ??? . 98F9 E8 INX . \increment handle number 98FA E0 16 CPX #&16 00010110 \have we run out of handles? 98FC D0 B3 BNE &98B1 .. \if not try next handle 98FE 60 RTS ` \if so then file not open, exit 98FF 29 7F AND #&7F 01111111 \Convert to uppercase. mask b7 9901 C9 61 CMP #&61 01100001 \less than "a"? 9903 90 06 BCC &990B .. \if so return 9905 C9 7B CMP #&7B 01111011 \more than "z"? 9907 B0 02 BCS &990B .. \if so return 9909 29 DF AND #&DF 11011111 \else return ASCII value A-Z 990B 60 RTS ` 990C 20 00 92 JSR &9200 .. \Flush file buffer 990F B9 89 10 LDA &1089,Y ... \test if page is dirty 9912 C9 02 CMP #&02 00000010 9914 A9 00 LDA #&00 00000000 9916 99 89 10 STA &1089,Y ... \mark it empty 9919 90 F0 BCC &990B .. 991B A9 4B LDA #&4B 01001011 \if it was dirty, write it out. 991D 4C 23 99 JMP &9923 L#. 9920 20 00 92 JSR &9200 .. \Transfer file buffer to LBA 9923 8D 16 10 STA &1016 ... \A=command, store it 9926 B9 93 10 LDA &1093,Y ... \get drive the file is on 9929 85 C9 STA &C9 .. 992B A5 CA LDA &CA .. \give address of buffer 992D 8D 11 10 STA &1011 ... 9930 A5 CB LDA &CB .. 9932 8D 12 10 STA &1012 ... 9935 A9 FF LDA #&FF 11111111 \in I/O processor 9937 8D 13 10 STA &1013 ... 993A 8D 14 10 STA &1014 ... 993D BE 96 10 LDX &1096,Y ... \and desired absolute sector 9940 B9 97 10 LDA &1097,Y ... 9943 A8 TAY . 9944 A9 01 LDA #&01 00000001 \one sector to transfer 9946 4C 06 9B JMP &9B06 L.. \do it 9949 20 0F 98 JSR &980F .. \Close or flush open file 994C 24 CD BIT &CD $. \flush buffer. if &CD b7=1 994E 30 33 BMI &9983 03 \then exit (flush only) 9950 48 PHA H \else clear channel flags 9951 A9 00 LDA #&00 00000000 9953 99 88 10 STA &1088,Y ... 9956 68 PLA h \if bit 7 of A clear then exit 9957 10 2A BPL &9983 .* 9959 20 1B 98 JSR &981B .. \else check volume not changed 995C 20 09 92 JSR &9209 .. \copy EXT to file length in cat 995F 9A TXS . 9960 10 4E BPL &99B0 .N 9962 10 03 BPL &9967 .. 9964 10 20 BPL &9986 . \JSR &A606 pack catalogue fields 9966 06 A6 ASL &A6 .. 9968 4C 03 9B JMP &9B03 L.. \write catalogue and exit. 996B A5 CD LDA &CD .. \Close or flush all files 996D 30 05 BMI &9974 0. \if &CD b7=0 996F A9 77 LDA #&77 01110111 \then close *SPOOL/*EXEC files. 9971 20 F4 FF JSR &FFF4 .. 9974 A2 11 LDX #&11 00010001 \set file handle=&11 9976 20 00 98 JSR &9800 .. \initialise for handle 9979 F0 03 BEQ &997E .. \if handle in use 997B 20 15 98 JSR &9815 .. \close or flush open file 997E E8 INX . \increment handle 997F E0 16 CPX #&16 00010110 \repeat for all handles and exit 9981 D0 F3 BNE &9976 .. 9983 60 RTS ` 9984 20 09 92 JSR &9209 .. \Check volume not changed 9987 8A TXA . \copy path of open file 9988 10 C0 BPL &994A .. \to immediate path 998A 00 BRK . 998B 0A ASL A . 998C 10 20 BPL &99AE . \softmount and catalogue 998E 00 BRK . \drive 998F 9B ??? . 9990 20 09 A5 JSR &A509 .. \find file in catalogue 9993 B0 26 BCS &99BB .& \if not found "Volume changed" 9995 20 03 A6 JSR &A603 .. \unpack fields from catalogue 9998 AD 51 10 LDA &1051 .Q. \compare start sector 999B D9 94 10 CMP &1094,Y ... \with one in file workspace 999E D0 1B BNE &99BB .. \"Volume changed" if different 99A0 AD 52 10 LDA &1052 .R. 99A3 D9 95 10 CMP &1095,Y ... 99A6 D0 13 BNE &99BB .. 99A8 AD 53 10 LDA &1053 .S. \compare allocated length 99AB D9 98 10 CMP &1098,Y ... \with one in file workspace 99AE D0 0B BNE &99BB .. \"Volume changed" if different 99B0 AD 54 10 LDA &1054 .T. 99B3 D9 99 10 CMP &1099,Y ... 99B6 D0 03 BNE &99BB .. 99B8 4C 21 A5 JMP &A521 L!. \else check file unlocked & exit 99BB 20 21 98 JSR &9821 !. \print disc error +"changed" 99BE C8 INY . 99BF 63 ??? c 99C0 68 PLA h 99C1 61 6E ADC (&6E,X) an 99C3 67 ??? g 99C4 65 64 ADC &64 ed 99C6 00 BRK . 99C7 20 09 98 JSR &9809 .. \Open a file 99CA 20 06 92 JSR &9206 .. \check free handle available 99CD 1E 9A 60 ASL &609A,X ..` \if so copy addresses and 99D0 10 10 BPL &99E2 .. \desired length to file 99D2 A2 00 LDX #&00 00000000 \workspace 99D4 20 18 A6 JSR &A618 .. \check perms/create file 99D7 B0 44 BCS &9A1D .D \if failed exit C=1, else: 99D9 20 09 98 JSR &9809 .. \get unused file handle 99DC 99 88 10 STA &1088,Y ... \store read/write flags from A 99DF A9 00 LDA #&00 00000000 99E1 99 89 10 STA &1089,Y ... \mark file buffer empty 99E4 99 9A 10 STA &109A,Y ... \clear low byte of EXT 99E7 20 09 92 JSR &9209 .. \copy zero to clear EXT & PTR 99EA 9A TXS . 99EB 10 9B BPL &9988 .. 99ED 10 05 BPL &99F4 .. 99EF 11 20 ORA (&20),Y . \copy immediate name and path 99F1 09 92 ORA #&92 10010010 \to name and path of open file 99F3 C0 00 CPY #&00 00000000 99F5 8A TXA . 99F6 10 0A BPL &9A02 .. 99F8 01 20 ORA (&20,X) . \copy absolute start sector 99FA 09 92 ORA #&92 10010010 \to file workspace 99FC 51 10 EOR (&10),Y Q. 99FE 94 10 STY &10,X .. 9A00 02 ??? . 9A01 01 20 ORA (&20,X) . \copy number of sectors used 9A03 09 92 ORA #&92 10010010 \to allocated length 9A05 53 ??? S 9A06 10 98 BPL &99A0 .. 9A08 10 02 BPL &9A0C .. 9A0A 01 B9 ORA (&B9,X) .. \LDA &1088,Y get channel flag 9A0C 88 DEY . 9A0D 10 2A BPL &9A39 .* \ROL A 9A0F 10 09 BPL &9A1A .. \if open for writing/update 9A11 20 09 92 JSR &9209 .. \then copy file length to EXT 9A14 4E 10 9A LSR &9A10 N.. 9A17 10 03 BPL &9A1C .. 9A19 01 B9 ORA (&B9,X) .. \LDA &1088,Y get channel flag 9A1B 88 DEY . 9A1C 10 60 BPL &9A7E .` \RTS exit 9A1E FF ??? . \table [0..15] of parameters 9A1F FF ??? . \for new open files 9A20 03 ??? . \copied to &1060..6F 9A21 FF ??? . \load address, then exec address 9A22 FF ??? . \(18 bits each) = &3FFFF 9A23 03 ??? . 9A24 00 BRK . \initial length (24 bits) 9A25 40 RTI @ \=&004000, 16K 9A26 00 BRK . 9A27 00 BRK . \reserved for abs end sector 9A28 00 BRK . 9A29 40 RTI @ \desired sec allocation =&0040 9A2A 00 BRK . \to open 5 files on a 100K disc 9A2B 00 BRK . 9A2C 00 BRK . 9A2D 00 BRK . 9A2E 20 00 92 JSR &9200 .. \Print disc/volume error message 9A31 20 18 90 JSR &9018 .. \set up message 9A34 08 PHP . 9A35 00 BRK . 9A36 20 03 92 JSR &9203 .. \get error number 9A39 20 00 90 JSR &9000 .. \"print" it 9A3C A5 C9 LDA &C9 .. \get drive number 9A3E AA TAX . 9A3F BC FC 0F LDY &0FFC,X ... \does drive have multiple vols? 9A42 D0 0D BNE &9A51 .. \if not 9A44 20 18 90 JSR &9018 .. \print "Disc "+number 9A47 C0 44 CPY #&44 01000100 9A49 69 73 ADC #&73 01110011 9A4B 63 ??? c 9A4C 20 00 4C JSR &4C00 .L \JMP &9A62 print space & string 9A4F 62 ??? b 9A50 9A TXS . 9A51 20 18 90 JSR &9018 .. \else print "Volume "+number 9A54 C0 56 CPY #&56 01010110 9A56 6F ??? o 9A57 6C 75 6D JMP (&6D75) lum 9A5A 65 20 ADC &20 e 9A5C 00 BRK . 9A5D A5 C8 LDA &C8 .. \get volume letter 9A5F 20 00 90 JSR &9000 .. \print it 9A62 20 03 90 JSR &9003 .. \print space 9A65 20 03 92 JSR &9203 .. \print error string immediate: 9A68 F0 06 BEQ &9A70 .. \get immediate byte, if not 0 9A6A 20 00 90 JSR &9000 .. \then print it 9A6D 4C 65 9A JMP &9A65 Le. \and loop 9A70 4C 09 90 JMP &9009 L.. \else display error/newline \EDOSPAT extensions, block 2 9ACA 20 88 9B JSR &9B88 .. \softmount disc 9ACD 08 PHP . \save status register 9ACE 4E 17 10 LSR &1017 N.. \track no. =2 to test stepping 9AD1 4E 17 10 LSR &1017 N.. \set it to 0 for *VERIFY 9AD4 28 PLP ( \restore status and exit 9AD5 60 RTS ` 9AD6 20 3A 97 JSR &973A :. \test flag in private page 9AD9 D0 0F BNE &9AEA .. \if abs wksp not ours, exit Z=0 9ADB A2 11 LDX #&11 00010001 \else start at channel &11: 9ADD 20 00 98 JSR &9800 .. \initialise for channel 9AE0 F0 03 BEQ &9AE5 .. \if not in use try next channel 9AE2 20 0F 98 JSR &980F .. \else flush the channel. 9AE5 E8 INX . \increment handle (?&CD=random) 9AE6 E0 16 CPX #&16 00010110 \have we done all handles? 9AE8 D0 F3 BNE &9ADD .. \if not then loop else exit Z=1 9AEA 60 RTS ` 9AEB A2 00 LDX #&00 00000000 \Call high OSBYTE 9AED A0 FF LDY #&FF 11111111 \set X&Y so not to change value 9AEF 4C F4 FF JMP &FFF4 L.. 9AF2 8D 12 10 STA &1012 ... \store updated address 2nd byte 9AF5 90 08 BCC &9AFF .. \if no carry out then exit 9AF7 EE 13 10 INC &1013 ... \else carry out to top word 9AFA D0 03 BNE &9AFF .. \of OSWORD &7F address 9AFC EE 14 10 INC &1014 ... 9AFF 60 RTS ` \Disc operations 9B00 4C 4A 9B JMP &9B4A LJ. \Softmount & load current cat 9B03 4C E1 9B JMP &9BE1 L.. \Write current catalogue 9B06 4C 1B 9B JMP &9B1B L.. \Do LBA transfer 9B09 4C 50 9B JMP &9B50 LP. \Load volume catalogue 9B0C 4C CA 9A JMP &9ACA L.. \Softmount disc 9B0F 4C 02 9C JMP &9C02 L.. \Call OSWORD &7F, report errors 9B12 4C FD 9C JMP &9CFD L.. \Call OSWORD &7F 9B15 4C FF 9B JMP &9BFF L.. \Call OSWORD &7F r/w w/errors 9B18 4C FA 9C JMP &9CFA L.. \Call OSWORD &7F read/write \Do LBA transfer. On entry A=no. of sectors, XY=absolute start sector, \?&C9=drive, !&1011=address, ?&1016=8271 command. \On exit XY=absolute end sector (last accessed+1), value used at &8EA3. \Transfers the first track and tail-recurses until done. 9B1B 48 PHA H \Do LBA transfer 9B1C 20 BD 9D JSR &9DBD .. \convert LBA to cylinder/sector 9B1F CD 19 10 CMP &1019 ... \compare request - dist to EOT 9B22 B0 03 BCS &9B27 .. \if >0 then transfer to EOT 9B24 8D 19 10 STA &1019 ... \else set O7F length = request 9B27 20 15 9B JSR &9B15 .. \call OSWORD &7F r/w w/errors 9B2A AD 19 10 LDA &1019 ... \get OSWORD &7F transfer length 9B2D 29 DF AND #&DF 11011111 \mask off sector size field 9B2F 8D 19 10 STA &1019 ... \put back in OSWORD &7F block 9B32 18 CLC . \and add to O7F address (*256) 9B33 6D 12 10 ADC &1012 m.. 9B36 20 F2 9A JSR &9AF2 .. \carry out to high bytes 9B39 8A TXA . \put LBA low byte in A 9B3A 18 CLC . \add OSWORD &7F transfer length 9B3B 6D 19 10 ADC &1019 m.. 9B3E AA TAX . \put result back in X 9B3F 90 01 BCC &9B42 .. \and carry out to Y 9B41 C8 INY . 9B42 68 PLA h \restore LBA request length 9B43 38 SEC 8 \subtract O7F transfer length 9B44 ED 19 10 SBC &1019 ... 9B47 D0 D2 BNE &9B1B .. \and loop if result >0 else exit 9B49 60 RTS ` 9B4A 20 0C 9B JSR &9B0C .. \Softmount disc 9B4D D0 BA BNE &9B09 .. \if multi-volume load vol cat 9B4F 60 RTS ` 9B50 20 00 92 JSR &9200 .. \Load volume catalogue 9B53 20 AA 9D JSR &9DAA .. \calculate sector offset 9B56 8A TXA . \divide by 2 again 9B57 4A LSR A J 9B58 A8 TAY . 9B59 B9 30 10 LDA &1030,Y .0. \does the volume exist? 9B5C F0 19 BEQ &9B77 .. \if not give error 9B5E A9 00 LDA #&00 00000000 \page E contains disc cat 9B60 AC 03 0E LDY &0E03 ... \get sectors per track 9B63 18 CLC . 9B64 7D 08 0E ADC &0E08,X }.. \accum cur vol start track 9B67 90 03 BCC &9B6C .. \we're multiplying to get 9B69 EE 39 10 INC &1039 .9. \absolute sector offset 9B6C 88 DEY . \to start of volume 9B6D D0 F4 BNE &9B63 .. \store in 1038..9 9B6F 8D 38 10 STA &1038 .8. \rollout read cat block, 9B72 A9 93 LDA #&93 10010011 \prepare O7F r/w, calculate 9B74 4C F1 9B JMP &9BF1 L.. \vol offset, read vol cat 9B77 20 21 98 JSR &9821 !. \Give volume error"non-existent" 9B7A D1 6E CMP (&6E),Y .n 9B7C 6F ??? o 9B7D 6E 2D 65 ROR &652D n-e 9B80 78 SEI x 9B81 69 73 ADC #&73 01110011 9B83 74 ??? t 9B84 65 6E ADC &6E en 9B86 74 ??? t 9B87 00 BRK . 9B88 20 00 92 JSR &9200 .. \Softmount disc 9B8B A9 00 LDA #&00 00000000 \clear volume offset 9B8D 8D 38 10 STA &1038 .8. 9B90 8D 39 10 STA &1039 .9. 9B93 A6 C9 LDX &C9 .. \get immediate drive 9B95 9D F4 0F STA &0FF4,X ... \clear number of tracks 9B98 9D F8 0F STA &0FF8,X ... \clear track stepping flag 9B9B 20 06 92 JSR &9206 .. \copy read catalogue command 9B9E E6 9C INC &9C .. \to OSWORD 7F block 9BA0 11 10 ORA (&10),Y .. 9BA2 09 AD ORA #&AD 10101101 \get *OPT 6 density 9BA4 84 10 STY &10 .. 9BA6 D0 14 BNE &9BBC .. \not 0? you asked for it 9BA8 BD F0 0F LDA &0FF0,X ... \0=autodetect. 9BAB C9 0A CMP #&0A 00001010 \validate current density 9BAD F0 06 BEQ &9BB5 .. \12=DD, 0A=SD, other ->0A 9BAF C9 12 CMP #&12 00010010 9BB1 F0 02 BEQ &9BB5 .. 9BB3 A9 0A LDA #&0A 00001010 9BB5 20 17 9D JSR &9D17 .. \try to load catalogue 9BB8 F0 0A BEQ &9BC4 .. \Z=success 9BBA 49 18 EOR #&18 00011000 \if failed swap 0A<->12 9BBC 20 17 9D JSR &9D17 .. \and try again 9BBF F0 03 BEQ &9BC4 .. \if another failure 9BC1 4C 08 9C JMP &9C08 L.. \interpret disc error 9BC4 AD 86 10 LDA &1086 ... \else get *OPT 8 tracks 9BC7 F0 14 BEQ &9BDD .. \0 means 1:1 stepping 9BC9 10 0F BPL &9BDA .. \1..127 means skip track(s) 9BCB A9 1F LDA #&1F 00011111 \>127 means autodetect. 9BCD 8D 16 10 STA &1016 ... \Prepare OSWORD &7F command 9BD0 A9 02 LDA #&02 00000010 \to verify track 2 9BD2 8D 17 10 STA &1017 ... 9BD5 20 18 9B JSR &9B18 .. \call OSWORD &7F (with 1:1) 9BD8 F0 03 BEQ &9BDD .. \if failed 9BDA 9D F8 0F STA &0FF8,X ... \set stepping for current drive 9BDD BD FC 0F LDA &0FFC,X ... \return Z=single volume disc 9BE0 60 RTS ` 9BE1 20 00 92 JSR &9200 .. \Write catalogue. 9BE4 F8 SED . \Increment catalogue cycle no. 9BE5 18 CLC . 9BE6 AD 04 0F LDA &0F04 ... 9BE9 69 01 ADC #&01 00000001 9BEB 8D 04 0F STA &0F04 ... 9BEE D8 CLD . 9BEF A9 0B LDA #&0B 00001011 \&0B = write. Fall through: 9BF1 20 06 92 JSR &9206 .. \Read/write volume catalogue. 9BF4 E6 9C INC &9C .. \stamp OSWORD &7F block 9BF6 11 10 ORA (&10),Y .. \A=8271 command 9BF8 09 8D ORA #&8D 10001101 \store it in the block 9BFA 16 10 ASL &10,X .. 9BFC 20 AA 9D JSR &9DAA .. \calculate volume offset 9BFF 20 9A 9D JSR &9D9A .. \OSWORD &7F read/write +errors 9C02 20 12 9B JSR &9B12 .. \OSWORD &7F with errors 9C05 D0 01 BNE &9C08 .. \if failed print error 9C07 60 RTS ` 9C08 AE 15 10 LDX &1015 ... \Decode errors 9C0B BD 17 10 LDA &1017,X ... 9C0E C9 12 CMP #&12 00010010 9C10 D0 16 BNE &9C28 .. 9C12 20 18 90 JSR &9018 .. \"Write protect" 9C15 08 PHP . 9C16 C7 ??? . 9C17 57 ??? W 9C18 72 ??? r 9C19 69 74 ADC #&74 01110100 9C1B 65 20 ADC &20 e 9C1D 70 72 BVS &9C91 pr 9C1F 6F ??? o 9C20 74 ??? t 9C21 65 63 ADC &63 ec 9C23 74 ??? t 9C24 00 BRK . 9C25 4C B8 9C JMP &9CB8 L.. 9C28 C9 20 CMP #&20 00100000 9C2A D0 1A BNE &9C46 .. 9C2C 20 18 90 JSR &9018 .. \"Deleted data read" 9C2F 08 PHP . 9C30 C7 ??? . 9C31 44 ??? D 9C32 65 6C ADC &6C el 9C34 65 74 ADC &74 et 9C36 65 64 ADC &64 ed 9C38 20 64 61 JSR &6164 da 9C3B 74 ??? t 9C3C 61 20 ADC (&20,X) a 9C3E 72 ??? r 9C3F 65 61 ADC &61 ea 9C41 64 ??? d 9C42 00 BRK . 9C43 4C B8 9C JMP &9CB8 L.. 9C46 C9 0C CMP #&0C 00001100 9C48 D0 15 BNE &9C5F .. 9C4A 20 18 90 JSR &9018 .. \"CRC error" 9C4D 08 PHP . 9C4E C7 ??? . 9C4F 49 44 EOR #&44 01000100 9C51 20 43 52 JSR &5243 CR 9C54 43 ??? C 9C55 20 65 72 JSR &7265 er 9C58 72 ??? r 9C59 6F ??? o 9C5A 72 ??? r 9C5B 00 BRK . 9C5C 4C B8 9C JMP &9CB8 L.. 9C5F C9 18 CMP #&18 00011000 9C61 D0 13 BNE &9C76 .. 9C63 20 18 90 JSR &9018 .. \"Seek error" 9C66 08 PHP . 9C67 C7 ??? . 9C68 53 ??? S 9C69 65 65 ADC &65 ee 9C6B 6B ??? k 9C6C 20 65 72 JSR &7265 er 9C6F 72 ??? r 9C70 6F ??? o 9C71 72 ??? r 9C72 00 BRK . 9C73 4C B8 9C JMP &9CB8 L.. 9C76 C9 0E CMP #&0E 00001110 9C78 D0 17 BNE &9C91 .. 9C7A 20 18 90 JSR &9018 .. \"Data CRC error" 9C7D 08 PHP . 9C7E C7 ??? . 9C7F 44 ??? D 9C80 61 74 ADC (&74,X) at 9C82 61 20 ADC (&20,X) a 9C84 43 ??? C 9C85 52 ??? R 9C86 43 ??? C 9C87 20 65 72 JSR &7265 er 9C8A 72 ??? r 9C8B 6F ??? o 9C8C 72 ??? r 9C8D 00 BRK . 9C8E 4C B8 9C JMP &9CB8 L.. 9C91 C9 0A CMP #&0A 00001010 9C93 D0 12 BNE &9CA7 .. 9C95 20 18 90 JSR &9018 .. \"Lost data" 9C98 08 PHP . 9C99 C7 ??? . 9C9A 4C 6F 73 JMP &736F Los 9C9D 74 ??? t 9C9E 20 64 61 JSR &6164 da 9CA1 74 ??? t 9CA2 61 00 ADC (&00,X) a. 9CA4 4C B8 9C JMP &9CB8 L.. 9CA7 20 18 90 JSR &9018 .. \"Disc fault "+nn 9CAA 48 PHA H 9CAB C7 ??? . 9CAC 44 ??? D 9CAD 69 73 ADC #&73 01110011 9CAF 63 ??? c 9CB0 20 46 61 JSR &6146 Fa 9CB3 75 6C ADC &6C,X ul 9CB5 74 ??? t 9CB6 20 00 A5 JSR &A500 .. \LDA &C9 Print address 9CB9 C9 20 CMP #&20 00100000 \print " on drive "+n 9CBB 18 CLC . 9CBC 90 C0 BCC &9C7E .. 9CBE 20 6F 6E JSR &6E6F on 9CC1 20 64 72 JSR &7264 dr 9CC4 69 76 ADC #&76 01110110 9CC6 65 20 ADC &20 e 9CC8 00 BRK . 9CC9 AD 17 10 LDA &1017 ... 9CCC 20 18 90 JSR &9018 .. \print "."+track no. 9CCF 80 ??? . 9CD0 2E 00 20 ROL &2000 .. \copy command to read 9CD3 06 92 ASL &92 .. \special register 05 9CD5 EF ??? . \(sector number) to 9CD6 9C ??? . \OSWORD block 9CD7 15 10 ORA &10,X .. 9CD9 03 ??? . 9CDA 20 12 9B JSR &9B12 .. \call plain OSWORD &7F 9CDD AD 18 10 LDA &1018 ... \load sector number 9CE0 20 18 90 JSR &9018 .. \error msg "."+sector no 9CE3 82 ??? . 9CE4 2E 00 00 ROL &0000 ... \OSWORD &7F block 9CE7 0E FF FF ASL &FFFF ... \load catalogue 9CEA 03 ??? . 9CEB 93 ??? . 9CEC 00 BRK . 9CED 00 BRK . 9CEE 22 ??? " 9CEF 01 3D ORA (&3D,X) .= \read special reg [0..2] 9CF1 05 9D ORA &9D .. \Read DFS/disc catalogue 9CF3 FC ??? . \Store volume count 9CF4 0F ??? . \for current drive 9CF5 0A ASL A . \Store sector offset 9CF6 8D 18 10 STA &1018 ... 9CF9 98 TYA . \what's in Y? 9CFA 20 9A 9D JSR &9D9A .. \OSWORD &7F r/w, prepare block 9CFD 20 00 92 JSR &9200 .. \OSWORD &7F 9D00 A5 C9 LDA &C9 .. \store current drive 9D02 29 03 AND #&03 00000011 9D04 8D 10 10 STA &1010 ... 9D07 A9 7F LDA #&7F 01111111 \call OSWORD 9D09 A2 10 LDX #&10 00010000 9D0B A0 10 LDY #&10 00010000 9D0D 20 F1 FF JSR &FFF1 .. 9D10 AE 15 10 LDX &1015 ... 9D13 BD 17 10 LDA &1017,X ... \return Z=success 9D16 60 RTS ` 9D17 20 00 92 JSR &9200 .. \Softmount part 2. 9D1A 9D F0 0F STA &0FF0,X ... \set density of current drive 9D1D A8 TAY . 9D1E AD 85 10 LDA &1085 ... \get *OPT 7 volumes 9D21 30 08 BMI &9D2B 0. \if cheeseburger treat as SD 9D23 D0 24 BNE &9D49 .$ \not 0? Load disc cat, YAFI 9D25 A9 08 LDA #&08 00001000 \0=autodetect: default 8 vols. 9D27 C0 12 CPY #&12 00010010 \if disc is double density 9D29 F0 1E BEQ &9D49 .. \load disc catalogue 9D2B A9 00 LDA #&00 00000000 \SD, disc has no volumes 9D2D 20 F2 9C JSR &9CF2 .. \read DFS catalogue 9D30 D0 4A BNE &9D7C .J \if read failed then exit 9D32 AD 06 0F LDA &0F06 ... \get sector count in AY 9D35 29 07 AND #&07 00000111 9D37 A8 TAY . 9D38 AD 07 0F LDA &0F07 ... 9D3B 38 SEC 8 \Subtract one track's worth 9D3C FD F0 0F SBC &0FF0,X ... 9D3F B0 03 BCS &9D44 .. 9D41 88 DEY . 9D42 30 36 BMI &9D7A 06 \If sectors run out exit 9D44 FE F4 0F INC &0FF4,X ... \Calculate track count 9D47 D0 F2 BNE &9D3B .. \lucky it was zeroed first! 9D49 20 F2 9C JSR &9CF2 .. \read disc catalogue 9D4C D0 2E BNE &9D7C .. \if read failed then exit 9D4E CC 03 0E CPY &0E03 ... \have we got density right? 9D51 D0 2A BNE &9D7D .* \if not complain bad layout 9D53 AD 04 0E LDA &0E04 ... \get track count from disc 9D56 9D F4 0F STA &0FF4,X ... \store it for current drive 9D59 A2 08 LDX #&08 00001000 \calculate number of tracks 9D5B A0 10 LDY #&10 00010000 \in each volume and store 9D5D 88 DEY . \in &1030,X 9D5E 88 DEY . \setup, then: decrement pointers 9D5F CA DEX . 9D60 30 18 BMI &9D7A 0. \when done exit 9D62 48 PHA H \save ceiling track number 9D63 B9 08 0E LDA &0E08,Y ... \get start track no. 9D66 9D 30 10 STA &1030,X .0. \store in &1030,X in case it's 0 9D69 C9 01 CMP #&01 00000001 \set C=1 if start track >0 9D6B 68 PLA h \restore ceiling track number 9D6C 90 EF BCC &9D5D .. \if volume absent then loop 9D6E F9 08 0E SBC &0E08,Y ... \else ceiling - start track 9D71 9D 30 10 STA &1030,X .0. \=volume size. store in 1030,X 9D74 B9 08 0E LDA &0E08,Y ... \get new ceiling and loop. 9D77 4C 5D 9D JMP &9D5D L]. 9D7A A9 00 LDA #&00 00000000 \0=success 9D7C 60 RTS ` 9D7D 20 18 90 JSR &9018 .. \Give error 9D80 0A ASL A . \"Bad multi-volume layout" 9D81 D0 42 BNE &9DC5 .B 9D83 61 64 ADC (&64,X) ad 9D85 20 6D 75 JSR &756D mu 9D88 6C 74 69 JMP (&6974) lti 9D8B 2D 76 6F AND &6F76 -vo 9D8E 6C 75 6D JMP (&6D75) lum 9D91 65 20 ADC &20 e 9D93 6C 61 79 JMP (&7961) lay 9D96 6F ??? o 9D97 75 74 ADC &74,X ut 9D99 00 BRK . 9D9A 48 PHA H \Prepare OSWORD &7F block 9D9B A9 03 LDA #&03 00000011 \for a read or write 9D9D 8D 15 10 STA &1015 ... \Three parameters 9DA0 AD 19 10 LDA &1019 ... \256 byte sectors 9DA3 09 20 ORA #&20 00100000 9DA5 8D 19 10 STA &1019 ... 9DA8 68 PLA h 9DA9 60 RTS ` 9DAA A6 C9 LDX &C9 .. \calculate sector offset 9DAC BD FC 0F LDA &0FFC,X ... \for volume catalogue 9DAF F0 07 BEQ &9DB8 .. \if disc has volumes 9DB1 A6 C8 LDX &C8 .. \get immediate volume 9DB3 CA DEX . \convert to binary 9DB4 8A TXA . 9DB5 29 0F AND #&0F 00001111 9DB7 0A ASL A . \and multiply by 2 9DB8 AA TAX . \store it in Osword block 9DB9 8E 18 10 STX &1018 ... \return in A and X 9DBC 60 RTS ` \Convert logical block address (LBA) to cylinder/sector address. \On entry XY contains an absolute logical block address and ?&C9 \contains the drive number. On exit ?&1017 contains the corresponding \cylinder (track) number, ?&1018 contains the sector number (zero based) \and ?&1019 contains the number of sectors until the end of the track \(i.e. ?&1018 + ?&1019 = sectors per track). All taking into account \the geometry of the drive identified by ?&C9. 9DBD 20 00 92 JSR &9200 .. \Convert LBA to cylinder/sector 9DC0 A9 FF LDA #&FF 11111111 \preset track number = -1 9DC2 8D 17 10 STA &1017 ... 9DC5 8A TXA . \LBA low byte to A 9DC6 A6 C9 LDX &C9 .. \X = drive number 9DC8 EE 17 10 INC &1017 ... \increment track number 9DCB 8D 18 10 STA &1018 ... \save LBA low byte as abs sector 9DCE 38 SEC 8 \subtract spt of drive from it 9DCF FD F0 0F SBC &0FF0,X ... 9DD2 B0 F4 BCS &9DC8 .. \if no borrow-in then loop 9DD4 88 DEY . \else borrow from LBA high byte 9DD5 10 F1 BPL &9DC8 .. \if LBA - spt >=0 then loop 9DD7 49 FF EOR #&FF 11111111 \else invert result 9DD9 AA TAX . \add 1 to make 2's complement 9DDA E8 INX . \(positive difference) in X 9DDB 8E 19 10 STX &1019 ... \=distance to end of track. exit 9DDE 60 RTS ` \Tube hosting \For disassemblies of the BRK handler and Tube host code, \please read J.G.Harston's extellent article: \http://mdfs.net/Software/Tube/BBC/Host.lst A000 4C 12 A0 JMP &A012 L.. \Initialise Tube A003 4C 53 A0 JMP &A053 LS. \Post-initialise tube A006 4C 6D A0 JMP &A06D Lm. \Call Tube entry point A009 4C 87 A0 JMP &A087 L.. \Transfer byte to/from Tube A00C 4C 9B A0 JMP &A09B L.. \Close Tube data channel A00F 4C A8 A0 JMP &A0A8 L.. \Call code in Tube processor A012 20 00 92 JSR &9200 .. \Initialise Tube A015 A9 8E LDA #&8E 10001110 \set Tube status (NAUG p.329) A017 8D E0 FE STA &FEE0 ... \enable NMI on R3, IRQ on R1,R4 A01A 20 06 92 JSR &9206 .. \copy BRK handler to &0016..56 A01D F1 A0 SBC (&A0),Y .. A01F 16 00 ASL &00,X .. A021 41 A9 EOR (&A9,X) A. \install BRK handler on BRKV A023 16 8D ASL &8D,X .. A025 02 ??? . A026 02 ??? . A027 A9 00 LDA #&00 00000000 A029 8D 03 02 STA &0203 ... A02C 20 06 92 JSR &9206 .. \copy Tube host code A02F 32 ??? 2 \to &0400..06CD A030 A1 00 LDA (&00,X) .. \in three sections <= 255 bytes A032 04 ??? . A033 FF ??? . A034 20 06 92 JSR &9206 .. A037 31 A2 AND (&A2),Y 1. A039 FF ??? . A03A 04 ??? . A03B FF ??? . A03C 20 06 92 JSR &9206 .. A03F 30 A3 BMI &9FE4 0. A041 FE 05 D0 INC &D005,X ... A044 A9 AD LDA #&AD 10101101 \install event routine at &06AD A046 8D 20 02 STA &0220 . . \on EVNTV A049 A9 06 LDA #&06 00000110 A04B 8D 21 02 STA &0221 .!. A04E 20 21 04 JSR &0421 !. \clear Tube status and owner A051 38 SEC 8 \and exit C=1. A052 60 RTS ` A053 20 00 92 JSR &9200 .. \Post-initialise Tube A056 A2 06 LDX #&06 00000110 \do *FX 14,6 A058 A9 14 LDA #&14 00010100 \to explode character set fully A05A 20 F4 FF JSR &FFF4 .. A05D AD E0 FE LDA &FEE0 ... \print Tube coprocessor banner: A060 10 FB BPL &A05D .. \poll until character in FIFO 0 A062 AD E1 FE LDA &FEE1 ... \then read data register 0 A065 F0 EA BEQ &A051 .. \if =NUL then exit C=1 A067 20 EE FF JSR &FFEE .. \else print the character & loop A06A 4C 5D A0 JMP &A05D L]. A06D 20 00 92 JSR &9200 .. \Call Tube entry point A070 20 76 A0 JSR &A076 v. \set flags and prepare A073 4C 06 04 JMP &0406 L.. \and jump to Tube entry point. A076 20 00 92 JSR &9200 .. \A=0 open channel 3 for reading A079 38 SEC 8 \A=1 open channel 3 for writing A07A 6A ROR A j \A=4 call code in Tube proc(*GO) A07B 6A ROR A j \set Tube flag A07C 8D 3A 10 STA &103A .:. \b6=1 (Tube), b7=write to Tube A07F A9 C1 LDA #&C1 11000001 \poll Tube entry point w/A=&C1 A081 20 06 04 JSR &0406 .. \to claim Tube for DFS (%000001) A084 90 F9 BCC &A07F .. \until C=1 returned, then exit. A086 60 RTS ` A087 20 00 92 JSR &9200 .. \Transfer byte to/from Tube A08A 2C 3A 10 BIT &103A ,:. \103A: b6=Tube, b7=write to Tube A08D 30 08 BMI &A097 0. \if read from Tube A08F AD E5 FE LDA &FEE5 ... \then read Tube FIFO 3 A092 BA TSX . \have it returned in A on exit A093 9D 05 01 STA &0105,X ... A096 60 RTS ` A097 8D E5 FE STA &FEE5 ... \else write Tube FIFO 3 & exit. A09A 60 RTS ` A09B 20 00 92 JSR &9200 .. \Close Tube data channel A09E A9 00 LDA #&00 00000000 \clear Tube channel flag A0A0 8D 3A 10 STA &103A .:. \set A=&81,DFS is releasing Tube A0A3 A9 81 LDA #&81 10000001 \and jump to Tube entry point. A0A5 4C 06 04 JMP &0406 L.. A0A8 A9 04 LDA #&04 00000100 \Call code in Tube processor A0AA 4C 06 04 JMP &0406 L.. A0F1 A9 FF LDA #&FF 11111111 \Tube BRK handler A0F3 20 9E 06 JSR &069E .. \copied to &0016 A0F6 AD E3 FE LDA &FEE3 ... A0F9 A9 00 LDA #&00 00000000 A0FB 20 95 06 JSR &0695 .. A0FE A8 TAY . A0FF B1 FD LDA (&FD),Y .. A101 20 95 06 JSR &0695 .. A104 C8 INY . A105 B1 FD LDA (&FD),Y .. A107 20 95 06 JSR &0695 .. A10A AA TAX . A10B D0 F7 BNE &A104 .. A10D A2 FF LDX #&FF 11111111 A10F 9A TXS . A110 58 CLI X A111 2C E0 FE BIT &FEE0 ,.. A114 10 06 BPL &A11C .. A116 AD E1 FE LDA &FEE1 ... A119 20 EE FF JSR &FFEE .. A11C 2C E2 FE BIT &FEE2 ,.. A11F 10 F0 BPL &A111 .. A121 2C E0 FE BIT &FEE0 ,.. A124 30 F0 BMI &A116 0. A126 AE E3 FE LDX &FEE3 ... A129 86 51 STX &51 .Q A12B 6C 00 05 JMP (&0500) l.. A12E 00 BRK . A12F 80 ??? . A130 00 BRK . A131 00 BRK . A132 4C 84 04 JMP &0484 L.. \Tube host code A135 4C A7 06 JMP &06A7 L.. \copied to &0400 A138 C9 80 CMP #&80 10000000 A13A 90 2B BCC &A167 .+ A13C C9 C0 CMP #&C0 11000000 A13E B0 1A BCS &A15A .. A140 09 40 ORA #&40 01000000 A142 C5 15 CMP &15 .. A144 D0 20 BNE &A166 . A146 08 PHP . A147 78 SEI x A148 A9 05 LDA #&05 00000101 A14A 20 9E 06 JSR &069E .. A14D A5 15 LDA &15 .. A14F 20 9E 06 JSR &069E .. A152 28 PLP ( A153 A9 80 LDA #&80 10000000 A155 85 15 STA &15 .. A157 85 14 STA &14 .. A159 60 RTS ` A15A 06 14 ASL &14 .. A15C B0 06 BCS &A164 .. A15E C5 15 CMP &15 .. A160 F0 04 BEQ &A166 .. A162 18 CLC . A163 60 RTS ` A164 85 15 STA &15 .. A166 60 RTS ` A167 08 PHP . A168 78 SEI x A169 84 13 STY &13 .. A16B 86 12 STX &12 .. A16D 20 9E 06 JSR &069E .. A170 AA TAX . A171 A0 03 LDY #&03 00000011 A173 A5 15 LDA &15 .. A175 20 9E 06 JSR &069E .. A178 B1 12 LDA (&12),Y .. A17A 20 9E 06 JSR &069E .. A17D 88 DEY . A17E 10 F8 BPL &A178 .. A180 A0 18 LDY #&18 00011000 A182 8C E0 FE STY &FEE0 ... A185 BD 18 05 LDA &0518,X ... A188 8D E0 FE STA &FEE0 ... A18B 4A LSR A J A18C 4A LSR A J A18D 90 06 BCC &A195 .. A18F 2C E5 FE BIT &FEE5 ,.. A192 2C E5 FE BIT &FEE5 ,.. A195 20 9E 06 JSR &069E .. A198 2C E6 FE BIT &FEE6 ,.. A19B 50 FB BVC &A198 P. A19D B0 0D BCS &A1AC .. A19F E0 04 CPX #&04 00000100 A1A1 D0 11 BNE &A1B4 .. A1A3 20 14 04 JSR &0414 .. A1A6 20 95 06 JSR &0695 .. A1A9 4C 32 00 JMP &0032 L2. A1AC 4A LSR A J A1AD 90 05 BCC &A1B4 .. A1AF A0 88 LDY #&88 10001000 A1B1 8C E0 FE STY &FEE0 ... A1B4 28 PLP ( A1B5 60 RTS ` A1B6 58 CLI X A1B7 B0 11 BCS &A1CA .. A1B9 D0 03 BNE &A1BE .. A1BB 4C 9C 05 JMP &059C L.. A1BE A2 00 LDX #&00 00000000 A1C0 A0 FF LDY #&FF 11111111 A1C2 A9 FD LDA #&FD 11111101 A1C4 20 F4 FF JSR &FFF4 .. A1C7 8A TXA . A1C8 F0 D9 BEQ &A1A3 .. A1CA A9 FF LDA #&FF 11111111 A1CC 20 06 04 JSR &0406 .. A1CF 90 F9 BCC &A1CA .. A1D1 20 D2 04 JSR &04D2 .. A1D4 A9 07 LDA #&07 00000111 A1D6 20 CB 04 JSR &04CB .. A1D9 A0 00 LDY #&00 00000000 A1DB 84 00 STY &00 .. A1DD B1 00 LDA (&00),Y .. A1DF 8D E5 FE STA &FEE5 ... A1E2 EA NOP . A1E3 EA NOP . A1E4 EA NOP . A1E5 C8 INY . A1E6 D0 F5 BNE &A1DD .. A1E8 E6 54 INC &54 .T A1EA D0 06 BNE &A1F2 .. A1EC E6 55 INC &55 .U A1EE D0 02 BNE &A1F2 .. A1F0 E6 56 INC &56 .V A1F2 E6 01 INC &01 .. A1F4 24 01 BIT &01 $. A1F6 50 DC BVC &A1D4 P. A1F8 20 D2 04 JSR &04D2 .. A1FB A9 04 LDA #&04 00000100 A1FD A0 00 LDY #&00 00000000 A1FF A2 53 LDX #&53 01010011 A201 4C 06 04 JMP &0406 L.. A204 A9 80 LDA #&80 10000000 A206 85 54 STA &54 .T A208 85 01 STA &01 .. A20A A9 20 LDA #&20 00100000 A20C 2D 06 80 AND &8006 -.. A20F A8 TAY . A210 84 53 STY &53 .S A212 F0 19 BEQ &A22D .. A214 AE 07 80 LDX &8007 ... A217 E8 INX . A218 BD 00 80 LDA &8000,X ... A21B D0 FA BNE &A217 .. A21D BD 01 80 LDA &8001,X ... A220 85 53 STA &53 .S A222 BD 02 80 LDA &8002,X ... A225 85 54 STA &54 .T A227 BC 03 80 LDY &8003,X ... A22A BD 04 80 LDA &8004,X ... A22D 85 56 STA &56 .V A22F 84 55 STY &55 .U A231 60 RTS ` A232 37 ??? 7 A233 05 96 ORA &96 .. A235 05 F2 ORA &F2 .. A237 05 07 ORA &07 .. A239 06 27 ASL &27 .' A23B 06 68 ASL &68 .h A23D 06 5E ASL &5E .^ A23F 05 2D ORA &2D .- A241 05 20 ORA &20 . A243 05 42 ORA &42 .B A245 05 A9 ORA &A9 .. A247 05 D1 ORA &D1 .. A249 05 86 ORA &86 .. A24B 88 DEY . A24C 96 98 STX &98,Y .. A24E 18 CLC . A24F 18 CLC . A250 82 ??? . A251 18 CLC . A252 20 C5 06 JSR &06C5 .. A255 A8 TAY . A256 20 C5 06 JSR &06C5 .. A259 20 D4 FF JSR &FFD4 .. A25C 4C 9C 05 JMP &059C L.. A25F 20 C5 06 JSR &06C5 .. A262 A8 TAY . A263 20 D7 FF JSR &FFD7 .. A266 4C 3A 05 JMP &053A L:. A269 20 E0 FF JSR &FFE0 .. A26C 6A ROR A j A26D 20 95 06 JSR &0695 .. A270 2A ROL A * A271 4C 9E 05 JMP &059E L.. A274 20 C5 06 JSR &06C5 .. A277 F0 0B BEQ &A284 .. A279 48 PHA H A27A 20 82 05 JSR &0582 .. A27D 68 PLA h A27E 20 CE FF JSR &FFCE .. A281 4C 9E 05 JMP &059E L.. A284 20 C5 06 JSR &06C5 .. A287 A8 TAY . A288 A9 00 LDA #&00 00000000 A28A 20 CE FF JSR &FFCE .. A28D 4C 9C 05 JMP &059C L.. A290 20 C5 06 JSR &06C5 .. A293 A8 TAY . A294 A2 04 LDX #&04 00000100 A296 20 C5 06 JSR &06C5 .. A299 95 FF STA &FF,X .. A29B CA DEX . A29C D0 F8 BNE &A296 .. A29E 20 C5 06 JSR &06C5 .. A2A1 20 DA FF JSR &FFDA .. A2A4 20 95 06 JSR &0695 .. A2A7 A2 03 LDX #&03 00000011 A2A9 B5 00 LDA &00,X .. A2AB 20 95 06 JSR &0695 .. A2AE CA DEX . A2AF 10 F8 BPL &A2A9 .. A2B1 4C 36 00 JMP &0036 L6. A2B4 A2 00 LDX #&00 00000000 A2B6 A0 00 LDY #&00 00000000 A2B8 20 C5 06 JSR &06C5 .. A2BB 99 00 07 STA &0700,Y ... A2BE C8 INY . A2BF F0 04 BEQ &A2C5 .. A2C1 C9 0D CMP #&0D 00001101 A2C3 D0 F3 BNE &A2B8 .. A2C5 A0 07 LDY #&07 00000111 A2C7 60 RTS ` A2C8 20 82 05 JSR &0582 .. A2CB 20 F7 FF JSR &FFF7 .. A2CE A9 7F LDA #&7F 01111111 A2D0 2C E2 FE BIT &FEE2 ,.. A2D3 50 FB BVC &A2D0 P. A2D5 8D E3 FE STA &FEE3 ... A2D8 4C 36 00 JMP &0036 L6. A2DB A2 10 LDX #&10 00010000 A2DD 20 C5 06 JSR &06C5 .. A2E0 95 01 STA &01,X .. A2E2 CA DEX . A2E3 D0 F8 BNE &A2DD .. A2E5 20 82 05 JSR &0582 .. A2E8 86 00 STX &00 .. A2EA 84 01 STY &01 .. A2EC A0 00 LDY #&00 00000000 A2EE 20 C5 06 JSR &06C5 .. A2F1 20 DD FF JSR &FFDD .. A2F4 20 95 06 JSR &0695 .. A2F7 A2 10 LDX #&10 00010000 A2F9 B5 01 LDA &01,X .. A2FB 20 95 06 JSR &0695 .. A2FE CA DEX . A2FF D0 F8 BNE &A2F9 .. A301 F0 D5 BEQ &A2D8 .. A303 A2 0D LDX #&0D 00001101 A305 20 C5 06 JSR &06C5 .. A308 95 FF STA &FF,X .. A30A CA DEX . A30B D0 F8 BNE &A305 .. A30D 20 C5 06 JSR &06C5 .. A310 A0 00 LDY #&00 00000000 A312 20 D1 FF JSR &FFD1 .. A315 48 PHA H A316 A2 0C LDX #&0C 00001100 A318 B5 00 LDA &00,X .. A31A 20 95 06 JSR &0695 .. A31D CA DEX . A31E 10 F8 BPL &A318 .. A320 68 PLA h A321 4C 3A 05 JMP &053A L:. A324 20 C5 06 JSR &06C5 .. A327 AA TAX . A328 20 C5 06 JSR &06C5 .. A32B 20 F4 FF JSR &FFF4 .. A32E 2C E2 FE BIT &FEE2 ,.. A331 50 FB BVC &A32E P. A333 8E E3 FE STX &FEE3 ... A336 4C 36 00 JMP &0036 L6. A339 20 C5 06 JSR &06C5 .. A33C AA TAX . A33D 20 C5 06 JSR &06C5 .. A340 A8 TAY . A341 20 C5 06 JSR &06C5 .. A344 20 F4 FF JSR &FFF4 .. A347 49 9D EOR #&9D 10011101 A349 F0 EB BEQ &A336 .. A34B 6A ROR A j A34C 20 95 06 JSR &0695 .. A34F 2C E2 FE BIT &FEE2 ,.. A352 50 FB BVC &A34F P. A354 8C E3 FE STY &FEE3 ... A357 70 D5 BVS &A32E p. A359 20 C5 06 JSR &06C5 .. A35C A8 TAY . A35D 2C E2 FE BIT &FEE2 ,.. A360 10 FB BPL &A35D .. A362 AE E3 FE LDX &FEE3 ... A365 CA DEX . A366 30 0F BMI &A377 0. A368 2C E2 FE BIT &FEE2 ,.. A36B 10 FB BPL &A368 .. A36D AD E3 FE LDA &FEE3 ... A370 9D 28 01 STA &0128,X .(. A373 CA DEX . A374 10 F2 BPL &A368 .. A376 98 TYA . A377 A2 28 LDX #&28 00101000 A379 A0 01 LDY #&01 00000001 A37B 20 F1 FF JSR &FFF1 .. A37E 2C E2 FE BIT &FEE2 ,.. A381 10 FB BPL &A37E .. A383 AE E3 FE LDX &FEE3 ... A386 CA DEX . A387 30 0E BMI &A397 0. A389 BC 28 01 LDY &0128,X .(. A38C 2C E2 FE BIT &FEE2 ,.. A38F 50 FB BVC &A38C P. A391 8C E3 FE STY &FEE3 ... A394 CA DEX . A395 10 F2 BPL &A389 .. A397 4C 36 00 JMP &0036 L6. A39A A2 04 LDX #&04 00000100 A39C 20 C5 06 JSR &06C5 .. A39F 95 00 STA &00,X .. A3A1 CA DEX . A3A2 10 F8 BPL &A39C .. A3A4 E8 INX . A3A5 A0 00 LDY #&00 00000000 A3A7 8A TXA . A3A8 20 F1 FF JSR &FFF1 .. A3AB 90 05 BCC &A3B2 .. A3AD A9 FF LDA #&FF 11111111 A3AF 4C 9E 05 JMP &059E L.. A3B2 A2 00 LDX #&00 00000000 A3B4 A9 7F LDA #&7F 01111111 A3B6 20 95 06 JSR &0695 .. A3B9 BD 00 07 LDA &0700,X ... A3BC 20 95 06 JSR &0695 .. A3BF E8 INX . A3C0 C9 0D CMP #&0D 00001101 A3C2 D0 F5 BNE &A3B9 .. A3C4 4C 36 00 JMP &0036 L6. A3C7 2C E2 FE BIT &FEE2 ,.. A3CA 50 FB BVC &A3C7 P. A3CC 8D E3 FE STA &FEE3 ... A3CF 60 RTS ` A3D0 2C E6 FE BIT &FEE6 ,.. A3D3 50 FB BVC &A3D0 P. A3D5 8D E7 FE STA &FEE7 ... A3D8 60 RTS ` A3D9 A5 FF LDA &FF .. A3DB 38 SEC 8 A3DC 6A ROR A j A3DD 30 0F BMI &A3EE 0. A3DF 48 PHA H \Tube event handler A3E0 A9 00 LDA #&00 00000000 \copied to &06AD A3E2 20 BC 06 JSR &06BC .. A3E5 98 TYA . A3E6 20 BC 06 JSR &06BC .. A3E9 8A TXA . A3EA 20 BC 06 JSR &06BC .. A3ED 68 PLA h A3EE 2C E0 FE BIT &FEE0 ,.. A3F1 50 FB BVC &A3EE P. A3F3 8D E1 FE STA &FEE1 ... A3F6 60 RTS ` A3F7 2C E2 FE BIT &FEE2 ,.. A3FA 10 FB BPL &A3F7 .. A3FC AD E3 FE LDA &FEE3 ... A3FF 60 RTS ` \EDOS console output A400 4C 1F A4 JMP &A41F L.. \Print filename A403 4C 0C A4 JMP &A40C L.. \Print directory and filename A406 4C 3D A4 JMP &A43D L=. \Print *INFO line A409 4C 6D A4 JMP &A46D Lm. \Print decimal word A40C 20 00 92 JSR &9200 .. \Print directory and filename A40F AD 47 10 LDA &1047 .G. A412 29 7F AND #&7F 01111111 \remove Locked bit A414 20 00 90 JSR &9000 .. \print directory letter A417 A9 2E LDA #&2E 00101110 \print "." A419 20 00 90 JSR &9000 .. \fall through: A41C 4C 22 A4 JMP &A422 L". A41F 20 00 92 JSR &9200 .. \Print filename A422 A0 00 LDY #&00 00000000 \set offset = 0 A424 B9 40 10 LDA &1040,Y .@. \get character from cat wksp A427 20 00 90 JSR &9000 .. \print the character A42A C8 INY . \increment offset A42B C0 07 CPY #&07 00000111 \reached end of name proper? A42D D0 F5 BNE &A424 .. \if not then loop. A42F AD 47 10 LDA &1047 .G. \get directory and attribute A432 10 08 BPL &A43C .. \if Locked A434 20 18 90 JSR &9018 .. \then print " L". A437 00 BRK . A438 20 20 4C JSR &4C20 L A43B 00 BRK . A43C 60 RTS ` \exit A43D 20 00 92 JSR &9200 .. \Print *INFO line A440 20 0F A4 JSR &A40F .. \print directory and filename A443 A9 0E LDA #&0E 00001110 \tab to column 14 A445 20 06 90 JSR &9006 .. A448 A2 00 LDX #&00 00000000 \catalogue field offset = 0 A44A 20 64 A4 JSR &A464 d. \print load address A44D 20 64 A4 JSR &A464 d. \print execution address A450 20 64 A4 JSR &A464 d. \print file length A453 CA DEX . \pretend startsec is 3 bytes: A454 18 CLC . \Print top word w/o leading 0s A455 BD 4A 10 LDA &104A,X .J. \load top byte A458 20 5E A4 JSR &A45E ^. \print hex byte, allow zeroes A45B BD 48 10 LDA &1048,X .H. \load middle byte A45E 20 0F 90 JSR &900F .. \print hex byte A461 38 SEC 8 \allow zeroes A462 E8 INX . \increment offset A463 60 RTS ` \exit. A464 20 54 A4 JSR &A454 T. \Print 3byte field from cat A467 BD 46 10 LDA &1046,X .F. \print top word w/o leading 0s A46A 4C 5E A4 JMP &A45E L^. \0s allowed, print bottom byte. A46D 20 00 92 JSR &9200 .. \Print decimal word A470 18 CLC . \similar algorithm to A471 A0 04 LDY #&04 00000100 \print-decimal-byte (&9012) A473 08 PHP . A474 A2 00 LDX #&00 00000000 A476 AD 61 10 LDA &1061 .a. A479 D9 B2 A4 CMP &A4B2,Y ... A47C D0 06 BNE &A484 .. A47E AD 60 10 LDA &1060 .`. A481 D9 AE A4 CMP &A4AE,Y ... A484 90 16 BCC &A49C .. A486 E8 INX . A487 AD 60 10 LDA &1060 .`. A48A F9 AE A4 SBC &A4AE,Y ... A48D 8D 60 10 STA &1060 .`. A490 AD 61 10 LDA &1061 .a. A493 F9 B2 A4 SBC &A4B2,Y ... A496 8D 61 10 STA &1061 .a. A499 4C 76 A4 JMP &A476 Lv. A49C 28 PLP ( A49D 8A TXA . A49E D0 02 BNE &A4A2 .. A4A0 90 03 BCC &A4A5 .. A4A2 20 0C 90 JSR &900C .. A4A5 88 DEY . A4A6 D0 CB BNE &A473 .. A4A8 AD 60 10 LDA &1060 .`. A4AB 38 SEC 8 A4AC 4C 0C 90 JMP &900C L.. A4AF 0A ASL A . \powers of ten, low bytes [0..3] A4B0 64 ??? d \(placevalues) A4B1 E8 INX . A4B2 10 00 BPL &A4B4 .. \high bytes [0..3] A4B4 00 BRK . A4B5 03 ??? . A4B6 27 ??? ' \File selection A500 4C 2A A5 JMP &A52A L*. \Select first file in catalogue A503 4C 24 A5 JMP &A524 L$. \Select and ensure first file A506 4C 31 A5 JMP &A531 L1. \Select next file in catalogue A509 4C 47 A5 JMP &A547 LG. \Find file in catalogue A50C 4C 41 A5 JMP &A541 LA. \Check file exists A50F 4C 51 A5 JMP &A551 LQ. \Find next match of afsp A512 4C 70 A5 JMP &A570 Lp. \Find unlocked file in cat A515 4C 57 A5 JMP &A557 LW. \Check unlocked file exists A518 4C 7A A5 JMP &A57A Lz. \Find next unlocked match A51B 4C 80 A5 JMP &A580 L.. \Compare filenames A51E 4C 99 A5 JMP &A599 L.. \Compare directory letters A521 4C CE A5 JMP &A5CE L.. \Check file not locked A524 20 00 A5 JSR &A500 .. \Select and ensure first file A527 4C 5A A5 JMP &A55A LZ. \give error if catalogue empty. A52A 48 PHA H \Select first file in catalogue A52B AD 05 0F LDA &0F05 ... \get file count from catalogue A52E 4C 34 A5 JMP &A534 L4. \set ptr = count - 8 and exit. A531 48 PHA H \Select next file in catalogue A532 A5 CC LDA &CC .. \get catalogue pointer A534 38 SEC 8 \Subtract 8 to pt to next entry A535 E9 08 SBC #&08 00001000 A537 90 05 BCC &A53E .. \if borrow then exit C=1 A539 85 CC STA &CC .. \else store catalogue pointer A53B 68 PLA h \restore A and exit C=0 A53C 18 CLC . A53D 60 RTS ` A53E 68 PLA h \restore A and exit C=1 A53F 38 SEC 8 A540 60 RTS ` A541 20 09 A5 JSR &A509 .. \Check file exists A544 4C 5A A5 JMP &A55A LZ. \find file, else "Not found". A547 20 00 A5 JSR &A500 .. \Find file in catalogue A54A B0 F3 BCS &A53F .. A54C 20 1B A5 JSR &A51B .. A54F F0 EB BEQ &A53C .. A551 20 06 A5 JSR &A506 .. A554 90 F6 BCC &A54C .. A556 60 RTS ` A557 20 12 A5 JSR &A512 .. \Check unlocked file exists A55A 90 E0 BCC &A53C .. \If C=1 A55C 20 18 90 JSR &9018 .. \then give "File not found". A55F 0A ASL A . A560 D6 46 DEC &46,X .F A562 69 6C ADC #&6C 01101100 A564 65 20 ADC &20 e A566 6E 6F 74 ROR &746F not A569 20 66 6F JSR &6F66 fo A56C 75 6E ADC &6E,X un A56E 64 ??? d A56F 00 BRK . A570 20 09 A5 JSR &A509 .. \Find unlocked match of afsp A573 B0 CA BCS &A53F .. \find file, else exit C=1 A575 20 E4 A5 JSR &A5E4 .. \get attribute bit of file A578 10 C2 BPL &A53C .. \if unlocked exit with C=0 A57A 20 0F A5 JSR &A50F .. \Find next unlocked match A57D 90 F6 BCC &A575 .. \if found loop else exit C=1 A57F 60 RTS ` A580 20 00 92 JSR &9200 .. \Compare filenames A583 20 9C A5 JSR &A59C .. \compare directory letters A586 D0 10 BNE &A598 .. \if mismatch then exit Z=0 A588 A0 00 LDY #&00 00000000 \else clear Y index register A58A BD 08 0E LDA &0E08,X ... \get character of entry name A58D 20 AD A5 JSR &A5AD .. \compare to immediate filename A590 D0 06 BNE &A598 .. \if mismatch then exit Z=0 A592 E8 INX . \else increment copy of cat ptr A593 C8 INY . \and immediate filename offset A594 C0 07 CPY #&07 00000111 \have we compared 7 characters? A596 D0 F2 BNE &A58A .. \if so then exit else loop. A598 60 RTS ` A599 20 00 92 JSR &9200 .. \Compare directory letters A59C 20 E7 A5 JSR &A5E7 .. \get dir/lock of current entry A59F 29 7F AND #&7F 01111111 \mask off attribute bit A5A1 20 C3 A5 JSR &A5C3 .. \convert to uppercase A5A4 85 B8 STA &B8 .. \store in temp A5A6 A5 C7 LDA &C7 .. \get immediate directory A5A8 29 7F AND #&7F 01111111 \mask off attribute bit A5AA 4C B5 A5 JMP &A5B5 L.. \and jump forward A5AD 20 C3 A5 JSR &A5C3 .. \Compare character of filename A5B0 85 B8 STA &B8 .. \convert to uppercase, store. A5B2 B9 C0 00 LDA &00C0,Y ... \get char of immediate filename A5B5 C9 2A CMP #&2A 00101010 \is search character '*'? A5B7 F0 09 BEQ &A5C2 .. \then match any character A5B9 C9 23 CMP #&23 00100011 \is search character '#'? A5BB F0 05 BEQ &A5C2 .. \then match any character A5BD 20 C3 A5 JSR &A5C3 .. \else convert to uppercase A5C0 C5 B8 CMP &B8 .. \and compare w/temp (Z=match). A5C2 60 RTS ` A5C3 C9 61 CMP #&61 01100001 \Convert to uppercase A5C5 90 06 BCC &A5CD .. \if less than "a" then exit A5C7 C9 7B CMP #&7B 01111011 \else compare with "{" A5C9 B0 02 BCS &A5CD .. \if greater than "z" then exit A5CB 29 DF AND #&DF 11011111 \else map ASCII a-z to A-Z. A5CD 60 RTS ` A5CE 20 E4 A5 JSR &A5E4 .. \Check file not locked A5D1 10 FA BPL &A5CD .. \Reads catalogue entry A5D3 20 18 90 JSR &9018 .. \pointed to by &CC A5D6 0A ASL A . A5D7 C3 ??? . A5D8 46 69 LSR &69 Fi A5DA 6C 65 20 JMP (&2065) le A5DD 6C 6F 63 JMP (&636F) loc A5E0 6B ??? k A5E1 65 64 ADC &64 ed A5E3 00 BRK . A5E4 20 00 92 JSR &9200 .. \Get dir/lock of current entry A5E7 A6 CC LDX &CC .. \at catalogue pointer. A5E9 BD 0F 0E LDA &0E0F,X ... A5EC 60 RTS ` \Catalogue operations A600 4C 21 A6 JMP &A621 L!. \Delete catalogue entry A603 4C 44 A6 JMP &A644 LD. \Unpack fields from catalogue A606 4C 93 A7 JMP &A793 L.. \Pack fields into catalogue A609 4C 22 A7 JMP &A722 L". \Create catalogue entry A60C 4C 07 A8 JMP &A807 L.. \Find a free space in volume A60F 4C 4C A8 JMP &A84C LL. \Calculate absolute end of file A612 4C 5E A6 JMP &A65E L^. \Unpack cat fields from wkspace A615 4C 62 A8 JMP &A862 Lb. \Determine if room to extend A618 4C E9 A6 JMP &A6E9 L.. \Check perms/create file A61B 4C 25 A8 JMP &A825 L%. \Get free space on volume A61E 4C 7B A8 JMP &A87B L{. \Get ceiling over cat entry A621 20 00 92 JSR &9200 .. \Delete catalogue entry A624 AD 05 0F LDA &0F05 ... \pointed to by &CC A627 38 SEC 8 \by moving valid entries A628 E9 08 SBC #&08 00001000 \over it A62A 8D 05 0F STA &0F05 ... A62D A6 CC LDX &CC .. A62F EC 05 0F CPX &0F05 ... A632 B0 0F BCS &A643 .. A634 BD 10 0E LDA &0E10,X ... A637 9D 08 0E STA &0E08,X ... A63A BD 10 0F LDA &0F10,X ... A63D 9D 08 0F STA &0F08,X ... A640 E8 INX . A641 D0 EC BNE &A62F .. A643 60 RTS ` A644 20 00 92 JSR &9200 .. \Unpack fields from catalogue A647 A6 CC LDX &CC .. \copy catalogue entry to wksp A649 20 09 92 JSR &9209 .. A64C 08 PHP . A64D 0E 40 10 ASL &1040 .@. A650 08 PHP . A651 20 20 09 JSR &0920 . A654 92 ??? . A655 08 PHP . A656 0F ??? . A657 48 PHA H A658 10 08 BPL &A662 .. A65A 20 4C 61 JSR &614C La \fall through: A65D A6 20 LDX &20 . \Unpack cat fields from wkspace A65F 00 BRK . A660 92 ??? . A661 A2 07 LDX #&07 00000111 A663 A0 0A LDY #&0A 00001010 A665 AD 06 0F LDA &0F06 ... \Is volume >= 256 KB? A668 29 04 AND #&04 00000100 A66A D0 1F BNE &A68B .. A66C AD 4E 10 LDA &104E .N. \If not A66F 48 PHA H \copy start sector to &1051..52 A670 20 D6 A6 JSR &A6D6 .. A673 C8 INY . A674 68 PLA h A675 4A LSR A J \push 00eelldd A676 4A LSR A J A677 48 PHA H A678 4A LSR A J \push 0000eell A679 4A LSR A J A67A 48 PHA H A67B 20 D6 A6 JSR &A6D6 .. \copy length to &104E..50 A67E 68 PLA h A67F 4A LSR A J A680 4A LSR A J A681 20 D6 A6 JSR &A6D6 .. \copy exec to 104B..4D A684 68 PLA h A685 20 D6 A6 JSR &A6D6 .. \copy load to 1048..4A A688 4C A7 A6 JMP &A6A7 L.. \chip up and exit A68B AD 4E 10 LDA &104E .N. \else same as above A68E 48 PHA H \for volumes >=256 KB A68F 20 D8 A6 JSR &A6D8 .. A692 C8 INY . A693 68 PLA h A694 4A LSR A J A695 4A LSR A J A696 48 PHA H A697 4A LSR A J A698 4A LSR A J A699 48 PHA H A69A 20 D8 A6 JSR &A6D8 .. A69D 68 PLA h A69E 4A LSR A J A69F 4A LSR A J A6A0 20 D0 A6 JSR &A6D0 .. A6A3 68 PLA h A6A4 20 D0 A6 JSR &A6D0 .. A6A7 18 CLC . \Chip up catalogue fields A6A8 AD 51 10 LDA &1051 .Q. \add volume offset A6AB 6D 38 10 ADC &1038 m8. \to start sector to make A6AE 8D 51 10 STA &1051 .Q. \absolute offset A6B1 AD 52 10 LDA &1052 .R. \store in &1051..52 A6B4 6D 39 10 ADC &1039 m9. A6B7 8D 52 10 STA &1052 .R. A6BA AD 4E 10 LDA &104E .N. \store number of sectors used A6BD C9 01 CMP #&01 00000001 \in &1053..54 A6BF AD 4F 10 LDA &104F .O. A6C2 69 00 ADC #&00 00000000 A6C4 8D 53 10 STA &1053 .S. A6C7 AD 50 10 LDA &1050 .P. A6CA 69 00 ADC #&00 00000000 A6CC 8D 54 10 STA &1054 .T. A6CF 60 RTS ` A6D0 29 02 AND #&02 00000010 \Extend 17 bit to 18 bit A6D2 F0 02 BEQ &A6D6 .. \catalogue field A6D4 09 03 ORA #&03 00000011 A6D6 29 03 AND #&03 00000011 \Unpack 18 bit field A6D8 29 07 AND #&07 00000111 \Unpack 19 bit field A6DA 20 E4 A6 JSR &A6E4 .. A6DD 20 E0 A6 JSR &A6E0 .. A6E0 BD 48 10 LDA &1048,X .H. A6E3 CA DEX . A6E4 99 48 10 STA &1048,Y .H. A6E7 88 DEY . A6E8 60 RTS ` A6E9 20 00 9B JSR &9B00 .. \Check perms/create file A6EC 20 09 A5 JSR &A509 .. \A=desired mode (OSFIND) A6EF 90 0A BCC &A6FB .. \read catalogue, find file A6F1 C9 80 CMP #&80 10000000 \if not found, then: A6F3 F0 1A BEQ &A70F .. \if OPENOUT A6F5 C9 A0 CMP #&A0 10100000 \or if called from OSFILE A6F7 F0 16 BEQ &A70F .. \then create catalogue entry A6F9 38 SEC 8 \else OPENIN/UP not found, A6FA 60 RTS ` \exit C=1. A6FB C9 40 CMP #&40 01000000 \else file found. if OPENIN A6FD F0 03 BEQ &A702 .. \then don't check lock A6FF 20 21 A5 JSR &A521 !. \else check file not locked. A702 20 06 98 JSR &9806 .. \check file not open (mutex) A705 20 03 A6 JSR &A603 .. \unpack fields from catalogue A708 C9 A0 CMP #&A0 10100000 \if not called from OSFILE A70A D0 11 BNE &A71D .. \then monitor and exit C=0. A70C 20 00 A6 JSR &A600 .. \else delete catalogue entry A70F 20 06 92 JSR &9206 .. \copy immediate dir+filename A712 C0 00 CPY #&00 00000000 \to catalogue block 2 A714 58 CLI X A715 10 08 BPL &A71F .. A717 20 09 A6 JSR &A609 .. \create catalogue entry A71A 20 03 9B JSR &9B03 .. \write catalogue A71D 20 1B B7 JSR &B71B .. \call file access monitor A720 18 CLC . \and exit C=0. A721 60 RTS ` A722 20 00 92 JSR &9200 .. \Create catalogue entry A725 AD 05 0F LDA &0F05 ... \get number of files A728 C9 F8 CMP #&F8 11111000 \if =31 A72A 90 13 BCC &A73F .. \then give volume error A72C 20 21 98 JSR &9821 !. \"catalogue full" A72F BE 63 61 LDX &6163,Y .ca A732 74 ??? t A733 61 6C ADC (&6C,X) al A735 6F ??? o A736 67 ??? g A737 75 65 ADC &65,X ue A739 20 66 75 JSR &7566 fu A73C 6C 6C 00 JMP (&006C) ll. A73F 20 0A A8 JSR &A80A .. \else find a free space in vol A742 90 31 BCC &A775 .1 \if C=0 then success, do insert A744 20 1B A6 JSR &A61B .. \else get amount of free space A747 AD 60 10 LDA &1060 .`. \16 bit compare: A74A CD 6B 10 CMP &106B .k. \free space - desired allocation A74D D0 06 BNE &A755 .. A74F AD 61 10 LDA &1061 .a. A752 CD 6C 10 CMP &106C .l. A755 90 15 BCC &A76C .. \if <0 then disc full error A757 20 21 98 JSR &9821 !. \else "needs compacting" error. A75A C6 6E DEC &6E .n \as there is enough free space A75C 65 65 ADC &65 ee \but not in one block. A75E 64 ??? d A75F 73 ??? s A760 20 63 6F JSR &6F63 co A763 6D 70 61 ADC &6170 mpa A766 63 ??? c A767 74 ??? t A768 69 6E ADC #&6E 01101110 A76A 67 ??? g A76B 00 BRK . A76C 20 21 98 JSR &9821 !. \Display disc/vol "full" error. A76F C6 66 DEC &66 .f A771 75 6C ADC &6C,X ul A773 6C 00 AD JMP (&AD00) l.. \Do insert at slot &CC points to A776 05 0F ORA &0F .. \LDA &0F05 get file pointer A778 AA TAX . \copy to X (assert X<=&F0) A779 18 CLC . \add 8 to pointer A77A 69 08 ADC #&08 00001000 \(assert 0<=?&CC<=&F0) A77C 8D 05 0F STA &0F05 ... \and store back in catalogue. A77F E4 CC CPX &CC .. \if catalogue slot at ?&CC free A781 F0 13 BEQ &A796 .. \then pack it (assert X>=?&CC) A783 CA DEX . \else bubble entries A784 BD 08 0E LDA &0E08,X ... \into the next slot up A787 9D 10 0E STA &0E10,X ... \going from end to start A78A BD 08 0F LDA &0F08,X ... A78D 9D 10 0F STA &0F10,X ... A790 4C 7F A7 JMP &A77F L.. \and loop back to the test. A793 20 00 92 JSR &9200 .. \Pack fields into catalogue A796 A6 CC LDX &CC .. \as pointed to by &CC A798 20 09 92 JSR &9209 .. \copy name and directory A79B 40 RTI @ A79C 10 08 BPL &A7A6 .. A79E 0E 08 02 ASL &0208 ... A7A1 A0 00 LDY #&00 00000000 A7A3 20 D2 A7 JSR &A7D2 .. \copy low bytes load address A7A6 20 D2 A7 JSR &A7D2 .. \copy low bytes exec address A7A9 0A ASL A . \A = %00ee0000 or %00e00000 A7AA 0A ASL A . A7AB 0A ASL A . A7AC 0A ASL A . A7AD 05 B8 ORA &B8 .. \A = %00ee00dd or %00e000d0 A7AF 0A ASL A . \A = %ee00dd00 or %e000d000 A7B0 0A ASL A . A7B1 20 EC A7 JSR &A7EC .. \copy low bytes length A7B4 0A ASL A . \A = %00ll0000 or %0lll0000 A7B5 0A ASL A . A7B6 0A ASL A . A7B7 0A ASL A . A7B8 05 B8 ORA &B8 .. \A = %eelldd00 or %ellld000 A7BA 85 B8 STA &B8 .. \save A A7BC 38 SEC 8 A7BD AD 51 10 LDA &1051 .Q. \subtract absolute start sector A7C0 ED 38 10 SBC &1038 .8. \from start of volume A7C3 9D 09 0F STA &0F09,X ... \store relative start sector A7C6 AD 52 10 LDA &1052 .R. \calculate high bits A7C9 ED 39 10 SBC &1039 .9. \A = %000000ss or %00000sss A7CC 05 B8 ORA &B8 .. \A = %eellddss or %ellldsss A7CE 9D 08 0F STA &0F08,X ... \store packed byte A7D1 60 RTS ` A7D2 20 EC A7 JSR &A7EC .. \Save A in temp, copy 2 bytes A7D5 29 03 AND #&03 00000011 \of address, A7D7 48 PHA H \return high 2 bits of source A7D8 AD 06 0F LDA &0F06 ... \(if both set and disc >=256K, A7DB 29 04 AND #&04 00000100 \returns binary 2 A7DD D0 02 BNE &A7E1 .. \to accommodate 19 bit addrs) A7DF 68 PLA h A7E0 60 RTS ` A7E1 68 PLA h A7E2 C9 03 CMP #&03 00000011 A7E4 D0 03 BNE &A7E9 .. A7E6 A9 02 LDA #&02 00000010 A7E8 60 RTS ` A7E9 A9 00 LDA #&00 00000000 A7EB 60 RTS ` A7EC 85 B8 STA &B8 .. \Save A in temp, copy 2 bytes, A7EE 20 FA A7 JSR &A7FA .. \load third from fields, A7F1 20 FA A7 JSR &A7FA .. \return low 3 bits A7F4 20 02 A8 JSR &A802 .. A7F7 29 07 AND #&07 00000111 A7F9 60 RTS ` A7FA 20 02 A8 JSR &A802 .. \Copy byte from fields to high A7FD 9D 08 0F STA &0F08,X ... \catalogue, increment X and Y A800 E8 INX . A801 60 RTS ` A802 B9 48 10 LDA &1048,Y .H. \Get byte from fields, A805 C8 INY . \increment Y A806 60 RTS ` A807 20 00 92 JSR &9200 .. \Find a free space in volume A80A 20 95 A8 JSR &A895 .. \initialise for zeroth file A80D 20 06 92 JSR &9206 .. \copy catalogue block 2 A810 58 CLI X \to catalogue block 1 A811 10 40 BPL &A853 .@ \(block 2 contains prospective A813 10 18 BPL &A82D .. \file) A815 20 0F A6 JSR &A60F .. \calculate absolute end of file A818 20 68 A8 JSR &A868 h. \determine if room to extend A81B B0 06 BCS &A823 .. \if so exit C=0 A81D 20 B3 A8 JSR &A8B3 .. \else unpack next file in cat A820 90 EB BCC &A80D .. \if more files then loop A822 60 RTS ` \else exit C=1. A823 18 CLC . A824 60 RTS ` A825 20 00 92 JSR &9200 .. \Get free space on volume A828 A9 00 LDA #&00 00000000 \set accumulator = 0 A82A 8D 60 10 STA &1060 .`. A82D 8D 61 10 STA &1061 .a. A830 20 95 A8 JSR &A895 .. \initialise for zeroth file A833 20 68 A8 JSR &A868 h. \get free space *before* file A836 90 13 BCC &A84B .. \if overlap then exit A838 18 CLC . \else add AX to accumulator A839 6D 60 10 ADC &1060 m`. A83C 8D 60 10 STA &1060 .`. A83F 8A TXA . A840 6D 61 10 ADC &1061 ma. A843 8D 61 10 STA &1061 .a. A846 20 B3 A8 JSR &A8B3 .. \select next file in catalogue A849 90 E8 BCC &A833 .. \inc.imaginary end-of-vol file A84B 60 RTS ` \and loop until no more files. A84C 48 PHA H \Calculate absolute end of file A84D 18 CLC . \(last used sector +1) A84E AD 53 10 LDA &1053 .S. A851 6D 51 10 ADC &1051 mQ. A854 8D 69 10 STA &1069 .i. A857 AD 54 10 LDA &1054 .T. A85A 6D 52 10 ADC &1052 mR. A85D 8D 6A 10 STA &106A .j. A860 68 PLA h A861 60 RTS ` A862 20 00 92 JSR &9200 .. \Determine if room to extend A865 20 0F A6 JSR &A60F .. \calculate absolute last sec+1 A868 20 1E A6 JSR &A61E .. \get ceiling over file A86B 38 SEC 8 \subtract absolute end of file A86C ED 69 10 SBC &1069 .i. A86F 48 PHA H A870 8A TXA . A871 ED 6A 10 SBC &106A .j. A874 AA TAX . A875 68 PLA h A876 D0 02 BNE &A87A .. A878 E8 INX . \return in AX A879 CA DEX . \Z=no free sectors A87A 60 RTS ` A87B A6 CC LDX &CC .. \Get ceiling over cat entry A87D 18 CLC . \end of free space above A87E BD 07 0F LDA &0F07,X ... \catalogue entry &CC-> A881 6D 38 10 ADC &1038 m8. \(ie absolute start sector of A884 48 PHA H \next file, or if &CC=0, A885 AD 06 0F LDA &0F06 ... \absolute start sector of A888 29 04 AND #&04 00000100 \next volume /end of disc) A88A 09 03 ORA #&03 00000011 \Return in A (low byte) and X A88C 3D 06 0F AND &0F06,X =.. \(high byte) A88F 6D 39 10 ADC &1039 m9. A892 AA TAX . A893 68 PLA h A894 60 RTS ` A895 48 PHA H \Initialise for zeroth file A896 AD 38 10 LDA &1038 .8. \copy offset to start of volume A899 8D 69 10 STA &1069 .i. \to absolute end of file A89C AD 39 10 LDA &1039 .9. \representing end of imaginary A89F 8D 6A 10 STA &106A .j. \zeroth file A8A2 0D 38 10 ORA &1038 .8. \if offset = 0 A8A5 D0 05 BNE &A8AC .. A8A7 A9 02 LDA #&02 00000010 \then set offset = 2 A8A9 8D 69 10 STA &1069 .i. A8AC AD 05 0F LDA &0F05 ... \set catalogue pointer A8AF 85 CC STA &CC .. \to number of entries in cat. A8B1 68 PLA h A8B2 60 RTS ` A8B3 20 06 A5 JSR &A506 .. \select next file in catalogue A8B6 B0 06 BCS &A8BE .. \if no more files exit A8B8 20 03 A6 JSR &A603 .. \else unpack fields from cat A8BB 20 0F A6 JSR &A60F .. \calculate absolute end of file A8BE 60 RTS ` \exit \'Heavy' DFS commands A900 4C 09 A9 JMP &A909 L.. \*FORMAT A903 4C C9 AB JMP &ABC9 L.. \*CATGEN A906 4C 8E AB JMP &AB8E L.. \*VERIFY A909 A9 FF LDA #&FF 11111111 \*FORMAT A90B 8D 70 10 STA &1070 .p. \set &1070..75 = &FF A90E 20 06 92 JSR &9206 .. A911 70 10 BVS &A923 p. A913 71 10 ADC (&10),Y q. A915 05 20 ORA &20 . \set default drive A917 04 ??? . A918 AE 20 18 LDX &1820 . . \get optional drive spec A91B 93 ??? . A91C 90 03 BCC &A921 .. \if no more arguments A91E 4C 9C A9 JMP &A99C L.. \then proceed with format A921 C9 34 CMP #&34 00110100 \else test first nonspace char A923 D0 21 BNE &A946 .! \Is it "4"? if not try others A925 A9 28 LDA #&28 00101000 \else set no. tracks = 40 A927 8D 71 10 STA &1071 .q. A92A 20 88 A9 JSR &A988 .. \do GSREAD, syntax error if EOW A92D C9 30 CMP #&30 00110000 \is next character "0"? A92F D0 54 BNE &A985 .T \syntax error if not A931 20 C5 FF JSR &FFC5 .. \call GSREAD A934 B0 E3 BCS &A919 .. \if end of arg, scan for another A936 8D 72 10 STA &1072 .r. \else store char A939 C9 2D CMP #&2D 00101101 \is it "-"? A93B D0 48 BNE &A985 .H \syntax error if not A93D 20 88 A9 JSR &A988 .. \else GSREAD, syntax err if EOW A940 C9 38 CMP #&38 00111000 \is character "8"? A942 D0 41 BNE &A985 .A \syntax error if not A944 F0 09 BEQ &A94F .. \else ensure "0" follows. A946 C9 38 CMP #&38 00111000 \does argument begin "8"? A948 D0 0F BNE &A959 .. \if not try other characters A94A A9 50 LDA #&50 01010000 \else set no. tracks = 80 A94C 8D 71 10 STA &1071 .q. A94F 20 88 A9 JSR &A988 .. \do GSREAD, syntax error if EOW A952 C9 30 CMP #&30 00110000 \is character "0"? A954 D0 2F BNE &A985 ./ \syntax error if not A956 4C 7D A9 JMP &A97D L}. \else skip " ", scan next arg. A959 29 5F AND #&5F 01011111 \convert to uppercase A95B C9 53 CMP #&53 01010011 \is character "S" A95D D0 08 BNE &A967 .. \if not try "D" or "O" A95F A9 0A LDA #&0A 00001010 \else set density = single A961 8D 70 10 STA &1070 .p. A964 4C 7D A9 JMP &A97D L}. \skip space, scan next arg. A967 C9 44 CMP #&44 01000100 \is character "D"? A969 D0 08 BNE &A973 .. \if not try "O" A96B A9 12 LDA #&12 00010010 \else set density = double A96D 8D 70 10 STA &1070 .p. A970 4C 7D A9 JMP &A97D L}. \skip space, scan next arg. A973 C9 4F CMP #&4F 01001111 \is character "O"? A975 D0 0E BNE &A985 .. \syntax error if not A977 20 8E A9 JSR &A98E .. \else get outstep value A97A 8D 74 10 STA &1074 .t. \and save it A97D 20 C5 FF JSR &FFC5 .. \call GSREAD to skip space A980 90 03 BCC &A985 .. \syntax error if another char A982 4C 19 A9 JMP &A919 L.. \else scan next argument. A985 4C 09 81 JMP &8109 L.. \print *FORMAT syntax error. A988 20 C5 FF JSR &FFC5 .. \call GSREAD A98B B0 F8 BCS &A985 .. \syntax error if end of word A98D 60 RTS ` \else return. A98E 20 88 A9 JSR &A988 .. \do GSREAD, syntax error if EOW A991 C9 30 CMP #&30 00110000 \is character less than "0"? A993 90 F0 BCC &A985 .. \syntax error if so A995 C9 39 CMP #&39 00111001 \is character "9" or greater? A997 B0 EC BCS &A985 .. \syntax error if so A999 29 0F AND #&0F 00001111 \else return value 0..9. A99B 60 RTS ` A99C 20 09 90 JSR &9009 .. \print newline A99F 20 70 AE JSR &AE70 p. \print "Formatting " A9A2 20 93 AE JSR &AE93 .. \print "drive n" A9A5 AD 70 10 LDA &1070 .p. \if density given on cmd line A9A8 10 0C BPL &A9B6 .. \then use that density A9AA AD 84 10 LDA &1084 ... \else get *OPT 6 density A9AD D0 07 BNE &A9B6 .. \if manual, use that setting A9AF BD F0 0F LDA &0FF0,X ... \else use density of curr drive A9B2 D0 02 BNE &A9B6 .. \if no disc has been used in it A9B4 A9 12 LDA #&12 00010010 \then default density = double! A9B6 8D 70 10 STA &1070 .p. \set density A9B9 0A ASL A . \multiply by 4 A9BA 0A ASL A . A9BB 8D 76 10 STA &1076 .v. \= number of CHRN bytes A9BE 2C 76 10 BIT &1076 ,v. \if fewer than 16 sectors A9C1 70 0D BVS &A9D0 p. A9C3 20 18 90 JSR &9018 .. \then print " Sing" A9C6 00 BRK . A9C7 20 53 69 JSR &6953 Si A9CA 6E 67 00 ROR &0067 ng. A9CD 4C DA A9 JMP &A9DA L.. A9D0 20 18 90 JSR &9018 .. \else print " Doub" A9D3 00 BRK . A9D4 20 44 6F JSR &6F44 Do A9D7 75 62 ADC &62,X ub A9D9 00 BRK . A9DA 20 18 90 JSR &9018 .. \print "le Density"+newline A9DD 02 ??? . A9DE 6C 65 20 JMP (&2065) le A9E1 44 ??? D A9E2 65 6E ADC &6E en A9E4 73 ??? s A9E5 69 74 ADC #&74 01110100 A9E7 79 00 AD ADC &AD00,Y y.. \LDA &1071 if no. tracks given A9EA 71 10 ADC (&10),Y q. A9EC 10 07 BPL &A9F5 .. \then validate that number A9EE BD F4 0F LDA &0FF4,X ... \else get tracks on curr drive A9F1 D0 02 BNE &A9F5 .. \if no disc has been used in it A9F3 A9 50 LDA #&50 01010000 \then default tracks = 80! A9F5 C9 50 CMP #&50 01010000 \allow 80 tracks maximum A9F7 90 02 BCC &A9FB .. A9F9 A9 50 LDA #&50 01010000 \(can save 2 bytes here) A9FB 8D 71 10 STA &1071 .q. \set number of tracks A9FE 20 18 90 JSR &9018 .. \print " Tracks = "+n AA01 80 ??? . AA02 20 54 72 JSR &7254 Tr AA05 61 63 ADC (&63,X) ac AA07 6B ??? k AA08 73 ??? s AA09 20 3D 20 JSR &203D = AA0C 00 BRK . AA0D AD 72 10 LDA &1072 .r. \if 40-80 mode specified AA10 10 0C BPL &AA1E .. \then set 2:1 stepping AA12 A9 00 LDA #&00 00000000 \else default to 1:1 AA14 AC 71 10 LDY &1071 .q. \check number of tracks = 40 AA17 C0 28 CPY #&28 00101000 AA19 D0 03 BNE &AA1E .. \if not then keep 1:1 stepping AA1B AD 86 10 LDA &1086 ... \else use *OPT 8 tracks setting AA1E 8D 72 10 STA &1072 .r. \save stepping parameter AA21 A8 TAY . AA22 F0 08 BEQ &AA2C .. \if not 1:1 stepping AA24 20 18 90 JSR &9018 .. \then print "-80". AA27 00 BRK . AA28 2D 38 30 AND &3038 -80 AA2B 00 BRK . AA2C 20 09 90 JSR &9009 .. \print newline AA2F AD 85 10 LDA &1085 ... \get *OPT 7 volumes AA32 30 09 BMI &AA3D 0. \if cheeseburger, volumes = 0 AA34 D0 09 BNE &AA3F .. \if manual, use that setting AA36 A9 08 LDA #&08 00001000 \else volumes = 8 in double den AA38 2C 76 10 BIT &1076 ,v. \if single density AA3B 70 02 BVS &AA3F p. AA3D A9 00 LDA #&00 00000000 \then volumes = 0. AA3F 8D 73 10 STA &1073 .s. \set number of volumes AA42 2C 76 10 BIT &1076 ,v. \if it is not the default AA45 70 06 BVS &AA4D p. \for that density AA47 C9 00 CMP #&00 00000000 AA49 F0 16 BEQ &AA61 .. AA4B D0 04 BNE &AA51 .. AA4D C9 08 CMP #&08 00001000 AA4F F0 10 BEQ &AA61 .. AA51 20 18 90 JSR &9018 .. \then print " Volumes = "+n+nl. AA54 82 ??? . AA55 20 56 6F JSR &6F56 Vo AA58 6C 75 6D JMP (&6D75) lum AA5B 65 73 ADC &73 es AA5D 20 3D 20 JSR &203D = AA60 00 BRK . AA61 AD 74 10 LDA &1074 .t. \if outstep specified AA64 10 0F BPL &AA75 .. \then print its value AA66 A9 05 LDA #&05 00000101 \else outstep = 5 in dbl dens AA68 2C 76 10 BIT &1076 ,v. \if single density AA6B 70 02 BVS &AA6F p. AA6D A9 03 LDA #&03 00000011 \then outstep = 3. AA6F 8D 74 10 STA &1074 .t. \set default outstep AA72 4C 85 AA JMP &AA85 L.. \and skip printing it. AA75 20 18 90 JSR &9018 .. \print " Outstep = "+n+nl AA78 82 ??? . AA79 20 4F 75 JSR &754F Ou AA7C 74 ??? t AA7D 73 ??? s AA7E 74 ??? t AA7F 65 70 ADC &70 ep AA81 20 3D 20 JSR &203D = AA84 00 BRK . AA85 AD 70 10 LDA &1070 .p. \calculate density - outstep AA88 38 SEC 8 \to obtain logical outstep. AA89 ED 74 10 SBC &1074 .t. \sector nos on the next track AA8C 8D 74 10 STA &1074 .t. \are higher by this amount. AA8F 8A TXA . \put drive number in A AA90 20 0C 8A JSR &8A0C .. \and confirm overwrite AA93 B0 02 BCS &AA97 .. \if refused exit C=1, else: AA95 38 SEC 8 AA96 60 RTS ` AA97 AD 70 10 LDA &1070 .p. \Do *FORMAT AA9A 9D F0 0F STA &0FF0,X ... \Configure target drive AA9D AD 71 10 LDA &1071 .q. AAA0 9D F4 0F STA &0FF4,X ... AAA3 AD 72 10 LDA &1072 .r. AAA6 9D F8 0F STA &0FF8,X ... AAA9 AD 73 10 LDA &1073 .s. AAAC 9D FC 0F STA &0FFC,X ... AAAF A9 00 LDA #&00 00000000 \Point O7F block to CHRN table AAB1 38 SEC 8 \at end of page &0E AAB2 ED 76 10 SBC &1076 .v. \and set a pointer to fill it AAB5 85 A8 STA &A8 .. AAB7 8D 11 10 STA &1011 ... AABA A9 0F LDA #&0F 00001111 AABC E9 00 SBC #&00 00000000 AABE 85 A9 STA &A9 .. AAC0 8D 12 10 STA &1012 ... AAC3 A9 FF LDA #&FF 11111111 AAC5 8D 13 10 STA &1013 ... AAC8 8D 14 10 STA &1014 ... AACB A9 00 LDA #&00 00000000 AACD 8D 17 10 STA &1017 ... \Track no. = 0 AAD0 8D 77 10 STA &1077 .w. \Sector no. = 0 AAD3 8D 1A 10 STA &101A ... \Gap 5 size = 0 (mini floppy) AAD6 A9 05 LDA #&05 00000101 \5 parameters AAD8 8D 15 10 STA &1015 ... AADB A9 23 LDA #&23 00100011 \&23 = 8271 Format command AADD 8D 16 10 STA &1016 ... AAE0 AD 70 10 LDA &1070 .p. \No. sectors to format = spt AAE3 09 20 ORA #&20 00100000 \256 byte sectors AAE5 8D 19 10 STA &1019 ... AAE8 A9 12 LDA #&12 00010010 \set gap1 and gap3 sizes AAEA 8D 18 10 STA &1018 ... \according to density AAED 8D 1B 10 STA &101B ... AAF0 2C 76 10 BIT &1076 ,v. AAF3 50 0A BVC &AAFF P. AAF5 A9 1B LDA #&1B 00011011 AAF7 8D 18 10 STA &1018 ... AAFA A9 24 LDA #&24 00100100 AAFC 8D 1B 10 STA &101B ... AAFF 20 09 90 JSR &9009 .. AB02 20 70 AE JSR &AE70 p. \print "Formatting " AB05 20 A2 AE JSR &AEA2 .. \print "track n" AB08 AE 70 10 LDX &1070 .p. \fill out CHRN block: AB0B A0 00 LDY #&00 00000000 AB0D AD 17 10 LDA &1017 ... \set cylinder AB10 91 A8 STA (&A8),Y .. AB12 C8 INY . AB13 AD 10 10 LDA &1010 ... \head is set according to drive AB16 29 02 AND #&02 00000010 AB18 4A LSR A J AB19 91 A8 STA (&A8),Y .. AB1B C8 INY . AB1C AD 77 10 LDA &1077 .w. \set record (sector) AB1F 91 A8 STA (&A8),Y .. AB21 C8 INY . AB22 A9 01 LDA #&01 00000001 \set record length = 256 bytes AB24 91 A8 STA (&A8),Y .. AB26 C8 INY . AB27 20 F6 AD JSR &ADF6 .. \add 1 to sector iter, mod spt. AB2A CA DEX . \loop until all sectors done AB2B D0 E0 BNE &AB0D .. AB2D 20 0F 9B JSR &9B0F .. \call OSWORD &7F, report errors AB30 AD 74 10 LDA &1074 .t. \get track skew AB33 20 F6 AD JSR &ADF6 .. \add to sector iterator AB36 EE 17 10 INC &1017 ... \increment track number AB39 AD 17 10 LDA &1017 ... \have we formatted all tracks? AB3C CD 71 10 CMP &1071 .q. AB3F D0 C1 BNE &AB02 .. \loop until all tracks done AB41 20 70 AE JSR &AE70 p. \print "Formatting " AB44 20 18 90 JSR &9018 .. \print "catalog " AB47 02 ??? . AB48 63 ??? c AB49 61 74 ADC (&74,X) at AB4B 61 6C ADC (&6C,X) al AB4D 6F ??? o AB4E 67 ??? g AB4F 20 00 AD JSR &AD00 .. \get no. volumes AB52 73 ??? s AB53 10 D0 BPL &AB25 .. \if =0 AB55 0C ??? . AB56 AD 71 10 LDA &1071 .q. \then get tracks on disc AB59 8D 78 10 STA &1078 .x. \set as tracks in volume AB5C 20 18 AE JSR &AE18 .. \create volume catalogues AB5F 4C 85 AB JMP &AB85 L.. \then go to verify AB62 20 F0 AE JSR &AEF0 .. \set size of volume A AB65 90 05 BCC &AB6C .. \if more than one volume AB67 A9 21 LDA #&21 00100001 \then set vol B = 33 tracks AB69 8D 79 10 STA &1079 .y. AB6C AD 71 10 LDA &1071 .q. \is it an 80 track disc? AB6F C9 50 CMP #&50 01010000 \if not AB71 F0 06 BEQ &AB79 .. AB73 4E 78 10 LSR &1078 Nx. \then halve those two values. AB76 4E 79 10 LSR &1079 Ny. AB79 20 91 AC JSR &AC91 .. \validate volume allocation AB7C 20 03 AD JSR &AD03 .. \adjust volumes to fill disc AB7F 20 4E AC JSR &AC4E N. \create volume and disc cats AB82 20 09 90 JSR &9009 .. \print newline AB85 20 70 AE JSR &AE70 p. \print "Formatting " AB88 20 B1 AE JSR &AEB1 .. \print "complete" AB8B 4C 99 AB JMP &AB99 L.. \verify disc and exit AB8E 20 04 AE JSR &AE04 .. \*VERIFY. set default drive AB91 20 18 93 JSR &9318 .. \get multiple drive spec AB94 B0 03 BCS &AB99 .. \if incorrectly formed AB96 4C 09 81 JMP &8109 L.. \print syntax and quit. AB99 20 09 90 JSR &9009 .. \else print newline AB9C 20 82 AE JSR &AE82 .. \print "Verifying " AB9F 20 93 AE JSR &AE93 .. \print "drive "+n ABA2 20 0C 9B JSR &9B0C .. \softmount disc ABA5 20 53 AE JSR &AE53 S. \verify track ABA8 24 FF BIT &FF $. \test Escape flag ABAA 10 0C BPL &ABB8 .. \if clear then continue ABAC 20 18 90 JSR &9018 .. \else "Escape" error ABAF 0A ASL A . ABB0 11 45 ORA (&45),Y .E ABB2 73 ??? s ABB3 63 ??? c ABB4 61 70 ADC (&70,X) ap ABB6 65 00 ADC &00 e. ABB8 EE 17 10 INC &1017 ... \increment track number ABBB AD 17 10 LDA &1017 ... \fetch it ABBE DD F4 0F CMP &0FF4,X ... \compare with tracks on disc ABC1 D0 E2 BNE &ABA5 .. \loop until all tracks done. ABC3 20 82 AE JSR &AE82 .. \print "Verifying complete". ABC6 4C B1 AE JMP &AEB1 L.. ABC9 8E 72 10 STX &1072 .r. \*CATGEN ABCC 20 04 AE JSR &AE04 .. \do some initialisation ABCF 20 18 93 JSR &9318 .. \get multiple drive spec ABD2 B0 27 BCS &ABFB .' \if absent proceed with catgen ABD4 20 1B 93 JSR &931B .. \else get volume letter ABD7 A5 C8 LDA &C8 .. \put it in A ABD9 29 0F AND #&0F 00001111 \convert to binary 1..8 ABDB AA TAX . ABDC CA DEX . \subtract 1 ABDD A9 00 LDA #&00 00000000 \clear this vol's track count ABDF 9D 78 10 STA &1078,X .x. ABE2 20 C5 FF JSR &FFC5 .. \call GSREAD ABE5 B0 E8 BCS &ABCF .. \if EOW scan next argument ABE7 C9 30 CMP #&30 00110000 \else is character "0"? ABE9 90 0A BCC &ABF5 .. \syntax error if less ABEB C9 3A CMP #&3A 00111010 \is it more than "9"? ABED B0 06 BCS &ABF5 .. \syntax error if more. ABEF 20 EF AC JSR &ACEF .. \add digit to track count ABF2 4C E2 AB JMP &ABE2 L.. \loop to process more digits. ABF5 AE 72 10 LDX &1072 .r. \restore command table pointer ABF8 4C 09 81 JMP &8109 L.. \give *CATGEN syntax error. ABFB 20 0C 9B JSR &9B0C .. \softmount disc ABFE A6 C9 LDX &C9 .. \get drive number in X AC00 8A TXA . \and A AC01 20 18 90 JSR &9018 .. \print "Drive "+n AC04 C0 44 CPY #&44 01000100 AC06 72 ??? r AC07 69 76 ADC #&76 01110110 AC09 65 20 ADC &20 e AC0B 00 BRK . AC0C BD FC 0F LDA &0FFC,X ... \get no. volumes on drive AC0F 8D 73 10 STA &1073 .s. \store in temp AC12 D0 1B BNE &AC2F .. \if =0 AC14 20 18 90 JSR &9018 .. \then print AC17 02 ??? . \": single volume disc"+nl AC18 3A ??? : AC19 20 73 69 JSR &6973 si AC1C 6E 67 6C ROR &6C67 ngl AC1F 65 20 ADC &20 e AC21 76 6F ROR &6F,X vo AC23 6C 75 6D JMP (&6D75) lum AC26 65 20 ADC &20 e AC28 64 ??? d AC29 69 73 ADC #&73 01110011 AC2B 63 ??? c AC2C 00 BRK . AC2D 38 SEC 8 \and exit C=1. AC2E 60 RTS ` AC2F 20 91 AC JSR &AC91 .. \else validate vol allocation AC32 AD 81 10 LDA &1081 ... \get total number of tracks AC35 D0 0D BNE &AC44 .. \if =0 AC37 20 06 92 JSR &9206 .. \then user wants a volume cat AC3A 30 10 BMI &AC4C 0. \copy actual vol allocations AC3C 78 SEI x \to command line workspace AC3D 10 08 BPL &AC47 .. AC3F 20 4A AD JSR &AD4A J. \print *CATGEN listing AC42 38 SEC 8 \and exit C=1. AC43 60 RTS ` AC44 20 03 AD JSR &AD03 .. \else adjust volumes to fill AC47 A5 C9 LDA &C9 .. \get drive number AC49 20 0C 8A JSR &8A0C .. \ask for confirmation AC4C 90 41 BCC &AC8F .A \if refused exit C=1, else: AC4E 20 18 AE JSR &AE18 .. \Create volume and disc cats AC51 A9 00 LDA #&00 00000000 \create volume catalogues AC53 AC 70 10 LDY &1070 .p. \get density (=sec/trk) AC56 8C 03 0E STY &0E03 ... \store in disc catalogue AC59 18 CLC . AC5A 6D 71 10 ADC &1071 mq. \add number of tracks AC5D 90 03 BCC &AC62 .. \carry out to disc cat AC5F EE 01 0E INC &0E01 ... AC62 88 DEY . \decrement sectors AC63 D0 F4 BNE &AC59 .. \and loop while more to go. AC65 20 E7 AE JSR &AEE7 .. \store no. of sectors on disc AC68 AD 71 10 LDA &1071 .q. \get number of tracks AC6B 8D 04 0E STA &0E04 ... \store in disc catalogue AC6E A9 01 LDA #&01 00000001 \start volumes on track 1 AC70 A2 00 LDX #&00 00000000 \clear X and Y offsets AC72 A0 00 LDY #&00 00000000 \to start at first volume: AC74 99 08 0E STA &0E08,Y ... \store start track number AC77 18 CLC . \add no. tracks in volume AC78 7D 78 10 ADC &1078,X }x. AC7B 48 PHA H AC7C BD 78 10 LDA &1078,X .x. \if volume is absent AC7F D0 03 BNE &AC84 .. AC81 99 08 0E STA &0E08,Y ... \then delete start track no. AC84 68 PLA h AC85 C8 INY . \increase disc cat offset by 2 AC86 C8 INY . AC87 E8 INX . \increment volume cat offset AC88 E0 08 CPX #&08 00001000 \and loop for all 8 volumes. AC8A D0 E8 BNE &AC74 .. AC8C 20 03 9B JSR &9B03 .. \write disc catalogue AC8F 38 SEC 8 \and exit C=1. AC90 60 RTS ` AC91 20 00 92 JSR &9200 .. \Validate volume allocation AC94 A6 C9 LDX &C9 .. \get drive number in X AC96 BD F4 0F LDA &0FF4,X ... \get no. tracks on this drive AC99 8D 71 10 STA &1071 .q. \store in cmd line parameter AC9C 8D 80 10 STA &1080 ... \and in temp AC9F BC F0 0F LDY &0FF0,X ... \get density of this drive ACA2 8C 70 10 STY &1070 .p. \store in cmd line parameter ACA5 A2 00 LDX #&00 00000000 \clear total number of tracks ACA7 8E 81 10 STX &1081 ... \x = volume offset = 0 (A) ACAA BD 78 10 LDA &1078,X .x. \get no. tracks in this volume ACAD F0 17 BEQ &ACC6 .. \if nonexistent vol then skip ACAF EC 73 10 CPX &1073 .s. \else if >= no.volumes ACB2 B0 18 BCS &ACCC .. \error "vol nn unavailable" ACB4 CD 80 10 CMP &1080 ... \else if >= tracks on disc ACB7 B0 23 BCS &ACDC .# \error "vol nn spec too large" ACB9 6D 81 10 ADC &1081 m.. \else add to total tracks ACBC B0 72 BCS &AD30 .r \if >255 ACBE CD 71 10 CMP &1071 .q. \or if >= tracks on disc ACC1 B0 6D BCS &AD30 .m \error "total tracks too many" ACC3 8D 81 10 STA &1081 ... \else store new total. ACC6 E8 INX . \increment volume pointer ACC7 E0 08 CPX #&08 00001000 \and loop for all 8 volumes ACC9 D0 DF BNE &ACAA .. \then exit. ACCB 60 RTS ` ACCC 20 21 98 JSR &9821 !. \Volume error "unavailable" ACCF D2 ??? . ACD0 75 6E ADC &6E,X un ACD2 61 76 ADC (&76,X) av ACD4 61 69 ADC (&69,X) ai ACD6 6C 61 62 JMP (&6261) lab ACD9 6C 65 00 JMP (&0065) le. ACDC 20 21 98 JSR &9821 !. \Volume error ACDF D2 ??? . \"spec too large" ACE0 73 ??? s ACE1 70 65 BVS &AD48 pe ACE3 63 ??? c ACE4 20 74 6F JSR &6F74 to ACE7 6F ??? o ACE8 20 6C 61 JSR &616C la ACEB 72 ??? r ACEC 67 ??? g ACED 65 00 ADC &00 e. ACEF 20 00 92 JSR &9200 .. \Add digit to track count ACF2 29 0F AND #&0F 00001111 \convert ASCII num to binary ACF4 A0 0A LDY #&0A 00001010 \set counter = 10 ACF6 18 CLC . \add former units digit ACF7 7D 78 10 ADC &1078,X }x. ACFA B0 E0 BCS &ACDC .. \give error if carry out ACFC 88 DEY . \else loop to multiply x10. ACFD D0 F8 BNE &ACF7 .. ACFF 9D 78 10 STA &1078,X .x. \store tens plus new unit. AD02 60 RTS ` AD03 20 00 92 JSR &9200 .. \Adjust volumes to fill disc AD06 AD 71 10 LDA &1071 .q. \get no. tracks on disc AD09 18 CLC . \sub (tracks in volumes + 1) AD0A ED 81 10 SBC &1081 ... AD0D F0 3E BEQ &AD4D .> \if zero result go and print AD0F AE 73 10 LDX &1073 .s. \else get no. volumes AD12 18 CLC . AD13 7D 77 10 ADC &1077,X }w. \add track slack to last vol AD16 9D 77 10 STA &1077,X .w. AD19 CD 80 10 CMP &1080 ... \compare new size - disc size AD1C 90 2F BCC &AD4D ./ \if <0 go and print AD1E 48 PHA H \else volume overflows. AD1F AD 80 10 LDA &1080 ... \get total tracks AD22 38 SEC 8 \reduce by 1 AD23 E9 01 SBC #&01 00000001 AD25 9D 77 10 STA &1077,X .w. \store as volume size AD28 68 PLA h \restore calculated size AD29 38 SEC 8 \subtract (total - 1) AD2A FD 77 10 SBC &1077,X .w. \= slack remaining AD2D CA DEX . \try again with next volume AD2E D0 E2 BNE &AD12 .. \if no more volumes then: AD30 20 21 98 JSR &9821 !. \volume error AD33 D2 ??? . \"total tracks too many". AD34 74 ??? t AD35 6F ??? o AD36 74 ??? t AD37 61 6C ADC (&6C,X) al AD39 20 74 72 JSR &7274 tr AD3C 61 63 ADC (&63,X) ac AD3E 6B ??? k AD3F 73 ??? s AD40 20 74 6F JSR &6F74 to AD43 6F ??? o AD44 20 6D 61 JSR &616D ma AD47 6E 79 00 ROR &0079 ny. AD4A 20 00 92 JSR &9200 .. \Print *CATGEN listing AD4D 20 18 90 JSR &9018 .. \print heading on its own line AD50 03 ??? . \"Volume Tracks Sectors " AD51 56 6F LSR &6F,X Vo \"K bytes" AD53 6C 75 6D JMP (&6D75) lum AD56 65 20 ADC &20 e AD58 20 54 72 JSR &7254 Tr AD5B 61 63 ADC (&63,X) ac AD5D 6B ??? k AD5E 73 ??? s AD5F 20 20 53 JSR &5320 S AD62 65 63 ADC &63 ec AD64 74 ??? t AD65 6F ??? o AD66 72 ??? r AD67 73 ??? s AD68 20 20 4B JSR &4B20 K AD6B 20 62 79 JSR &7962 by AD6E 74 ??? t AD6F 65 73 ADC &73 es AD71 00 BRK . AD72 A9 01 LDA #&01 00000001 \A=1, cats take one track AD74 20 18 90 JSR &9018 .. \print nl+" Cat" AD77 01 20 ORA (&20,X) . AD79 43 ??? C AD7A 61 74 ADC (&74,X) at AD7C 00 BRK . AD7D 20 9B AD JSR &AD9B .. \print volume listing line AD80 A0 41 LDY #&41 01000001 \Y="A" AD82 B9 37 10 LDA &1037,Y .7. \get size from 1078..F AD85 F0 0E BEQ &AD95 .. \if =0 then skip volume AD87 48 PHA H \else save no. tracks AD88 98 TYA . \A=volume letter AD89 20 18 90 JSR &9018 .. \print 3 spaces + letter AD8C C0 20 CPY #&20 00100000 AD8E 20 20 00 JSR &0020 . AD91 68 PLA h \restore no. tracks AD92 20 9B AD JSR &AD9B .. \print volume listing line. AD95 C8 INY . \increment volume letter AD96 C0 49 CPY #&49 01001001 \have we gone past "H"? AD98 D0 E8 BNE &AD82 .. \if so exit C=1 else loop. AD9A 60 RTS ` AD9B 48 PHA H \Print volume listing line AD9C A9 0A LDA #&0A 00001010 \save no. tracks in A AD9E 20 06 90 JSR &9006 .. \tab to column 10 ADA1 68 PLA h \peek no. tracks ADA2 48 PHA H ADA3 20 12 90 JSR &9012 .. \print decimal byte ADA6 8D 74 10 STA &1074 .t. \store in temp ADA9 A9 12 LDA #&12 00010010 \A=18 ADAB 20 06 90 JSR &9006 .. \tab to this column ADAE 20 DB AD JSR &ADDB .. \multiply to get sectors ADB1 20 09 A4 JSR &A409 .. \print decimal word ADB4 A9 1B LDA #&1B 00011011 \A=27 ADB6 20 06 90 JSR &9006 .. \tab to this column ADB9 20 DB AD JSR &ADDB .. \regenerate no. sectors ADBC 4E 61 10 LSR &1061 Na. \shift right twice ADBF 6E 60 10 ROR &1060 n`. \to divide by 4 ADC2 4E 61 10 LSR &1061 Na. \and get kilobytes. ADC5 6E 60 10 ROR &1060 n`. \C=1 if we get half a K ADC8 08 PHP . \save carry flag ADC9 20 09 A4 JSR &A409 .. \print decimal word ADCC 28 PLP ( \restore carry flag ADCD 90 07 BCC &ADD6 .. \if set ADCF 20 18 90 JSR &9018 .. \then print ".5". ADD2 00 BRK . ADD3 2E 35 00 ROL &0035 .5. ADD6 20 09 90 JSR &9009 .. \print newline ADD9 68 PLA h \restore no. tracks and exit. ADDA 60 RTS ` ADDB 20 00 92 JSR &9200 .. \Multiply tracks by spt ADDE A9 00 LDA #&00 00000000 \clear A ADE0 8D 61 10 STA &1061 .a. \and result word high byte. ADE3 AE 70 10 LDX &1070 .p. \get density (=sectors/track) ADE6 18 CLC . \into X. ADE7 6D 74 10 ADC &1074 mt. \add track count to total ADEA 90 03 BCC &ADEF .. \if carry out occurs ADEC EE 61 10 INC &1061 .a. \increment result high byte. ADEF CA DEX . \decrement sectors remaining ADF0 D0 F4 BNE &ADE6 .. \loop if more to go ADF2 8D 60 10 STA &1060 .`. \else store low byte and exit. ADF5 60 RTS ` ADF6 18 CLC . \Add A to sector iterator ADF7 6D 77 10 ADC &1077 mw. \and modulo sectors-per-track. ADFA 38 SEC 8 ADFB 8D 77 10 STA &1077 .w. ADFE ED 70 10 SBC &1070 .p. AE01 B0 F8 BCS &ADFB .. AE03 60 RTS ` AE04 20 00 92 JSR &9200 .. \Set immed. drive = default, AE07 AD 09 10 LDA &1009 ... \zero *command argument space AE0A 85 C9 STA &C9 .. AE0C A2 00 LDX #&00 00000000 AE0E 8A TXA . AE0F 9D 78 10 STA &1078,X .x. AE12 E8 INX . AE13 E0 08 CPX #&08 00001000 AE15 D0 F8 BNE &AE0F .. AE17 60 RTS ` AE18 20 00 92 JSR &9200 .. \Create volume catalogues AE1B A9 41 LDA #&41 01000001 \Set immediate volume = A AE1D 85 C8 STA &C8 .. AE1F A9 00 LDA #&00 00000000 \Zero catalogue pages AE21 AA TAX . AE22 9D 00 0E STA &0E00,X ... AE25 9D 00 0F STA &0F00,X ... AE28 E8 INX . AE29 D0 F7 BNE &AE22 .. AE2B A9 99 LDA #&99 10011001 \Cat version no, will => &00 AE2D 8D 04 0F STA &0F04 ... AE30 A9 00 LDA #&00 00000000 AE32 8D 06 0F STA &0F06 ... AE35 AC 70 10 LDY &1070 .p. \Multiply spt by tracks in vol AE38 18 CLC . AE39 7D 78 10 ADC &1078,X }x. AE3C 90 03 BCC &AE41 .. AE3E EE 06 0F INC &0F06 ... AE41 88 DEY . AE42 D0 F4 BNE &AE38 .. AE44 8D 07 0F STA &0F07 ... \Store in size field of cat AE47 20 03 9B JSR &9B03 .. \write current catalogue AE4A E6 C8 INC &C8 .. \increment volume letter AE4C E8 INX . AE4D EC 73 10 CPX &1073 .s. \have we created all volumes? AE50 90 D9 BCC &AE2B .. \loop until done AE52 60 RTS ` \then exit AE53 48 PHA H \Verify track AE54 20 82 AE JSR &AE82 .. \print "Verifying " AE57 20 A2 AE JSR &AEA2 .. \print "track "+n AE5A A9 1F LDA #&1F 00011111 \=8271 verify command AE5C 8D 16 10 STA &1016 ... \store in OSWORD &7F block AE5F A9 00 LDA #&00 00000000 \set start sector = 0 AE61 8D 18 10 STA &1018 ... AE64 A6 C9 LDX &C9 .. \get current drive in X AE66 BD F0 0F LDA &0FF0,X ... \get density of current drive AE69 8D 19 10 STA &1019 ... \store number of sectors AE6C 68 PLA h \and jump to O7F r/w w/errors. AE6D 4C 15 9B JMP &9B15 L.. AE70 20 18 90 JSR &9018 .. \Print "Formatting " AE73 00 BRK . AE74 0B ??? . AE75 46 6F LSR &6F Fo AE77 72 ??? r AE78 6D 61 74 ADC &7461 mat AE7B 74 ??? t AE7C 69 6E ADC #&6E 01101110 AE7E 67 ??? g AE7F 20 00 60 JSR &6000 .` AE82 20 18 90 JSR &9018 .. \Print "Verifying " AE85 00 BRK . AE86 0B ??? . AE87 56 65 LSR &65,X Ve AE89 72 ??? r AE8A 69 66 ADC #&66 01100110 AE8C 79 69 6E ADC &6E69,Y yin AE8F 67 ??? g AE90 20 00 60 JSR &6000 .` AE93 A6 C9 LDX &C9 .. \Print "drive n" AE95 8A TXA . AE96 20 18 90 JSR &9018 .. AE99 C2 ??? . AE9A 64 ??? d AE9B 72 ??? r AE9C 69 76 ADC #&76 01110110 AE9E 65 20 ADC &20 e AEA0 00 BRK . AEA1 60 RTS ` AEA2 AD 17 10 LDA &1017 ... \Print "track n" AEA5 20 18 90 JSR &9018 .. AEA8 82 ??? . AEA9 74 ??? t AEAA 72 ??? r AEAB 61 63 ADC (&63,X) ac AEAD 6B ??? k AEAE 20 00 60 JSR &6000 .` AEB1 20 18 90 JSR &9018 .. \Print "complete", C=1 AEB4 02 ??? . AEB5 63 ??? c AEB6 6F ??? o AEB7 6D 70 6C ADC &6C70 mpl AEBA 65 74 ADC &74 et AEBC 65 00 ADC &00 e. AEBE 38 SEC 8 AEBF 60 RTS ` \EDOSPAT extensions, block 3 AEE7 8D 02 0E STA &0E02 ... \store sector count low byte AEEA A9 20 LDA #&20 00100000 \set catalogue version=&20 AEEC 8D 00 0E STA &0E00 ... \to show count is big-endian. AEEF 60 RTS ` AEF0 C9 02 CMP #&02 00000010 \C=1 if more than one volume AEF2 A9 2E LDA #&2E 00101110 \default to 46 tracks in vol A AEF4 B0 06 BCS &AEFC .. \use A=46 if multiple volumes AEF6 AD 71 10 LDA &1071 .q. \else get number of tracks AEF9 E9 00 SBC #&00 00000000 \C=0, take 1 for catalogue track AEFB 18 CLC . \reset C to indicate single vol. AEFC 8D 78 10 STA &1078 .x. \set number of tracks in volume AEFF 60 RTS ` \exit AF04 B9 9D 10 LDA &109D,Y ... \OSGBPB read/write w/sector ops AF07 D0 60 BNE &AF69 .` \if not on sector boundary AF09 AD 78 10 LDA &1078 .x. \do a bytewise transfer AF0C 0D 77 10 ORA &1077 .w. \else OR high bytes of L AF0F F0 02 BEQ &AF13 .. \if either >0 AF11 A9 FF LDA #&FF 11111111 \then request=255 AF13 0D 76 10 ORA &1076 .v. \else request=2nd byte of L AF16 F0 39 BEQ &AF51 .9 \if request=0 finish sector loop AF18 85 BA STA &BA .. \else store it in temp AF1A 98 TYA . \copy channel pointer to A AF1B 2C 3A 10 BIT &103A ,:. \test Tube channel flag AF1E 10 02 BPL &AF22 .. \if reading from disc AF20 09 03 ORA #&03 00000011 \then point A to EXT mid/hi AF22 AA TAX . \instead of allocated length. AF23 BD 98 10 LDA &1098,X ... \copy to X, get alloc length low AF26 38 SEC 8 \subtract PTR middle byte AF27 F9 9E 10 SBC &109E,Y ... \=maximum transfer size low AF2A 85 BB STA &BB .. \store in another temp AF2C BD 99 10 LDA &1099,X ... \get allocated length high AF2F A6 BA LDX &BA .. \load request for later AF31 F9 9F 10 SBC &109F,Y ... \subtract PTR high =maximum high AF34 90 1B BCC &AF51 .. \if maximum<0 finish sector loop AF36 D0 08 BNE &AF40 .. \if max>=256 transfer sectors AF38 E4 BB CPX &BB .. \else 0<=maximum<256. AF3A 90 04 BCC &AF40 .. \if request=0 (alw?) loop for more. AF51 2C 3A 10 BIT &103A ,:. \test Tube channel flag AF54 30 0E BMI &AF64 0. \if writing to disc AF56 20 0C B4 JSR &B40C .. \test if we are at end-of-file AF59 90 09 BCC &AF64 .. \if so AF5B 20 09 92 JSR &9209 .. \set EXT=PTR, extending file. AF5E 9D 10 9A STA &9A10,X ... AF61 10 03 BPL &AF66 .. AF63 11 20 ORA (&20),Y . \test if L>0 bytes. AF65 D6 B6 DEC &B6,X .. AF67 F0 10 BEQ &AF79 .. \if no more to transfer, exit. AF69 2C 3A 10 BIT &103A ,:. \bytewise transfer. test flag AF6C 30 0C BMI &AF7A 0. \if writing to disc AF6E 20 E5 B6 JSR &B6E5 .. \get byte from memory AF71 20 4B B6 JSR &B64B K. \put byte to disc AF74 20 C8 B6 JSR &B6C8 .. \decrement L AF77 D0 8B BNE &AF04 .. \if more bytes then loop AF79 60 RTS ` \else exit. AF7A 20 21 B6 JSR &B621 !. \else get byte from disc AF7D B0 FA BCS &AF79 .. \if EOF then exit AF7F 20 E5 B6 JSR &B6E5 .. \else put byte to memory AF82 4C 74 AF JMP &AF74 Lt. \decrement L and loop if >0. AF85 8D 16 10 STA &1016 ... \Multi-sector op on open file. AF88 86 BB STX &BB .. \A=command,X=sector count AF8A B9 94 10 LDA &1094,Y ... \Y=channel pointer.get start LBA AF8D 18 CLC . \add PTR middle byte AF8E 79 9E 10 ADC &109E,Y y.. \=transfer start LBA low byte. AF91 AA TAX . \save in X AF92 B9 95 10 LDA &1095,Y ... \get start LBA high byte AF95 79 9F 10 ADC &109F,Y y.. \add PTR high byte. AF98 84 BA STY &BA .. \LBA now in XA. save pointer AF9A 48 PHA H \save LBA high byte AF9B B9 93 10 LDA &1093,Y ... \copy drive of open file AF9E 85 C9 STA &C9 .. \to immediate drive for OSWORD. AFA0 68 PLA h \restore LBA high byte AFA1 A8 TAY . \set up LBA in XY AFA2 A5 BB LDA &BB .. \set A=sector count AFA4 20 06 92 JSR &9206 .. \copy data addr back to OSGBPB AFA7 BC 00 71 LDY &7100,X ..q \block AFAA 10 02 BPL &AFAE .. AFAC 20 06 92 JSR &9206 .. \copy OSGBPB address to OSWORD AFAF 71 10 ADC (&10),Y q. \block AFB1 11 10 ORA (&10),Y .. AFB3 04 ??? . AFB4 20 06 9B JSR &9B06 .. \do LBA transfer AFB7 A4 BA LDY &BA .. \set Y=channel ptr for return AFB9 A6 BA LDX &BA .. \and X too for incrementing PTR AFBB A5 BB LDA &BB .. \set A=sector count AFBD 18 CLC . \add to PTR middle byte AFBE 7D 9E 10 ADC &109E,X }.. AFC1 9D 9E 10 STA &109E,X ... AFC4 90 03 BCC &AFC9 .. \carry out to PTR high byte AFC6 FE 9F 10 INC &109F,X ... AFC9 A5 BB LDA &BB .. \set A=sector count again AFCB 18 CLC . \add to data address 2nd byte AFCC 65 BD ADC &BD e. AFCE 85 BD STA &BD .. AFD0 90 03 BCC &AFD5 .. \carry out to hi bytes in OSGBPB AFD2 20 F7 AF JSR &AFF7 .. \block AFD5 A9 FE LDA #&FE 11111110 \A=&FE mask AFD7 AA TAX . \copy to X as reverse counter AFD8 39 88 10 AND &1088,Y 9.. \clear EOF-warning-given flag AFDB 99 88 10 STA &1088,Y ... AFDE AD 76 10 LDA &1076 .v. \get 2nd byte of L AFE1 38 SEC 8 \subtract sector count AFE2 E5 BB SBC &BB .. AFE4 8D 76 10 STA &1076 .v. AFE7 BD 79 0F LDA &0F79,X .y. \borrow from 3rd and top bytes AFEA E9 00 SBC #&00 00000000 \of L AFEC 9D 79 0F STA &0F79,X .y. AFEF E8 INX . \return top byte of L AFF0 D0 F5 BNE &AFE7 .. \and C=1 if L>=0 bytes AFF2 60 RTS ` AFF3 E6 BD INC &BD .. \Increment top 3 bytes of data AFF5 D0 08 BNE &AFFF .. \address AFF7 EE 73 10 INC &1073 .s. \Increment top word of data AFFA D0 03 BNE &AFFF .. \address AFFC EE 74 10 INC &1074 .t. AFFF 60 RTS ` \EDOS API, part 1 B000 4C 0C B0 JMP &B00C L.. \OSFILE B003 4C 58 B9 JMP &B958 LX. \OSARGS B006 4C 7C B1 JMP &B17C L|. \OSFIND B009 4C A9 B1 JMP &B1A9 L.. \OSFSC B00C 20 00 92 JSR &9200 .. \OSFILE B00F 20 06 B7 JSR &B706 .. \call monitor B012 20 09 B4 JSR &B409 .. \copy user's block to 1070..81 B015 AA TAX . \transfer reason code to X B016 E8 INX . \add 1 B017 E0 08 CPX #&08 00001000 \does A equal 0..6 or &FF? B019 90 01 BCC &B01C .. \if so continue B01B 60 RTS ` \else exit C=1. B01C BD 12 B1 LDA &B112,X ... \get microcode byte from B112..9 B01F 85 CD STA &CD .. \store in shift register B021 BA TSX . \have A=1 returned on exit B022 A9 01 LDA #&01 00000001 \as no hierarchical directories B024 9D 05 01 STA &0105,X ... \and err given if file not found B027 AE 70 10 LDX &1070 .p. \put address of filename in XY B02A AC 71 10 LDY &1071 .q. B02D 20 33 B3 JSR &B333 3. \set up GSINIT B030 20 12 93 JSR &9312 .. \and get f-spec from the string. B033 46 CD LSR &CD F. \sample first bit of microcode B035 90 43 BCC &B07A .C B037 A2 72 LDX #&72 01110010 \......1 Save file B039 A0 60 LDY #&60 01100000 \OSFILE load addr to cat block 2 B03B 20 51 B3 JSR &B351 Q. \do 32 to 18 bit copy B03E A2 76 LDX #&76 01110110 \OSFILE exec addr to cat block 2 B040 A0 63 LDY #&63 01100011 B042 20 51 B3 JSR &B351 Q. \do 32 to 18 bit copy B045 38 SEC 8 B046 AD 7E 10 LDA &107E .~. \subtract OSFILE end address B049 ED 7A 10 SBC &107A .z. \from start address B04C 8D 66 10 STA &1066 .f. \to get length B04F AD 7F 10 LDA &107F ... \(note 16 bit so file 64K max) B052 ED 7B 10 SBC &107B .{. B055 8D 67 10 STA &1067 .g. B058 AE 66 10 LDX &1066 .f. \is low byte of length zero? B05B E0 01 CPX #&01 00000001 \if not set carry flag B05D 69 00 ADC #&00 00000000 \and increment high byte B05F 8D 6B 10 STA &106B .k. \to make the sector count B062 A9 00 LDA #&00 00000000 \clear high byte B064 8D 6C 10 STA &106C .l. \of sector count B067 8A TXA . \low byte to A and discard B068 A9 A0 LDA #&A0 10100000 \&A0 = OSFILE reason code B06A 20 18 A6 JSR &A618 .. \check perms/create file B06D 20 06 92 JSR &9206 .. \copy start address B070 7A ??? z \to OSWORD &7F block B071 10 11 BPL &B084 .. B073 10 04 BPL &B079 .. B075 A9 0B LDA #&0B 00001011 \= 8271 write command B077 4C 42 B3 JMP &B342 LB. \save data to disc and exit. B07A 20 00 9B JSR &9B00 .. \......0 Not a file save B07D 20 0C A5 JSR &A50C .. \load cat, check file exists B080 20 03 A6 JSR &A603 .. \unpack fields from catalogue B083 46 CD LSR &CD F. B085 90 13 BCC &B09A .. B087 20 06 92 JSR &9206 .. \.....10 Load file B08A 72 ??? r \copy OSFILE load address B08B 10 11 BPL &B09E .. \to OSWORD &7F block B08D 10 04 BPL &B093 .. B08F AD 76 10 LDA &1076 .v. \test low byte of exec address B092 F0 03 BEQ &B097 .. \if =0 then skip, else: B094 20 70 B3 JSR &B370 p. \copy load addr from cat to O7F B097 20 40 B3 JSR &B340 @. \load data from disc and exit. B09A 46 CD LSR &CD F. B09C 90 38 BCC &B0D6 .8 B09E A2 48 LDX #&48 01001000 \....1x0 Get file info B0A0 A0 72 LDY #&72 01110010 \load addr from cat to OSFILE B0A2 20 74 B3 JSR &B374 t. \do 18 to 32 bit copy B0A5 A2 4B LDX #&4B 01001011 \exec addr from cat to OSFILE B0A7 A0 76 LDY #&76 01110110 B0A9 20 74 B3 JSR &B374 t. \do 18 to 32 bit copy B0AC 20 06 92 JSR &9206 .. \copy length from cat to OSFILE B0AF 4E 10 7A LSR &7A10 N.z B0B2 10 03 BPL &B0B7 .. B0B4 A9 00 LDA #&00 00000000 \clear top byte of length B0B6 AA TAX . \and attribute word B0B7 9D 7D 10 STA &107D,X .}. B0BA E8 INX . B0BB E0 05 CPX #&05 00000101 B0BD D0 F8 BNE &B0B7 .. B0BF 2C 47 10 BIT &1047 ,G. \test lock bit of cat entry B0C2 10 05 BPL &B0C9 .. \if clear then skip, else: B0C4 A9 08 LDA #&08 00001000 \set low attribute byte = &08 B0C6 8D 7E 10 STA &107E .~. \(same as DFS) B0C9 A0 00 LDY #&00 00000000 \copy OSFILE block back B0CB B9 70 10 LDA &1070,Y .p. \to user's area B0CE 91 BE STA (&BE),Y .. B0D0 C8 INY . B0D1 C0 12 CPY #&12 00010010 B0D3 D0 F6 BNE &B0CB .. \and exit. B0D5 60 RTS ` B0D6 46 CD LSR &CD F. \....0x0 Not save or get info B0D8 90 09 BCC &B0E3 .. B0DA 20 21 A5 JSR &A521 !. \...10x0 Delete file B0DD 20 00 A6 JSR &A600 .. \check file not locked B0E0 4C 03 9B JMP &9B03 L.. \delete entry & write catalogue. B0E3 46 CD LSR &CD F. B0E5 90 07 BCC &B0EE .. B0E7 A2 72 LDX #&72 01110010 \..100x0 Set load address B0E9 A0 48 LDY #&48 01001000 \load address to cat block 1 B0EB 20 51 B3 JSR &B351 Q. \do 32 to 18 bit copy. B0EE 46 CD LSR &CD F. B0F0 90 07 BCC &B0F9 .. B0F2 A2 76 LDX #&76 01110110 \.1x00x0 Set exec address B0F4 A0 4B LDY #&4B 01001011 \exec address to cat block 1 B0F6 20 51 B3 JSR &B351 Q. \to 32 to 18 bit copy B0F9 46 CD LSR &CD F. B0FB 90 0F BCC &B10C .. B0FD AD 7E 10 LDA &107E .~. \1xx00x0 Set attributes B100 29 0A AND #&0A 00001010 \test bits 1 and 3 of attributes B102 49 00 EOR #&00 00000000 \no-op (may be used later) B104 0E 47 10 ASL &1047 .G. \discard old lock bit B107 C9 01 CMP #&01 00000001 \C=1 if A>0 (attr b1 or b3 set) B109 6E 47 10 ROR &1047 nG. \put lock bit in catalog block 1 B10C 20 06 A6 JSR &A606 .. \xxx00x0 Not save delete or info B10F 4C 03 9B JMP &9B03 L.. \pack fields & write catalogue. B112 06 01 ASL &01 .. \8 microcode bytes for OSFILE B114 70 10 BVS &B126 p. \&FF and 0 to 6 B116 20 40 04 JSR &0440 @. B119 08 PHP . B11A 20 09 B7 JSR &B709 .. \OSARGS B11D 85 CD STA &CD .. \when A=&FF flush routne flushes B11F C0 00 CPY #&00 00000000 B121 D0 25 BNE &B148 .% B123 C9 00 CMP #&00 00000000 B125 D0 03 BNE &B12A .. B127 60 RTS ` \a=0, y=0: return FS number B128 00 BRK . \exit; the wrapper does that. B129 00 BRK . B12A 20 00 92 JSR &9200 .. B12D C9 01 CMP #&01 00000001 B12F D0 10 BNE &B141 .. B131 20 09 92 JSR &9209 .. \a=1, y=0: return cmd line tail B134 82 ??? . \copy from workspace B135 10 00 BPL &B137 .. \to bottom of user's block B137 00 BRK . B138 02 ??? . \2 bytes B139 02 ??? . \X indexed destination. B13A A9 FF LDA #&FF 11111111 \set top word to &FFFF B13C 95 02 STA &02,X .. \indicating I/O memory B13E 95 03 STA &03,X .. \and exit. B140 60 RTS ` B141 C9 FF CMP #&FF 11111111 B143 D0 FB BNE &B140 .. \a=&FF, y=0: flush all files B145 4C DB 9A JMP &9ADB L.. \jump to our routine. B148 20 00 92 JSR &9200 .. \y>0: file handle given B14B 20 0C 98 JSR &980C .. \ensure file is open B14E C9 00 CMP #&00 00000000 B150 D0 11 BNE &B163 .. B152 C8 INY . \a=0, y>0: return PTR B153 C8 INY . \increment channel pointer B154 C8 INY . \to point to PTR not EXT: B155 20 09 92 JSR &9209 .. \a=2, y>0: return EXT B158 9A TXS . \copy from workspace B159 10 00 BPL &B15B .. \to bottom of user's block B15B 00 BRK . B15C 03 ??? . \3 bytes B15D 12 ??? . \y index source, x index dest. B15E A9 00 LDA #&00 00000000 \clear top byte of PTR B160 95 03 STA &03,X .. \and exit. B162 60 RTS ` B163 C9 01 CMP #&01 00000001 B165 D0 0A BNE &B171 .. B167 20 09 92 JSR &9209 .. \a=1, y>0: write PTR B16A 00 BRK . \copy from user's block B16B 00 BRK . \to workspace. nothing happens B16C 9D 10 03 STA &0310,X ... \to file until next write! B16F 21 60 AND (&60,X) !` \exit. B171 C9 02 CMP #&02 00000010 B173 F0 E0 BEQ &B155 .. B175 C9 FF CMP #&FF 11111111 B177 D0 F7 BNE &B170 .. \a=&FF, y>0: flush file. B179 4C 0F 98 JMP &980F L.. B17C 20 00 92 JSR &9200 .. \OSFIND B17F 20 15 B7 JSR &B715 .. \call monitor B182 C9 00 CMP #&00 00000000 \is it a CLOSE# ? B184 F0 03 BEQ &B189 .. \if so, then: B186 4C 98 B1 JMP &B198 L.. B189 85 CD STA &CD .. \flag=0 so flush routine closes B18B 98 TYA . \channel number to X B18C AA TAX . B18D D0 03 BNE &B192 .. \if channel number =0 B18F 4C 18 98 JMP &9818 L.. \then close all channels &exit B192 20 03 98 JSR &9803 .. \else set up for channel X B195 4C 15 98 JMP &9815 L.. \close channel and exit. B198 48 PHA H \save file open mode B199 20 33 B3 JSR &B333 3. \GSINIT string in XY B19C 20 12 93 JSR &9312 .. \get file spec B19F 68 PLA h \restore mode B1A0 20 1E 98 JSR &981E .. \open file B1A3 8A TXA . \return channel in A B1A4 BA TSX . B1A5 9D 05 01 STA &0105,X ... \and exit. B1A8 60 RTS ` B1A9 20 18 B7 JSR &B718 .. \OSFSC B1AC C9 00 CMP #&00 00000000 \if A=0 then *OPT B1AE F0 03 BEQ &B1B3 .. B1B0 4C 90 B2 JMP &B290 L.. B1B3 E0 01 CPX #&01 00000001 \*OPT B1B5 F0 0E BEQ &B1C5 .. B1B7 B0 10 BCS &B1C9 .. B1B9 A9 00 LDA #&00 00000000 \*OPT 0 B1BB A2 06 LDX #&06 00000110 \Clear options 6..9 B1BD 9D 7E 10 STA &107E,X .~. B1C0 E8 INX . B1C1 E0 0A CPX #&0A 00001010 B1C3 D0 F8 BNE &B1BD .. \then fall through: B1C5 8C 0E 10 STY &100E ... \*OPT 1 monitor B1C8 60 RTS ` B1C9 E0 04 CPX #&04 00000100 \bad options 2 or 3 B1CB 90 25 BCC &B1F2 .% B1CD D0 33 BNE &B202 .3 B1CF 20 06 92 JSR &9206 .. \*OPT 4 B1D2 07 ??? . \set boot option B1D3 10 C7 BPL &B19C .. \copy default dir/vol/drive B1D5 00 BRK . \to immediate path B1D6 03 ??? . B1D7 20 00 9B JSR &9B00 .. \softmount and read catalogue B1DA AD 06 0F LDA &0F06 ... \clear boot option bits B1DD 29 CF AND #&CF 11001111 B1DF 8D 06 0F STA &0F06 ... B1E2 98 TYA . \replace them with bits from Y B1E3 29 03 AND #&03 00000011 B1E5 0A ASL A . B1E6 0A ASL A . B1E7 0A ASL A . B1E8 0A ASL A . B1E9 0D 06 0F ORA &0F06 ... B1EC 8D 06 0F STA &0F06 ... \write catalogue and exit. B1EF 4C 03 9B JMP &9B03 L.. B1F2 20 18 90 JSR &9018 .. \Give "Bad option" error B1F5 0A ASL A . B1F6 CB ??? . B1F7 42 ??? B B1F8 61 64 ADC (&64,X) ad B1FA 20 6F 70 JSR &706F op B1FD 74 ??? t B1FE 69 6F ADC #&6F 01101111 B200 6E 00 E0 ROR &E000 n.. B203 05 D0 ORA &D0 .. B205 7E AD 0E ROR &0EAD,X ~.. \*OPT 5 display options B208 10 20 BPL &B22A . \LDA &100E get option 1 B20A 18 CLC . \JSR &9018 B20B 90 82 BCC &B18F .. \print "*opt 1 monitor = "+n B20D 2A ROL A * B20E 6F ??? o B20F 70 74 BVS &B285 pt B211 20 31 20 JSR &2031 1 B214 6D 6F 6E ADC &6E6F mon B217 69 74 ADC #&74 01110100 B219 6F ??? o B21A 72 ??? r B21B 20 3D 20 JSR &203D = B21E 00 BRK . B21F AD 84 10 LDA &1084 ... \get option 6 B222 20 18 90 JSR &9018 .. \print "*opt 6 density = "+n B225 82 ??? . B226 2A ROL A * B227 6F ??? o B228 70 74 BVS &B29E pt B22A 20 36 20 JSR &2036 6 B22D 64 ??? d B22E 65 6E ADC &6E en B230 73 ??? s B231 69 74 ADC #&74 01110100 B233 79 20 3D ADC &3D20,Y y = B236 20 00 AD JSR &AD00 .. \LDA &1085 get option 7 B239 85 10 STA &10 .. B23B 20 18 90 JSR &9018 .. \print "*opt 7 volumes = "+n B23E 82 ??? . B23F 2A ROL A * B240 6F ??? o B241 70 74 BVS &B2B7 pt B243 20 37 20 JSR &2037 7 B246 76 6F ROR &6F,X vo B248 6C 75 6D JMP (&6D75) lum B24B 65 73 ADC &73 es B24D 20 3D 20 JSR &203D = B250 00 BRK . B251 AD 86 10 LDA &1086 ... \get option 8 B254 20 18 90 JSR &9018 .. \print "*opt 8 tracks = "+n B257 82 ??? . B258 2A ROL A * B259 6F ??? o B25A 70 74 BVS &B2D0 pt B25C 20 38 20 JSR &2038 8 B25F 74 ??? t B260 72 ??? r B261 61 63 ADC (&63,X) ac B263 6B ??? k B264 73 ??? s B265 20 20 3D JSR &3D20 = B268 20 00 AD JSR &AD00 .. \LDA &1087 B26B 87 ??? . \print "*opt 9 saverom = "+n B26C 10 20 BPL &B28E . B26E 18 CLC . B26F 90 82 BCC &B1F3 .. B271 2A ROL A * B272 6F ??? o B273 70 74 BVS &B2E9 pt B275 20 39 20 JSR &2039 9 B278 73 ??? s B279 61 76 ADC (&76,X) av B27B 65 72 ADC &72 er B27D 6F ??? o B27E 6D 20 3D ADC &3D20 m = B281 20 00 60 JSR &6000 .` B284 E0 0A CPX #&0A 00001010 \reject options >=10 B286 90 03 BCC &B28B .. B288 4C F2 B1 JMP &B1F2 L.. B28B 98 TYA . \*OPT 6..9 B28C 9D 7E 10 STA &107E,X .~. \set EDOS options B28F 60 RTS ` B290 C9 02 CMP #&02 00000010 B292 F0 1E BEQ &B2B2 .. B294 B0 0D BCS &B2A3 .. B296 20 03 98 JSR &9803 .. \OSFSC 1 B299 20 0C B4 JSR &B40C .. \Test EOF (don't warn) B29C A2 00 LDX #&00 00000000 B29E 90 02 BCC &B2A2 .. B2A0 A2 FF LDX #&FF 11111111 \C=1, X=&FF if EOF B2A2 60 RTS ` B2A3 C9 04 CMP #&04 00000100 B2A5 F0 0B BEQ &B2B2 .. B2A7 B0 6A BCS &B313 .j B2A9 20 33 B3 JSR &B333 3. \OSFSC 3. Unknown OSCLI offered B2AC 20 00 81 JSR &8100 .. \to current FS. If not built in B2AF 90 04 BCC &B2B5 .. \to EDOS try to *RUN it. B2B1 60 RTS ` B2B2 20 33 B3 JSR &B333 3. \OSFSC 2 & 4. *RUN, */ B2B5 20 12 93 JSR &9312 .. \string init, expand path at XY B2B8 20 00 9B JSR &9B00 .. \softmount & load catalogue B2BB 20 09 A5 JSR &A509 .. \find file B2BE 90 21 BCC &B2E1 .! \if not found B2C0 20 06 92 JSR &9206 .. \replace path with library's B2C3 0A ASL A . B2C4 10 C7 BPL &B28D .. B2C6 00 BRK . B2C7 03 ??? . B2C8 20 00 9B JSR &9B00 .. \load library catalogue B2CB 20 09 A5 JSR &A509 .. \find file B2CE 90 11 BCC &B2E1 .. \if not found: B2D0 20 18 90 JSR &9018 .. \Print "Bad Command" error B2D3 0A ASL A . B2D4 FE 42 61 INC &6142,X .Ba B2D7 64 ??? d B2D8 20 63 6F JSR &6F63 co B2DB 6D 6D 61 ADC &616D mma B2DE 6E 64 00 ROR &0064 nd. B2E1 98 TYA . \else store pointer B2E2 18 CLC . \to arguments B2E3 65 F2 ADC &F2 e. B2E5 8D 82 10 STA &1082 ... B2E8 A5 F3 LDA &F3 .. B2EA 69 00 ADC #&00 00000000 B2EC 8D 83 10 STA &1083 ... B2EF 20 03 A6 JSR &A603 .. \unpack fields from catalogue B2F2 20 3D B3 JSR &B33D =. \load file B2F5 AD 4D 10 LDA &104D .M. \if execution address B2F8 49 03 EOR #&03 00000011 \has high bits clear B2FA 2D 7A 02 AND &027A -z. \and Tube is present B2FD D0 0B BNE &B30A .. \then call address over Tube B2FF 20 06 92 JSR &9206 .. \else copy exec to zero page B302 4B ??? K B303 10 BE BPL &B2C3 .. B305 00 BRK . B306 02 ??? . B307 6C BE 00 JMP (&00BE) l.. \and call it B30A A2 4B LDX #&4B 01001011 \Do a *GO to the exec address B30C A0 10 LDY #&10 00010000 B30E A9 04 LDA #&04 00000100 B310 4C 06 A0 JMP &A006 L.. B313 C9 06 CMP #&06 00000110 B315 F0 08 BEQ &B31F .. B317 B0 0B BCS &B324 .. B319 20 33 B3 JSR &B333 3. \OSFSC 5 *CAT. string init. B31C 4C 03 86 JMP &8603 L.. B31F A9 77 LDA #&77 01110111 \OSFSC 6 FS about to change. B321 4C F4 FF JMP &FFF4 L.. \close *SPOOL and *EXEC files B324 C9 08 CMP #&08 00001000 B326 F0 07 BEQ &B32F .. B328 B0 08 BCS &B332 .. B32A A2 11 LDX #&11 00010001 \OSFSC 7 Return range B32C A0 15 LDY #&15 00010101 \of valid file handles. B32E 60 RTS ` B32F 4E 0F 10 LSR &100F N.. \OSFSC 8 *command issued B332 60 RTS ` \Clear *ENABLE status B333 86 F2 STX &F2 .. \String init. B335 84 F3 STY &F3 .. \store XY in GS pointer B337 A0 00 LDY #&00 00000000 B339 18 CLC . \jump to GSINIT B33A 4C C2 FF JMP &FFC2 L.. B33D 20 70 B3 JSR &B370 p. \Load file. copy addr to O7F B340 A9 13 LDA #&13 00010011 \=8271 read command B342 8D 16 10 STA &1016 ... \store command in block B345 AE 51 10 LDX &1051 .Q. \absolute start sector in XY B348 AC 52 10 LDY &1052 .R. B34B AD 53 10 LDA &1053 .S. \sector length (mod 256) in A B34E 4C 06 9B JMP &9B06 L.. \do LBA transfer and exit B351 48 PHA H \Copy 32 bit to 18 bit addr B352 20 09 92 JSR &9209 .. \from 1000,X to 1000,Y B355 00 BRK . B356 10 00 BPL &B358 .. B358 10 02 BPL &B35C .. B35A 21 BD AND (&BD,X) !. \do AND high bytes of source B35C 02 ??? . \together B35D 10 3D BPL &B39C .= B35F 03 ??? . B360 10 C9 BPL &B32B .. \are they &FFFF? B362 FF ??? . B363 F0 04 BEQ &B369 .. B365 A9 00 LDA #&00 00000000 \if not clear high bits B367 F0 02 BEQ &B36B .. B369 A9 03 LDA #&03 00000011 \else set high bits B36B 99 02 10 STA &1002,Y ... \and store with address B36E 68 PLA h B36F 60 RTS ` B370 A2 48 LDX #&48 01001000 \Copy load address B372 A0 11 LDY #&11 00010001 \to OSWORD &7F block: B374 48 PHA H \Copy 18 bit to 32 bit addr B375 20 09 92 JSR &9209 .. \from 1000,X to 1000,Y B378 00 BRK . B379 10 00 BPL &B37B .. B37B 10 02 BPL &B37F .. B37D 21 BD AND (&BD,X) !. \are both high bits set? B37F 02 ??? . B380 10 29 BPL &B3AB .) B382 03 ??? . B383 C9 03 CMP #&03 00000011 B385 F0 04 BEQ &B38B .. B387 A9 00 LDA #&00 00000000 \if not high bytes = 0000 B389 F0 02 BEQ &B38D .. B38B A9 FF LDA #&FF 11111111 \else high bytes = FFFF B38D 99 02 10 STA &1002,Y ... B390 99 03 10 STA &1003,Y ... B393 68 PLA h B394 60 RTS ` \EDOSPAT extensions, block 4 B395 A9 02 LDA #&02 00000010 \Return binary 2 plus default B397 20 E5 B6 JSR &B6E5 .. \or library drive number B39A B9 09 10 LDA &1009,Y ... \to OSGBPB data address B39D 4C E5 B6 JMP &B6E5 L.. \(so volume letter can be added) B3A0 2C 8F 02 BIT &028F ,.. \Jump to disc operation busywait B3A3 10 03 BPL &B3A8 .. B3A5 4C 20 0D JMP &0D20 L . B3A8 4C A5 B3 JMP &B3A5 L.. B3AB 00 BRK . B3AC 00 BRK . B3AD 00 BRK . B3AE 00 BRK . B3AF 00 BRK . B3B0 00 BRK . B3B1 00 BRK . B3B2 29 43 AND #&43 01000011 \Convert DDOS latch to Acorn B3B4 C9 40 CMP #&40 01000000 \mask unused bits, C=1 if DD B3B6 2A ROL A * \A = 2*drive number + density B3B7 29 07 AND #&07 00000111 \mask old density bit B3B9 AA TAX . \use as index B3BA BD BE B3 LDA &B3BE,X ... \look up latch value in table B3BD 60 RTS ` \and exit. B3BE 00 BRK . \Latch value table [0..7] B3BF 40 RTI @ \b2=side, b1=unit, b0=density B3C0 01 41 ORA (&41,X) .A \(b0=1 for double density) B3C2 02 ??? . \Table set to identity for Opus B3C3 42 ??? B \controllers B3C4 03 ??? . B3C5 43 ??? C B3C6 A4 F0 LDY &F0 .. \OSWORD &7D, &7E B3C8 84 BE STY &BE .. \copy OSWORD block pointer B3CA A4 F1 LDY &F1 .. \to scratch space B3CC 84 BF STY &BF .. \as OSWORD &7F will overwrite. B3CE 20 06 92 JSR &9206 .. \copy default dir vol and drive B3D1 07 ??? . \to immediate path B3D2 10 C7 BPL &B39B .. B3D4 00 BRK . B3D5 03 ??? . B3D6 20 00 9B JSR &9B00 .. \softmount and load catalogue B3D9 A0 00 LDY #&00 00000000 \clear Y=0 for later B3DB C9 7E CMP #&7E 01111110 \if command is OSWORD &7D B3DD B0 09 BCS &B3E8 .. B3DF AD 04 0F LDA &0F04 ... \then copy catalogue cycle B3E2 91 BE STA (&BE),Y .. \number to user's block B3E4 98 TYA . \break out of ROM call and exit B3E5 38 SEC 8 B3E6 B0 17 BCS &B3FF .. B3E8 98 TYA . \else OSWORD &7E. B3E9 91 BE STA (&BE),Y .. \low byte of volume size =0 B3EB C8 INY . \increment pointer B3EC AD 07 0F LDA &0F07 ... \next byte = low byte of sector B3EF 91 BE STA (&BE),Y .. \count B3F1 C8 INY . \increment pointer B3F2 AD 06 0F LDA &0F06 ... \mask all but low 3 bits of B3F5 29 07 AND #&07 00000111 \high byte of sector count B3F7 91 BE STA (&BE),Y .. \(volumes <512 KB) and store B3F9 C8 INY . \increment pointer B3FA A9 00 LDA #&00 00000000 \top byte of volume size =0 B3FC 91 BE STA (&BE),Y .. B3FE A8 TAY . \exit C=1 to break ROM call. B3FF 60 RTS ` \EDOS API, part 2: random access I/O B400 4C 0F B4 JMP &B40F L.. \OSBGET B403 4C 1D B4 JMP &B41D L.. \OSBPUT B406 4C 2B B4 JMP &B42B L+. \OSGBPB B409 4C 71 B5 JMP &B571 Lq. \Copy user's OSFILE/GBPB block B40C 4C 82 B5 JMP &B582 L.. \Test EOF (warned flag not set) B40F 20 00 92 JSR &9200 .. \OSBGET B412 20 0C B7 JSR &B70C .. \call monitor B415 98 TYA . B416 AA TAX . B417 20 03 98 JSR &9803 .. \init for file handle B41A 4C 24 B6 JMP &B624 L$. \get byte and exit B41D 20 00 92 JSR &9200 .. \OSBPUT B420 20 0F B7 JSR &B70F .. \call monitor B423 98 TYA . B424 AA TAX . B425 20 AF B6 JSR &B6AF .. \check file is writeable B428 4C 4E B6 JMP &B64E LN. \put byte and exit B42B 20 00 92 JSR &9200 .. \OSGBPB B42E 20 12 B7 JSR &B712 .. \call OSGBPB monitor B431 20 09 B4 JSR &B409 .. \copy user's OSGBPB block B434 AA TAX . \Validate call number B435 CA DEX . B436 E0 08 CPX #&08 00001000 B438 90 01 BCC &B43B .. \If invalid exit with C=1 B43A 60 RTS ` \how convenient B43B BD 69 B5 LDA &B569,X .i. \get microcode from table B43E 85 CD STA &CD .. \store in temp B440 20 06 92 JSR &9206 .. \copy low word of user address B443 71 10 ADC (&10),Y q. \to workspace B445 BC 00 02 LDY &0200,X ... B448 29 80 AND #&80 10000000 \take high bit of microcode B44A 8D 3A 10 STA &103A .:. \1=read, store in Tube flag B44D A9 00 LDA #&00 00000000 \have A=0 returned on exit B44F BA TSX . \to indicate the command is B450 9D 05 01 STA &0105,X ... \implemented B453 AD 73 10 LDA &1073 .s. \test high word of address B456 2D 74 10 AND &1074 -t. B459 49 FF EOR #&FF 11111111 \A=0 if in I/O space B45B 2D 7A 02 AND &027A -z. \A=0 if Tube absent too B45E F0 0D BEQ &B46D .. \in which case skip forward B460 AD 3A 10 LDA &103A .:. \else a Tube transfer. B463 18 CLC . \set A=0 if writing to disc, B464 2A ROL A * \A=1 if reading from disc B465 2A ROL A * B466 A2 71 LDX #&71 01110001 \point XY to the full address B468 A0 10 LDY #&10 00010000 B46A 20 06 A0 JSR &A006 .. \open Tube data channel. B46D 46 CD LSR &CD F. \now sample microcode B46F 90 72 BCC &B4E3 .r \to select actions: B471 20 06 92 JSR &9206 .. \.....1 Get title / get cat B474 07 ??? . \copy default to immediate path B475 10 C7 BPL &B43E .. B477 00 BRK . B478 03 ??? . B479 20 00 9B JSR &9B00 .. \softmount and load catalogue. B47C 46 CD LSR &CD F. B47E 90 27 BCC &B4A7 .' B480 A0 00 LDY #&00 00000000 \....11 Get title B482 A9 0C LDA #&0C 00001100 \clear offset; length byte = 12 B484 20 E5 B6 JSR &B6E5 .. \send byte in A to user B487 C8 INY . \send first 8 bytes of sector 0 B488 B9 FF 0D LDA &0DFF,Y ... \(with Y = 1 to 8) B48B C0 09 CPY #&09 00001001 B48D D0 F5 BNE &B484 .. B48F B9 F7 0E LDA &0EF7,Y ... \send first 4 bytes of sector 1 B492 20 E5 B6 JSR &B6E5 .. \(with Y = 9 to 12) B495 C8 INY . B496 C0 0D CPY #&0D 00001101 B498 D0 F5 BNE &B48F .. B49A 20 09 96 JSR &9609 .. \get boot option B49D 20 E5 B6 JSR &B6E5 .. \send it B4A0 A5 C9 LDA &C9 .. \get immed (=default) drive B4A2 29 03 AND #&03 00000011 \make binary, send and exit. B4A4 10 58 BPL &B4FE .X B4A6 00 BRK . B4A7 AD 04 0F LDA &0F04 ... \....01 Get catalogue B4AA 8D 70 10 STA &1070 .p. \get catalogue cycle number B4AD AD 05 0F LDA &0F05 ... \store in file handle byte of B4B0 38 SEC 8 \OSGBPB block. B4B1 ED 79 10 SBC &1079 .y. \files * 8 - OSGBPB pointer B4B4 85 CC STA &CC .. \=starting catalogue pointer B4B6 20 06 A5 JSR &A506 .. \select next file in catalogue B4B9 B0 1C BCS &B4D7 .. \if no more files then finish B4BB 20 1E A5 JSR &A51E .. \else compare directory letters B4BE D0 F6 BNE &B4B6 .. \if unequal skip to next file B4C0 20 03 A6 JSR &A603 .. \else unpack fields from cat B4C3 A0 00 LDY #&00 00000000 \clear offset B4C5 A9 07 LDA #&07 00000111 \set length byte = 7 B4C7 20 E5 B6 JSR &B6E5 .. \send byte in A to user B4CA B9 40 10 LDA &1040,Y .@. \send 7 bytes of filename proper B4CD C8 INY . \(with Y = 1 to 7) B4CE C0 08 CPY #&08 00001000 B4D0 D0 F5 BNE &B4C7 .. B4D2 20 C8 B6 JSR &B6C8 .. \decrement number of entries B4D5 D0 DF BNE &B4B6 .. \remaining to be transferred B4D7 AD 05 0F LDA &0F05 ... \if more then loop B4DA 38 SEC 8 \else files * 8 - final cat ptr B4DB E5 CC SBC &CC .. \=new OSGBPB pointer B4DD 8D 79 10 STA &1079 .y. \store in OSGBPB block & finish. B4E0 4C 4C B5 JMP &B54C LL. B4E3 46 CD LSR &CD F. \.....0 B4E5 90 1D BCC &B504 .. B4E7 A0 00 LDY #&00 00000000 \....10 Get default/get library B4E9 46 CD LSR &CD F. \Y=0 to point to default path B4EB 90 02 BCC &B4EF .. B4ED A0 03 LDY #&03 00000011 \...110 Get library. Y=3 B4EF 20 95 B3 JSR &B395 .. \...x10 Get default/get library B4F2 B9 08 10 LDA &1008,Y ... \send binary 2 + drive number B4F5 20 E5 B6 JSR &B6E5 .. \send volume letter B4F8 20 E3 B6 JSR &B6E3 .. \send binary 1 B4FB B9 07 10 LDA &1007,Y ... \get directory letter B4FE 20 E5 B6 JSR &B6E5 .. \send it and finish B501 4C 60 B5 JMP &B560 L`. B504 AE 70 10 LDX &1070 .p. \....00 Read/write. get handle B507 46 CD LSR &CD F. B509 90 03 BCC &B50E .. B50B 20 AF B6 JSR &B6AF .. \...100 Write. check writeable B50E 46 CD LSR &CD F. \...x00 Read/write B510 90 03 BCC &B515 .. B512 20 03 98 JSR &9803 .. \..1x00 Read. check file is open B515 46 CD LSR &CD F. \..xx00 Read/write B517 90 09 BCC &B522 .. B519 20 09 92 JSR &9209 .. \.1xx00 Set PTR B51C 79 10 9D ADC &9D10,Y y.. B51F 10 03 BPL &B524 .. B521 01 20 ORA (&20,X) . \.xxx00 Read/write. compare L=0 B523 D6 B6 DEC &B6,X .. B525 F0 1C BEQ &B543 .. \if no bytes to transfer, finish B527 20 04 AF JSR &AF04 .. \else do transfer with sector op B52A 4C 43 B5 JMP &B543 LC. \and finish B52F 46 CD LSR &CD F. \take next bit of microcode B531 90 05 BCC &B538 .. \if clear C=0 on exit B533 20 D6 B6 JSR &B6D6 .. \else test L B536 C9 01 CMP #&01 00000001 \C=1 if L>0 B538 08 PHP . \save status B539 2C 3A 10 BIT &103A ,:. \test transfer flag B53C 50 03 BVC &B541 P. \if a Tube transfer B53E 20 0C A0 JSR &A00C .. \then close the Tube channel. B541 28 PLP ( \restore status B542 60 RTS ` \and return C B543 20 09 92 JSR &9209 .. \Read/write finished. B546 9D 10 79 STA &7910,X ..y \copy PTR to OSGBPB block B549 10 03 BPL &B54E .. B54B 10 20 BPL &B56D . \copy address to OSGBPB block B54D 06 92 ASL &92 .. B54F BC 00 71 LDY &7100,X ..q B552 10 02 BPL &B556 .. B554 A0 00 LDY #&00 00000000 \copy OSGBPB block to user's B556 B9 70 10 LDA &1070,Y .p. \block B559 91 BE STA (&BE),Y .. B55B C8 INY . B55C C0 0D CPY #&0D 00001101 B55E D0 F6 BNE &B556 .. B560 4C 2F B5 JMP &B52F L/. \go to set C correctly and exit. B569 34 ??? 4 \OSGBPB microcode table 1..8 B56A 24 B8 BIT &B8 $. B56C A8 TAY . B56D 83 ??? . B56E 82 ??? . B56F 86 85 STX &85 .. B571 48 PHA H \Copy user's OSFILE/GBPB block B572 86 BE STX &BE .. \to workspace at &1070..81 B574 84 BF STY &BF .. B576 A0 11 LDY #&11 00010001 B578 B1 BE LDA (&BE),Y .. B57A 99 70 10 STA &1070,Y .p. B57D 88 DEY . B57E 10 F8 BPL &B578 .. B580 68 PLA h B581 60 RTS ` B582 B9 9D 10 LDA &109D,Y ... \Test EOF (warned flag not set) B585 38 SEC 8 \compare PTR - EXT, channel in Y B586 F9 9A 10 SBC &109A,Y ... \return C=1 if EOF B589 B9 9E 10 LDA &109E,Y ... B58C F9 9B 10 SBC &109B,Y ... B58F B9 9F 10 LDA &109F,Y ... B592 F9 9C 10 SBC &109C,Y ... B595 60 RTS ` B596 B9 88 10 LDA &1088,Y ... \Increment PTR. B599 29 FE AND #&FE 11111110 \invoked by BGET/BPUT/GBPB. B59B 99 88 10 STA &1088,Y ... \note AXY not saved! B59E 18 CLC . \clear warning-given flag B59F B9 94 10 LDA &1094,Y ... \get start sector of file B5A2 79 9E 10 ADC &109E,Y y.. \add middle & high bytes PTR B5A5 85 BA STA &BA .. \store &BA,&BB: target page B5A7 B9 95 10 LDA &1095,Y ... B5AA 79 9F 10 ADC &109F,Y y.. B5AD 85 BB STA &BB .. B5AF B9 89 10 LDA &1089,Y ... \is page empty? B5B2 F0 11 BEQ &B5C5 .. \if so go to set target B5B4 A5 BA LDA &BA .. \else get target page B5B6 D9 96 10 CMP &1096,Y ... \compare with current page B5B9 D0 07 BNE &B5C2 .. B5BB A5 BB LDA &BB .. B5BD D9 97 10 CMP &1097,Y ... B5C0 F0 24 BEQ &B5E6 .$ \if same don't touch page/flag B5C2 20 0F 98 JSR &980F .. \if different flush page B5C5 A5 BA LDA &BA .. \set target as current page B5C7 99 96 10 STA &1096,Y ... B5CA A5 BB LDA &BB .. B5CC 99 97 10 STA &1097,Y ... B5CF 38 SEC 8 B5D0 A9 00 LDA #&00 00000000 \supposing LSB of PTR = 0, B5D2 20 85 B5 JSR &B585 .. \would we be at end-of-file? B5D5 B0 0C BCS &B5E3 .. B5D7 A9 13 LDA #&13 00010011 \if not read current page B5D9 20 12 98 JSR &9812 .. B5DC A9 01 LDA #&01 00000001 \mark as clean B5DE 99 89 10 STA &1089,Y ... B5E1 D0 03 BNE &B5E6 .. B5E3 20 15 B6 JSR &B615 .. \else definite EOF, clear page B5E6 B9 9D 10 LDA &109D,Y ... \get PTR low byte B5E9 48 PHA H \push it B5EA 20 0C B4 JSR &B40C .. \are we really at EOF? B5ED 08 PHP . \remember for later B5EE 18 CLC . B5EF B9 9D 10 LDA &109D,Y ... \increment PTR nevertheless B5F2 69 01 ADC #&01 00000001 B5F4 99 9D 10 STA &109D,Y ... B5F7 B9 9E 10 LDA &109E,Y ... B5FA 69 00 ADC #&00 00000000 B5FC 99 9E 10 STA &109E,Y ... B5FF B9 9F 10 LDA &109F,Y ... B602 69 00 ADC #&00 00000000 B604 99 9F 10 STA &109F,Y ... B607 28 PLP ( B608 90 09 BCC &B613 .. \if we weren't at EOF then exit B60A 20 09 92 JSR &9209 .. \else extend file B60D 9D 10 9A STA &9A10,X ... \by copying PTR to EXT B610 10 03 BPL &B615 .. \(we're still at EOF) B612 11 68 ORA (&68),Y .h \return A=offset of byte in buf B614 60 RTS ` B615 20 00 92 JSR &9200 .. \Clear page &CA,CB points to B618 A9 00 LDA #&00 00000000 B61A A8 TAY . B61B 91 CA STA (&CA),Y .. B61D C8 INY . B61E D0 FB BNE &B61B .. B620 60 RTS ` B621 20 00 92 JSR &9200 .. \Get byte B624 20 0C B4 JSR &B40C .. \test for end-of-file B627 B0 0C BCS &B635 .. \if so set warned and exit C=1 B629 20 96 B5 JSR &B596 .. \else increment PTR B62C A8 TAY . B62D BA TSX . B62E B1 CA LDA (&CA),Y .. \get byte that PTR had PTd to B630 9D 05 01 STA &0105,X ... \return it in A B633 18 CLC . \exit C=0 B634 60 RTS ` B635 B9 88 10 LDA &1088,Y ... \We've read past end-of-file. B638 6A ROR A j \test warning-given flag B639 B0 07 BCS &B642 .. \if set give EOF error B63B 38 SEC 8 \else set warning-given B63C 2A ROL A * \flag and return C=1 B63D 99 88 10 STA &1088,Y ... B640 38 SEC 8 B641 60 RTS ` B642 20 18 90 JSR &9018 .. B645 0A ASL A . B646 DF ??? . B647 45 4F EOR &4F EO B649 46 00 LSR &00 F. B64B 20 00 92 JSR &9200 .. \Put byte to file B64E 38 SEC 8 B64F B9 9E 10 LDA &109E,Y ... \compare PTR high bytes B652 F9 98 10 SBC &1098,Y ... \ - allocated length B655 B9 9F 10 LDA &109F,Y ... B658 F9 99 10 SBC &1099,Y ... B65B 90 40 BCC &B69D .@ \if PTR1 see if it is <6 B861 B0 22 BCS &B885 ." B863 8A TXA . else print x=X, y=Y, exit B864 20 18 90 JSR &9018 .. B867 40 RTI @ B868 20 78 3D JSR &3D78 x= B86B 00 BRK . B86C 98 TYA . B86D 20 18 90 JSR &9018 .. B870 40 RTI @ B871 20 79 3D JSR &3D79 y= B874 00 BRK . B875 4C AB B8 JMP &B8AB L.. B878 8A TXA . \transfer X to A B879 20 18 90 JSR &9018 .. \print " h=" plus hex byte in A B87C 40 RTI @ \then exit monitor B87D 20 68 3D JSR &3D68 h= B880 00 BRK . B881 4C AB B8 JMP &B8AB L.. B884 60 RTS ` B885 C9 06 CMP #&06 00000110 \if type>=6 exit, else: B887 B0 22 BCS &B8AB ." B889 20 18 90 JSR &9018 .. \Dump string value and exit mon B88C 00 BRK . B88D 20 24 3D JSR &3D24 $= B890 00 BRK . B891 20 1F B9 JSR &B91F .. B894 C9 0D CMP #&0D 00001101 B896 F0 13 BEQ &B8AB .. B898 20 00 90 JSR &9000 .. B89B 4C 91 B8 JMP &B891 L.. B89E 20 00 92 JSR &9200 .. \File access monitor B8A1 AD 0E 10 LDA &100E ... \Print *INFO if b1 set. B8A4 29 01 AND #&01 00000001 B8A6 F0 DC BEQ &B884 .. B8A8 20 06 A4 JSR &A406 .. B8AB AD 0E 10 LDA &100E ... \Exit monitor. B8AE 10 09 BPL &B8B9 .. \get *OPT 1 monitor byte B8B0 CA DEX . \pause if b7=1 B8B1 D0 FD BNE &B8B0 .. B8B3 88 DEY . B8B4 D0 FA BNE &B8B0 .. B8B6 4A LSR A J B8B7 D0 F7 BNE &B8B0 .. \print newline & exit B8B9 4C E7 FF JMP &FFE7 L.. B8BC 48 PHA H \test *OPT 1 monitor bit 2 B8BD AD 0E 10 LDA &100E ... B8C0 4A LSR A J B8C1 4A LSR A J B8C2 4A LSR A J B8C3 68 PLA h B8C4 90 1E BCC &B8E4 .. \no message if clear B8C6 20 18 90 JSR &9018 .. \Start monitor message B8C9 00 BRK . B8CA 45 44 EOR &44 ED B8CC 4F ??? O B8CD 53 ??? S B8CE 3A ??? : B8CF 20 00 48 JSR &4800 .H \set up LDA instruction B8D2 A9 AD LDA #&AD 10101101 \in stack page B8D4 8D 20 01 STA &0120 . . \to load from address in XY B8D7 8E 21 01 STX &0121 .!. B8DA 8C 22 01 STY &0122 .". B8DD A9 60 LDA #&60 01100000 \follow with RTS B8DF 8D 23 01 STA &0123 .#. B8E2 68 PLA h B8E3 38 SEC 8 \return C=1 since mon bit set B8E4 60 RTS ` B8E5 20 14 B9 JSR &B914 .. \Dump 8-bit value. B8E8 4C 10 B9 JMP &B910 L.. B8EB 20 14 B9 JSR &B914 .. \Dump 16-bit value. B8EE 48 PHA H \print " n=", push low byte B8EF 20 1F B9 JSR &B91F .. \get high byte B8F2 4C 0C B9 JMP &B90C L.. \print hex word B8F5 20 14 B9 JSR &B914 .. \Dump 32-bit value. B8F8 48 PHA H \print " n=", push low byte B8F9 20 1F B9 JSR &B91F .. \push low middle byte B8FC 48 PHA H B8FD 20 1F B9 JSR &B91F .. \push high middle byte B900 48 PHA H B901 20 1F B9 JSR &B91F .. \get high byte. Fall though: B904 20 10 B9 JSR &B910 .. \Print 32-bit hex word (JMP) B907 68 PLA h \High byte in A, other bytes B908 20 10 B9 JSR &B910 .. \on stack, pushed in ascending B90B 68 PLA h \order. Fall through: B90C 20 10 B9 JSR &B910 .. \Print 16-bit hex word (JMP) B90F 68 PLA h \high byte in A, low byte B910 38 SEC 8 \on stack. print hex byte B911 4C 0F 90 JMP &900F L.. B914 20 03 90 JSR &9003 .. \Print " n=" & get byte value B917 20 00 90 JSR &9000 .. \print character in A B91A A9 3D LDA #&3D 00111101 \print = sign B91C 20 00 90 JSR &9000 .. \Fall through: B91F 20 20 01 JSR &0120 . \call LDA in stack page B922 EE 21 01 INC &0121 .!. \increment LDA address B925 D0 03 BNE &B92A .. B927 EE 22 01 INC &0122 .". B92A 60 RTS ` \EDOSPAT extensions, block 5 B931 C9 7D CMP #&7D 01111101 \compare call number with &7D B933 90 22 BCC &B957 ." \if not ours then exit C=0 B935 08 PHP . \else save interrupt state B936 78 SEI x \interrupts off (temp memory) B937 48 PHA H \save call number B938 A5 A8 LDA &A8 .. \localise private page pointer B93A 48 PHA H \(as zero page may not be ours) B93B A5 A9 LDA &A9 .. B93D 48 PHA H B93E 20 3A 97 JSR &973A :. \test flag in private page B941 49 41 EOR #&41 01000001 \A=&FF if the workspace is ours B943 AA TAX . \save the result B944 68 PLA h \restore private page pointer B945 85 A9 STA &A9 .. B947 68 PLA h B948 85 A8 STA &A8 .. B94A 68 PLA h \restore call number B94B 28 PLP ( \restore interrupt state B94C E0 FF CPX #&FF 11111111 \is absolute workspace ours? B94E B0 07 BCS &B957 .. \if so then exit C=1 (from CPX) B950 2C 8F 02 BIT &028F ,.. \else if keyboard link 1 unmade B953 30 02 BMI &B957 0. \then exit C=0 (proper behav.) B955 C9 7F CMP #&7F 01111111 \else C=0 vol query/1 sector op B957 60 RTS ` B958 D8 CLD . \OSARGS wrapper B959 20 1A B1 JSR &B11A .. \clear decimal, call EDOS routn B95C 38 SEC 8 \set carry for return and SBC B95D 08 PHP . \save interrupt status B95E 78 SEI x \interrupts off (temp memory) B95F 85 CD STA &CD .. \store call number B961 E9 FF SBC #&FF 11111111 \map calls FF..03 to 00..04 B963 C0 01 CPY #&01 00000001 \set C=1 if Y>0 B965 2A ROL A * \double call number and add C B966 B0 0F BCS &B977 .. \if call was 7F..FE exit C=1 B968 C9 09 CMP #&09 00001001 B96A B0 0B BCS &B977 .. \if call was 04..7E exit C=1 B96C 86 CD STX &CD .. \else store zero page pointer B96E AA TAX . \transfer to X as index B96F BD 7B B9 LDA &B97B,X .{. \look up return value in table B972 A6 CD LDX &CD .. \restore zero page pointer B974 28 PLP ( \restore interrupt status B975 18 CLC . \set C=0 as all was well, exit B976 60 RTS ` B977 A5 CD LDA &CD .. \restore call number B979 28 PLP ( \restore interrupt state B97A 60 RTS ` \exit C=1, call not implemented B97B 00 BRK . \Return values for A=&FF to &03 B97C 00 BRK . \in pairs Y=0, then Y>0 B97D 04 ??? . B97E 00 BRK . B97F DC ??? . B980 FF ??? . B981 01 00 ORA (&00,X) .. B983 FF ??? . B984 2C 8F 02 BIT &028F ,.. \FDC register access emulators. B987 10 06 BPL &B98F .. \Load track register B989 AD 81 FE LDA &FE81 ... B98C 49 FF EOR #&FF 11111111 B98E 60 RTS ` B98F 4C 89 B9 JMP &B989 L.. B992 2C 8F 02 BIT &028F ,.. \Load sector register B995 10 06 BPL &B99D .. B997 AD 82 FE LDA &FE82 ... B99A 49 FF EOR #&FF 11111111 B99C 60 RTS ` B99D 4C 97 B9 JMP &B997 L.. B9A0 2C 8F 02 BIT &028F ,.. \Store latch B9A3 10 07 BPL &B9AC .. B9A5 49 00 EOR #&00 00000000 \a JSR &B3B2 would go here B9A7 EA NOP . B9A8 8D 84 FE STA &FE84 ... B9AB 60 RTS ` B9AC 4C A5 B9 JMP &B9A5 L.. B9AF 00 BRK . B9B0 00 BRK . B9B1 00 BRK . B9B2 2C 8F 02 BIT &028F ,.. \Store command register B9B5 10 06 BPL &B9BD .. B9B7 49 FF EOR #&FF 11111111 B9B9 8D 80 FE STA &FE80 ... B9BC 60 RTS ` B9BD 4C B7 B9 JMP &B9B7 L.. B9C0 2C 8F 02 BIT &028F ,.. \Store track register B9C3 10 06 BPL &B9CB .. B9C5 49 FF EOR #&FF 11111111 B9C7 8D 81 FE STA &FE81 ... B9CA 60 RTS ` B9CB 4C C5 B9 JMP &B9C5 L.. B9CE 2C 8F 02 BIT &028F ,.. \Store sector register B9D1 10 06 BPL &B9D9 .. B9D3 49 FF EOR #&FF 11111111 B9D5 8D 82 FE STA &FE82 ... B9D8 60 RTS ` B9D9 4C D3 B9 JMP &B9D3 L.. B9DC 2C 8F 02 BIT &028F ,.. \Store data register B9DF 10 06 BPL &B9E7 .. B9E1 49 FF EOR #&FF 11111111 B9E3 8D 83 FE STA &FE83 ... B9E6 60 RTS ` B9E7 4C E1 B9 JMP &B9E1 L.. B9EA 2C 8F 02 BIT &028F ,.. \Increment sector register B9ED 10 04 BPL &B9F3 .. B9EF CE 82 FE DEC &FE82 ... B9F2 60 RTS ` B9F3 4C EF B9 JMP &B9EF L.. B9F6 08 PHP . B9F7 18 CLC . B9F8 69 01 ADC #&01 00000001 B9FA 28 PLP ( B9FB 49 00 EOR #&00 00000000 B9FD 4C D3 B9 JMP &B9D3 L.. \EDOS API, part 3: OSWORD BA00 20 00 92 JSR &9200 .. \OSWORD BA03 18 CLC . \clear carry flag BA04 A5 EF LDA &EF .. \if OSWORD call >=&80 BA06 30 05 BMI &BA0D 0. \then return BA08 20 31 B9 JSR &B931 1. \if <&7D or no wksp then return BA0B B0 01 BCS &BA0E .. \(C=0; passed to lower ROMs) BA0D 60 RTS ` BA0E 58 CLI X BA0F C9 7F CMP #&7F 01111111 \if not &7F (ie &7D or &7E) BA11 F0 03 BEQ &BA16 .. \then process via hook BA13 4C C6 B3 JMP &B3C6 L.. BA16 A0 06 LDY #&06 00000110 \else &7F disc op. BA18 B1 F0 LDA (&F0),Y .. \get command byte BA1A 29 3F AND #&3F 00111111 \mask it BA1C A2 00 LDX #&00 00000000 \search for it in table BA1E DD FD BA CMP &BAFD,X ... BA21 F0 0E BEQ &BA31 .. \if found carry on BA23 48 PHA H \else go to next row BA24 8A TXA . \8 bytes in each row BA25 18 CLC . BA26 69 08 ADC #&08 00001000 BA28 AA TAX . BA29 68 PLA h BA2A E0 70 CPX #&70 01110000 \have we reached end of table? BA2C D0 F0 BNE &BA1E .. \if so unrecognised command BA2E 4C FC BA JMP &BAFC L.. \so quit C=1 (hook) BA31 BD FE BA LDA &BAFE,X ... \get microcode BA34 29 10 AND #&10 00010000 \if b4 set BA36 F0 13 BEQ &BA4B .. BA38 A0 07 LDY #&07 00000111 \then get first 8271 parameter BA3A B1 F0 LDA (&F0),Y .. \(special register number) BA3C C9 05 CMP #&05 00000101 \if none of these values BA3E F0 0B BEQ &BA4B .. BA40 C9 12 CMP #&12 00010010 BA42 F0 07 BEQ &BA4B .. BA44 C9 1A CMP #&1A 00011010 BA46 F0 03 BEQ &BA4B .. \then quit. BA48 4C FC BA JMP &BAFC L.. BA4B 20 00 B7 JSR &B700 .. \call OSWORD monitor BA4E A0 00 LDY #&00 00000000 \get O7F drive number BA50 B1 F0 LDA (&F0),Y .. \if top bit clear BA52 10 01 BPL &BA55 .. \copy it to workspace. BA54 C8 INY . \copy rest of block to worksp. BA55 B1 F0 LDA (&F0),Y .. BA57 99 10 10 STA &1010,Y ... BA5A C8 INY . BA5B C0 0C CPY #&0C 00001100 BA5D D0 F6 BNE &BA55 .. BA5F 20 06 92 JSR &9206 .. \copy address of user O7F block BA62 F0 00 BEQ &BA64 .. \(XY entry values) to workspace BA64 1C ??? . BA65 10 02 BPL &BA69 .. BA67 EA NOP . BA68 EA NOP . BA69 EA NOP . BA6A BD FE BA LDA &BAFE,X ... \get microcode BA6D 29 60 AND #&60 01100000 \if b5 and b6 clear BA6F F0 1A BEQ &BA8B .. \then start O7F command BA71 AD 17 10 LDA &1017 ... \else get track number BA74 20 40 BE JSR &BE40 @. \test if drive double-stepped BA77 90 01 BCC &BA7A .. \if so BA79 0A ASL A . \then double track number. BA7A 20 CF BB JSR &BBCF .. \seek that track BA7D C9 FF CMP #&FF 11111111 \if Escape pressed during seek BA7F D0 03 BNE &BA84 .. BA81 4C 9A BB JMP &BB9A L.. \save status and ack. error. BA84 29 99 AND #&99 10011001 \if { NotReady RecordNotFound BA86 F0 03 BEQ &BA8B .. \CRCError Busy } any are set BA88 4C 6D BB JMP &BB6D Lm. \then finish O7F, else: BA8B BD FE BA LDA &BAFE,X ... \Start O7F command. BA8E 29 20 AND #&20 00100000 \test b5 of microcode BA90 F0 08 BEQ &BA9A .. \if set BA92 20 43 BC JSR &BC43 C. \prepare for read/write BA95 D0 03 BNE &BA9A .. \if no. sectors to transfer =0 BA97 4C 6D BB JMP &BB6D Lm. \then finish O7F, else: BA9A 20 06 92 JSR &9206 .. \Save original transfer address BA9D 11 10 ORA (&10),Y .. \in z.p. BA9F A2 00 LDX #&00 00000000 BAA1 02 ??? . BAA2 A9 00 LDA #&00 00000000 BAA4 8D 65 0D STA &0D65 .e. BAA7 AD 13 10 LDA &1013 ... \test high bits of address BAAA 2D 14 10 AND &1014 -.. BAAD 49 FF EOR #&FF 11111111 \if any are clear BAAF 2D 7A 02 AND &027A -z. \and Tube is present, then: BAB2 F0 1E BEQ &BAD2 .. BAB4 BD FE BA LDA &BAFE,X ... \a Tube transfer. Get microcode BAB7 29 03 AND #&03 00000011 \test two low bits BAB9 F0 06 BEQ &BAC1 .. \if either one is set BABB 20 5B BC JSR &BC5B [. \open channel 3 for data BABE 8D 64 0D STA &0D64 .d. \set flag >0 iff writing to Tube BAC1 BC 01 BB LDY &BB01,X ... \get offset of NMI code BAC4 F0 28 BEQ &BAEE .( \if zero there's no NMI handler BAC6 20 09 92 JSR &9209 .. \Copy NMI handler to &0D00 BAC9 A4 BE LDY &BE .. BACB 00 BRK . BACC 0D 20 10 ORA &1020 . . BACF 4C EE BA JMP &BAEE L.. BAD2 BC FF BA LDY &BAFF,X ... \an I/O transfer. Get NMI BAD5 F0 17 BEQ &BAEE .. \offset, no handler if zero. BAD7 20 09 92 JSR &9209 .. \Copy NMI handler to &0D00 BADA A4 BE LDY &BE .. BADC 00 BRK . BADD 0D 20 10 ORA &1020 . . BAE0 BC 00 BB LDY &BB00,X ... \does NMI take an address? BAE3 F0 09 BEQ &BAEE .. \0=no address / fixed address BAE5 20 09 92 JSR &9209 .. \if so copy O7F address low BAE8 11 10 ORA (&10),Y .. \bytes into NMI handler BAEA FF ??? . \(the address of an LDA/STA.) BAEB 0C ??? . BAEC 02 ??? . BAED 01 BD ORA (&BD,X) .. \get 2793 command BAEF 02 ??? . BAF0 BB ??? . BAF1 49 FF EOR #&FF 11111111 \pre-invert BAF3 A8 TAY . BAF4 BD 04 BB LDA &BB04,X ... \get jump-table address BAF7 48 PHA H \for command routine BAF8 BD 03 BB LDA &BB03,X ... \(minus 1 of course) BAFB 48 PHA H BAFC 60 RTS ` \and jump to the routine. BAFD 36 00 ROL &00,X 6. \OSWORD &7F 8271 command BAFF 00 BRK . \lookup table. BB00 00 BRK . \&36 (Force interrupt) BB01 00 BRK . BB02 D0 4E BNE &BB52 .N BB04 BE 13 E2 LDX &E213,Y ... \&13 Read data BB07 31 10 AND (&10),Y 1. BB09 4D 80 69 EOR &6980 M.i BB0C BC 0B E1 LDY &E10B,X ... \&0B Write data BB0F 01 0B ORA (&0B,X) .. BB11 1D A0 65 ORA &65A0,X ..e BB14 BC 29 40 LDY &4029,X .)@ \&29 Seek BB17 00 BRK . BB18 00 BRK . BB19 00 BRK . BB1A 00 BRK . BB1B BE BC 1F LDX &1FBC,Y ... \&1F Verify data BB1E E0 99 CPX #&99 10011001 BB20 00 BRK . BB21 99 80 65 STA &6580,Y ..e BB24 BC 17 E2 LDY &E217,X ... \&17 Read data & deleted data BB27 31 10 AND (&10),Y 1. BB29 4D 80 65 EOR &6580 M.e BB2C BC 0F E1 LDY &E10F,X ... \&0F Write deleted data BB2F 01 0B ORA (&0B,X) .. BB31 1D A1 65 ORA &65A1,X ..e BB34 BC 1B 62 LDY &621B,X ..b \&1B Read ID BB37 61 14 ADC (&14,X) a. BB39 81 C4 STA (&C4,X) .. BB3B AD BC 23 LDA &23BC ..# \&23 Format track BB3E C1 9D CMP (&9D,X) .. BB40 00 BRK . BB41 9D F4 CF STA &CFF4,X ... BB44 BC 24 41 LDY &4124,X .$A \&24 (Write track) BB47 01 0B ORA (&0B,X) .. BB49 1D F4 A5 ORA &A5F4,X ... BB4C BD 25 42 LDA &4225,X .%B \&25 (Read track) BB4F 31 10 AND (&10),Y 1. BB51 4D E4 A5 EOR &A5E4 M.. BB54 BD 2C 00 LDA &002C,X .,. \&2C Read drive status BB57 00 BRK . BB58 00 BRK . BB59 00 BRK . BB5A 00 BRK . BB5B AB ??? . BB5C BD 3A 10 LDA &103A,X .:. \&3A Write special registers BB5F 00 BRK . BB60 00 BRK . BB61 00 BRK . BB62 00 BRK . BB63 E9 BD SBC #&BD 10111101 BB65 3D 10 00 AND &0010,X =.. \&3D Read special registers BB68 00 BRK . BB69 00 BRK . BB6A 00 BRK . BB6B 11 BE ORA (&BE),Y .. BB6D C9 FF CMP #&FF 11111111 \Finish OSWORD &7F. BB6F F0 15 BEQ &BB86 .. \Bogus status? else 2791 result BB71 29 7C AND #&7C 01111100 \mask off { NotReady Track BB73 F0 11 BEQ &BB86 .. \Index } if other bits then BB75 A2 05 LDX #&05 00000101 \error. search in table BB77 DD C3 BB CMP &BBC3,X ... BB7A F0 07 BEQ &BB83 .. \found. BB7C CA DEX . BB7D 10 F8 BPL &BB77 .. BB7F 09 01 ORA #&01 00000001 \not found. BB81 D0 03 BNE &BB86 .. BB83 BD C9 BB LDA &BBC9,X ... \if found get 8271 equivalent BB86 48 PHA H BB87 AD 64 0D LDA &0D64 .d. \was it a Tube transfer? BB8A F0 03 BEQ &BB8F .. \if so BB8C 20 0C A0 JSR &A00C .. \close Tube data channel. BB8F A2 0B LDX #&0B 00001011 \issue Rom Call &0B, BB91 AC 61 0D LDY &0D61 .a. \release NMI. give our ROM BB94 A9 8F LDA #&8F 10001111 \number as parameter BB96 20 F4 FF JSR &FFF4 .. BB99 68 PLA h BB9A 20 06 92 JSR &9206 .. \copy user's O7F block address BB9D 1C ??? . \to zero page BB9E 10 A0 BPL &BB40 .. BBA0 00 BRK . BBA1 02 ??? . BBA2 48 PHA H BBA3 A0 05 LDY #&05 00000101 \get no. parameters to command BBA5 B1 A0 LDA (&A0),Y .. BBA7 18 CLC . \point to byte after parameters BBA8 69 07 ADC #&07 00000111 BBAA A8 TAY . BBAB 68 PLA h \store O7F result there BBAC 91 A0 STA (&A0),Y .. BBAE EA NOP . BBAF EA NOP . BBB0 EA NOP . BBB1 C9 FF CMP #&FF 11111111 \if bogus status returned BBB3 D0 0C BNE &BBC1 .. BBB5 20 18 90 JSR &9018 .. \give Escape error BBB8 0A ASL A . BBB9 11 45 ORA (&45),Y .E BBBB 73 ??? s BBBC 63 ??? c BBBD 61 70 ADC (&70,X) ap BBBF 65 00 ADC &00 e. BBC1 38 SEC 8 \else end OSWORD & break ROM BBC2 60 RTS ` \call chain. BBC3 04 ??? . \2793 error table 0..5 BBC4 08 PHP . BBC5 10 18 BPL &BBDF .. BBC7 20 40 0A JSR &0A40 @. \8271 equivalent errors BBCA 0E 18 0C ASL &0C18 ... BBCD 20 12 20 JSR &2012 . \Seek command BBD0 00 BRK . \A = track number BBD1 92 ??? . BBD2 48 PHA H BBD3 A2 0C LDX #&0C 00001100 \issue Rom Call &0B, BBD5 A0 FF LDY #&FF 11111111 \claim NMI BBD7 A9 8F LDA #&8F 10001111 BBD9 20 F4 FF JSR &FFF4 .. BBDC 8C 61 0D STY &0D61 .a. \Y = previous owner BBDF 20 06 92 JSR &9206 .. \copy disc op code to &0D20 BBE2 66 BE ROR &BE f. BBE4 20 0D 40 JSR &400D .@ BBE7 A9 40 LDA #&40 01000000 \= RTI instruction BBE9 8D 00 0D STA &0D00 ... \store it at NMI entry point BBEC A9 10 LDA #&10 00010000 \set retry counter = 16 BBEE 8D 62 0D STA &0D62 .b. BBF1 A9 00 LDA #&00 00000000 \set Tube flag = 0 BBF3 8D 64 0D STA &0D64 .d. BBF6 AD 10 10 LDA &1010 ... \get drive number BBF9 29 03 AND #&03 00000011 BBFB A8 TAY . BBFC BE 20 10 LDX &1020,Y . . \get density for drive BBFF E0 12 CPX #&12 00010010 \if =18 sectors/track BC01 D0 02 BNE &BC05 .. \set MFM latch bit BC03 09 40 ORA #&40 01000000 BC05 20 A0 B9 JSR &B9A0 .. BC08 20 36 BE JSR &BE36 6. \get track no. under head BC0B 20 C0 B9 JSR &B9C0 .. BC0E 49 00 EOR #&00 00000000 BC10 A0 08 LDY #&08 00001000 \=Restore command BC12 68 PLA h \recover logical track number BC13 F0 07 BEQ &BC1C .. \if >0 BC15 20 DC B9 JSR &B9DC .. BC18 49 00 EOR #&00 00000000 BC1A A0 18 LDY #&18 00011000 \=Seek command BC1C 8C 63 0D STY &0D63 .c. BC1F AD 8F 02 LDA &028F ... \get MOS option byte BC22 4A LSR A J \b4..b5 = stepping rate BC23 4A LSR A J \default = 11 = slowest BC24 4A LSR A J BC25 4A LSR A J BC26 29 03 AND #&03 00000011 BC28 0D 63 0D ORA &0D63 .c. \merge into command BC2B 49 FF EOR #&FF 11111111 BC2D A8 TAY . BC2E 20 5B BE JSR &BE5B [. \do disc operation BC31 48 PHA H \save result status BC32 20 36 BE JSR &BE36 6. \set X to actuator number BC35 20 84 B9 JSR &B984 .. BC38 49 00 EOR #&00 00000000 BC3A 9D 1E 10 STA &101E,X ... \set new track no. under head BC3D 68 PLA h BC3E BA TSX . BC3F 9D 05 01 STA &0105,X ... \return status in A BC42 60 RTS ` BC43 AD 17 10 LDA &1017 ... \Prepare for read/write. BC46 20 C0 B9 JSR &B9C0 .. BC49 49 00 EOR #&00 00000000 \store track register BC4B AD 18 10 LDA &1018 ... \get O7F sector no. BC4E 20 CE B9 JSR &B9CE .. BC51 49 00 EOR #&00 00000000 BC53 AD 19 10 LDA &1019 ... \Get no. sectors BC56 29 1F AND #&1F 00011111 \mask off sector size bits BC58 85 A4 STA &A4 .. \store in counter for later BC5A 60 RTS ` BC5B 20 00 92 JSR &9200 .. \Open Tube channel to O7F addr BC5E 4A LSR A J \now A=0 if reading from Tube BC5F A2 11 LDX #&11 00010001 \a=1 if writing to Tube. BC61 A0 10 LDY #&10 00010000 \point XY to OSWORD &7F address BC63 4C 06 A0 JMP &A006 L.. BC66 A9 00 LDA #&00 00000000 \Write data command BC68 F0 02 BEQ &BC6C .. BC6A A9 FF LDA #&FF 11111111 \Read data command BC6C 8D 66 0D STA &0D66 .f. BC6F 20 5B BE JSR &BE5B [. \do disc op, return status BC72 C9 20 CMP #&20 00100000 \if { Ready DeletedData } BC74 F0 08 BEQ &BC7E .. \then scrub last sector BC76 E6 A3 INC &A3 .. BC78 29 DF AND #&DF 11011111 \else mask off { HeadLoaded } BC7A D0 2F BNE &BCAB ./ \other bits? finish O7F BC7C F0 23 BEQ &BCA1 .# \no other bits? do next sector BC7E 8D 65 0D STA &0D65 .e. \Scrub sector. save status BC81 AD 66 0D LDA &0D66 .f. \if Write Data command BC84 F0 1B BEQ &BCA1 .. \then we requested it, carry on BC86 AD 64 0D LDA &0D64 .d. \else is Read. if I/O transfer BC89 D0 06 BNE &BC91 .. BC8B CE 0B 0D DEC &0D0B ... BC8E 4C A1 BC JMP &BCA1 L.. \and do next sector BC91 20 0C A0 JSR &A00C .. \else close TUBE channel BC94 20 06 92 JSR &9206 .. \and copy address to O7F block BC97 A2 00 LDX #&00 00000000 BC99 11 10 ORA (&10),Y .. \scrubbing all sectors in track. BC9B 02 ??? . \i/o only scrubs the deleted one BC9C A9 02 LDA #&02 00000010 BC9E 20 5B BC JSR &BC5B [. \and open Tube channel BCA1 20 EA B9 JSR &B9EA .. BCA4 C6 A4 DEC &A4 .. \decrement sector count BCA6 D0 C7 BNE &BC6F .. \loop if more sectors BCA8 AD 65 0D LDA &0D65 .e. \else retrieve status BCAB 4C 6D BB JMP &BB6D Lm. \post disc op BCAE A9 04 LDA #&04 00000100 \Read ID command. 4 bytes to get BCB0 85 A1 STA &A1 .. \save in counter BCB2 20 5B BE JSR &BE5B [. \do disc op BCB5 D0 0D BNE &BCC4 .. \if status = zero BCB7 98 TYA . \then set b2 of command BCB8 09 04 ORA #&04 00000100 \{ SettlingDelay } BCBA A8 TAY . BCBB C6 A4 DEC &A4 .. \decrement sector counter BCBD D0 EF BNE &BCAE .. \repeat command if more. BCBF A9 00 LDA #&00 00000000 \else finish with zero status. BCC1 4C 6D BB JMP &BB6D Lm. BCC4 C9 08 CMP #&08 00001000 \was there a { CRCError } ? BCC6 D0 F9 BNE &BCC1 .. \if not then finish. BCC8 CE 62 0D DEC &0D62 .b. \decrement retry counter BCCB F0 F4 BEQ &BCC1 .. \exit if run out BCCD 4C 8B BA JMP &BA8B L.. \else restart command. BCD0 8C 63 0D STY &0D63 .c. \Format command BCD3 A0 00 LDY #&00 00000000 \zero RLE table index BCD5 84 A1 STY &A1 .. BCD7 20 53 BC JSR &BC53 S. \set &A4 = no. sectors BCDA AD 19 10 LDA &1019 ... \get no. sectors BCDD 0A ASL A . \multiply by 8 BCDE 0A ASL A . BCDF 0A ASL A . BCE0 85 A0 STA &A0 .. \save in temp. BCE2 AD 10 10 LDA &1010 ... \get drive number 0..3 BCE5 29 03 AND #&03 00000011 BCE7 24 A0 BIT &A0 $. \if no. sectors >=16 BCE9 10 02 BPL &BCED .. BCEB 09 40 ORA #&40 01000000 \then set double density bit. BCED 20 A0 B9 JSR &B9A0 .. BCF0 AE 1B 10 LDX &101B ... \get gap1 length BCF3 A9 FE LDA #&FE 11111110 \do gap (&FE emits IDAM) BCF5 20 41 BD JSR &BD41 A. BCF8 24 A0 BIT &A0 $. \if SD BCFA 30 09 BMI &BD05 0. BCFC 20 66 BD JSR &BD66 f. \then fetch C byte BCFF 20 66 BD JSR &BD66 f. \fetch H byte BD02 4C 0F BD JMP &BD0F L.. BD05 A2 02 LDX #&02 00000010 \else fetch C byte, BD07 20 68 BD JSR &BD68 h. \to be sent twice (C and H) BD0A 20 66 BD JSR &BD66 f. \fetch H byte BD0D C6 A1 DEC &A1 .. \and discard. BD0F 20 66 BD JSR &BD66 f. \fetch R byte BD12 20 66 BD JSR &BD66 f. \fetch N byte BD15 20 79 BD JSR &BD79 y. \place CRC here BD18 A2 0B LDX #&0B 00001011 \gap2 = 11 if SD, BD1A 24 A0 BIT &A0 $. BD1C 10 02 BPL &BD20 .. BD1E A2 16 LDX #&16 00010110 \or 22 if DD. BD20 A9 FB LDA #&FB 11111011 \append gap (&FB emits DAM) BD22 20 41 BD JSR &BD41 A. BD25 A9 E5 LDA #&E5 11100101 \append sector BD27 A2 00 LDX #&00 00000000 \256 x &E5 BD29 20 88 BD JSR &BD88 .. BD2C 20 79 BD JSR &BD79 y. \append CRC BD2F AE 18 10 LDX &1018 ... \get gap3 length specified in BD32 C6 A4 DEC &A4 .. \o7F param 2. Dec sector count BD34 D0 BD BNE &BCF3 .. \loop if more sectors BD36 A2 00 LDX #&00 00000000 \else append gap4 BD38 20 80 BD JSR &BD80 .. BD3B AC 63 0D LDY &0D63 .c. \get command BD3E 4C A6 BD JMP &BDA6 L.. \do it and finish. BD41 20 00 92 JSR &9200 .. \Append gap to bytestream. BD44 20 80 BD JSR &BD80 .. \Write initial part (X=length) BD47 A9 00 LDA #&00 00000000 \if SD BD49 A2 06 LDX #&06 00000110 \then append 6 x &00 BD4B 24 A0 BIT &A0 $. BD4D 10 0B BPL &BD5A .. BD4F A9 00 LDA #&00 00000000 \else append 12 x &00 BD51 A2 0C LDX #&0C 00001100 BD53 20 88 BD JSR &BD88 .. BD56 A9 F5 LDA #&F5 11110101 \then 3 x &F5 sync tokens BD58 A2 03 LDX #&03 00000011 BD5A 20 88 BD JSR &BD88 .. BD5D BA TSX . \retrieve A on entry BD5E BD 05 01 LDA &0105,X ... BD61 A2 01 LDX #&01 00000001 \add address mark and exit BD63 4C 88 BD JMP &BD88 L.. BD66 A2 01 LDX #&01 00000001 \Fetch 1xbyte from I/O/Tube: BD68 AD 64 0D LDA &0D64 .d. \Fetch byte from I/O/Tube BD6B F0 06 BEQ &BD73 .. \to be repeated X times. BD6D AD E5 FE LDA &FEE5 ... \If Tube, read FIFO 3 BD70 4C 76 BD JMP &BD76 Lv. BD73 B1 A2 LDA (&A2),Y .. \else read from (XY+1) BD75 C8 INY . \and increment pointer BD76 4C 88 BD JMP &BD88 L.. \add to RLE table and exit BD79 A9 F7 LDA #&F7 11110111 \Add CRC token to table. BD7B A2 01 LDX #&01 00000001 BD7D 4C 88 BD JMP &BD88 L.. BD80 A9 FF LDA #&FF 11111111 \Add first part of gap. BD82 24 A0 BIT &A0 $. \if SD then value = &FF BD84 10 02 BPL &BD88 .. BD86 A9 4E LDA #&4E 01001110 \else value = &4E. BD88 20 00 92 JSR &9200 .. \Add (byte,runlen) to table BD8B A4 A1 LDY &A1 .. \get RLE table pointer BD8D 99 00 0E STA &0E00,Y ... \store byte value BD90 8A TXA . BD91 99 00 0F STA &0F00,Y ... \store run length BD94 E6 A1 INC &A1 .. \increment table pointer BD96 F0 01 BEQ &BD99 .. \"Bad spt" error if overrun BD98 60 RTS ` \else exit. BD99 20 18 90 JSR &9018 .. BD9C 0A ASL A . BD9D D0 42 BNE &BDE1 .B BD9F 61 64 ADC (&64,X) ad BDA1 20 73 70 JSR &7073 sp BDA4 74 ??? t BDA5 00 BRK . BDA6 20 5B BE JSR &BE5B [. \Do disc op and finish O7F. BDA9 4C 6D BB JMP &BB6D Lm. BDAC 20 36 BE JSR &BE36 6. BDAF 20 CF BB JSR &BBCF .. BDB2 48 PHA H \Read drive status. BDB3 A0 81 LDY #&81 10000001 \Preset b7 = unused, BDB5 68 PLA h \b0 = "CNT/OP1" BDB6 48 PHA H \if { Ready } BDB7 30 10 BMI &BDC9 0. BDB9 AD 10 10 LDA &1010 ... \then set relevant RDYn bit BDBC 4A LSR A J \according to O7F drive; BDBD 90 06 BCC &BDC5 .. BDBF 98 TYA . BDC0 09 40 ORA #&40 01000000 \b6 = RDY1 BDC2 A8 TAY . BDC3 D0 04 BNE &BDC9 .. BDC5 98 TYA . BDC6 09 04 ORA #&04 00000100 \b2 = RDY0 BDC8 A8 TAY . BDC9 68 PLA h BDCA 48 PHA H BDCB 29 40 AND #&40 01000000 \if { WriteProtect } BDCD F0 04 BEQ &BDD3 .. BDCF 98 TYA . BDD0 09 08 ORA #&08 00001000 \then set b3 = WRPROT BDD2 A8 TAY . BDD3 68 PLA h BDD4 48 PHA H BDD5 29 04 AND #&04 00000100 \if { Track00 } BDD7 F0 04 BEQ &BDDD .. BDD9 98 TYA . BDDA 09 02 ORA #&02 00000010 \then set b1 = TRACK0 BDDC A8 TAY . BDDD 68 PLA h BDDE 29 02 AND #&02 00000010 \if { Index } BDE0 F0 04 BEQ &BDE6 .. BDE2 98 TYA . BDE3 09 10 ORA #&10 00010000 \then set b4 = INDEX BDE5 A8 TAY . BDE6 98 TYA . BDE7 4C 9A BB JMP &BB9A L.. \store result and exit BDEA AD 17 10 LDA &1017 ... \Write special registers BDED C9 05 CMP #&05 00000101 \if not register 5 BDEF F0 14 BEQ &BE05 .. BDF1 20 2D BE JSR &BE2D -. \then set X b0 = parm b3 BDF4 AD 18 10 LDA &1018 ... \get track no. to write BDF7 20 40 BE JSR &BE40 @. \if drive is double-stepped BDFA 90 01 BCC &BDFD .. BDFC 0A ASL A . \double the track number. BDFD 9D 1E 10 STA &101E,X ... \store in workspace BE00 A9 00 LDA #&00 00000000 \return zero status. BE02 4C 9A BB JMP &BB9A L.. BE05 AD 18 10 LDA &1018 ... \&05 (Current sector) BE08 20 CE B9 JSR &B9CE .. BE0B 49 00 EOR #&00 00000000 BE0D A9 00 LDA #&00 00000000 \return zero status BE0F 4C 9A BB JMP &BB9A L.. BE12 AD 17 10 LDA &1017 ... \Read special registers BE15 C9 05 CMP #&05 00000101 \if not register 5 BE17 F0 0C BEQ &BE25 .. BE19 20 2D BE JSR &BE2D -. \then set X b0 = parm b3 BE1C 20 40 BE JSR &BE40 @. \if drive is double-stepped BE1F 90 01 BCC &BE22 .. BE21 4A LSR A J \then halve the track number BE22 4C 9A BB JMP &BB9A L.. \return value as result BE25 20 92 B9 JSR &B992 .. BE28 49 00 EOR #&00 00000000 \read sector register BE2A 4C 9A BB JMP &BB9A L.. \return value as result BE2D AD 17 10 LDA &1017 ... \&12, &1A (Current track) BE30 4A LSR A J \returns track under head of BE31 4A LSR A J \drives 0 and 1; 8271 returns BE32 4A LSR A J \track for surfaces 0 and 1 BE33 4C 39 BE JMP &BE39 L9. \fall through: BE36 AD 10 10 LDA &1010 ... \Get track no. under head BE39 29 01 AND #&01 00000001 \of drive specified in BE3B AA TAX . \the OSWORD &7F command BE3C BD 1E 10 LDA &101E,X ... BE3F 60 RTS ` BE40 20 00 92 JSR &9200 .. \Test if drive double-stepped BE43 AD 10 10 LDA &1010 ... \get drive number BE46 29 03 AND #&03 00000011 BE48 A8 TAY . BE49 B9 28 10 LDA &1028,Y .(. \get track stepping for drive BE4C C9 01 CMP #&01 00000001 \return C=1 if enabled. BE4E 60 RTS ` BE4F A9 D0 LDA #&D0 11010000 \Force interrupt BE51 20 B2 B9 JSR &B9B2 .. BE54 49 00 EOR #&00 00000000 BE56 A9 00 LDA #&00 00000000 \return zero result BE58 4C 9A BB JMP &BB9A L.. BE5B A5 F4 LDA &F4 .. \Do disc op. save EDOS socket BE5D 8D 60 0D STA &0D60 .`. \number in NMI area BE60 AD 87 10 LDA &1087 ... \get *OPT 9 saverom BE63 4C A0 B3 JMP &B3A0 L.. BE66 85 F4 STA &F4 .. \Disc ancillary loop BE68 8D 30 FE STA &FE30 .0. \copied to &0D20 BE6B AD 80 FE LDA &FE80 ... \set ROM bank to *OPT 9 saverom BE6E 49 5F EOR #&5F 01011111 \if { NotReady SpinUpComplete } BE70 29 A0 AND #&A0 10100000 \then wait. (Core must clear BE72 F0 F7 BEQ &BE6B .. \other cases of NotReady) BE74 8C 80 FE STY &FE80 ... \issue FDC command BE77 A9 14 LDA #&14 00010100 \allow status register BE79 E9 01 SBC #&01 00000001 \to settle (50 us) BE7B D0 FC BNE &BE79 .. BE7D AD 80 FE LDA &FE80 ... \poll status register BE80 49 FF EOR #&FF 11111111 BE82 10 12 BPL &BE96 .. \if Ready then test Busy flag BE84 AD 16 10 LDA &1016 ... \else if top bit of O7F command BE87 25 FF AND &FF %. \or Escape flag clear BE89 10 F2 BPL &BE7D .. \then poll again BE8B A9 00 LDA #&00 00000000 \else issue Restore command BE8D 49 FF EOR #&FF 11111111 BE8F 8D 80 FE STA &FE80 ... BE92 A9 FF LDA #&FF 11111111 \and exit with bogus status BE94 D0 04 BNE &BE9A .. BE96 6A ROR A j \if busy flag set BE97 B0 E4 BCS &BE7D .. \poll again BE99 2A ROL A * BE9A 48 PHA H BE9B AD 60 0D LDA &0D60 .`. \else restore ROM bank (EDOS) BE9E 85 F4 STA &F4 .. BEA0 8D 30 FE STA &FE30 .0. BEA3 68 PLA h \and return status register BEA4 60 RTS ` BEA5 85 A0 STA &A0 .. \NMI write I/O BEA7 A9 02 LDA #&02 00000010 \All NMIs copied to &0D00 BEA9 2C 80 FE BIT &FE80 ,.. \If not Data Request BEAC D0 10 BNE &BEBE .. \then ignore interrupt BEAE AD 00 0D LDA &0D00 ... \else read memory BEB1 49 FF EOR #&FF 11111111 \invert it for WD2791 BEB3 8D 83 FE STA &FE83 ... \store in Data Register BEB6 EE 0A 0D INC &0D0A ... \modify read instruction BEB9 D0 03 BNE &BEBE .. \incrementing the address BEBB EE 0B 0D INC &0D0B ... BEBE A5 A0 LDA &A0 .. \restore accumulator and exit BEC0 40 RTI @ BEC1 85 A0 STA &A0 .. \NMI write Tube BEC3 A9 02 LDA #&02 00000010 BEC5 2C 80 FE BIT &FE80 ,.. BEC8 D0 08 BNE &BED2 .. BECA AD E5 FE LDA &FEE5 ... \Fetch from Tube FIFO 3 BECD 49 FF EOR #&FF 11111111 \invert BECF 8D 83 FE STA &FE83 ... \Store in data register BED2 A5 A0 LDA &A0 .. BED4 40 RTI @ BED5 85 A0 STA &A0 .. \NMI read I/O BED7 A9 02 LDA #&02 00000010 BED9 2C 80 FE BIT &FE80 ,.. BEDC D0 10 BNE &BEEE .. BEDE AD 83 FE LDA &FE83 ... \read from data register BEE1 49 FF EOR #&FF 11111111 \invert BEE3 8D 00 0D STA &0D00 ... \store BEE6 EE 0F 0D INC &0D0F ... \modify store instruction BEE9 D0 03 BNE &BEEE .. \incrementing the address BEEB EE 10 0D INC &0D10 ... BEEE A5 A0 LDA &A0 .. BEF0 40 RTI @ BEF1 85 A0 STA &A0 .. \NMI read Tube BEF3 A9 02 LDA #&02 00000010 BEF5 2C 80 FE BIT &FE80 ,.. BEF8 D0 08 BNE &BF02 .. BEFA AD 83 FE LDA &FE83 ... \fetch from data register BEFD 49 FF EOR #&FF 11111111 \invert BEFF 8D E5 FE STA &FEE5 ... \store in Tube FIFO 3 BF02 A5 A0 LDA &A0 .. BF04 40 RTI @ BF05 85 A0 STA &A0 .. \NMI read ID I/O BF07 A9 02 LDA #&02 00000010 \ignore if not Data Request BF09 2C 80 FE BIT &FE80 ,.. BF0C D0 14 BNE &BF22 .. BF0E AD 83 FE LDA &FE83 ... \read data register BF11 49 FF EOR #&FF 11111111 \invert BF13 C6 A1 DEC &A1 .. \decrement counter BF15 30 0B BMI &BF22 0. \discard data if enough read BF17 8D 00 0D STA &0D00 ... \store in memory BF1A EE 13 0D INC &0D13 ... \increment store address BF1D D0 03 BNE &BF22 .. BF1F EE 14 0D INC &0D14 ... BF22 A5 A0 LDA &A0 .. BF24 40 RTI @ BF25 85 A0 STA &A0 .. \NMI read ID Tube BF27 A9 02 LDA #&02 00000010 BF29 2C 80 FE BIT &FE80 ,.. BF2C D0 0C BNE &BF3A .. BF2E AD 83 FE LDA &FE83 ... \fetch from data register BF31 49 FF EOR #&FF 11111111 \invert BF33 C6 A1 DEC &A1 .. \decrement counter BF35 30 03 BMI &BF3A 0. \discard data if enough read BF37 8D E5 FE STA &FEE5 ... \store in Tube FIFO 3 BF3A A5 A0 LDA &A0 .. BF3C 40 RTI @ BF3D 2C 83 FE BIT &FE83 ,.. \NMI verify BF40 40 RTI @ \fetch data and discard BF41 85 A0 STA &A0 .. \NMI format BF43 A9 02 LDA #&02 00000010 BF45 2C 80 FE BIT &FE80 ,.. BF48 D0 13 BNE &BF5D .. BF4A AD 00 0E LDA &0E00 ... \get byte from table BF4D 49 FF EOR #&FF 11111111 \invert BF4F 8D 83 FE STA &FE83 ... \store in data register BF52 CE 00 0F DEC &0F00 ... \decrement run length BF55 D0 06 BNE &BF5D .. \(01..00, 1..256 bytes) BF57 EE 0A 0D INC &0D0A ... \if run out BF5A EE 12 0D INC &0D12 ... \move to next entry in table BF5D A5 A0 LDA &A0 .. BF5F 40 RTI @ \Summary of microcode byte to &9018, Print string immediate \&01 .......1 Print newline before string \&02 ......1. Print newline after string \&04 .....1.. Beep at end of string \&08 ...01... Error message, issue it if b1=1 or on JSR &9009 \&10 ...10... Ask question, get yes/no answer, return Z=1, C=1 if yes \&40 01...... Print hex value in A after string \&80 10...... Print decimal value in A after string \&C0 11...... Print character in A after string \Summary of OSWORD &7F command table \BAFD,X bits 0..5 = 8271 command byte \BAFE,X Microcode byte (see below) \BAFF,X 1 + offset of NMI handler for I/O memory (0 = no handler) \BB00,X 1 + offset of address within handler (0 =fixed or no address) \BB01,X 1 + offset of NMI handler for Tube memory (0 = no handler) \BB02,X Equivalent 2793 command byte \BB03,X Action address - 1, low byte \BB04,X Action address - 1, high byte \Summary of microcode byte to OSWORD &7F \&01 ......01 PIO write to disc, source address required \&02 ......10 PIO read from disc, target address required \&10 ...1.... Read/write 8271 special registers \&40 .1...... Motor operation (seek required) \&60 .11..... Sector operation (scans or reads sector IDs) \&80 1....... Not used; set if operation accesses or overwrites sector data area (i.e. read/write sectors, and format) \Variables \00A0..A1 Pointer to user's OSWORD &7F block \00A0 Temporary for A in NMI service routines \00A1 No. bytes to fetch in Read ID NMI service routine \00A2..A3 CHRN block address from O7F 1..2 for Format command \00A4 No. sectors to read \00A8 Catalogue flag in medium *commands 0=empty 1=clean >1=dirty \00A8..A9 Pointer to CHRN table in *FORMAT \00A8..A9 Pointer to private page when stowing/restoring workspace \00A9..AA Pointer to backup/copy second catalogue buffer \00AA..AB Pointer to extended vector table while setting up FS \00AB Pointer to first free entry in catalogue 2 \00AC High byte of data buffer address, low byte = 0 \00AD Data buffer size in pages \00AE Sector count in *BACKUP, *COPY \00AF Temporary for Y in *BACKUP, *COPY: 0=source 1=target \00B2..B3 Pointer to hex word in print-absolute \00B8 Temp for high bits when packing catalogue entry \00B8 Uppercased character to compare with names of open handles \00B9 Counter to compare filename with names of open handles \00BA..BB Target absolute sector when advancing PTR \00BA..BB Temporary during OSGBPB sector operations \00BC..BD Pointer to user memory in OSGBPB \00BE..BF Pointer to user's OSGBPB block \00C0..C6 Immediate file name \00C7..C9 Immediate dir, volume, drive (ASCII) \00CA..CB Pointer to buffer of open file (CB=file handle) \00CC Pointer to file entry in catalogue \00CD Microcode shift register in OSGBPB, OSFIND/OSARGS, OSFILE, OSWORD &7F \00CE 0=ambiguous spec not allowed 1=ambiguous spec allowed, current spec is specific &FF=current spec is ambiguous \0D60 Socket no. of EDOS rom during disc op \0D61 Socket no. of previous NMI owner during disc op \0D62 Retry counter in Read ID command \0D63 Temp. 2791 command (may not be the exact one issued) \0D64 >0 = Disc op is transferring to Tube \0D65 Temporary for status after disc operation \0D66 0 = Write to disc, &FF = Read from disc \1000..06 Default file name \1007..09 Default directory, volume, drive (ASCII) \100A..0C Library directory, volume, drive (ASCII) \100D In absolute workspace: &BE=workspace in absolute page, other=absolute page not initialised. Private page+&D: &BE=workspace in absolute page, &EF=workspace in private page, other=private page not initialised. \100E *OPT 1 monitor \100F b1=1 if *ENABLEd \1010..1B OSWORD &7F block \101C..1D Address of user's OSWORD &7F block \101E..1F Track no. under heads on drives 0&2, 1&3 \1020..23 0FF0,X Density of drives 0..3 0A=SD 12=DD \1024..27 0FF4,X No. tracks on drives 0..3 \1028..2B 0FF8,X Track stepping on drives 0..3 >0=step \102C..2F 0FFC,X No. volumes on disc, offset of disc cat /2 \1030..37 No. tracks in volumes A..H \1038..39 Offset to start of volume in sectors \103A b6=Tube transfer, b7=write to Tube or I/O memory (when transferring bytes to/from open files) \1040..57 Catalogue block 1 \1040..46 Filename (used by *INFO) \1047 Directory letter (used by *INFO) \1048..4F Load/exec/length/start sector in catalogue format \1048..4A Load address from catalogue (18 bit) \104B..4D Execution address from catalogue (18 bit) \104E..50 File length from catalogue \1051..52 Absolute start sector \1053..54 Number of sectors used \1058..6F Catalogue block 2, for creating catalogue entries \1058..64 OSCLI boot command string \1060..61 Result from 'calculate free space on volume' routine \1060..61 Input to 'print decimal word' routine \1060..6F Table from &9A1E..2D for newly created files \1060..62 cf. 1048..4A Load address of new file (18 bit) \1063..65 cf. 104B..4D Execution address of new file (18 bit) \1066..68 cf. 104E..50 Initial file length \1069..6A cf. 1051..52 Absolute end sector (last used +1) \106B..6C cf. 1053..54 Desired sector allocation \1070..81 OSFILE/OSGBPB block \1070.. Workspace used by *BACKUP and *COPY \1070 Source drive \1071 Target drive \1072 Source volume \1073 Target volume \1074..75 =&13,&0B 8271 read/write commands for source, target \1076..77 Low byte of sectors-to-go for source, target \1078..79 High byte of sectors-to-go for source, target \107A..7B Low byte of start sector for source, target \107C..7D High byte of start sector for source, target \1080 b7 = Single disc operation (*COMPACT) b6 = Prompt to change discs b0 = b6? \1081 High byte of volume size of source disc (to select 18/19 bit fields in catalogue 2) \1070..81 Workspace used by *FORMAT \1070..73 Density,tracks,track stepping,volumes \1072 Pointer to *command table entry in *CATGEN \1074 Outstep (track skew) \1076 4 * sector count (density) \1077 Sector iterator \1078..7F No. tracks in each volume of disc to format \1082..83 Pointer to arguments of *RUN, */ command \1084..87 *OPT 6..9 density, volumes, tracks, saverom \1088,Y Channel flags b0=EOF warning given b6=open for reading b7=open for writing \1089,Y Current buffer 0=empty 1=clean 2=dirty \108A..0,Y Name of open file \1091,Y Directory of open file \1092,Y Volume containing open file \1093,Y Drive containing open file \1094..5,Y Absolute start LBA of open file \1096..7,Y Absolute LBA of sector currently in buffer \1098..9,Y Allocated file length (!== EXT) \109A..C,Y EXT file length \109D..F,Y PTR file pointer \This Perl script recreates the binary from this listing. \Copy the text between the cut lines. \Paste it into a new file, asm2bin.pl, and remove the column of \ \Then call it with \ perl asm2bin.pl -b 8000 -o o2791w o2791w.asm.txt \-------->8--- \#!/usr/bin/perl \ \#Usage: perl asm2bin.pl [-D] [-b BASE] -o OUTFILE [FILE...] \ \use Getopt::Std; \use IO::Seekable qw(SEEK_SET SEEK_CUR SEEK_END); \ \getopts("Db:o:"); \die "No output file specified" if $opt_o eq ''; \$opt_b = hex($opt_b); \ \open(BIN,"+>$opt_o") or die; \binmode(BIN); \while(<>) { \ y/\n\r//d; \ if(/^ {0,2}([0-9A-F]{4})/) { \ print STDERR "seek $1\n" if $opt_D; \ seek(BIN,hex($1)-$opt_b,SEEK_SET); \ } \ if(/^ {0,2}[^;\\]{4}((?: {0,2}[0-9A-F]{2}){1,3})/) { \ ($a=$1)=~y/ //d; \ print STDERR " write $a\n" if $opt_D; \ print BIN pack("H*",$a); \ } \ if(/^ {0,2}[^;\\]{4} {0,2}EQUS ((?:"[^"]*")*)/) { \ ($a=substr($1,1,length($1)-2))=~s/""/"/g; \ print STDERR " write $a\n" if $opt_D; \ print BIN $a; \ } \ if(/^ {0,2}[^;\\]{4} {0,2}EQU[^S] (&[0-9A-F]{2}(?:,&[0-9A-F]{2})*)/){ \ ($a=$1)=~y/,&//d; \ print STDERR " write $a\n" if $opt_D; \ print BIN pack("H*",$a); \ } \} \close(BIN); \-------->8--- \End of o2791w.asm.txt