s$$$$$$s All_About_Your_1581-Online Help V0.13 s$$$$$$p $$$S S$$ (c) by Ninja/The Dreams in 2002-2005 $$$S S$$ $$$S S$J HQ - [http://www.the-dreams.de] $$$S S$$ $$$$$$l $$$S S$$ $$$$ $$l 1581 RAM-Area (German) $$$S S$$ $$$P $$l 1581 ROM-Listing (German) Y$$$$$$$P 1581 ROM-Differences d$$$b Job-Codes s$$$$$$b d$$$ $$b Error Messages $$$$ $$$$ $$$ $$$$sss $$$&%%&$$ CIA8520A-Registers $$$$""' $$$$ $$ WD177X-Registers $$$$ Y$$$ SP Y$$$$$$$P o$$$$$Ss s$$ $s S$$S $$$$ $$$ S$$$ $$$ $$ $$ S$$s $$$ "" $$ $$ $$$ $$ sS$$$$$$P Y$$ $P +------------------------------------------------------------------------ | | DISK-DRIVE 1581: ZEROPAGE, EXTENDED ZEROPAGE, BUFFERS | +------------------------------------------------------------------------ | | Comments done by Peter Steiner, used with permission. | | $00-$01/0-1 frei | $02-$0A/2-10 Jobspeicher fuer die Puffer 0-8 | $0B-$1C/11-28 T&S fuer jeden Job | $1D-$1E/29-30 ID | $1F/31 Spurnummer | $20/32 Seitennummer (0: Vorder-/ 1: Rueckseite) | $21/33 Sektornummer | $22/34 Sektorengroesse | $23-$24/35-36 CRC-Pruefsumme | $25/37 Flag fuer Diskettenwechsel | $26/38 Drivemodus 0: Laufwerk inaktiv | $27/39 Aktuelle Kopfposition | $28/40 Zwischenspeicher fuer Jobcode | $29/41 Laenge der Befehlszeile | $2A-$2B/42-43 An- bzw. Nachlaufzaehler fuer Laufwerksmotor | $2C/44 Stackpointer bei Controllerschleifen-Aufruf | $2D/45 Init-Modus | $2E/46 Sektorversatz (1) | $2F/47 freie Blocks auf der aktuellen Spur beim BAM-Check | $30/48 Optionen bei Fehlern | $31-$32/49-50 Zeiger in die BAM | $33-$34/51-52 Zeiger auf User-Sprungtabelle | $35/53 Flags fuer BAM-Zustand | $36/54 Zwischenspeicher | $37/55 Modus von JOB $9e: BUFMOV_DV (Programmfehler) | $38/56 Zwischenspeicher bei Burst-Load / 'u9' (Warmstart) | $39/57 Zwischenspeicher: | $3A/58 Zwischenspeicher | $3B/59 Position des '*' in Kommandozeile | $3C/60 Flag vom Burst-Load: Datei hat nur einen Block | $3D/61 Zaehler fuer gefundene Sektoren bei QUERY DISK FORMAT | $3E/62 1. gefundene Sektornummer bei QUERY DISK FORMAT | $3F/63 Zwischensp.: aktueller Puffer (bei BAM-Arbeiten) | $40-$44/64-68 Zwischenspeicher fuer diverse Zwecke | $45/69 (frei) | $46-$47/70-71 Sprungvektor fuer User-Befehle | $48-$49/72-73 Pufferadresse fuer Jobs | $4A-$4B/74-75 Zeiger in Cachepuffer | $4C/76 Tracknummer der letzten Datei (LOAD"*") | $4D/77 Aktuelle Tracknummer | $4E/78 Aktuelle Sektornummer | $4F/79 Speicher fuer obere Stackgrenze | $50/80 Aktuelle Kanalnummer | $51/81 0: EOI vom Bus / Dateiende | $52/82 Aktuelle Sekundaeradresse | $53/83 Sekundaeradresse vom IEC-Bus | $54/84 Zwischenspeicher fuer aktuelles Datenbyte | $55/85 Zwischenspeicher fuer: | $56/86 Zwischenspeicher fuer: | $57/87 Sektornummer des aktuellen Side-Sektors | $58/88 Zeiger auf T&S eines Datenblocks im Side-Sektor | $59/89 Zeiger in die SS-Tabelle des aktuellen SS | $5A/90 Beim Vergroessern einer REL-Datei | $5B-$5D/91-93 Rechenregister 1 (z.B. Division) | $5E-$5F/94-95 (frei) | $60-$62/96-98 Rechenregister 2 | $63/99 (frei) | $64-$65/100-101 temporaerer Pufferzeiger | $66/102 Bitzaehler fuer seriellen Bus | $67/103 Zaehler (z.B. fuer Laufwerks-/Kanalsuche) | $68/104 Position im Record | $69/105 Side-Sektor-Nummer des Records | $6A/106 Position der gesuchten T&S im Side-Sektor | $6B/107 Position des Records im Datenblock | $6C/108 Zwischenspeicher fuer Jobnummer | $6D/109 Pufferbelegung (b0-6:Puffer0-6, 1=belegt) | $6E/110 Drivestatus | $6F/111 Formatkennzeichen von Diskette | $70/112 Kanalbelegungstabelle | $71/113 Dir-Block in dem die Datei gefunden wurde | $72/114 1. Dir-Block mit einem freien Eintrag | $73/115 Position des freien Eintrags im Dir-Block | $74/116 Zeiger auf aktuelle Puffernummer | $75/117 Anzahl der Sektoren pro Track | $76/118 Bus-Modus | $77/119 LISTEN-Geraeteadresse (Adresse +$20) | $78/120 TALK-Geraeteadresse (Adresse +$40) | $79/121 LED-Flag | $7A/122 Zwischenspeicher fuer die Sekundaeradresse | $7B/123 Befehlsmodus-Flag | $7C/124 Burst-Kommandobyte | $7D/125 Zwischenspeicher fuer Jobstatus | $7E-$7F/126-127 Cache-Pufferzeiger fuer Burst-Befehle | $80/128 Burst-Status | $81/129 DOS-Fehlerunterdrueckung (Burstzugriff) | $82/130 Zwischenspeicher im Controller-Programm | $83/131 Nummer des aktiven Jobs | $84/132 Nummer der aktiven Jobroutine (0-32) | $85-$86/133-134 Steuer-Bits fuer Jobbearbeitung (s. $c163) | $87/135 b7: 1: Cache Puffer veraendert | $88/136 Solltrack (bei Kopfbewegung) | $89/137 AND-Maske fuer Burst-Status | $8A/138 OR-Maske fuer Burst-Status | $8B-$8C/139-140 Zeiger auf Cachepuffer | $8D/141 E/A Byte | $8E/142 Nummer der ersten physikalischen Spur | $8F/143 Nummer der letzten physikalischen Spur | $90/144 Starttrack der aktuellen Partition | $91/145 Sektorengroesse | $92/146 Anzahl Sektoren auf der Spur | $93/147 letzter Sektor auf der Spur | $94/148 1. Sektornummer auf der Spur | $95/149 Aktueller Track (im Cache Puffer) | $96/150 Diskettenseite des aktuellen Jobs | $97/151 Aktuelle Seite (im Cache Puffer) | $98/152 Kopfberuhigungszeit nach Verschiebung | $99/153 Index fuer 2-Byte Jobspeicher (z.B. T&S) | $9A/154 Groesse der Luecke zwischen zwei Sektoren | $9B/155 Fuellbyte fuer Datenblock | $9C/156 Zaehler fuer Cache-Verzoegerungszeit | $9D/157 Cache-Verzoegerungszeit | $9E/158 Blinkzaehler fuer LED | $9F-$A7/159-167 (???) | $A8-$BA/168-186 Sekundaeradressentabelle | $BB-$CC/187-204 Pufferzeiger 0-8 | $CD-$CE/205-206 Zeiger in INPUT-Puffer | $CF-$D0/207-208 Zeiger in ERROR-Puffer | $D1-$D7/209-215 1. Puffer fuer Kanal | $D8-$DE/216-222 2. Puffer fuer Kanal | $DF-$E4/223-228 Tabelle: Am laengsten inaktive Kanaele | $E5-$E9/229-233 Dir-Block, in dem Dateieintrag ist | $EA-$EE/234-238 Zeiger in den Dir-Block mit dem Eintrag | $EF-$F3/239-243 Drivenummern der Parameter | $F4-$F8/244-248 Dateitypen und Flags fuer Joker | $F9-$FF/249-255 Dateitypentabelle | | $0100/256 Gruppennummer des aktuellen Records | $0101/257 Modus der REL-Datei | $0102-$0108/258-264 Aktuelle Gruppennummer | $0109-$010F/265-271 Sektor des Super-Side Sektors | $0110-$0116/272-278 Track des Super-Side Sektors | $0117-$018F/279-399 Stackbereich | $0190-$0191/400-401 w b0f0 Haupt-Leerschleife | $0192-$0193/402-403 w dafd Interrupt-Routine | $0194-$0195/404-405 w afca Warmstartvector | $0196-$0197/406-407 w b262 VALIDATE | $0198-$0199/408-409 w 8ec5 INITIALIZE | $019A-$019B/410-411 w b781 Partition | $019C-$019D/412-413 w 892f Memory-Read/Write | $019E-$019F/414-415 w 8a5d Block-Befehle | $01A0-$01A1/416-417 w 898f USER | $01A2-$01A3/418-419 w a1a1 POSITION (RECORD) | $01A4-$01A5/420-421 w a956 Utility-Loader (&) | $01A6-$01A7/422-423 w 876e COPY | $01A8-$01A9/424-425 w 88c5 RENAME | $01AA-$01AB/426-427 w 8688 SCRATCH | $01AC-$01AD/428-429 w b348 NEW | $01AE-$01AF/430-431 w a7ae Error-Routine des Controllers | $01B0-$01B1/432-433 w abcf ATN-bearbeiten | $01B2-$01B3/434-435 w ad5c Daten auf ser. Bus | $01B4-$01B5/436-437 w aeb8 Daten vom ser. Bus | $01B6-$01B7/438-439 w c0be Controller-Routine | $01B8-$01B9/440-441 w cedc log. in phy. Format | $01BA-$01BB/442-443 w a7f1 Error-Routine des DOS | $01BC-$01CD/444-461 Jobspeicher HDRS2 | $01CE-$01D6/462-470 Jobspeicher SIDS | $01D7-$01D8/471-472 Timer B Wert im Hi/Lo-Format | $01D9/473 Anlaufzeit des Motors | $01DA/474 Controller-Befehl: 'Restore' | $01DB/475 Controller-Befehl: 'Seek' | $01DC/476 Controller-Befehl: 'Step' | $01DD/477 Controller-Befehl: 'Step-in' | $01DE/478 Controller-Befehl: 'Step-out' | $01DF/479 Controller-Befehl: 'Read Sector' | $01E0/480 Controller-Befehl: 'Write Sector' | $01E1/481 Controller-Befehl: 'Read Adress' | $01E2/482 Controller-Befehl: 'Read Track' | $01E3/483 Controller-Befehl: 'Write Track' | $01E4/484 Controller-Befehl: 'Force Interrupt' | $01E5/485 1. Sektor des Verzeichnisses | $01E6-$01E7/486-487 Zwischenspeicher | $01E8-$01E9/488-489 Zwischenspeicher | $01EA/490 Zwischenspeicher: (Burst-) Status/Fehlercode | $01EB/491 1581-Formatkennzeichen 'D' | $01EC/492 DOS-Versionsnummer '3' | $01ED-$01EE/493-494 Laenge der Partition | $01EF/495 kleinste gefundene Sektornummer (BURST) | $01F0/496 groesste gefundene Sektornummer (BURST) | $01F1-$01F9/497-505 Hi-Bytes der Pufferadressen | $01FA/506 Schreibschutz Status | $01FB/507 Autoboot-Flag | $01FC-$01FE/508-510 JMP $BA40: Byte auf FSM-Bus ausgeben | $01FF/511 (frei) | | $0200-$0229/512-553 Kommandopuffer | $022A-$00/554-0 Aktuelle Befehlsnummer ($80-$89: Block-Befehle) | $022B/555 Track des Direktory | $022C/556 letzter Track der aktuellen Partition + 1 | $022D/557 Aktueller Dateityp | $022E/558 Anzahl der Parameter (vor '=') (Zwischenspeicher) | $022F/559 Anzahl der Parameter in der Kommandozeile | $0230/560 Anzahl der Parameter vor '=' | $0231/561 Zaehler fuer Suche im Directory | $0232/562 Zeiger auf den gefundenen Dir-Eintrag | $0233/563 Dateityp aus der Kommandozeile | $0234-$0239/564-569 Kanalstatustabelle | $023A/570 Kanalstatus fuer Fehlerkanal | $023B-$0240/571-576 Ausgabe-Bytes der Kanaele an seriellen Bus | $0241/577 Ausgabe-Byte des Fehlerkanals | $0242-$0248/578-584 Anzahl der gueltigen Bytes im Datenblock | $0249-$024F/585-591 Aktuelle Recordnummer oder Dateilaenge Lo | $0250-$0256/592-598 Aktuelle Recordnummer oder Dateilaenge Hi | $0257-$025D/599-605 Position des naechsten Records im Block | $025E-$0264/606-612 Aktuelle Recordlaenge | $0265-$026B/613-619 Side-Sektor-Puffer fuer Kanal | $026C/620 aktuelle Parameterlaenge (s. $8526) | $026D/621 Nummer des gefundenen Dateinamens | $026E/622 >0: formatiertes Directory wird auf SA 0 ausgegeben | $026F/623 aktuelle Recordlaenge | $0270/624 Track des aktuellen Super-Side-Sektors | $0271/625 Sektor des aktuellen Super-Side-Sektors | $0272-$027A/626-634 Zwischenspeicher fuer Jobcodes | $027B-$027C/635-636 (frei) | $027D-$0283/637-643 Dir-Block mit dem Dateieintrag des Kanals | $0284-$028A/644-650 Position des Dateieintrags im Dir-Block | $028B/651 1. Sektornummer der letzten Datei ("*") | $028C/652 Zwischenspeicher (Kanalnummer) | $028D/653 Directory: Basic Zeilennummer Lo | $028E/654 Directory: Basic Zeilennummer Hi | $028F/655 Zwischenspeicher fuer Zeichensuche | $0290/656 Zeiger hinter aktuellen Parameter | $0291-$0296/657-662 Position der Parameter in der Kommandozeile | $0297-$029B/663-667 Werte aus Kommandozeile Hi-Bytes | $029C-$02A0/668-672 Werte aus Kommandozeile Lo-Bytes | $02A1/673 Jokerflag: Aktueller Dateiname enthaelt '*' oder '?' | $02A2/674 Bitmaske bei Kommandozeilen-Test | $02A3/675 Anzahl der Laufwerke | $02A4/676 eine Art Drivenummer (bei Directory-Laden) | $02A5/677 Such-Ergebnis | $02A6/678 Flag fuer Directory-Ende (0: Ende) | $02A7/679 Zugriffsart aus Kommandozeile (R,W,A,M) | $02A8/680 Fehlerpruefung ausschalten | $02A9-$02AA/681-682 Anzahl freie Blocks | $02AB/683 Fehlernummer | $02AC-$02C7/684-711 Directory-Zeile | $02C8-$02CF/712-719 (frei) | $02D0-$02FF/720-767 Fehlerpuffer fuer Meldungen im Klartext | | $0300-$03FF/768-1023 Puffer 0 | $0400-$04FF/1024-1279 Puffer 1 | $0500-$05FF/1280-1535 Puffer 2 (User-Puffer) | $0600-$06FF/1536-1791 Puffer 3 | $0700-$07FF/1792-2047 Puffer 4 | $0800-$08FF/2048-2303 Puffer 5 | $0900-$09FF/2304-2559 Puffer 6 | $0A00-$0AFF/2560-2815 Puffer 7 (BAM Teil 1) | $0B00-$0BFF/2816-3071 Puffer 8 (BAM Teil 2) | $0C00-$1FFF/3072-8191 Cache-Puffer | $1FFF/8191 End of RAM | +------------------------------------------------------------------------ $00-$01/0-1: frei (wahrscheinlich fuer den Einbau eines 6510 gedacht) ROM-Reference: CMP $00,X : $AF59 $AF62 INC $00,X : $AF5D LDA $00,X : $AF68 STA $00,X : $AF53 STY $00,X : $AF66 $02-$0A/2-10: Jobspeicher fuer die Puffer 0-8 ROM-Reference: LDA $0002,Y: $B120 $C0C7 LDA $02 : $AB1F LDA $02,X : $9211 $92BB $9534 $9560 $95A3 $95A8 $BFCA ROL $02 : $AB5A STA $0002,Y: $C39D $CDCE STA $02 : $AB52 $ABBA STA $02,X : $8A30 $9217 $959F LDA $03 : $AB22 $AB91 ROL $03 : $AB5C STA $03 : $AB4C $ABB7 BIT $04 : $AB64 LDA $04 : $AB25 STA $04 : $AB57 $ABB4 EOR $05 : $AB87 LDA $05 : $AB28 $AB74 STA $05 : $AB60 $AB6A $AB78 $ABB1 EOR $06 : $AB8D LDA $06 : $AB2B $AB7A STA $06 : $AB62 $AB6E $AB7E $ABAE LDA $07 : $AB2E $AB85 LDY $07 : $AB9D ROL $07 : $AB81 STA $07 : $AB3C $AB89 $ABAB BIT $08 : $AB70 LDA $08 : $AB31 $AB8B LDX $08 : $AB9F ROL $08 : $AB83 STA $08 : $AB3E $AB8F $ABA8 LDA $09 : $AB34 LDA ($09),Y: $AB4A $AB50 STA $09 : $AB42 $ABA5 INC $0A : $AB99 LDA $0A : $AB37 STA $0A : $AB46 $ABA2 $0B-$1C/11-28: T&S fuer jeden Job ROM-Reference: LDA $000B,Y: $9D83 $CEB8 $CEED $CF31 LDA $0B,X : $9482 $94AC $A7B4 $C70E $C80E STA $000B,Y: $90F6 $958C STA $0B,X : $B945 $B986 $BABC $BB21 $BBC8 $BC18 $BF52 CMP $000C,Y: $CEFA LDA $000C,Y: $9D88 $C58B $CF0F $CF37 LDA $0C,X : $947E $94B0 $A7B8 $C713 $C813 STA $000C,Y: $90FB $9591 STA $0C,X : $B94D $B98B $BAC1 $BB26 $BBCD $BC1D $1D-$1E/29-30: ID ROM-Reference: LDA $1D : $B3C2 $B474 STA $1D : $8F67 STA $1D,X : $B36A STX $1D : $8FD1 LDA $1E : $B3C7 $B47C STA $1E : $8F6C STA $1E,X : $B36F STX $1E : $8FD3 $1F/31: Spurnummer ROM-Reference: CMP $1F : $C605 $C705 $C805 $C905 $CA05 LDA $001F,Y: $DA82 $DA89 LDA $1F : $BE16 $BE91 $CFAB STA $1F,X : $CD03 $CD24 $20/32: Seitennummer (0: Vorder-/ 1: Rueckseite) $21/33: Sektornummer ROM-Reference: CMP $21 : $CAF9 LDA $21 : $BE46 $BE55 $C619 $C91A $CA1A $22/34: Sektorengroesse ROM-Reference: LDA $22 : $CFAF LDX $22 : $BCF3 $23-$24/35-36: CRC-Pruefsumme $25/37: Flag fuer Diskettenwechsel (Wird auch bei Diskettenfehlern gesetzt) ROM-Reference: BIT $25 : $84B4 $9462 LDA $25 : $B137 $BB11 $BC01 STA $25 : $8F46 $9468 $B063 $BEF3 $CE48 STX $25 : $8FC7 $26/38: Drivemodus 0: Laufwerk inaktiv b4=1: Motor ausschalten (laeuft noch nach) b5=1: Laufwerksmotor ist an b6=1: Schrittmotor ist aktiv b7=1: Laufwerk ist am Anfahren ROM-Reference: LDA $26 : $C140 $CD63 $CD7B $CDE4 $CDEC $CE4A $CE96 LDY $26 : $CE71 STA $26 : $C144 $CD78 $CDB4 $CDF0 $CE5C $CE6B $CE9A $27/39: Aktuelle Kopfposition ROM-Reference: CMP $27 : $C125 $C13C $C3B1 $CE7A LDA $27 : $CAE7 $CE81 STA $27 : $CB1A $CE91 $CFAD $28/40: Zwischenspeicher fuer Jobcode ROM-Reference: CMP $28 : $949A DEC $28 : $C008 LDA $28 : $9471 $94E8 $BFD8 STA $28 : $9004 $93C3 $9480 $94D6 $94E6 $9D90 $9D96 $9D9C $9DA2 $9DA8 $9DAE $9E60 $B6C8 $BFB9 $BFFC $29/41: Laenge der Befehlszeile ROM-Reference: CPX $29 : $8543 $BA38 CPY $29 : $811F $8261 $8ABC $8AF4 $B363 DEC $29 : $BA2B LDA $29 : $8153 $8958 $8996 $B784 $B856 $BA08 $BD1E $BF47 LDX $29 : $89ED $98FE $AA3D LDY $29 : $8265 STA $29 : $BA0D $BD6B STY $29 : $819F $A93F $2A-$2B/42-43: An- bzw. Nachlaufzaehler fuer Laufwerksmotor ROM-Reference: DEC $2A : $CE53 LDA $2A : $CD7F STA $2A : $CD71 $CDF4 DEC $2B : $CE62 STA $2B : $CDF8 $2C/44: Stackpointer bei Controllerschleifen-Aufruf ROM-Reference: LDX $2C : $CDFA $CE00 $CE6D STX $2C : $C0BF $2D/45: Init-Modus 0: Automatisch initialisieren 1: Nur von Hand initialisieren ROM-Reference: LDA $2D : $84AE $2E/46: Sektorversatz (1) ROM-Reference: ADC $2E : $B6C2 LDA $2E : $93EE STA $2E : $93F3 $93F9 $AA2A $B06D $2F/47: freie Blocks auf der aktuellen Spur beim BAM-Check ROM-Reference: CMP $2F : $B777 INC $2F : $B76D STA $2F : $B760 $30/48: Optionen bei Fehlern b0-5: Anzahl der Leseversuche b6 : ohne Bedeutung (bei 1541: Kopf justieren) b7 : 0: bei Lesefehler Spur 0 anfahren ROM-Reference: BIT $30 : $9523 LDA $30 : $9564 $BFF8 STA $30 : $AA30 $B071 $31-$32/49-50: Zeiger in die BAM ROM-Reference: ADC $31 : $B5CF LDA $31 : $B52D LDA ($31),Y: $8F4C $8F54 $8F65 $8F6A $8F6F $8F79 $8FA3 $B54E $B55C $B57A $B587 $B5E4 $B678 $B713 $B72E $B768 $B775 STA $31 : $B523 $B5CB $B5D3 $B658 STA ($31),Y: $B4C1 $B4D6 $B553 $B560 $B57F $B58C INC $32 : $B4E7 $B539 $B5C8 LDA $32 : $B4E1 $B533 STA $32 : $B654 $33-$34/51-52: Zeiger auf User-Sprungtabelle ROM-Reference: LDA ($33),Y: $89D8 $89DD STA $33 : $89C5 STA $34 : $89C9 $35/53: Flags fuer BAM-Zustand $00: BAM wurde nicht geaendert $01: BAM wurde geaendert und muss zurueckgeschrieben werden ROM-Reference: LDA $35 : $B515 $B811 ORA $35 : $B671 $B6EF STA $35 : $8006 $804E $A7F9 $B4ED $B543 $B557 $B583 $B630 $B673 $B6F1 $B83E $B84A $36/54: Zwischenspeicher (LED ein-/ausschalten) (Seitenauswahl) ROM-Reference: ORA $36 : $C581 $CE34 $CFCB STA $36 : $C57A $CE2D $CFC4 $37/55: Modus von JOB $9e: BUFMOV_DV (Programmfehler) Nur wenn b5=1 ist, werden Daten kopiert !!!! ROM-Reference: BIT $37 : $CEB1 $38/56: Zwischenspeicher bei Burst-Load / 'u9' (Warmstart) ROM-Reference: DEC $38 : $B9CC LDA $38 : $BA03 $DA63 ORA $38 : $AD54 ROL $38 : $DA94 STA $38 : $AD4D $B9A0 $DA8C $DAEC STX $38 : $B9BE $B9FC $39/57: Zwischenspeicher: Modus von JOB $9e: BUFMOV_DV 1. logischer Sektor auf der aktuellen Diskettenseite (JTRANS_TS) aktuelle Diskettenseite ROM-Reference: BIT $39 : $C590 $CEA4 $CED2 DEC $39 : $CAFD INC $39 : $C527 LDA $39 : $C463 $CECD $DA66 $DACB ROL $39 : $DA96 SBC $39 : $CF13 STA $39 : $C3E0 $C58E $C914 $CA14 $CF0B $DA85 $DAE9 STY $39 : $CAEF $3A/58: Zwischenspeicher bei Track lesen/schreiben/vergleichen ROM-Reference: BIT $3A : $DA9E DEC $3A : $C523 $C68A $C98C $CA94 LDA $3A : $DA69 STA $3A : $C3E4 $C617 $C918 $CA18 $DA91 $DAE6 $3B/59: Position des '*' in Kommandozeile ROM-Reference: CPX $3B : $8400 $841A EOR $3B : $DAC1 LDA $3B : $DA6C $DAAE STA $3B : $DA9A $DAA4 $DAB2 $DAE3 STX $3B : $83FA $3C/60: Flag vom Burst-Load: Datei hat nur einen Block ROM-Reference: ASL $3C : $B972 BIT $3C : $B995 EOR $3C : $DAC7 LDA $3C : $DA6F $DAB4 STA $3C : $B8EC $DA9C $DAA8 $DAB8 $DAE0 $3D/61: Zaehler fuer gefundene Sektoren bei QUERY DISK FORMAT ROM-Reference: ADC $3D : $C074 CMP $3D : $C084 INC $3D : $BE5C LDA $3D : $BE66 $DA72 $DABF LDY $3D : $BE57 $DAD5 ROL $3D : $DABB STA $3D : $C04B $C07F $DA7A $DAC3 $DADD STX $3D : $BE0B $3E/62: 1. gefundene Sektornummer bei QUERY DISK FORMAT ROM-Reference: BIT $3E : $DAAA CMP $3E : $BE62 LDA $3E : $DA75 $DAC5 LDX $3E : $DAD7 ROL $3E : $DABD STA $3E : $BE48 $DA7E $DAC9 $DADA $3F/63: Zwischensp.: aktueller Puffer (bei BAM-Arbeiten) ROM-Reference: LDA $3F : $B62A STA $3F : $B5F4 $B614 $40-$44/64-68: Zwischenspeicher fuer diverse Zwecke $40-$41: Zeiger fuer div. Zwecke (z.B. jmp ($0040), ...) $40-$42: Speicher fuer ASCII-Zahl beim Umwandeln in 2-Byte $40-$44: Zwischenspeicher fuer BAM-Erzeugung $41-$42: Laenge einer REL-Datei (ohne Super-Side-Sektoren) $42-$43: Zeiger fuer div. Zwecke (z.B. Pufferinhalt kopieren) $43 : Anzahl Datenbloecke im letzten Side-Sektor *2 $44 : Zwischenspeicher fuer Side-Sektor-Nummern Anzahl Side-Sektoren Einsprung von $8049, $8951, $8A9C, $8BF7 ROM-Reference: ADC $40 : $8966 $913E DEC $40 : $917D $9191 $B69C $B6B9 INC $40 : $8968 $AF6F $AF91 JMP ($0040): $8049 $8951 $8A9C $8BF7 LDA $40 : $896D $8A15 $8A1B $8AEC $8CF2 $90C6 $9291 $942D LDA $40,X : $B4D4 LDA ($40),Y: $8954 $9DF2 LDX $40 : $92C7 $AEF5 LDY $40 : $92CF LDY $40,X : $8B03 LSR $40 : $8CE8 ORA $40 : $83AE $83B6 ROL $40 : $8A10 $B4C6 SBC $40 : $8D25 STA $40 : $8042 $82A4 $83A3 $83B0 $8632 $8939 $8A0D $8A9A $8AD2 $8AF1 $8BE8 $8CE6 $8D0E $90B4 $9138 $915C $92D7 $93EC $9422 $9DE1 $9E02 $B4B0 $B66D STX $40 : $92B6 $ABCA ADC $41 : $9E8E BIT $41 : $9F30 CMP $41 : $9D1A $A376 LDA $41 : $8971 $8AE8 $99EE LDX $41 : $A33D ROL $41 : $B4C8 STA $41 : $8047 $893E $8A95 $8AD4 $8AEE $8BEF $99DE $9D11 $9DE8 $9DFE $9E90 $9F2C $B4B2 STX $41 : $A331 INC $42 : $9E94 LDA $42 : $99F3 $A339 LDA ($42),Y: $8DDF $8DF7 $945D LDX $42 : $9CFF LDY $42 : $9AD6 ROL $42 : $B4CA STA $42 : $8AEA $8DCD $8DE5 $9450 $99E0 $9DE3 $B4B4 STA ($42),Y: $9DF4 STX $42 : $9CF7 $9D07 $A333 STY $42 : $9AB7 INC $43 : $8B0E LDA $43 : $8B16 $9E85 $9EBB ROL $43 : $B4CC STA $43 : $8AD6 $8DDB $8DF3 $9459 $99E7 $9A0A $9DED $A327 $A345 $B4B6 INC $44 : $99DA LDA $44 : $9E8B LDY $44 : $9EAC ROL $44 : $B4CE STA $44 : $A32D $A351 $B4B8 STX $44 : $99D3 $45/69: (frei) $46-$47/70-71: Sprungvektor fuer User-Befehle Einsprung von $89C0, $89E1 ROM-Reference: ADC ($46),Y: $AF7F CMP ($46),Y: $AFAC EOR ($46),Y: $AFB4 JMP ($0046): $89C0 $89E1 LDA ($46),Y: $AAC6 STA $46 : $89AA $89DA $AF78 STA ($46),Y: $AAF1 $AF99 $AFB2 $AFB6 STY $46 : $AAB1 ADC $47 : $AF97 $AFAA DEC $47 : $AFA5 INC $47 : $AACE $AAF6 $AF7D $AF9E STA $47 : $89AF $89DF $AAB6 $AF89 $AF8F STX $47 : $AF73 $48-$49/72-73: Pufferadresse fuer Jobs Einsprung von $C160, $CB32 ROM-Reference: JMP ($0048): $C160 $CB32 LDA ($48),Y: $D03E $D043 $D539 STA $48 : $C159 STA ($48),Y: $D55A $DA55 STY $48 : $CB2F $CEC2 $CF76 INC $49 : $D541 $DA5B STA $49 : $C15E $CB2B $CECB $CF69 $4A-$4B/74-75: Zeiger in Cachepuffer Pufferzeiger fuer Jobs: SP_READ / SP_WRITE ROM-Reference: INC $4A : $C4F6 $C67C $C756 $C856 $C97E $CA86 LDA ($4A),Y: $C4EF $C675 $C74F $CA7D $D558 $DA53 STA $4A : $C71A $C81A $CFB9 STA ($4A),Y: $C852 $C97A $D040 $D045 $D53B STY $4A : $CEC4 $CF78 INC $4B : $C4FA $C680 $C75A $C85A $C982 $CA8A $D543 $DA5D STA $4B : $C6AE $C71E $C81E $C9B0 $CAB8 $CB90 $CEBE $CF72 $CFBD $4C/76: Tracknummer der letzten Datei (LOAD"*") ROM-Reference: LDA $4C : $968D $B8F8 STA $4C : $98A1 $B941 $4D/77: Aktuelle Tracknummer ROM-Reference: CMP $4D : $A27A DEC $4D : $B6AB INC $4D : $8B4D $B312 $B499 $B685 LDA $4D : $8728 $8B4F $8DC5 $8F85 $8FED $90F4 $9120 $9400 $94B5 $958A $95B4 $97CE $989F $9B21 $9C0A $9C36 $9C48 $9CAF $9D3D $9FEE $A248 $A257 $A3B8 $A3C4 $A49E $A4DA $A4F1 $A88E $B167 $B2DF $B30B $B49B $B562 $B58E $B5C0 $B67C $B687 $B6A5 $B7DB $B822 $B8A8 $C01D STA $4D : $805B $842F $847A $86B9 $86E1 $86F7 $870A $8721 $8748 $8847 $8C3C $8C51 $8DF9 $8E22 $8E2B $8FB4 $8FE2 $90D3 $94AE $9691 $96C1 $9876 $9A88 $9AB5 $9AC3 $9D4E $9D86 $9DD6 $9E64 $A269 $A3E3 $A589 $A5DC $A7B6 $A988 $B176 $B27B $B294 $B2A2 $B2D8 $B327 $B411 $B43A $B44C $B4F7 $B700 $B71D $B802 $B866 $BDCD $BFEA STX $4D : $8EEC $8F94 $B64A $B692 $B6B3 STY $4D : $807E $9B56 $A869 $4E/78: Aktuelle Sektornummer ROM-Reference: CMP $4E : $8B3E $94C4 $95DB $A282 $B303 $B6CA DEC $4E : $B6D7 INC $4E : $B2FF $B41A $B41F $B500 $B505 $B757 LDA $4E : $8397 $8462 $84A9 $8B35 $8DC8 $90F9 $9125 $9405 $958F $95B1 $95F8 $97D3 $98A3 $9B25 $9C0F $9C3B $9C4D $9CB7 $9D42 $A3BB $A3C1 $A4A5 $A4DF $A4EE $A898 $B16A $B5D8 $B5DF $B6BF $B6CF $B74C LDX $4E : $98D9 STA $4E : $8434 $847E $86BE $86E6 $86FC $8726 $874C $884B $88DE $8B4B $8C37 $8C4C $8DE1 $8E1F $8E28 $8FE7 $90D8 $94B2 $95DF $969E $96C5 $987B $9A7D $9AC6 $9ADD $9D53 $9D8B $9DDB $9E69 $A26E $A3E0 $A58E $A5E1 $A7BA $A98D $B173 $B276 $B299 $B29F $B2DD $B309 $B32C $B415 $B427 $B435 $B4FB $B50D $B69A $B6B7 $B6C4 $B6D3 $B6E3 $B737 $B86C $BDD1 $BFEE STX $4E : $8EE7 $B645 STY $4E : $805D $8080 $9B5B $A86B $B808 $4F/79: Speicher fuer obere Stackgrenze ROM-Reference: LDX $4F : $A805 $A94C $ABDA STX $4F : $AFCD $50/80: Aktuelle Kanalnummer ROM-Reference: CMP $50 : $8D71 LDA $50 : $8550 $95AE $97B2 LDX $50 : $887F $8A26 $8CC6 $8D6A $8D80 $8DB7 $8E0D $8E4D $905F $9071 $90B6 $90DD $90E8 $91B5 $91BF $91CE $91DF $91F0 $923E $92FD $9303 $935F $96A8 $98E7 $994E $99EC $9A1B $9A2A $9A4A $9A72 $9B1F $9B47 $9B7B $9B90 $9B9B $9BD1 $9BFF $9C14 $9C65 $9C82 $9CAD $9CCB $9CD5 $9CDB $9CE4 $9D5E $9DB0 $9E17 $9E39 $9E75 $9F11 $9F1C $9F33 $9F3E $9F58 $9F62 $9F6C $9F76 $9FAE $9FB7 $A0EC $A0FD $A116 $A126 $A13D $A181 $A1CE $A215 $A2BC $A382 $A469 $A4C0 $A4C9 $A51F $A55D $A574 $A584 $A5A1 $A5C0 $A5E7 $A5F9 $AD62 $AD83 $ADC6 $ADF2 $B18A $B22C $B8B5 LDY $50 : $8A3D $8BCC $8E94 $906E $907D $910A $9880 $A00D $A017 $A2DF $B1F6 $B24D ORA $50 : $98F0 STA $50 : $8557 $8E9B $903D $9056 $9164 $91AF $927C $965A $99AA $A823 $51/81: 0: EOI vom Bus / Dateiende ROM-Reference: LDA $51 : $8EA9 $A03F $A065 $A9E8 $A9F8 STA $51 : $8817 $8886 $ABE2 $AE85 $52/82: Aktuelle Sekundaeradresse ROM-Reference: DEC $52 : $9269 $928C $998D LDA $52 : $854D $89E4 $8E70 $9027 $9042 $919E $930D $932F $95AB $9678 $982D $9896 $995C $9972 $9A77 LDX $52 : $8A35 $9166 $91A5 $9272 $98F2 $999F $A819 LDY $52 : $9B2F $9BE5 STA $52 : $855A $855F $87D9 $8808 $883C $8878 $88A9 $89EB $8C22 $9264 $9270 $93D6 $93E2 $9436 $943D $95B9 $965E $97B9 $9832 $983B $9988 $9B08 $A1A7 $A80C $AC46 $B17E $B897 $B8CA STX $52 : $8E5E $972B $53/83: Sekundaeradresse vom IEC-Bus ROM-Reference: LDA $53 : $800B $8E78 $A808 $AC48 $AEC4 STA $53 : $AC42 $54/84: Zwischenspeicher fuer aktuelles Datenbyte ROM-Reference: LDA $54 : $8E85 $8E8F $8EA4 $90AC $9104 $910F $93A4 $A004 $A03A $A06A $A0E7 $A9DA $AA04 $AEB5 $B1FE $B259 ROR $54 : $AEA2 STA $54 : $887D $8956 $90A0 $937F $9392 $9F80 $9FA8 $A071 $A084 $AE97 $B24B $55/85: Zwischenspeicher fuer: Side-Sektor-Nummer Anzahl 'Files Scratched' Flag vom Utility Loader: 'Startadresse gefunden' Zeiger fuer Fehlermeldung ROM-Reference: ADC $55 : $B71B CMP $55 : $A8D8 CMP ($55,X): $A8BF INC $55 : $8701 $A3D5 $A90E $A91F $B71F LDA $55 : $8708 $A3F3 $A4E8 $A547 $A8AE $A9A8 $B6F3 LDA ($55),Y: $9A9F $9AAC $9AB3 $9ABB $9ABF $9ADB $9AE8 LDA ($55,X): $A914 $A917 SBC $55 : $A32B $A349 $B6FE STA $55 : $8693 $9A9D $A450 $A552 $A8B6 $A8F8 $A972 $A9B4 $B6F8 $B733 $B91C STA ($55),Y: $9AB0 $9AD0 $9AD3 $9AD8 $9AE0 $9AEE $9AF8 $9AFE $56/86: Zwischenspeicher fuer: Tracknummer des aktuellen Side-Sektors Position der gesuchten T&S im Side-Sektor Zeiger auf letztes genutztes Record-Byte Checksumme bei Autoboot & Utility-Loader Zeiger fuer Fehlermeldung ROM-Reference: ADC $56 : $AA08 CMP $56 : $A118 $A9DC DEC $56 : $A104 INC $56 : $A912 $A923 LDA $56 : $A2F7 $A52F $A8B1 $A8CE LDY $56 : $A146 SBC $56 : $A319 STA $56 : $9A98 $A102 $A10C $A133 $A44C $A4A0 $A8BA $A8F5 $A996 $AA0C $57/87: Sektornummer des aktuellen Side-Sektors genutzte Recordlaenge Flag: 'nur 1 neuen Datenblock anlegen' Zeiger fuer Autoboot & Utility-Loader (Lo) Einsprung von $A9F2 ROM-Reference: DEC $57 : $A151 $A155 INC $57 : $A36A JMP ($0057): $A9F2 LDA $57 : $A38D $A534 $A9AC $A9C8 STA $57 : $A111 $A454 $A4A7 $A99B $A9CD $A9F0 STA ($57),Y: $A9C3 $58/88: Zeiger auf T&S eines Datenblocks im Side-Sektor Anzahl existierender Gruppen Zeiger fuer Autoboot & Utility-Loader (Hi) ROM-Reference: INC $58 : $A34D $A9D1 LDA $58 : $A9AF LDA ($58),Y: $A267 $A26C $A278 $A280 LDY $58 : $9E9D $A52D SBC $58 : $A357 STA $58 : $9A0F $A237 $A359 $A448 $A496 $A9A3 $A9ED $59/89: Zeiger in die SS-Tabelle des aktuellen SS Blockgroesse bei Autoboot & Utility-Loader ROM-Reference: DEC $59 : $A529 $A52B $A9D3 LDY $59 : $A53E STA $59 : $A23B $A49C $A9B9 $5A/90: Beim Vergroessern einer REL-Datei aktuell bearbeitete Gruppe ROM-Reference: INC $5A : $A500 LDA $5A : $A3EC $A502 $A516 STA $5A : $A446 $5B-$5D/91-93: Rechenregister 1 (z.B. Division) ROM-Reference: ADC $5B : $8CF9 ASL $5B : $8D18 INC $5B : $8D2E LDA $5B : $8C9F $8CBB $9A1D LDX $5B : $A362 STA $5B : $8CFB $8D3A INC $5C : $8CFF LDA $5C : $9A22 $A35E ROL $5C : $8D1A STA $5C : $8D3C INC $5D : $8D03 ROL $5D : $8D1C STA $5D : $8D3E $5E-$5F/94-95: (frei) ROM-Reference: LDA $5E,X : $8D4F STA $5E,X : $8D53 $60-$62/96-98: Rechenregister 2 ROM-Reference: LDA $60 : $8C8F $8CA3 $8CAC $8CB7 $8CD4 $8CD8 $8D22 ROL $60 : $8D1E $8D45 STA $60 : $8CCB $8CDD $8D12 $9ECE STX $60 : $9EC5 STY $60 : $8D32 DEC $61 : $8CE1 LDA $61 : $8D28 ROL $61 : $8D20 $8D47 STA $61 : $8CD0 $8D14 $8D30 STX $61 : $9EC7 $9ECC ROL $62 : $8D49 STA $62 : $8CC4 STX $62 : $9EC9 $63/99: (frei) ROM-Reference: ADC $63,X : $8D51 $64-$65/100-101: temporaerer Pufferzeiger (Kann von jeder Routine fuer eigene Zwecke gesetzt werden) ROM-Reference: CMP ($64),Y: $835C $8410 LDA $64 : $8466 $84A1 $A235 LDA ($64),Y: $8364 $837F $839D $83C0 $83C6 $83D2 $8407 $8457 $858F $8599 $85AF $85E3 $864A $86A1 $86B7 $86BC $86C2 $86C8 $86DD $86E4 $97C6 $9827 $984F $9855 $985B $9D4C $9D51 $9E12 $9E62 $9E67 $9EED $9F05 $A148 $A175 $A18D $A192 $A485 $A5D5 $A5DF $B287 $B28B $B290 $B297 $B2AE $B325 $B32A $B330 $B336 $B7D6 $B7E6 SBC ($64),Y: $B7DE STA $64 : $850E $8646 $90CA $9142 $9431 $944D $9D74 $9E15 $9F03 $A16B $B3F5 STA ($64),Y: $8501 $851A $873E $9648 $964E $9654 $97CA $97D0 $97D5 $982B $9D3F $9D44 $9D5B $9D66 $A29F $A2AD $A40E $A415 $A491 $A4A2 $A4A9 $A4AE $A4B3 $A4DC $A4E1 $A531 $A536 $A55B $A563 $B3A9 $B3B1 $B3B9 $B3BE $B3C4 $B3C9 $B3CE $B3D4 $B3D9 $B3DE $B3E1 $B3E6 $B400 STY $64 : $A18B $B3A4 LDA $65 : $9377 $A239 STA $65 : $8513 $8641 $90C4 $942B $9449 $9D70 $9E20 $66/102: Bitzaehler fuer seriellen Bus ROM-Reference: DEC $66 : $AE26 $AEAE $B528 STA $66 : $ADE9 $AE47 $B51C $67/103: Zaehler (z.B. fuer Laufwerks-/Kanalsuche) ROM-Reference: INC $67 : $8C11 LDX $67 : $8215 $8C0F $8C32 $8C47 STA $67 : $81BD STX $67 : $820D $68/104: Position im Record ROM-Reference: LDA $68 : $8CF6 SBC $68 : $A21B STA $68 : $A1EB $A456 $69/105: Side-Sektor-Nummer des Records ROM-Reference: CMP $69 : $9EE7 $A17B $A3F5 INC $69 : $A2F1 LDA $69 : $88A4 $9EF9 $A2FF $A329 $A347 $A44E LDX $69 : $99D1 STA $69 : $88B4 $8CA1 $8CB9 $A167 $A17F $A30A $6A/106: Position der gesuchten T&S im Side-Sektor ROM-Reference: CMP $6A : $A3FC INC $6A : $A2EB $A2ED LDA $6A : $88A1 $99E2 $9A05 $9E4D $A316 $A44A LDY $6A : $9EEB STA $6A : $88B7 $8CA9 $8CB2 $A2F5 STY $6A : $A196 $6B/107: Position des Records im Datenblock ROM-Reference: ADC $6B : $A223 $A2E7 INC $6B : $8C96 $8C98 LDA $6B : $A210 STA $6B : $88B1 $8C91 $6C/108: Zwischenspeicher fuer Jobnummer aktueller Puffer ROM-Reference: LDA $6C : $8BFD $8F27 $93C5 $94A8 $9E6B $B164 $B390 $B5F2 $B612 $B638 LDX $6C : $863C $8BEA $8EF6 $93CA $94D3 $94E4 $95C2 $9E70 $BFF6 STA $6C : $8C2C $8EDF $9A8E $9D7F $9E56 $9E5C $A598 $A5EF $B179 $B62C $B643 STX $6C : $9474 $A7AF $BFD6 $BFF0 $6D/109: Pufferbelegung (b0-6:Puffer0-6, 1=belegt) ROM-Reference: AND $6D : $8A17 LDA $6D : $922A $9235 ORA $6D : $8A1D $8C5C ROR $6D : $9258 STA $6D : $8A1F $8C5E $923A $B05F $6E/110: Drivestatus $00: Ok. $ff: Fehler aufgetreten / Fremdformat ROM-Reference: LDA $6E : $84EB $B5B4 $B8E6 STA $6E : $8069 $84D7 $84E9 $8F48 $B356 STX $6E : $8FC9 $6F/111: Formatkennzeichen von Diskette ROM-Reference: LDA $6F : $9491 $B386 $B3D7 STA $6F : $8F3A $B3B7 $70/112: Kanalbelegungstabelle b0-6: Kanal 0-6 (1 = Kanal frei) b5-6: von DOS reserviert (immer 0) b7 : unbenutzt (immer 0) ROM-Reference: AND $70 : $92EE BIT $70 : $92DF ORA $70 : $91C9 STA $70 : $8775 $91CB $92F0 $B051 $71/113: Dir-Block in dem die Datei gefunden wurde ROM-Reference: LDA $71 : $847C STA $71 : $84AB $72/114: 1. Dir-Block mit einem freien Eintrag ROM-Reference: LDA $72 : $845B $95D7 $9660 STA $72 : $8464 $95FE STY $72 : $8426 $73/115: Position des freien Eintrags im Dir-Block ROM-Reference: CPX $73 : $8471 LDA $73 : $9604 $9667 LDX $73 : $8468 STA $73 : $82BE $82EF $846A $95EE $9602 $B26D STX $73 : $95CE $74/116: Zeiger auf aktuelle Puffernummer Kanal (0-6: 1.Puffer; 7-13: 2. Puffer) ROM-Reference: LDX $74 : $A097 $A0A1 $A4CF STA $74 : $9F28 STX $74 : $9F1E $75/117: Anzahl der Sektoren pro Track ROM-Reference: CMP $75 : $B74E LDA $75 : $9498 $94C2 $B301 $B6C6 $C07A $CEF6 LDX $75 : $B4BA SBC $75 : $B6D1 STA $75 : $B0D1 $76/118: Bus-Modus b0: 1: ATN aufgetreten b1: 1: ATN-Modus; 0: Daten-Modus b2: letzter Burst-Clock-Zustand b3: Ein-/Ausschalten des FSM-Busses 1: FSM erlaubt, 0: immer seriell langsam b4: 1: VC20 Modus , 0: C64 Modus b5: Mode-Anforderung vom Computer 1: FSM Bus , 0: seriell langsam b6: 1: LISTEN bearbeiten b7: 1: TALK bearbeiten ROM-Reference: AND $76 : $DB06 BIT $76 : $A813 $AC68 $AC6E $AC7B $AD17 $ADAF $AE0A $AE19 $B108 $B8D7 EOR $76 : $BA4C $BA55 $BF93 $C035 $C03B LDA $76 : $89B4 $AA88 $AAA9 $ABD4 $ABE4 $AC08 $AC15 $AC22 $AC30 $AC5A $AD50 $AED9 $BF9D $DB0C $DB17 ORA $76 : $AA95 STA $76 : $89B8 $AA8C $AA97 $AAAD $ABD8 $ABE8 $AC0C $AC19 $AC28 $AC36 $AC5E $AD56 $AEDD $B085 $BA57 $BFA1 $C03D $DB10 $DB1B $77/119: LISTEN-Geraeteadresse (Adresse +$20) ROM-Reference: ADC $77 : $AA7E CMP $77 : $AC2C STA $77 : $AA74 $AA80 $AFF7 $78/120: TALK-Geraeteadresse (Adresse +$40) ROM-Reference: ADC $78 : $AA78 CMP $78 : $AC1E STA $78 : $AA70 $AA7A $AFF3 $79/121: LED-Flag b5: LED-Blinken b6: Drive LED an ROM-Reference: AND $79 : $CE2B LDA $79 : $81EA $81F6 $9569 $957D $B128 $B131 $B143 $B14B $C546 $C54F $C558 $C561 $CE11 $CE27 STA $79 : $81EE $81FA $956D $9581 $B12C $B135 $B147 $B14F $C54A $C553 $C55C $C565 $7A/122: Zwischenspeicher fuer die Sekundaeradresse ROM-Reference: LDA $7A : $9685 $96B4 LDX $7A : $9729 STA $7A : $967A $7B/123: Befehlsmodus-Flag >0 bedeutet, dass ein Befehl ueber den Bus an das Laufwerk gesendet worden ist, und dass er analysiert werden muss. ROM-Reference: INC $7B : $8EAE LDA $7B : $B0F7 STA $7B : $B0FD $7C/124: Burst-Kommandobyte ROM-Reference: BIT $7C : $B928 $BACB $BB37 $BBDA $BC7D $BE1A $BEA9 $BEBB $BECF $BEDD LDA $7C : $BB18 $BB28 $BB79 $BBBD $BC05 $BC0E $BC2F $BC74 $BCD1 $BE2D $C05B STA $7C : $89A0 $BB7D $BC33 $C060 $7D/125: Zwischenspeicher fuer Jobstatus (Wird nur gesetzt, nicht abgefragt) ROM-Reference: LDA $7D : $CD57 STA $7D : $CD3B $CD55 $7E-$7F/126-127: Cache-Pufferzeiger fuer Burst-Befehle ROM-Reference: LDA ($7E),Y: $B96E $B979 $B984 $B989 $B99B $B9A7 $B9AE $B9BA $B9C5 $BAE1 $BB57 STA ($7E),Y: $BBA7 $BC59 STY $7E : $B962 $BADB $BB44 $BB87 $BC9B INC $7F : $BB62 $BC5E STA $7F : $B96C $BADF $BB4E $BB8B $BCAF $80/128: Burst-Status b0-3: Fehlercode b4-5: Sektorengroesse b6 : Laufwerksnummer b7 : 1: Fremdformat ROM-Reference: LDA $80 : $BF6B $BFAB STA $80 : $BECB $BF79 STX $80 : $BCBB $81/129: DOS-Fehlerunterdrueckung (Burstzugriff) $80: Fehlermeldung unterdruecken $00: Fehler ausgeben ROM-Reference: ASL $81 : $BCCE $BEED $BF39 BIT $81 : $950F $9539 $C00C STA $81 : $BCC6 $BEE5 $BF34 $82/130: Zwischenspeicher im Controller-Programm beim ' echten' Laden/Speichern (nicht nur Cachezugriffe) ROM-Reference: LDY $82 : $C4F1 $C67A $C754 $C854 $C97C $CA7F STY $82 : $C4EB $C671 $C74B $C84B $C973 $CA79 $83/131: Nummer des aktiven Jobs $80: kein Job angefordert/aktiv (dient als Zaehler und als Index bei Jobbehandlung) ROM-Reference: LDX $83 : $C70C $C80C $CB26 $CEC6 $CEE6 $CF0D $CF2A $CF64 LDY $83 : $C0D7 $C0FF $C39B $C56A $C599 $CDCC $CDE2 STA $83 : $C0C3 $C3A2 STY $83 : $C0DE $CDDD $84/132: Nummer der aktiven Jobroutine (0-32) ROM-Reference: LDA $84 : $C152 STA $84 : $C0E8 $85-$86/133-134: Steuer-Bits fuer Jobbearbeitung (s. $c163) ROM-Reference: ASL $85 : $C0F8 $C104 $C10B $C112 $C119 $C131 $C149 $CEE2 $CF4E STA $85 : $C0EE ASL $86 : $CEDC $CF7C $CF80 $CF98 STA $86 : $C0F3 $87/135: b7: 1: Cache Puffer veraendert ROM-Reference: ASL $87 : $C9EB LDA $87 : $B10F $B15B $BF24 $C11D STA $87 : $BC2D $BF22 $C01B $C2F7 $CDD9 $CE40 $CEAD $CF94 $88/136: Solltrack (bei Kopfbewegung) ROM-Reference: CMP $88 : $CAE9 LDA $88 : $C3AF $C3D6 $C703 $C803 $C903 $C9D7 $CA03 $CB5A $CE78 $CE8F STA $88 : $C123 $C13A $CB1C $89/137: AND-Maske fuer Burst-Status ROM-Reference: AND $89 : $BF75 STA $89 : $B079 $BEDB $8A/138: OR-Maske fuer Burst-Status ROM-Reference: BIT $8A : $84E3 LDA $8A : $8F0B $8F5D $BAB3 $BB81 ORA $8A : $BF77 STA $8A : $8F0F $8F61 $B075 $BED6 $8B-$8C/139-140: Zeiger auf Cachepuffer ROM-Reference: LDA $8B : $CFB7 STA $8B : $B07D ADC $8C : $B96A $BB4C $BCAD $CB8E $CEBC $CF70 LDA $8C : $C6AC $C9AE $CAB6 $CFBB STA $8C : $B081 $8D/141: E/A Byte b5: 1: Super-Side-Sektoren unterdruecken b6: 0: keine Pruefsumme bilden b7: 0: Automatisches Verify ausschalten ROM-Reference: BIT $8D : $C9E1 $CD32 LDA $8D : $AA9A $B484 ORA $8D : $AAA3 STA $8D : $8F71 $AA9E $AAA5 $B093 STX $8D : $8FC0 $8E/142: Nummer der ersten physikalischen Spur ROM-Reference: LDA $8E : $CB18 STA $8E : $B0B5 $BE18 $8F/143: Nummer der letzten physikalischen Spur ROM-Reference: CMP $8F : $CB5C LDA $8F : $BDA8 STA $8F : $B0C7 $BDAE $BDED STX $8F : $B7F2 $90/144: Starttrack der aktuellen Partition ROM-Reference: CMP $90 : $94BE $B49D $B6A7 $B703 CPX $90 : $B694 LDA $90 : $8746 $B800 $BDA2 $BDCB LDX $90 : $8F90 STA $90 : $B0B9 $B7EB $BDF3 STY $90 : $BDC4 $91/145: Sektorengroesse $00: 128 Bytes $01: 256 Bytes $02: 512 Bytes $03: 1024 Bytes ROM-Reference: LDA $91 : $8F1B $A959 $C473 LDX $91 : $BB50 $BC38 $BCA3 $BD85 $BD9B $BF69 $CF1B $CF3E LDY $91 : $C4D4 $C62D $C660 $C739 $C839 $C92E $C961 $CA2E $CA61 STA $91 : $BD29 $BD7E $CFB1 STY $91 : $B0D5 $92/146: Anzahl Sektoren auf der Spur ROM-Reference: CPY $92 : $BEB6 LDA $92 : $BE8C $C3E2 $C615 $C916 $CA16 LDY $92 : $C097 $C0AA STA $92 : $B0DA $BCFA $BDB3 $BE68 $93/147: letzter Sektor auf der Spur ROM-Reference: CMP $93 : $C61C $C6A8 $C91D $C9AA $CA1D $CAB2 STA $93 : $B0DC $BCFC $BDBB $BE87 $94/148: 1. Sektornummer auf der Spur ROM-Reference: ADC $94 : $BDB6 $CF25 LDA $94 : $BFEC $C06A $C3DE $C621 $C641 $C6B0 $C922 $C942 $C9B2 $CA22 $CA42 $CABA SBC $94 : $BCA1 $C628 $C929 $CA29 $CF3C $CFE4 STA $94 : $BCF1 $BD3D $BD99 $BE82 STY $94 : $B0E2 $95/149: Aktueller Track (im Cache Puffer) $80: Cache ist leer ROM-Reference: CMP $95 : $CF56 LDA $95 : $BFE8 $C121 $C603 STA $95 : $BF1E $C01F $C2F3 $C597 $C9D9 $CE44 STY $95 : $CDDB $96/150: Diskettenseite des aktuellen Jobs ROM-Reference: INC $96 : $CB52 LDA $96 : $C14D $C453 $C912 $C9D3 $CA12 $CB39 $CB54 $CF5A STA $96 : $CB37 $CF06 $CF2F $97/151: Aktuelle Seite (im Cache Puffer) ROM-Reference: CMP $97 : $CF5C LDA $97 : $C129 STA $97 : $BF19 $C571 $C59E $C9D5 $98/152: Kopfberuhigungszeit nach Verschiebung ROM-Reference: LDY $98 : $CB1E $CD9C $CE9C STA $98 : $C345 $99/153: Index fuer 2-Byte Jobspeicher (z.B. T&S) ROM-Reference: LDY $99 : $C135 $C589 $CAF4 $CB68 $CEB6 $CEE0 $CF51 STA $99 : $C0E3 $9A/154: Groesse der Luecke zwischen zwei Sektoren ROM-Reference: LDX $9A : $C50E STA $9A : $B0ED $BD45 $BDA0 $9B/155: Fuellbyte fuer Datenblock $00: beim normalen Formatieren ('n:xx,y') $e5: beim normalen BURST-Formatieren $f5: Statt eines Fuellbytes wird der Cacheinhalt genommen. (wenn nicht formatiert wird, damit der Verify funktioniert; s. $c4e5, $ca73). ROM-Reference: LDA $9B : $BDA5 $C4E5 $CA73 LDY $9B : $8759 STA $9B : $875D $B0E9 $BDC9 $BDF0 STY $9B : $8764 $9C/156: Zaehler fuer Cache-Verzoegerungszeit ROM-Reference: DEC $9C : $CE0F LDA $9C : $B151 $CE0B STA $9C : $ABD2 $9D/157: Cache-Verzoegerungszeit ROM-Reference: LDA $9D : $ABD0 STA $9D : $AA36 $B09C $9E/158: Blinkzaehler fuer LED ROM-Reference: DEC $9E : $CE17 STA $9E : $CE1D $9F-$A7/159-167: (???) b0-6: Position des Sektors im Cachepuffer (Hi-Byte) b7=1: T&S sind bereits ins physikalische Format umgewandelt worden: Normalerweise sind fuer die bearbeitung eines Jobs mehrere Durchlaeufe des Controllerpro- gramms notwendig. Die T&S muessen aber nur beim 1. Mal umgewandelt werden. ROM-Reference: LDA $009F,Y: $B964 $BB46 $C0CC LDA $9F,X : $CEE8 $CF6B STA $009F,Y: $C0D1 STA $9F,X : $CF17 $CF47 $A8-$BA/168-186: Sekundaeradressentabelle b0-3 Kanalnummer fuer die Sekundaeradresse b76= 00: Lesen 01: Lesen/Schreiben 10: Schreiben ROM-Reference: LDA $00A8,Y: $9B31 $9BE7 LDA $A8,X : $8A37 $9037 $904B $91A7 $9274 $99A1 $9CF9 $A81B $B117 STA $00A8,Y: $9B36 $9BEE STA $A8,X : $8A3B $916D $91B3 $98F4 $B02E STA $B7 : $B04D STA $B8 : $B049 LDA $B9 : $87DB STA $B9 : $87E1 STA $BA : $87DD $BB-$CC/187-204: Pufferzeiger 0-8 ROM-Reference: DEC $BB,X : $93B7 $B1BF $B1C1 $B215 $B217 INC $BB,X : $8EC2 $9093 $9098 $9348 $A023 $A0B7 LDA $00BB,Y: $850B $B229 LDA $BB,X : $9087 $933D $934F $944B $9FA1 $A0B0 $A0D3 LDA ($BB,X): $8B6E $8F2F $8F38 $9084 $9096 $934A $93B3 $9F7E $A0C9 LDY $BB,X : $A008 STA $00BB,Y: $9221 $9BA5 $9BB4 STA $BB,X : $8A53 $8C04 $8F2D $8F36 $9013 $9090 $90C8 $9140 $9346 $93B1 $942F $9E2F $B00C $B012 $B01C $B1F2 $B398 STA ($BB,X): $8EC0 $A006 LDA $00BC,Y: $8510 LDA $BC,X : $90C2 $9429 $9447 $9D6E STA $BC,X : $939D $9E2C $B020 STA $BD,X : $B024 STA $BE,X : $B028 $CD-$CE/205-206: Zeiger in INPUT-Puffer ROM-Reference: LDA ($CD),Y: $801B $8123 $8259 $8284 LDY $CD : $8165 STA $CD : $81B2 $9959 $A803 STY $CD : $805F $CF-$D0/207-208: Zeiger in ERROR-Puffer ROM-Reference: DEC $CF : $9389 INC $CF : $A8A5 STA $CF : $896F STA ($CF),Y: $A85E $A87C $A88B $A895 $A902 $A90A STX $CF : $A871 STA $D0 : $8973 STX $D0 : $A875 $D1-$D7/209-215: 1. Puffer fuer Kanal ROM-Reference: LDA $00D1,Y: $8A49 LDA $D1,X : $8D82 $8D8C $8DA4 $8DCF $8DE7 $8E0F $8E4F $9073 $90B8 $90DF $90EA $91D0 $9240 $9298 $92A5 $9B9D $9F13 $9F20 $9F35 LDY $D1,X : $8DBB $9F42 STA $00D1,Y: $9174 $918E $92D3 STA $D1,X : $8A2B $8D90 $8DBF $8E13 $8E53 $91D9 $924F $9F46 $A099 $A0A3 $A4D1 $B035 STA $D6 : $B041 STA $D7 : $B045 $D8-$DE/216-222: 2. Puffer fuer Kanal b0-3: Puffernummer b6 : 1: Flag 'Puffer geaendert' b7 : 1: Puffer inaktiv ROM-Reference: LDA $D8,X : $8D86 $8D93 $8DA8 $8DD3 $8DEB $8E15 $8E55 $9077 $90BC $90E3 $90EE $91E1 $9244 $9BA8 $9F17 $9F2A $9F39 STA $00D8,Y: $9177 $919A STA $D8,X : $8D97 $8DC3 $8E19 $8E59 $91EA $9BAC $9F49 $B037 $DF-$E4/223-228: Tabelle: Am laengsten inaktive Kanaele ROM-Reference: LDA $00DF,Y: $8D6C LDX $DF,Y : $9296 STA $DF,X : $8D5C $8D65 STX $DF,Y : $8D6F STA $E4,X : $81D3 $E5-$E9/229-233: Dir-Block, in dem Dateieintrag ist ROM-Reference: CMP $E5,X : $9D21 LDA $E5 : $87B8 $97DA LDA $E5,X : $8849 $9885 STA $E5 : $9662 STA $E5,X : $8399 CMP $E6 : $87BA LDA $E6 : $88DC STA $E9,X : $81D5 $EA-$EE/234-238: Zeiger in den Dir-Block mit dem Eintrag ROM-Reference: CMP $EA,X : $9D28 LDA $EA : $87B2 $97DF LDA $EA,X : $8853 $988A STA $EA : $9669 STA $EA,X : $8395 CMP $EB : $87B4 LDA $EB : $88E6 STA $EE,X : $81D7 $EF-$F3/239-243: Drivenummern der Parameter ROM-Reference: CMP $EF : $88CE EOR $EF,X : $833D LDA $EF : $87AC $95C4 $B34B LDA $EF,X : $83BA $9D16 STA $EF : $88D4 $9675 $9695 $990E STA $EF,X : $821B $83BE CMP $F0 : $87AE LDA $F0 : $88C8 STA $F0 : $88CC STA $F3,X : $81D9 $F4-$F8/244-248: Dateitypen und Flags fuer Joker b0-2: Dateityp $00: DEL-File $01: SEQ-Datei $02: PRG-File $03: USR-File $04: REL-Datei $05: CBM-Bereich $07: Direktzugriff b5 : 1: offene Datei b6 : 1: Scratch-Schutz b7 : 1: Joker im Filenamen ROM-Reference: AND $F4,X : $83B4 $86F0 BIT $F4 : $977C $9800 LDA $F4 : $9743 $9773 $97A2 $9809 $B7BF $B92C LDA $F4,X : $831D $838B $83EB $885B STA $F4 : $9671 $9699 $991B STA $F4,X : $8147 $8161 $83B8 LDA $F5 : $8903 $F9-$FF/249-255: Dateitypentabelle b0 : Drivenummer b1-3: Dateityp (siehe $f4-$f8) b4 : ??? b5 : 1=aktueller Record ist voll b6 : 1=REL-Datei wurde geaendert (Dir. updaten) b7 : 1=gesuchter Record existiert nicht / Fileende erreicht ROM-Reference: AND $F9,X : $9CDF $9CE6 LDA $00F9,Y: $9D0C LDA $F9,X : $9061 ORA $F9,X : $9CD7 STA $00F9,Y: $8A57 $96AA STA $F9,X : $9955 $9B1A $9BD8 $9CE1 $0100/256: Gruppennummer des aktuellen Records $ff: keine Gruppe angewaehlt ROM-Reference: CMP $0100 : $A3EE DEC $0100 : $A5B4 INC $0100 : $A30C LDA $0100 : $889D $9A0C $9ED8 $A353 $A443 $A5B7 STA $0100 : $88BF $8CBD $A5AB $0101/257: Modus der REL-Datei b4: 1: 2. Teil eines Records geladen b5: 0: Super-Side-Sektor verwenden (s. E/A-Byte b5) ROM-Reference: LDA $0101 : $A027 $A0BB $A286 $A28D $A56E STA $0101 : $8F75 $A02C $A0C0 $A292 STX $0101 : $8FC4 $0102-$0108/258-264: Aktuelle Gruppennummer $fe: Super-Side-Sektor geladen $ff: kein (Super-) Side-Sektor geladen ROM-Reference: CMP $0102,X: $A578 $A5C2 STA $0102,X: $9B78 $9CC1 $A592 $A5A5 $A5E9 $A5FC LDA $0104,X: $CE04 $DB26 $0109-$010F/265-271: Sektor des Super-Side Sektors ROM-Reference: LDA $0109,X: $A58B STA $0109,X: $9B73 $9CB9 $0110-$0116/272-278: Track des Super-Side Sektors ROM-Reference: LDA $0110,X: $A586 STA $0110,X: $9B6D $9CB1 $0117-$018F/279-399: Stackbereich $0190-$0191/400-401: w b0f0 Haupt-Leerschleife Einsprung von $FF00 ROM-Reference: JMP ($0190): $FF00 STA $0190,Y: $FFB2 $0192-$0193/402-403: w dafd Interrupt-Routine Einsprung von $FF03 ROM-Reference: JMP ($0192): $FF03 $0194-$0195/404-405: w afca Warmstartvector Einsprung von $FF06 ROM-Reference: JMP ($0194): $FF06 $0196-$0197/406-407: w b262 VALIDATE Einsprung von $FF09 ROM-Reference: JMP ($0196): $FF09 $0198-$0199/408-409: w 8ec5 INITIALIZE Einsprung von $FF0C ROM-Reference: JMP ($0198): $FF0C $019A-$019B/410-411: w b781 Partition Einsprung von $FF0F ROM-Reference: JMP ($019A): $FF0F $019C-$019D/412-413: w 892f Memory-Read/Write Einsprung von $FF12 ROM-Reference: JMP ($019C): $FF12 $019E-$019F/414-415: w 8a5d Block-Befehle Einsprung von $FF15 ROM-Reference: JMP ($019E): $FF15 $01A0-$01A1/416-417: w 898f USER Einsprung von $FF18 ROM-Reference: JMP ($01A0): $FF18 $01A2-$01A3/418-419: w a1a1 POSITION (RECORD) Einsprung von $FF1B ROM-Reference: JMP ($01A2): $FF1B $01A4-$01A5/420-421: w a956 Utility-Loader (&) Einsprung von $FF1E ROM-Reference: JMP ($01A4): $FF1E $01A6-$01A7/422-423: w 876e COPY Einsprung von $FF21 ROM-Reference: JMP ($01A6): $FF21 $01A8-$01A9/424-425: w 88c5 RENAME Einsprung von $FF24 ROM-Reference: JMP ($01A8): $FF24 $01AA-$01AB/426-427: w 8688 SCRATCH Einsprung von $FF27 ROM-Reference: JMP ($01AA): $FF27 $01AC-$01AD/428-429: w b348 NEW Einsprung von $FF2A ROM-Reference: JMP ($01AC): $FF2A $01AE-$01AF/430-431: w a7ae Error-Routine des Controllers Einsprung von $FF2D ROM-Reference: JMP ($01AE): $FF2D LDA $01AE : $BA7C STA $01AE : $AA1E $BA69 $BA98 LDA $01AF : $BA82 STA $01AF : $AA23 $BA6E $BA9E $01B0-$01B1/432-433: w abcf ATN-bearbeiten Einsprung von $FF30 ROM-Reference: JMP ($01B0): $FF30 $01B2-$01B3/434-435: w ad5c Daten auf ser. Bus Einsprung von $FF33 ROM-Reference: JMP ($01B2): $FF33 $01B4-$01B5/436-437: w aeb8 Daten vom ser. Bus Einsprung von $FF36 ROM-Reference: JMP ($01B4): $FF36 $01B6-$01B7/438-439: w c0be Controller-Routine Einsprung von $FF39 ROM-Reference: JMP ($01B6): $FF39 $01B8-$01B9/440-441: w cedc log. in phy. Format Einsprung von $FF3C ROM-Reference: JMP ($01B8): $FF3C $01BA-$01BB/442-443: w a7f1 Error-Routine des DOS Einsprung von $FF3F ROM-Reference: JMP ($01BA): $FF3F LDA $01BA : $BA88 STA $01BA : $AA14 $BA73 $BAA4 LDA $01BB : $BA8E STA $01BB : $AA19 $BA78 $BAAA $01BC-$01CD/444-461: Jobspeicher HDRS2 Physikalische Spur/Sektor fuer jeden Job ROM-Reference: LDA $01BC,Y: $C137 $C594 $CB6A $CF53 STA $01BC : $BE21 STA $01BC,Y: $CB70 $CEF3 $CF34 LDA $01BD,Y: $CAF6 STA $01BD,Y: $CF4A $01CE-$01D6/462-470: Jobspeicher SIDS Physikalische Seite fuer jeden Job ROM-Reference: LDA $01CE,X: $CF2C LDA $01CE,Y: $C56C $C59B STA $01CE,X: $BB2C $BC12 $BCD9 $BE35 $01D7-$01D8/471-472: Timer B Wert im Hi/Lo-Format ROM-Reference: LDA $01D7 : $CB9F STA $01D7 : $C301 LDA $01D8 : $CBA5 STA $01D8 : $C306 $01D9/473: Anlaufzeit des Motors ROM-Reference: LDA $01D9 : $CD6E STA $01D9 : $B097 $01DA/474: Controller-Befehl: 'Restore' ROM-Reference: INC $01DA : $C377 LDA $01DA : $CB0F STA $01DA : $C30E $01DB/475: Controller-Befehl: 'Seek' ROM-Reference: INC $01DB : $C37A LDA $01DB : $CE86 STA $01DB : $C313 $01DC/476: Controller-Befehl: 'Step' ROM-Reference: INC $01DC : $C37D STA $01DC : $C318 $01DD/477: Controller-Befehl: 'Step-in' ROM-Reference: INC $01DD : $C380 LDA $01DD : $CD8A STA $01DD : $C31D $01DE/478: Controller-Befehl: 'Step-out' ROM-Reference: INC $01DE : $C383 LDA $01DE : $CD93 STA $01DE : $C322 $01DF/479: Controller-Befehl: 'Read Sector' ROM-Reference: LDA $01DF : $C833 $C95B $CA5B STA $01DF : $C327 $01E0/480: Controller-Befehl: 'Write Sector' ROM-Reference: LDA $01E0 : $C65A $C733 $CFEA $CFFC STA $01E0 : $C32C $CFEF $D001 $01E1/481: Controller-Befehl: 'Read Adress' ROM-Reference: LDA $01E1 : $CD0D STA $01E1 : $C331 $01E2/482: Controller-Befehl: 'Read Track' ROM-Reference: STA $01E2 : $C336 $01E3/483: Controller-Befehl: 'Write Track' ROM-Reference: LDA $01E3 : $C3E6 $CFF2 $D004 STA $01E3 : $C33B $CFF7 $D009 $01E4/484: Controller-Befehl: 'Force Interrupt' ROM-Reference: LDA $01E4 : $CFD1 STA $01E4 : $C340 $01E5/485: 1. Sektor des Verzeichnisses ROM-Reference: LDA $01E5 : $8431 $B402 $B424 $B50A STA $01E5 : $8F31 $B0BD $B3AE STX $01E5 : $8FBB $01E6-$01E7/486-487: Zwischenspeicher Sprungvektor der Controller-Error-Routine ROM-Reference: LDA $01E6 : $BA95 STA $01E6 : $BA7F LDA $01E7 : $BA9B STA $01E7 : $BA85 $01E8-$01E9/488-489: Zwischenspeicher Sprungvektor der DOS-Error-Routine ROM-Reference: LDA $01E8 : $BAA1 STA $01E8 : $BA8B LDA $01E9 : $BAA7 STA $01E9 : $BA91 $01EA/490: Zwischenspeicher: (Burst-) Status/Fehlercode ROM-Reference: LDA $01EA : $BB02 $BBB4 $BBDE $BC6B $BC81 $BF7B ORA $01EA : $BF6F STA $01EA : $BB76 $BBFB $BF66 $01EB/491: 1581-Formatkennzeichen 'D' ROM-Reference: CMP $01EB : $8F4E $8F58 $9493 $B388 LDA $01EB : $B3B4 $B463 STA $01EB : $B08E $01EC/492: DOS-Versionsnummer '3' ROM-Reference: LDA $01EC : $B3D1 STA $01EC : $B089 $01ED-$01EE/493-494: Laenge der Partition $01EE: Zwischenspeicher fuer Filetyp ROM-Reference: ADC $01ED : $B880 DEC $01ED : $B2F9 LDA $01ED : $B2F4 $B317 $B8BD STA $01ED : $86CA $B338 $B879 DEC $01EE : $B2FC LDA $01EE : $86AD $B2EF $B87D $B8B7 ORA $01EE : $B31A STA $01EE : $86A3 $86C4 $B332 $B872 $01EF/495: kleinste gefundene Sektornummer (BURST) ROM-Reference: LDA $01EF : $BE7F $BE96 $C041 STA $01EF : $BCEE $C0A7 STY $01EF : $B0E4 $01F0/496: groesste gefundene Sektornummer (BURST) ROM-Reference: CMP $01F0 : $C050 LDA $01F0 : $BE84 $BE9C SBC $01F0 : $C070 STA $01F0 : $B0DE $BCFE $BDBD $C0BA $01F1-$01F9/497-505: Hi-Bytes der Pufferadressen ROM-Reference: LDA $01F1,X: $863E $8BEC $9456 $9A95 $9DEA $9E1D $CB28 $CEC8 $CF66 LDA $01F1,Y: $8DD8 $8DF0 $9DE5 $9DFB $B00F STA $01F1,X: $AFFD $01FA/506: Schreibschutz Status $00: Schreiben erlaubt $08: Diskette schreibgeschuetzt andere Werte ergeben falsche Fehlercodes ROM-Reference: LDA $01FA : $CF8A $CF9C STA $01FA : $8EFE $B358 $BF2D $01FB/507: Autoboot-Flag b6: 1: Autoboot ein bei INITIALIZE (Diskinfo) b7: 1: Autoboot ein bei Warmstart (Benutzeroption) ROM-Reference: BIT $01FB : $8ED1 $AFD6 LDA $01FB : $8F03 $8F7D $9145 ORA $01FB : $9150 STA $01FB : $8F08 $8F82 $914A $9153 $AFC2 $01FC-$01FE/508-510: JMP $BA40: Byte auf FSM-Bus ausgeben Einsprung von $B974, $B97C, $B992, $B9A3, $B9AA, $B9B1, $B9C0, $B9C8, $B9E4, $BA00 ROM-Reference: JSR $01FC : $B974 $B97C $B992 $B9A3 $B9AA $B9B1 $B9C0 $B9C8 $B9E4 $BA00 STA $01FC : $FFBA STA $01FD : $FFBF STA $01FE : $FFC4 $01FF/511: (frei) $0200-$0229/512-553: Kommandopuffer ROM-Reference: CMP $0200,X: $822E LDA $0200 : $816C $8185 $978E $B8F1 LDA $0200,X: $823A $8359 $8371 $840D $8517 $852D $878F LDA $0200,Y: $817A $8193 $8A77 $8AAC $8ADA $9761 $98AE $B367 $B863 $B869 $B86F $B876 $BA30 LDX $0200 : $9682 STA $0200 : $991F STA $0200,X: $BA33 STA $0200,Y: $8075 $A944 $BD63 CMP $0201,X: $8229 LDA $0201 : $8173 $818C $892F $9906 $A1A4 LDA $0201,Y: $B36C LDY $0201 : $898F STA $0201 : $9922 LDA $0202 : $8942 $899D $A1C2 $AD3C $BCB2 $BD12 $BD19 $BF02 INC $0203 : $C067 $C08E LDA $0203 : $8936 $A1C8 $AA43 $AA4A $BA16 $BA24 $BAB9 $BB1E $BBC5 $BC15 $BD26 $BE1E $BEC8 $BF1B LDA $0204 : $893B $A1D5 $AA27 $AA2D $AA33 $AAB8 $AB09 $BA0F $BABE $BB23 $BBCA $BC1A $BC9D $BDAB $BED3 $C04D $C081 STA $0204 : $BD82 $C076 $C093 CPY $0205 : $8989 DEC $0205 : $BAE9 $BB66 $BBE8 $BC8B LDA $0205 : $AAB3 $BDB0 $BED8 LDX $0205 : $895E STA $0205 : $BD8A DEC $0206 : $AAD0 $AAF8 $BF44 LDA $0206 : $BF4F LDA $0206,X: $B7B5 LDA $0206,Y: $8983 LDY $0206 : $BDC0 STA $0206 : $BD8F LDA $0207 : $BDC6 STA $0207 : $BD94 LDA $0208 : $BD3A LDA $0209 : $BD42 CMP $020B,Y: $C09C $C0AF LDA $020B,Y: $BEAF $C0A1 $C0B4 STA $020B,Y: $BE59 $022A/554: Aktuelle Befehlsnummer ($80-$89: Block-Befehle) ROM-Reference: LDA $022A : $8A8D $A7DA LDX $022A : $803C $810B STA $022A : $8A87 $98F9 $A7E3 STX $022A : $8032 $967F STY $022A : $81A7 $022B/555: Track des Direktory ROM-Reference: CMP $022B : $B30D $B564 $B590 $B67E CPX $022B : $8F96 LDA $022B : $842C $8477 $8844 $96BE $9A85 $B278 $B3A6 $B40E $B437 $B44E $B4F4 $B6FA $B717 LDX $022B : $8EE9 $B647 $B68E $B6AF STA $022B : $B0CB $B7E8 $022C/556: letzter Track der aktuellen Partition + 1 ROM-Reference: CMP $022C : $8B51 $9486 $94B9 $B4A3 $B689 $B721 CPX $022C : $8F9B LDA $022C : $B519 LDY $022C : $B804 STA $022C : $B0C2 STX $022C : $B7ED $022D/557: Aktueller Dateityp ROM-Reference: CMP $022D : $97A6 $980D LDA $022D : $95BE $963C $966E $9734 $973E $9B15 $9BD3 STA $022D : $81B7 $885F $8907 $93D1 $960A $973B $9747 $9751 $B892 STX $022D : $9710 STY $022D : $98C8 $022E/558: Anzahl der Parameter (vor '=') (Zwischenspeicher) ROM-Reference: CPX $022E : $80F9 $890E $9714 $971D INC $022E : $8AC4 $9910 LDA $022E : $80E2 $8272 LDX $022E : $87FD $8B13 STA $022E : $81C2 $8200 STX $022E : $80C4 $022F/559: Anzahl der Parameter in der Kommandozeile oder auch Anzahl der Filenamen in der Kommandozeile ROM-Reference: CMP $022F : $8275 CPX $022F : $821E $8835 DEC $022F : $827A INC $022F : $9913 LDA $022F : $81FD $83DC $87A5 $A967 $B911 LDX $022F : $890A LDY $022F : $827D STA $022F : $81C5 $8205 $A96D $A982 $B917 $B922 STX $022F : $80C7 $80EE $96FC $0230/560: Anzahl der Parameter vor '=' Zaehler fuer Dateisuche ROM-Reference: DEC $0230 : $83E2 LDX $0230 : $8385 $83E8 $8831 $8841 $8850 $8858 $9870 $9882 LDY $0230 : $8AC7 STA $0230 : $80E5 $81BF $8208 $83DF $87C3 STX $0230 : $8800 STY $0230 : $8AF8 $9819 $0231/561: Zaehler fuer Suche im Directory ROM-Reference: DEC $0231 : $8452 LDA $0231 : $848E STA $0231 : $8444 $0232/562: Zeiger auf den gefundenen Dir-Eintrag ROM-Reference: LDA $0232 : $8392 $8483 $97BE $9A9A STA $0232 : $84A3 $9A82 $0233/563: Dateityp aus der Kommandozeile ROM-Reference: CMP $0233 : $8321 LDA $0233 : $8318 STA $0233 : $81BA $8291 $96D8 $0234-$0239/564-569: Kanalstatustabelle b0: 1: Daten vom Computer holen (Schreiben) b3: 0: EOI (End-Or-Identify) b7: 1: Daten an Computer senden (Lesen) ROM-Reference: LDA $0234,X: $8881 $9313 $AD64 $AD85 $AEBE STA $0234,X: $91B9 $9323 $932B $98EB $9B97 $9BE1 $A0F5 $A1D2 STA $0234,Y: $8A46 $8B81 $90A9 $9358 $A0D0 $A0DD $B1FB $B256 STA $0239 : $B055 $023A/570: Kanalstatus fuer Fehlerkanal ROM-Reference: STA $023A : $93A1 $A8A9 $B05A $023B-$0240/571-576: Ausgabe-Bytes der Kanaele an seriellen Bus ROM-Reference: LDA $023B,X: $92FF $ADC8 $ADF4 STA $023B,X: $9361 $9950 $9B92 $A0F0 $ADF8 STA $023B,Y: $8A4C $8BA3 $934C $A0CB $0241/577: Ausgabe-Byte des Fehlerkanals ROM-Reference: STA $0241 : $93A6 $A882 $0242-$0248/578-584: Anzahl der gueltigen Bytes im Datenblock 0: noch nicht letzter Datenblock ROM-Reference: CMP $0242,Y: $9089 $933F $9351 $A0B2 $A0D5 DEC $0242,X: $B231 LDA $0242,Y: $8BA0 $907F $90A2 $B24F STA $0242,X: $9B27 $9BB9 $A128 $A13F $B18E $B22E STA $0242,Y: $8A41 $8B7C $8BA8 $910C $9FA3 STA $0248 : $896A $A8A2 $0249-$024F/585-591: Aktuelle Recordnummer oder Dateilaenge Lo ROM-Reference: DEC $0249,X: $9A54 INC $0249,X: $901C $9F5A LDA $0249,X: $8CC8 $9A2C $9A4C $9AF5 STA $0249,X: $99F0 $9A1F $9BBC $A1C5 $B8BA $0250-$0256/592-598: Aktuelle Recordnummer oder Dateilaenge Hi ROM-Reference: DEC $0250,X: $9A51 INC $0250,X: $9021 $9F5F LDA $0250,X: $8CCD $9AFB ORA $0250,X: $9A2F STA $0250,X: $99F5 $9A24 $9BBF $A1CB $B8C0 $0257-$025D/599-605: Position des naechsten Records im Block ROM-Reference: CMP $0257,X: $9F6E CMP $0257,Y: $A019 LDA $0257,X: $9D60 $9F64 $9F78 $A0FF $A2BE LDA $0257,Y: $A00F STA $0257,X: $9B7F $9C6D $9FB2 $9FB9 $A2A7 $A2B8 $A384 $025E-$0264/606-612: Aktuelle Recordlaenge ROM-Reference: ADC $025E,X: $A2C5 CMP $025E,X: $A1DF LDA $025E,X: $8CE3 $A10E $A217 $A55F LDX $025E,Y: $A2E1 SBC $025E,X: $9C6A STA $025E,X: $9B3C $9BF4 $0265-$026B/613-619: Side-Sektor-Puffer fuer Kanal ROM-Reference: LDA $0265,X: $91F2 $9C16 $9C84 $9CCD $9DB2 $9E19 $9E3B $9E77 $A183 $A46B $A4C2 $A595 $A5EC STA $0265,X: $91FC $9B49 $9C01 $A4CB $B039 STA $0265,Y: $917A $026C/620: aktuelle Parameterlaenge (s. $8526) ROM-Reference: CMP $026C : $853E INC $026C : $8538 SBC $026C : $84F7 STA $026C : $8528 $026D/621: Nummer des gefundenen Dateinamens ROM-Reference: LDA $026D : $82D9 $8567 LDX $026D : $830C $86EB $9D13 STA $026D : $848B STX $026D : $8329 $8388 STY $026D : $8429 $026E/622: >0: formatiertes Directory wird auf SA 0 ausgegeben ROM-Reference: LDA $026E : $9365 STA $026E : $9962 $B1F8 $026F/623: aktuelle Recordlaenge ROM-Reference: CMP $026F : $9866 LDA $026F : $83CB $9651 $9B39 $9BF1 $9C30 LDX $026F : $985D STA $026F : $81B4 $83D4 $8864 $9764 $9860 STX $026F : $970A $0270/624: Track des aktuellen Super-Side-Sektors ROM-Reference: LDA $0270 : $9645 $9B6A $9C8D $9C9E LDY $0270 : $9B53 STA $0270 : $9851 $9C0C $9CB4 $0271/625: Sektor des aktuellen Super-Side-Sektors ROM-Reference: LDA $0271 : $964B $9B70 $9C93 $9CA4 LDY $0271 : $9B58 STA $0271 : $9857 $9C11 $9CBC $0272-$027A/626-634: Zwischenspeicher fuer Jobcodes ROM-Reference: EOR $0272,X: $95C6 LDA $0272,X: $9282 $956F $9CED STA $0272,X: $8A32 $9219 $94D8 $952C $9554 $9DC1 $B197 $BFDA $BFE5 $027B-$027C/635-636: (frei) $027D-$0283/637-643: Dir-Block mit dem Dateieintrag des Kanals ROM-Reference: LDA $027D,X: $9A7A LDA $027D,Y: $9D1E STA $027D,X: $9664 $97DC STA $027D,Y: $9887 $0284-$028A/644-650: Position des Dateieintrags im Dir-Block ROM-Reference: LDA $0284,X: $9A7F LDA $0284,Y: $9D25 STA $0284,X: $966B $97E1 STA $0284,Y: $988C $028B/651: 1. Sektornummer der letzten Datei ("*") ROM-Reference: LDA $028B : $969B $B8FD STA $028B : $98A5 $B94A $028C/652: Zwischenspeicher (Kanalnummer) ROM-Reference: LDX $028C : $97D7 $9AF0 STA $028C : $97B4 STX $028C : $9A74 $028D/653: Directory: Basic Zeilennummer Lo (Drivenummer, Dateilaenge, 'Blocks Free') ROM-Reference: LDA $028D : $A373 $B1AC $B1D5 $B201 STA $028D : $859B $8636 $B65E $028E/654: Directory: Basic Zeilennummer Hi ROM-Reference: CMP $028E : $A36C LDA $028E : $B1DB $B207 STA $028E : $8580 $8591 $8639 $B664 $028F/655: Zwischenspeicher fuer Zeichensuche ROM-Reference: CMP $028F : $8025 $8126 STA $028F : $801D $811C $0290/656: Zeiger hinter aktuellen Parameter (s. $8526) ROM-Reference: CPX $0290 : $836C $8520 LDX $0290 : $83FC $B7B2 LDY $0290 : $B85F SBC $0290 : $B859 STA $0290,X: $81D0 STX $0290 : $8547 $0291-$0296/657-662: Position der Parameter in der Kommandozeile $0291: Position der Drivenummer in Kommandozeile Position des 1. Filenamens ROM-Reference: INC $0291 : $9916 LDA $0291 : $9628 LDA $0291,X: $820F $834D LDA $0291,Y: $8280 LDX $0291 : $878C $88F2 $B39A LDY $0291 : $8256 LDY $0291,X: $975E $98AB STA $0291 : $A961 $B78C $B90B $BD74 STA $0291,X: $80DF $8217 STX $0291 : $8087 STY $0291 : $8093 $80AE $96F3 $9933 LDY $0292 : $B360 STA $0292 : $BD6F STA $0292,X: $813B $8155 STA $0296,X: $81DB $0297-$029B/663-667: Werte aus Kommandozeile Hi-Bytes Tracknummer(n) der Datei(en) ROM-Reference: LDA $0297 : $974A $9767 $9786 $97ED $A977 $A985 $B795 $B934 LDA $0297,X: $83EF $86F4 $8913 $8921 $9873 STA $0297 : $9617 STA $0297,X: $83C2 $8B18 STA $029B,X: $81DE $029C-$02A0/668-672: Werte aus Kommandozeile Lo-Bytes Sektornummer(n) der Datei(en) ROM-Reference: LDA $029C : $8A28 $A98A $B947 LDA $029C,X: $86F9 $8C13 $9878 LDX $029C : $8A04 STA $029C : $961E $B900 STA $029C,X: $83C8 $8B1C LDA $029D : $8C01 LDA $029D,X: $8C39 $8C4E LDA $029E,X: $8C34 $8C49 $02A1/673: Jokerflag: Aktueller Dateiname enthaelt '*' oder '?' ROM-Reference: INC $02A1 : $8133 LDA $02A1 : $80CA $80F2 $813E $8158 STA $02A1 : $80D9 $8149 $81C8 $838F STX $02A1 : $832D $02A2/674: Bitmaske bei Kommandozeilen-Test ROM-Reference: DEC $02A2 : $826A EOR $02A2 : $8102 LDA $02A2 : $8108 $8785 $879B ORA $02A2 : $80D1 STA $02A2 : $80C0 $80D4 $8105 $8253 $02A3/675: Anzahl der Laufwerke ROM-Reference: CMP $02A3 : $8348 DEC $02A3 : $82C5 $82FE STA $02A3 : $82A9 $02A4/676: eine Art Drivenummer (bei Directory-Laden) ROM-Reference: DEC $02A4 : $8576 LDA $02A4 : $8571 STA $02A4 : $82A6 $8583 $02A5/677: Such-Ergebnis $00: Es existieren noch nicht gefundene Dateinamen $ff: Alle angegebenen Dateinamen wurden gefunden ROM-Reference: LDA $02A5 : $82D3 $82E0 $82F9 $8311 STA $02A5 : $82F6 $83D9 $83F6 $02A6/678: Flag fuer Directory-Ende (0: Ende) ROM-Reference: LDA $02A6 : $843C STA $02A6 : $8436 $844C $02A7/679: Zugriffsart aus Kommandozeile (R,W,A,M) ROM-Reference: LDA $02A7 : $9754 $97F7 $9840 LDX $02A7 : $981C STA $02A7 : $976E STX $02A7 : $970D $9731 STY $02A7 : $98BB $02A8/680: Fehlerpruefung ausschalten b6: 1: T&S nicht auf Gueltigkeit pruefen b7: 1: Job-Fehlerbehandlung ausschalten ROM-Reference: BIT $02A8 : $9476 $9513 $953D $C010 LDA $02A8 : $BFCE STA $02A8 : $84C0 $84DD $8C58 $94F3 $9531 $B161 $BFB3 $BFC7 $BFD3 $02A9-$02AA/681-682: Anzahl freie Blocks ROM-Reference: ADC $02A9 : $8FA6 DEC $02A9 : $B59D INC $02A9 : $B569 LDA $02A9 : $B595 $B5A5 $B65B $B814 STA $02A9 : $8FA9 $B4F1 $B83A $B846 STX $02A9 : $8F8A $8FCB DEC $02AA : $B59A INC $02AA : $8FAE $B56E LDA $02AA : $B5A0 $B661 $B818 STA $02AA : $B836 $B842 STX $02AA : $8F8D $8FCE $02AB/683: Fehlernummer ROM-Reference: LDA $02AB : $8050 $9978 $9991 $A056 LDX $02AB : $B13E STA $02AB : $8114 $81CB $81E7 $81F3 $A04D $A1E6 STA $02AB,Y: $8620 $02AC-$02C7/684-711: Directory-Zeile ROM-Reference: AND $02AC,X: $860F LDA $02AC,X: $85F8 LDA $02AC,Y: $B239 STA $02AC : $865A STA $02AC,X: $85C1 $85C8 $85CF $85DD $85E5 $85F0 $8605 $8612 STA $02AC,Y: $8673 STA $02AD : $865F STA $02AD,X: $85B7 $85D8 STA $02AE,Y: $8652 STA $02BE : $8662 STA $02BF : $8667 $02C8-$02CF/712-719: (frei) $02D0-$02FF/720-767: Fehlerpuffer fuer Meldungen im Klartext ROM-Reference: LDA $02D0 : $A87F $0300-$03FF/768-1023: Puffer 0 $0400-$04FF/1024-1279: Puffer 1 $0500-$05FF/1280-1535: Puffer 2 (User-Puffer) $0500/1280: Einsprung des Kommandos "U3" $0503/1283: Einsprung des Kommandos "U4" $0506/1286: Einsprung des Kommandos "U5" $0509/1289: Einsprung des Kommandos "U6" $050C/1292: Einsprung des Kommandos "U7" $050F/1295: Einsprung des Kommandos "U8" $0600-$06FF/1536-1791: Puffer 3 $0700-$07FF/1792-2047: Puffer 4 $0800-$08FF/2048-2303: Puffer 5 $0900-$09FF/2304-2559: Puffer 6 $0A00-$0AFF/2560-2815: Puffer 7 (BAM Teil 1) $0A00: $00 = Keine BAM geladen ROM-Reference: LDA $0A00 : $B5F6 STA $0A00 : $8770 $8F3E $B451 STA $0A00,Y: $B440 STA $0A01 : $B45B STA $0A02 : $B466 STA $0A03 : $B46E STA $0A04 : $B476 STA $0A05 : $B47E STA $0A06 : $B486 STA $0A07 : $B48E $0B00-$0BFF/2816-3071: Puffer 8 (BAM Teil 2) ROM-Reference: STA $0B00 : $B456 STA $0B00,Y: $B443 STA $0B01 : $B460 STA $0B02 : $B469 STA $0B03 : $B471 STA $0B04 : $B479 STA $0B05 : $B481 STA $0B06 : $B489 STA $0B07 : $B491 $0C00-$1FFF/3072-8191: Cache-Puffer $1FFF/8191: End of RAM +------------------------------------------------------------------------ | | DISK-DRIVE 1581: ROM-LISTING | +------------------------------------------------------------------------ | | Comments done by Peter Steiner, used with permission. | | $8000/32768 Checksumme | $8004/32772 Befehlsstring vom Computer auswerten ($c146) | $804C/32844 Abschluss eines Befehls ($c194) | $8071/32881 INPUT-Puffer loeschen ($c1bd) | $807C/32892 Fehler ausgeben mit T&S = 00 ($c1c8) | $8085/32901 Sucht Drivenummer in der Befehlszeile ($c1d1) | $8099/32921 Eingabezeile bis zum ':' auswerten ($c1e5) | $80A2/32930 Eingabezeile pruefen bei Copy, Rename, New ($c1ee) | $811C/33052 Eingabezeile bis zu einem bestimmten Zeichen auswerten ($c268) | $8165/33125 Kommandozeilenende feststellen (CR (/LF) entfernen) ($c2b3) | $81E5/33253 LED-Routinen ($c100) | $81FD/33277 Laufwerksnummer holen und setzen ($c312) | $820B/33291 Alle Parameter auf Laufwerksnummer pruefen und diese ggf. loeschen ($c320) | $8224/33316 Laufwerksnummer testen und entfernen ($c33c) | $8251/33361 Drivenummer setzen, LED einschalten ($c368) | $8270/33392 Dateityp feststellen ('s,p,u,r,c') (z.B. '$*=s') ($c398) | $8295/33429 Laufwerksnummer pruefen ($c3bd) | $82A2/33442 Drive initialisieren, LED einschalten ($c3ca) | $82B9/33465 alle angegebenen Dateien im Directory suchen ($c44f) | $82E6/33510 Dateien einzeln suchen ($c48b) | $8327/33575 Eintrag im Directory mit gesuchten Eintraegen vergleichen ($c4d8) | $83D7/33751 Prueft, ob alle Dateien gefunden worden sind ($c617) | $83FA/33786 1581: Zeichen hinter '*' vergleichen | $8424/33828 naechsten Eintrag im Directory suchen : ($c5ac) | $84AE/33966 Testet auf Diskettenwechsel und initialisiert ggf. ($c63d) | $84EE/34030 Parameter aus dem INPUT-Puffer in Disk-Puffer kopieren ($c66e) | $8526/34086 Laenge eines Parameters ermitteln ($c6a6) | $854D/34125 Directory-Zeile im Zwischenpuffer erzeugen ($c6ce) | $8688/34440 Scratch ($c823) | $8746/34630 Partition formatieren | $876E/34670 Copy ($c8f0) | $8841/34881 aktuelles File oeffnen ($c9fa) | $8876/34934 Byte aus aktueller Datei holen und auf Dateiende pruefen ($ca35) | $8895/34965 REL-File zum Kopieren vorbereiten ($ca53) | $88C5/35013 RENAME ($ca88) | $8903/35075 aktuellen Filetyp ermitteln und | $891E/35102 pruefen, ob alle Files vor dem '=' nicht existieren | $892F/35119 Memory-Befehle ($caf8) | $898F/35215 User-Befehle ($cb5c) | $89E4/35300 '#', oeffnen eines Direktzugriffkanals ($cb84) | $8A5D/35421 Block-Befehle ($cc1b) | $8A9F/35487 Parameter der Block-Befehle holen ($cc7c) | $8AD0/35536 ASCII-Werte aus dem Input-Puffer in HEX-Werte umwandeln | $8B23/35619 Block-Free ($ccf5) | $8B2F/35631 Block-Allocate ($cd03) | $8B65/35685 Block-Read-Parameter pruefen und Block lesen ($cd36) | $8B6B/35691 Byte aus Puffer holen ($cd3c) | $8B71/35697 Block lesen und Pufferzeiger setzen ($cd42) | $8B85/35717 Block-Read ($cd56) | $8B8E/35726 Super-Read | $8B9A/35738 u1 ($cd5f) | $8BAE/35758 Block-Write ($cd73) | $8BD1/35793 Super-Write | $8BD7/35799 u2 ($cd97) | $8BE3/35811 Block-Execute ($cda3) | $8BFA/35834 Block-Pointer ($cdbd) | $8C0F/35855 Kanal oeffnen ($cdd2) | $8C2F/35887 Kanal oeffnen, Blockparameter holen und testen ($cdf2) | $8C44/35908 Kanal oeffnen, Blockparameter holen und NICHT testen | $8C5C/35932 Puffer allokieren | $8C61/35937 Block-Befehle und Adressen ($cc5d) | $8C89/35977 Position des Records berechnen ($ce0e) | $8CC1/36033 Zahl der Bytes bis zum gesuchten Record berechnen ($ce2c) | $8CE6/36070 24*8-Bit-Multiplikationsroutine ($ce4e) | $8D06/36102 24/8-Bit-Divisionsroutine ($ce71) | $8D38/36152 Rechenregister 1 loeschen ($ced9) | $8D41/36161 Rechenregister 2 *2 bzw. *4 ($cee2) | $8D4C/36172 Rechenregister addieren ($ceed) | $8D59/36185 Feststellen, welcher Kanal schon am laengsten inaktiv ist | $8D7D/36221 Puffer wechseln im Zwei-Puffer-Betrieb ($cf1e) | $8E37/36407 Falls dem Kanal ein Puffer fehlt, einen neuen zuordnen ($cf7b) | $8E4D/36429 Aktiven Puffer wechseln ($cf8c) | $8E5C/36444 Byte ueber internen Schreibkanal in Puffer schreiben ($cf9b) | $8E78/36472 Byte in aktuelle Datei schreiben ($cfb7) | $8EB1/36529 Byte in Puffer schreiben, Pufferzeiger erhoehen ($cff1) | $8EC5/36549 Initialize ($d005) | $8EDC/36572 Blockheader des Verzeichnisheaders suchen | $8F03/36611 Partition initialisieren ($d042) | $8FD6/36822 Block einlesen und Folgeblock merken ($d09b) | $8FEA/36842 Block (und ggf. Folgeblock) im 2-Puffer-Modus lesen ($d0af) | $8FFE/36862 ??? | $9027/36903 Kanal zum Lesen holen und pruefen ($d0eb) | $9042/36930 Kanal zum Schreiben holen und pruefen ($d107) | $905F/36959 Aktuellen Filetyp holen ($d125) | $9069/36969 Kanal- und Puffernummer holen ($d12f) | $9071/36977 Byte aus aktuellem Puffer holen ($d137) | $909B/37019 Byte aus aktueller Datei holen ($d156) | $9112/37138 Schreiben eines Bytes in eine Datei im 2-Puffer Modus. ($d19d) | $9138/37176 Erhoehen des aktuellen Pufferzeigers ($d1c6) | $9145/37189 Autoboot bei Warmstart ein/aus | $9157/37207 Kanal oeffnen und entsprechende Zahl Puffer zuordnen ($d1df) | $919E/37278 Freigeben einer SA ausser der des Kommandokanals; Puffer freigeben ($d227) | $91CE/37326 Puffer und dessen Kanalzuordnung freigeben ($d25a) | $9204/37380 Suchen eines freien oder inaktiven Puffers ($d28e) | $9228/37416 Suchen und belegen eines freien Puffers ($d2ba) | $923E/37438 einen inaktiven Puffer eines Kanals freigeben ($d2da) | $9252/37458 Puffer freigeben <-- Einsprung | $9262/37474 Kanaele der Sekundaeradressen 1-14 freigeben ($d307) | $926E/37486 Die SA 0-14 des Laufwerks 0 freigeben | $9291/37521 'Stehlen' eines inaktiven Puffers ($d339) | $92DB/37595 Freien Kanal suchen ($d37f) | $92F4/37620 Byte fuer beliebige SA holen ($d39b) | $9303/37635 Byte aus beliebigem Kanal holen ($d3aa) | $9370/37744 Fehlerkanal auslesen bzw M-R-Befehl ($d414) | $93AA/37802 Lesen des naechsten Blocks ($d44d) | $93BD/37821 Lesen/Schreiben des aktuellen Puffers ($d460) | $93CF/37839 Datei auf internem Lesekanal oeffnen, | $93E0/37856 Datei auf internem Schreibkanal oeffnen, | $93E7/37863 Neuen Block an das Directory anhaengen ($d48d) | $9422/37922 Pufferzeiger auf bestimmten Wert setzen ($d4c8) | $9434/37940 interne Schreib-/Lesekanaele freigeben ($d4da) | $9450/37968 Holt Byte aus aktuellem Puffer ($d4f6) | $9460/37984 Prueft auf Diskettenwechsel | $9471/38001 T&S auf Gueltigkeit pruefen ($d506) | $94A8/38056 Track und Sektor aus Jobpuffer holen und als aktuelle T&S merken ($d552) | $94B5/38069 Auf gueltigen Block (T&S) pruefen ($d55f) | $94CB/38091 Meldung fuer falsches Formatkennzeichen ausgeben ($d572) | $94D3/38099 Job setzen und Controller aufrufen ($d57a) | $94DE/38110 Schreib-/Lesejobs pruefen und Durchfuehrung abwarten ($d586) | $94F8/38136 Job auf fehlerfreie Durchfuehrung pruefen ($d5a6) | $9585/38277 T&S an DC uebergeben ($d6d0) | $9598/38296 Aufruf des Controllers | $95AB/38315 Neue Datei im Directory eintragen ($d6e4) | $9678/38520 Datei mit SA 0-14 oeffnen ($d7b4) | $9773/38771 File zum Schreiben oeffnen ($d8c6) | $97A2/38818 Oeffnen eines Files mit Ueberschreiben ($d8f5) | $97ED/38893 Zugriffsart feststellen und File zum Lesen oeffnen ($d940) | $984D/38989 Oeffnen eines Files zum Lesen ($d9a0) | $9890/39056 neues File anlegen und zum Schreiben oeffnen ($d9e3) | $9896/39062 T&S eines Files holen und fuer 'LOAD "*",8' merken ($d9ef) | $98AB/39083 File-Modus oder File-Typ aus Kommandozeile holen ($da09) | $98CC/39116 APPEND: Fileende suchen und auf Schreiben umschalten ($da2a) | $98F7/39159 Oeffnen des Directory als Basicprogramm ($da55) | $995C/39260 CLOSE-Routine: aktuelle Sekundaeradresse schliessen ($dac0) | $9986/39302 Alle Dateien schliessen ($daec) | $999F/39327 Datei schliessen ($db02) | $9A2A/39466 letzten Dateiblock abspeichern ($db62) | $9A72/39538 Eintrag im Directory nach dem Schreiben updaten ($dba5) | $9B0D/39693 Kanal zum Lesen suchen | $9B9B/39835 Pufferzeiger initialisieren ($dcb6) | $9BC3/39875 File zum Schreiben oeffnen ($dcda) | $9CCA/40138 Byte in aktuellen Side-Sektor schreiben ($dd8d) | $9CD3/40147 Dateistatus setzen/loeschen ($dd95) | $9CE9/40169 Prueft den Jobcode des aktuellen Puffers auf 'Schreiben' ($ddab) | $9CF5/40181 prueft, ob gesuchtes File durch eine SA angesprochen wird ($ddb7) | $9D2E/40238 Puffer schreiben, wenn er veraendert wurde ($ddf1) | $9D3A/40250 Folgeblock im aktuellen Block eintragen ($ddfd) | $9D49/40265 T&S des Folgeblocks holen ($de0c) | $9D56/40278 Blocklaenge des letzten Datenblocks setzen ($de19) | $9D69/40297 Zeiger auf Anfang des aktiven Puffers setzen ($de2b) | $9D79/40313 T&S der aktuellen Datei holen ($de3b) | $9D8E/40334 Schreib-Lesejobs aufrufen ($de50) | $9DCE/40398 T&S des Folgeblocks des aktiven Kanals holen | $9DDE/40414 Pufferinhalte kopieren ($dea5) | $9DFA/40442 Puffer mit $00 fuellen ($dec1) | $9E0B/40459 Nummer des aktuellen Side-Sektors holen ($ded2) | $9E15/40469 Side-Sektor-Pufferzeiger auf beliebigen Wert setzen ($dedc) | $9E23/40483 Pufferzeiger des aktuellen Side-Sektors auf beliebigen | $9E32/40498 Gruppe anwaehlen, ggf. Side-Sektor laden ($def8) | $9E56/40534 Side-Sektor lesen/schreiben ($df1b) | $9E75/40565 Pufferzeiger des Side-Sektors nach $64-$65 holen ($df45) | $9E7D/40573 Anzahl der benoetigten Blocks einer REL-Datei berechnen ($df4c) | $9E97/40599 Anzahl der benoetigten Blocks einer REL-Datei berechnen | $9ED3/40659 Feststellen, ob Record existiert und ggf. richtige Gruppe anwaehlen ($df66) | $9F11/40721 Nummer des aktiven Puffers holen ($df93) | $9F1C/40732 Aktiven Puffer pruefen und holen ($df9e) | $9F33/40755 Pruefen, ob ein Puffer des Kanals nicht belegt ist ($dfb7) | $9F3E/40766 einem Kanal einen neuen Puffer zuordnen ($dfc2) | $9F4C/40780 naechsten Record holen ($dfd0) | $9FBF/40895 ggf. alten Puffer speichern, dann Folgeblock(s) einlesen ($e03c) | $9FFC/40956 Ein Byte in Record-Puffer schreiben ($e07c) | $A033/41011 Empfangene Daten in Record schreiben ($e0ab) | $A07B/41083 Rest eines Records mit $00 auffuellen ($e0f3) | $A08D/41101 Flag fuer 'Puffer geaendert' setzen ($e105) | $A09C/41116 Flag fuer 'Puffer geaendert' loeschen ($e115) | $A0A6/41126 Byte aus Record-Puffer holen ($e120) | $A0E1/41185 Naechsten Record lesen ($e153) | $A0EC/41196 Abbruch bei Fehler ($e15e) | $A0FD/41213 Letztes benutzte Zeichen im Record suchen ($e16e) | $A15C/41308 Letzten Datenblock einer REL-Datei | $A1A1/41377 Position-Befehl ($e207) | $A20D/41485 gesuchten Record zur Ausgabe bereitstellen ($e275) | $A235/41525 benoetigte Datenbloecke ggf. einlesen ($e29c) | $A298/41624 Puffer mit leeren Records fuellen ($e2e2) | $A2BC/41660 Position des naechsten Records berechnen ($e304) | $A2D6/41686 Bloecke zu REL-File hinzufuegen ($e31c) | $A438/42040 Parameter des letzten Records der Datei merken | $A459/42073 Neuen Side-Sektor zur relativen Datei hinzufuegen ($e31c) | $A547/42311 Wenn Gruppe voll, dann neue Gruppe anlegen | $A56E/42350 Prueft, ob Super-Side-Sektoren verwendet werden, oder nicht | $A574/42356 Super-Side-Sektor laden | $A5A9/42409 letzte existierende Gruppe ermitteln | $A5C0/42432 Gruppe anwaehlen | $A602/42498 Fehlermeldungen ($e4fc) | $A7AE/42926 Error-Routine des Controllers ($e60a) | $A7F1/42993 CmdError: Error-Routine des DOS ($e645) | $A83E/43070 Byte in Ziffernstring umwandeln ($e69b) | $A862/43106 Fehlermeldung bereitstellen ($e6bc) | $A8AD/43181 Fehlertext in Puffer schreiben ($e706) | $A926/43302 Autoboot-Routine | $A938/43320 JCBMBOOT: Autoboot-Programm aufrufen | $A94C/43340 JCBMBOOTRTN: Ruecksprung aus Autoboot-Programm | $A956/43350 Utility-Loader (&) ($e7a3) | $AA0F/43535 Sprungadressen der Error-Routinen merken | $AA27/43559 Sektorversatz einstellen | $AA2D/43565 Anzahl Leseversuche einstellen | $AA33/43571 Cache-Verzoegerung einstellen | $AA39/43577 ROM-Test | $AA3C/43580 Burst-Befehl $1e: CHGUTL (bei der 1571: $8fe5) | $AAA8/43688 Burst-Memory-Read/Write | $AB09/43785 Parameter '0' und '1' auswerten (CHGUTL-Parameter) | $AB1D/43805 ROM-Signatur pruefen (CRC-Test) (bei der 1571: $924e) | | BUS-Routinen | [Ein grosses Problem bei der Kommentierung der Bus-Routinen ist, dass die | Leitungen zwischen dem Computer und den Laufwerken low-aktiv sind und | im Computer sogar die Eingangs-Signale nicht wieder zurueckgekippt werden. | Zwischen den verschiedenen ROM-Listings gehen daher die Meinungen | auseiander, was nun unter einem High- und einem Low-Signal zu verstehen | ist. Weil selbst ein im Computer abgeschicktes Hi wieder als Lo empfangen | wird, wird dort deshalb haeufig der am Bus messbare Pegel benutzt. Dagegen | bezeichnen die mir bekannten DOS-Listings ein 1-Bit im Register als Hi | (bei dem die entsprechende Bus-Leitung dann aber Lo ist), weil dann der | 'aktive' Pegel mit Hi bezeichnet wird. Wenn also die Ausgaberegister Lo | sind, sind die entsprechenden Treiber inaktiv und stoeren andere Geraete | nicht bei der Datenuebertragung. Das bedeutet aber auch, dass das DATA OUT- | auf Lo gesetzt werden muss, wenn ein 1-Datenbit uebertragen werden soll. | Ich habe mich bei der Kommentierung der BUS-Routinen an das System der | mir bekannten DOS-Listings gehalten und bezeichne ein Signal als Hi, wenn | das entsprechende Register-Bit 1 ist.] | | $ABCF/43983 ATN-bearbeiten ($e85b; bei der 1571: $80ce) | $AC9D/44189 FSM: DRF (Device Request Fast) Signal senden (bei der 1571: $8199) | $ACB6/44214 FSM auf Eingang schalten | $ACCF/44239 FSM auf Ausgabe schalten | $ACE8/44264 DATA OUT auf Lo (die Busleitung wird dadurch Hi) | $ACF1/44273 DATA OUT auf Hi (die Busleitung wird dadurch Lo) | $ACFA/44282 CLOCK OUT auf Hi (die Busleitung wird dadurch Lo) | $AD03/44291 CLOCK OUT auf Lo (die Busleitung wird dadurch Hi) | $AD0C/44300 Bus auslesen und entprellen | $AD15/44309 ATN-Modus testen ($ea59; bei der 1571: $ea59) | $AD2F/44335 Kurze Zeit warten (bei der 1571: $a47e) | $AD3C/44348 NMI-Routine ($ff01) | $AD5C/44380 Daten auf seriellen Bus ausgeben ($e909; bei der 1571: $823d) | $AE42/44610 Byte vom seriellen Bus holen ($e9c9; bei der 1571: $82c7) | $AEB8/44728 Daten vom seriellem Bus holen ($ea2e; bei der 1571: $8342) | $AED9/44761 Ende bei Uebertragungsfehler | $AEDF/44767 Busbetrieb beenden | $AEEA/44778 JSPINOUT: FSM-Datenrichtung festlegen | $AEF2/44786 Fehlerblinken nach Selbsttest ($ea6e) | $AF24/44836 Reset-Routine ($eaa0) | $AFCA/45002 Warmstart ($eb22) | $AFE9/45033 Dos-Tabellen initialisieren ($eb3a) | $B0B3/45235 Ganze Diskette als Partition setzen | $B0CF/45263 Physikalisches 1581-Diskettenformat festlegen | $B0F0/45296 JIDLE - Hauptleerschleife ($ebe7) | $B15B/45403 Cache am Ende der Verzoegerungszeit auf Diskette schreiben | $B17C/45436 Directory formatieren und in Ausgabepuffer schreiben ($ec9e) | $B237/45623 Directoryzeile in Ausgabepuffer kopieren ($ed59) | $B245/45637 Byte aus Directory holen und zur Ausgabe bereitstellen ($ed67) | $B262/45666 Validate-Befehl ($ed84) | $B2C7/45767 Blocks eines Files in BAM belegen ($ede5) | $B2EF/45807 naechsten Block einer Partition holen | $B323/45859 Partition-Parameter aus Verzeichniseintrag holen | $B33C/45884 Partition in Bam belegen | $B348/45896 NEW-Befehl ($ee0d) | $B380/45952 ??? | $B390/45968 Verzeichnis-Header und BAM anlegen ($ee56) | $B43D/46141 BAM-Puffer loeschen ($f005) | $B44A/46154 neue BAM erzeugen ($eeb7) | $B515/46357 Wenn die BAM geaendert wurde, dann | $B546/46406 Block in Bam freigeben ($ef5f) | $B572/46450 Block in BAM belegen ($ef93) | $B5B4/46516 BAM-Zeiger auf Eintrag fuer aktuellen Track setzen ($f011) | $B5D8/46552 Pruefen, ob Block $4e im aktuellen Track frei ist ($efd2) | $B5F2/46578 Wenn BAM-Puffer leer, dann BAM einlesen ($f0df) | $B612/46610 BAM auf Diskette schreiben | $B633/46643 Verzeichnis-Header in aktuellen Puffer lesen, ggf. BAM lesen | $B643/46659 T&S und Puffernummer eines Dir-Sektors an DC uebergeben | $B64F/46671 BAM-Zeiger auf 1. BAM-Puffer setzen ($ef3a) | $B65B/46683 Anzahl freier Blocks zur Ausgabe bereitstellen ($ef4d) | $B668/46696 Folgeblock fuer Datei suchen ($f11e) | $B6ED/46829 Startblock einer neuen Datei suchen ($f1a9) | $B746/46918 naechsten freien Block im aktuellen Track suchen ($f1fa) | $B75E/46942 Prueft, ob im aktuellen Track die Anzahl freier Blocks stimmt. ($f220) | $B781/46977 Partition-Befehl | $B811/47121 Pruefen, ob alle Blocks der Partition vor dem Anlegen noch frei sind | $B851/47185 Partition-Namen holen | $B85F/47199 Parameter fuer die Partitionerstellung holen | $B88D/47245 Neuen Bereich anlegen | $B8D2/47314 Burst-Befehl $1f: Fastload (bei der 1571: $9080) | $B9D3/47571 ERROR: Controller-Error-Routine des Burst-Fastloads | $B9DF/47583 CMDERR: Fehler-Routine des Burst-Fastloads | $B9EC/47596 Fehlermeldung ausgeben (bei der 1571: $91ad) | $B9FB/47611 #$02 auf FSM-Bus ausgeben (File not found), TXA | $BA06/47622 Filenamen nach Drivenummer durchsuchen | $BA40/47680 Byte auf FSM-Bus ausgeben (bei der 1571: $9228) | $BA64/47716 Fehlerbehandlung fuer Burst-Fastload setzen | $BA7C/47740 Sprungvektoren der Fehlerbehandlung retten | $BA95/47765 Sprungvektoren der Fehlerbehandlung zurueckschreiben | $BAAE/47790 Burst-Befehl: Read mit logischen Blockangaben (bei der 1571: $83a4) | $BAF7/47863 Burst-Status uebermitteln (bei der 1571: $837c) | $BAFC/47868 Status in a setzen und uebermitteln (bei der 1571: $8381) | $BB11/47889 Burst-Befehle $00,$10: Read (bei der 1571: $8371) | $BB74/47988 Burst-Befehl: Write mit logischen Blockangaben | $BBF6/48118 Burststatus bei Schreibfehlern ausgeben | $BC01/48129 Burst-Befehle $02,$12: Write (bei der 1571: $83ec) | $BCB2/48306 Burst-Befehle $04,$14: Inquire Disk (bei der 1571: $848b) | $BD0A/48394 ??? | $BD12/48402 Burst-Befehle $06,$07,$16,$17: Format (bei der 1571: $84b7) | $BDFC/48636 Burst-Befehle $08,$09: (n.v.) (bei der 1571: $85a5) | $BE06/48646 Burst-Befehle $0a,$1a: Query Disk Format (bei der 1571: $8517) | $BEBB/48827 Burst-Befehl $0c: Inquire Status (bei der 1571: $856b) | $BEF8/48888 Burst-Befehle $0e,$0f: (n.v.) | $BF02/48898 Burst-Befehle $1c,$1d: Dump Cache | $BF44/48964 Kopf ggf. auf die angegebene Spur setzen (bei der 1571: $891b) | $BF5A/48986 Burst-Status senden, wenn gerade Daten vom Computer empfangen werden | $BF66/48998 Burst-Status setzen | $BF83/49027 FSM: Byte ausgeben (bei der 1571: $9228) | $BFAB/49067 Statusbyte ausgeben | $BFB0/49072 Job ausfuehren und ggf. bei Fehlern mehrmals versuchen (bei der 1571: $864b) | $BFE3/49123 Cachepuffer auf Diskette schreiben | $C026/49190 FSM: Wartet, bis naechstes Byte gesendet werden soll (bei der 1571: $86a0) | $C040/49216 physikalischen Folgesektor holen (bei der 1571: $886c) | $C07A/49274 logischen Folgesektor holen (bei der 1571: $886c) | $C097/49303 Groesste/kleinste Sektornummer suchen (bei der 1571: $8961) | $C0BE/49342 JLCC: Controller-Routine | $C163/49507 Tabellen des Controller-Programms | $C390/50064 JOB $84: MOTON_DV | $C393/50067 JOB $86: MOTOFF_DV | $C396/50070 JOB $88: MOTONI_DV | $C3A9/50089 JOB $8a: MOTOFFI_DV | $C3AF/50095 JOB $8c: SEEK_DV | $C3BB/50107 JOB $8e: FORMAT_DV | $C3D6/50134 Spur formatieren | $C546/50502 LED-Routinen des Controller-Programms | $C56A/50538 JOB $9c: SIDE_DV | $C589/50569 JOB $9e: BUFMOVE_DV | $C5AC/50604 JOB $a2: TRKWRT_DV | $C5AF/50607 Patches | $C600/50688 Cachepuffer auf Diskette schreiben | $C6D7/50903 JOBs $92, $a8: DISKIN_DV, PSEEK_DV | $C700/50944 JOB $a6: SP_WRITE | $C800/51200 JOB $a4: SP_READ | $C900/51456 JOBs $80, $90: READ_DV, WRITE_DV | $C9E1/51681 Job $a0: WRTVER_DV | $CA00/51712 Spur mit Cachedaten vergleichen | $CADC/51932 Verify-Error ausgeben | $CAE4/51940 JOB $b8: SEEKPHD_DV | $CB0F/51983 JOB $c0: RESTORE_DV | $CB26/52006 JOBs $d0, $e0: JUMPC_DV, EXBUF_DV: Programm im Jobpuffer ausfuehren | $CB35/52021 JOB $f0: FORMATDK_DV | $CB76/52086 JOB $b6: DETWP_DV | $CB85/52101 Job-Fehlermeldungen | $CB8D/52109 Prueft, ob Sektor in Cachepuffer passt, Cachezeiger setzen | $CB9F/52127 Timer setzen und starten | $CBB1/52145 Laufwerksmotor ein-/ausschalten | $CBC3/52163 Drive LED ein-/ausschalten | $CBD5/52181 Warten ... . . .zzz . .z .. | $CBEC/52204 Auf Controller-Ready warten | $CBF4/52212 Kommandobyte in Controller schreiben | $CD00/52480 Blockheader lesen | $CD3F/52543 Controller-Status pruefen | $CD63/52579 Wenn der Motor aus war, Motor einschalten und Verzoegerungszeit einstellen | $CD7B/52603 Anlaufvorgang ueberwachen | $CDBC/52668 Abfragen, ob Diskette eingelegt ist | $CDCC/52684 Jobauftrag beenden, alle Jobs nochmal pruefen | $CDE2/52706 Ruecksprung von Jobroutine, den selben Job nochmal pruefen | $CE00/52736 Hauptsteuerroutine des Controllers | $CE71/52849 Schrittmotor ansteuern | $CEA4/52900 Daten zwischen Cache und Puffer transferieren | $CEDC/52956 JTRANS_TS: logisches in physikalisches Format umwandeln | $CF51/53073 Schreiben/Lesen mit Cache-Daten | $CFA6/53158 Blockheader lesen | $CFB7/53175 Copy-Zeiger auf Cachepuffer-Anfang setzen | $CFC0/53184 Seite auswaehlen | $CFD1/53201 Controller initialisieren | $CFE3/53219 Precompensation ein/ausschalten | $D00D/53261 Daten vom Puffer in den Cache kopieren | $D549/54601 Daten vom Cache in den Puffer kopieren | $DA63/55907 CRC-Pruefsumme des Blockheaders testen | $DAFD/56061 IRQ-Routine | $DBC7/56263 Patches | $FF00/65280 Sprungvektoren | $FF75/65397 Tabelle der DOS-Funktionen | +------------------------------------------------------------------------ Checksumme 8000: 4D 19 CD 01 Checksumme Befehlsstring vom Computer auswerten ($c146) [Wenn die SA 15 angesprochen wird, oder die SA ein OPEN-Kommando enthaelt, dann werden alle ankommenden Daten in den Kommandopuffer geschrieben und das Befehlsmodus-Flag ($7b) gesetzt. (s. $8e78) Am Ende der Befehlsuebertragung wird wieder die Haupt-Leerschleife aufgerufen. Die erkennt nun, dass ein Kommando anliegt und ruft diese Routine auf.] Einsprung von $B0FF: 8004: A9 00 LDA #$00 Flag: 'BAM auf Diskette schreiben' loeschen 8006: 85 35 STA $35 8008: 20 62 A8 JSR $A862 '00, ok,00,00' Meldung bereitstellen 800B: A5 53 LDA $53 Sekundaeradresse vom IEC-Bus 800D: 10 09 BPL $8018 SA oeffnen ? nein, (also Befehlskanal) ==> 800F: 29 0F AND #$0F ja: SA 15 oeffnen ? 8011: C9 0F CMP #$0F 8013: F0 03 BEQ $8018 ja, (Kommando ausfuehren) ==> 8015: 4C 78 96 JMP $9678 Datei-OPEN-Routine ==> Einsprung von $800D, $8013: 8018: 20 65 81 JSR $8165 Kommandotabellen initialisieren 801B: B1 CD LDA ($CD),Y Zeichen aus INPUT-Puffer holen 801D: 8D 8F 02 STA $028F und merken 8020: A2 0B LDX #$0B Kommando suchen Einsprung von $802B: 8022: BD 78 DB LDA $DB78,X gueltige Kommandos der Reihe nach holen 8025: CD 8F 02 CMP $028F und mit angegebenem vergleichen 8028: F0 08 BEQ $8032 Kommando gefunden, ==> 802A: CA DEX 802B: 10 F5 BPL $8022 naechstes Kommando pruefen, ==> Einsprung von $8247, $857B: 802D: A9 31 LDA #$31 gesuchtes Kommando wurde nicht gefunden 802F: 4C 7C 80 JMP $807C 31, Syntax Error Einsprung von $8028: 8032: 8E 2A 02 STX $022A 8035: E0 09 CPX #$09 Kommando mit Dateiname(n) ? 8037: 90 03 BCC $803C nein, ==> 8039: 20 A2 80 JSR $80A2 Befehlsstring pruefen Einsprung von $8037: 803C: AE 2A 02 LDX $022A 803F: BD 84 DB LDA $DB84,X Aufruf des Befehls 8042: 85 40 STA $40 8044: BD 90 DB LDA $DB90,X 8047: 85 41 STA $41 8049: 6C 40 00 JMP ($0040) Abschluss eines Befehls ($c194) Einsprung von $87EB, $87F1, $8900, $89BD, $89CF, $8A5A, $8B8B, $8BAB, $8BE0, $8BF4, $8C0C, $8ED9, $96AD, $984A, $9980, $9999, $A20A, $AAFD, $B283, $B432, $B8CF, $B8D2, $B9D0: 804C: A9 00 LDA #$00 Flag: 'BAM auf Diskette schreiben' loeschen 804E: 85 35 STA $35 Einsprung von $8B2C, $8B45, $98A8: 8050: AD AB 02 LDA $02AB Fehlernummer holen 8053: F0 03 BEQ $8058 kein Fehler, ==> 8055: 4C 7C 80 JMP $807C Einsprung von $8053: 8058: A0 00 LDY #$00 00, Ok 805A: 98 TYA 805B: 85 4D STA $4D ,00 Einsprung von $8710: 805D: 84 4E STY $4E ,00 Einsprung von $B80E: 805F: 84 CD STY $CD Zeiger in INPUT-Puffer loeschen 8061: 20 6D A8 JSR $A86D Errormeldung ausgeben 8064: 20 E5 81 JSR $81E5 LEDs ausschalten Einsprung von $9983, $999C: 8067: A9 00 LDA #$00 Drivestatus loeschen 8069: 85 6E STA $6E 806B: 20 71 80 JSR $8071 INPUT-Puffer loeschen 806E: 4C 34 94 JMP $9434 interne Kanaele freigeben INPUT-Puffer loeschen ($c1bd) Einsprung von $806B, $A7F4: 8071: A0 28 LDY #$28 8073: A9 00 LDA #$00 Puffer mit $00 fuellen Einsprung von $8079: 8075: 99 00 02 STA $0200,Y 8078: 88 DEY 8079: 10 FA BPL $8075 807B: 60 RTS Fehler ausgeben mit T&S = 00 ($c1c8) Einsprung von $802F, $8055, $80A9, $8119, $81AC, $82B3, $8798, $87D4, $891A, $8928, $8980, $89FC, $8A6A, $8A6F, $8B62, $8C1F, $8DB4, $8E39, $8EBA, $918B, $92E9, $95E9, $96EC, $979A, $979F, $97F4, $9806, $9814, $986D, $A05B, $A0FA, $A1B0, $A1BF, $A232, $A313, $A435, $A97E, $AA85, $B351, $B6A2, $B7AA, $B88A, $B9F8, $BE03, $BEFF: 807C: A0 00 LDY #$00 T&S = 0 807E: 84 4D STY $4D 8080: 84 4E STY $4E 8082: 4C 3F FF JMP $FF3F zur DOS-Fehlerroutine Sucht Drivenummer in der Befehlszeile ($c1d1) Die Position wird in $0291 gespeichert (0: keine Drivenummer) E: y: Position, an der die Suche beginnen soll Die Routine schaltet die Drive-LED an Einsprung von $8EC5, $96BB, $B262: 8085: A2 00 LDX #$00 Flag fuer 'keine Drivenummer' 8087: 8E 91 02 STX $0291 808A: A9 3A LDA #$3A Kommandozeile nach ':' durchsuchen 808C: 20 1C 81 JSR $811C 808F: F0 05 BEQ $8096 nicht gefunden, dann ==> 8091: 88 DEY 8092: 88 DEY Position der Drivenummer merken 8093: 8C 91 02 STY $0291 (steht genau vor dem ':') Einsprung von $808F: 8096: 4C 51 82 JMP $8251 LED einschalten Eingabezeile bis zum ':' auswerten ($c1e5) A: y: Position des ':' + 1 (x: Anzahl gefundener Kommas (sollte normalerweise 0 sein)) Einsprung von $80A2, $8777, $96DE, $9927: 8099: A0 00 LDY #$00 Am Zeilenbeginn anfangen 809B: A2 00 LDX #$00 Noch kein gefundenes Komma 809D: A9 3A LDA #$3A Suchzeichen 809F: 4C 1C 81 JMP $811C Eingabezeile pruefen bei Copy, Rename, New ($c1ee) Befehlszeile bis zum ':' auswerten Einsprung von $8039: 80A2: 20 99 80 JSR $8099 ':' in der Kommandozeile suchen 80A5: D0 05 BNE $80AC gefunden, ==> Einsprung von $80B2: 80A7: A9 34 LDA #$34 34, Syntax Error 80A9: 4C 7C 80 JMP $807C (':' fehlt) Einsprung von $80A5, $877F: 80AC: 88 DEY 80AD: 88 DEY Zeiger auf Drivenummer merken 80AE: 8C 91 02 STY $0291 (falls vorhanden) 80B1: 8A TXA Anzahl der gefundenen Kommas >0 ? 80B2: D0 F3 BNE $80A7 ja, Fehler: ',' vor ':' ==> Befehlszeile zwischen ':' und '=' auswerten Einsprung von $9936: 80B4: A9 3D LDA #$3D 80B6: 20 1C 81 JSR $811C '=' suchen 80B9: 8A TXA 80BA: F0 02 BEQ $80BE ist ein ',' vor dem '=' ? 80BC: A9 40 LDA #$40 ja, ', vor =' -Flag setzen Einsprung von $80BA: 80BE: 09 21 ORA #$21 b0-1 = 01: 'Kein =' -Flag setzen 80C0: 8D A2 02 STA $02A2 Bitmaske merken 80C3: E8 INX Anzahl der gefundenen Kommas 80C4: 8E 2E 02 STX $022E +1 = Anzahl der Parameter 80C7: 8E 2F 02 STX $022F (z.B. 'xxx,p,r') 80CA: AD A1 02 LDA $02A1 Ist ein Joker vorhanden ? 80CD: F0 0D BEQ $80DC nein, ==> 80CF: A9 80 LDA #$80 'Joker vor =' -Flag setzen 80D1: 0D A2 02 ORA $02A2 In Bitmaske eintragen 80D4: 8D A2 02 STA $02A2 80D7: A9 00 LDA #$00 Jokerflag loeschen 80D9: 8D A1 02 STA $02A1 Einsprung von $80CD: 80DC: 98 TYA Wurde ein '=' gefunden ? 80DD: F0 29 BEQ $8108 Nein, ==> 80DF: 9D 91 02 STA $0291,X Position des '=' merken 80E2: AD 2E 02 LDA $022E Anzahl Parameter vor dem '=' merken 80E5: 8D 30 02 STA $0230 Befehlszeile vom '=' bis zum Zeilenende auswerten 80E8: A9 8D LDA #$8D $8d = 80EA: 20 1C 81 JSR $811C vom '=' bis zum Zeilenende untersuchen 80ED: E8 INX Anzahl der Parameter merken 80EE: 8E 2F 02 STX $022F 80F1: CA DEX = Anzahl ',' 80F2: AD A1 02 LDA $02A1 Joker vorhanden ? 80F5: F0 02 BEQ $80F9 Nein, ==> 80F7: A9 08 LDA #$08 'Joker hinter ='-Flag setzen Einsprung von $80F5: 80F9: EC 2E 02 CPX $022E Anzahl Kommas = Anzahl Kommas vor '=' ? 80FC: F0 02 BEQ $8100 ja, (keine Kommas gefunden) ==> 80FE: 09 04 ORA #$04 ', hinter =' -Flag setzen Einsprung von $80FC: 8100: 09 03 ORA #$03 b0-1 = 10: '=' -Flag setzen 8102: 4D A2 02 EOR $02A2 Evtl. b7-8 setzen 8105: 8D A2 02 STA $02A2 b0-1 kippen Einsprung von $80DD: 8108: AD A2 02 LDA $02A2 Bitmaske mit Kontrollmaske 810B: AE 2A 02 LDX $022A (aktuelle Befehlsnummer) 810E: 3D 94 DB AND $DB94,X bei $db9c verknuepfen 8111: D0 01 BNE $8114 muss 0 werden, sonst Fehler ==> 8113: 60 RTS Format OK. Einsprung von $8111: 8114: 8D AB 02 STA $02AB Fehlerflag setzen 8117: A9 30 LDA #$30 30, Syntax Error 8119: 4C 7C 80 JMP $807C Eingabezeile bis zu einem bestimmten Zeichen auswerten ($c268) Die Anzahl der ',' bis zur Fundstelle werden gezaehlt und Joker registriert. x sollte vor dem ersten Aufruf auf 0 gesetzt werden. E: a: Ende-Zeichen x: Alte Anzahl gefundener Kommas y: Startposition A: a: Position des Zeichens + 1 (0 = Zeichen nicht gefunden) x: Anzahl der gefundenen Kommas y: (= a) n: 1: Zeichen nicht gefunden Einsprung von $808C, $809F, $80B6, $80EA, $8A63, $8AA5, $96F8: 811C: 8D 8F 02 STA $028F Suchzeichen Einsprung von $8138, $814F: 811F: C4 29 CPY $29 Ende der Befehlszeile erreicht ? 8121: B0 2E BCS $8151 ja, ==> 8123: B1 CD LDA ($CD),Y Zeichen aus der Kommandozeile holen 8125: C8 INY 8126: CD 8F 02 CMP $028F = Suchzeichen ? 8129: F0 28 BEQ $8153 ja 812B: C9 2A CMP #$2A Joker ? 812D: F0 04 BEQ $8133 ja, ==> 812F: C9 3F CMP #$3F 8131: D0 03 BNE $8136 nein, ==> Einsprung von $812D: 8133: EE A1 02 INC $02A1 Jokerflag setzen Einsprung von $8131: 8136: C9 2C CMP #$2C 8138: D0 E5 BNE $811F ',' gefunden 813A: 98 TYA ja, Position des naechsten Parameters 813B: 9D 92 02 STA $0292,X merken 813E: AD A1 02 LDA $02A1 War Joker im Parameter ? 8141: 29 7F AND #$7F 8143: F0 07 BEQ $814C 8145: A9 80 LDA #$80 ja, Jokerflag setzen 8147: 95 F4 STA $F4,X 8149: 8D A1 02 STA $02A1 Jokerflag fuer neue Suche loeschen Einsprung von $8143: 814C: E8 INX b7=1: Es wurden Joker gefunden 814D: E0 04 CPX #$04 wurden zu viele Parameter angegeben ? 814F: 90 CE BCC $811F nein, ==> Einsprung von $8121: 8151: A0 00 LDY #$00 ja, Ende der Suche Einsprung von $8129: 8153: A5 29 LDA $29 Zeilenlaenge bzw. Position des gesuchten 8155: 9D 92 02 STA $0292,X Zeichens merken 8158: AD A1 02 LDA $02A1 War im letzten Parameter ein Joker (b7=1) ? 815B: 29 7F AND #$7F 815D: F0 04 BEQ $8163 nein, ==> 815F: A9 80 LDA #$80 Jokerflag setzen 8161: 95 F4 STA $F4,X Einsprung von $815D: 8163: 98 TYA 8164: 60 RTS Kommandozeilenende feststellen (CR (/LF) entfernen) ($c2b3) (bei u0 Zeilenende nicht veraendern) Kommandozeilen-Parameter loeschen Einsprung von $8018, $967C, $A1A1: 8165: A4 CD LDY $CD Laenge der Kommandozeile 8167: F0 36 BEQ $819F = 0 ? ==> 8169: 88 DEY 816A: F0 32 BEQ $819E = 1 ? ==> (kann kein u0 sein) 816C: AD 00 02 LDA $0200 (etwas umstaendliche) Ueberpruefung auf 'u0' 816F: C9 55 CMP #$55 8171: D0 07 BNE $817A (u0) 8173: AD 01 02 LDA $0201 8176: C9 30 CMP #$30 8178: F0 04 BEQ $817E = u0 ? ==> Einsprung von $8171: 817A: B9 00 02 LDA $0200,Y Zeilenende mit CR vergleichen 817D: 2C B $2C (u0) Einsprung von $8178: 817E: A9 00 LDA #$00 u0: CR nicht beachten 8180: C9 0D CMP #$0D 8182: F0 1B BEQ $819F 8184: 88 DEY 8185: AD 00 02 LDA $0200 (u0 Abfrage) (wozu ?) 8188: C9 55 CMP #$55 818A: D0 07 BNE $8193 818C: AD 01 02 LDA $0201 818F: C9 30 CMP #$30 8191: F0 04 BEQ $8197 = u0 ? ==> Einsprung von $818A: 8193: B9 00 02 LDA $0200,Y vorletztes Zeichen mit CR vergleichen 8196: 2C B $2C Einsprung von $8191: 8197: A9 00 LDA #$00 u0: CR nicht beachten 8199: C9 0D CMP #$0D 819B: F0 02 BEQ $819F 819D: C8 INY <= kein CR vorhanden bzw. u0 Einsprung von $816A: 819E: C8 INY <= CR vorhanden / Laenge=1 Einsprung von $8167, $8182, $819B: 819F: 84 29 STY $29 <= CL,LF vorhanden / Laenge=0 81A1: C0 2A CPY #$2A Zeile zu lang ? 81A3: A0 FF LDY #$FF 81A5: 90 08 BCC $81AF nein, ==> 81A7: 8C 2A 02 STY $022A 81AA: A9 32 LDA #$32 32, SYNTAX ERROR 81AC: 4C 7C 80 JMP $807C Kommandozeilenparameter initialisieren ($c2dc) Einsprung von $81A5, $992C: 81AF: A0 00 LDY #$00 81B1: 98 TYA 81B2: 85 CD STA $CD Zeiger auf INPUT-Puffer Lo = 0 81B4: 8D 6F 02 STA $026F Aktuelle Recordlaenge = 0 81B7: 8D 2D 02 STA $022D Aktueller Dateityp = DEL 81BA: 8D 33 02 STA $0233 Dateityp fuer Dateisuche loeschen 81BD: 85 67 STA $67 Zaehler (z.B. fuer Block-Befehle) loeschen 81BF: 8D 30 02 STA $0230 Anzahl Parameter vor '=' bzw. Anzahl der Dateinamen 81C2: 8D 2E 02 STA $022E Parameterzaehler (vor '=') loeschen 81C5: 8D 2F 02 STA $022F Anzahl Parameter in Kommandozeile loeschen 81C8: 8D A1 02 STA $02A1 Jokerflag loeschen 81CB: 8D AB 02 STA $02AB Fehlerflag loeschen 81CE: A2 05 LDX #$05 Einsprung von $81E2: 81D0: 9D 90 02 STA $0290,X Positionen der Parameter 81D3: 95 E4 STA $E4,X Dir-Block mit dem Dateieintrag 81D5: 95 E9 STA $E9,X Zeiger auf den Eintrag 81D7: 95 EE STA $EE,X Drivenummern 81D9: 95 F3 STA $F3,X Jokerflags loeschen 81DB: 9D 96 02 STA $0296,X T&S der Dateien = 0 bzw. 81DE: 9D 9B 02 STA $029B,X Parameter der Block-Befehle = 0 81E1: CA DEX 81E2: D0 EC BNE $81D0 81E4: 60 RTS LED-Routinen ($c100) Einsprung von $8064, $9381, $A862: 81E5: A9 00 LDA #$00 LEDs ausschalten 81E7: 8D AB 02 STA $02AB Fehlerflag loeschen 81EA: A5 79 LDA $79 Drive-LED ausschalten 81EC: 29 DF AND #$DF 81EE: 85 79 STA $79 81F0: 60 RTS Einsprung von $A7FB: 81F1: A9 50 LDA #$50 LED-Blinken 81F3: 8D AB 02 STA $02AB Einsprung von $826D, $82B6, $89B1, $8C41, $8C53, $8E63, $92F7, $96A0, $B35B: 81F6: A5 79 LDA $79 Drive-LED einschalten 81F8: 09 40 ORA #$40 81FA: 85 79 STA $79 81FC: 60 RTS Laufwerksnummer holen und setzen ($c312) (fuer Kommandos mit einem Dateinamen und evtl. anderen Parametern z.B. OPEN 1,ga,2,"0:xxxx,p,r", "n0:xxxx,yy", ...) Einsprung von $96FF, $A964, $B348, $B78F, $B90E: 81FD: AD 2F 02 LDA $022F Anzahl der Parameter 8200: 8D 2E 02 STA $022E zwischenspeichern 8203: A9 01 LDA #$01 nur der 1. Parameter ist ein Dateiname 8205: 8D 2F 02 STA $022F und soll getestet werden 8208: 8D 30 02 STA $0230 1 Dateiname in Kommandozeile Alle Parameter auf Laufwerksnummer pruefen und diese ggf. loeschen ($c320) (z.B. "c0:xxx=0:yyy,0:zzz", "s0:xxx,0:yyy", LOAD"$0:xxx,0:yyy",ga ...) Einsprung von $868B, $8782, $88C5, $993C: 820B: A2 00 LDX #$00 mit dem 1. Parameter anfangen Einsprung von $8221: 820D: 86 67 STX $67 820F: BD 91 02 LDA $0291,X Position des Parameters holen 8212: 20 24 82 JSR $8224 und testen 8215: A6 67 LDX $67 Neue Position zurueckschreiben 8217: 9D 91 02 STA $0291,X (zum Entfernen der Drivenummer) 821A: 98 TYA Drivenummer merken 821B: 95 EF STA $EF,X 821D: E8 INX Naechsten Parameter pruefen 821E: EC 2F 02 CPX $022F < Anzahl der Parameter ? 8221: 90 EA BCC $820D ja, ==> 8223: 60 RTS Laufwerksnummer testen und entfernen ($c33c) Einsprung von $8212: 8224: AA TAX a: Position, an der eine Drivenummer 8225: A0 00 LDY #$00 erwartet wird. y=0 (Default-Drivenummer) 8227: A9 3A LDA #$3A Anhand der Position des ':' die Art der 8229: DD 01 02 CMP $0201,X Driveangabe feststellen (z.B.':' oder '0:') 822C: F0 0C BEQ $823A Drivenummer vorhanden, ('0:') ==> 822E: DD 00 02 CMP $0200,X nur ':', Default-Drive ==> 8231: D0 17 BNE $824A kein ':', ==> 8233: E8 INX Drivenummer (':') entfernen Einsprung von $8245: 8234: 98 TYA unnoetig, Einsprung von $8241: 8235: 29 01 AND #$01 ist sowieso 0 Einsprung von $824F: 8237: A8 TAY 8238: 8A TXA x zeigt jetzt hinter die Drivenummer 8239: 60 RTS Einsprung von $822C: 823A: BD 00 02 LDA $0200,X Drivenummer auslesen 823D: E8 INX Drivenummer ('0:') entfernen 823E: E8 INX 823F: C9 30 CMP #$30 8241: F0 F2 BEQ $8235 Drive 0, dann ok ==> 8243: C9 31 CMP #$31 Drive 1, dann '31, Syntax Error' 8245: D0 ED BNE $8234 nicht 0 oder 1, dann Drive 0 8247: 4C 2D 80 JMP $802D 31, Syntax Error Einsprung von $8231: 824A: 98 TYA 824B: 09 80 ORA #$80 Flag fuer 'Keine Laufwerksangabe' (a = $80) 824D: 29 81 AND #$81 824F: D0 E6 BNE $8237 immer ==> Drivenummer setzen, LED einschalten ($c368) Einsprung von $8096: 8251: A9 00 LDA #$00 Befehlssyntaxflag loeschen 8253: 8D A2 02 STA $02A2 8256: AC 91 02 LDY $0291 Position der Drivenummer holen Einsprung von $8268: 8259: B1 CD LDA ($CD),Y Drivenummer holen 825B: 20 95 82 JSR $8295 mit '0' und '1' vergleichen 825E: 10 0D BPL $826D Drivenummer ok., ==> 8260: C8 INY Zeilenende erreicht ? 8261: C4 29 CPY $29 8263: B0 05 BCS $826A ja, ==> 8265: A4 29 LDY $29 Drivenummer am Zeilenende suchen 8267: 88 DEY (z.B. 'I0','V0','$0', ...) 8268: D0 EF BNE $8259 Befehlslaenge <>1, ==> Einsprung von $8263: 826A: CE A2 02 DEC $02A2 = $ff Einsprung von $825E: 826D: 4C F6 81 JMP $81F6 Drive-LED einschalten Dateityp feststellen ('s,p,u,r,c') (z.B. '$*=s') ($c398) Einsprung von $8688, $9939: 8270: A0 00 LDY #$00 8272: AD 2E 02 LDA $022E Anzahl der Parameter vor '=' 8275: CD 2F 02 CMP $022F = Anzahl P. in Kommandozeile ? 8278: F0 16 BEQ $8290 ja, kein Typ angegeben, ==> 827A: CE 2F 02 DEC $022F Zeiger auf Zeilenende entfernen 827D: AC 2F 02 LDY $022F Letzten Parameter (zukuenftiges Zeilenende) 8280: B9 91 02 LDA $0291,Y holen 8283: A8 TAY 1. Zeichen des Parameters holen 8284: B1 CD LDA ($CD),Y 8286: A0 05 LDY #$05 mit allen Einsprung von $828E: 8288: D9 AB DB CMP $DBAB,Y Dateitypenbezeichnungen vergleichen 828B: F0 03 BEQ $8290 gleich, ==> 828D: 88 DEY wenn der Typ nicht gefunden wird, oder 828E: D0 F8 BNE $8288 der Typ = del ist: Einsprung von $8278, $828B: 8290: 98 TYA 'Typ nicht gefunden bzw. angegeben' merken 8291: 8D 33 02 STA $0233 Dateityp merken 8294: 60 RTS Laufwerksnummer pruefen ($c3bd) Einsprung von $825B, $9909: 8295: C9 30 CMP #$30 8297: F0 06 BEQ $829F 8299: C9 31 CMP #$31 829B: F0 02 BEQ $829F 829D: 09 80 ORA #$80 keine bzw. falsche Drivenummer Einsprung von $8297, $829B: 829F: 29 81 AND #$81 0, 1 oder $80 zurueckliefern 82A1: 60 RTS Drive initialisieren, LED einschalten ($c3ca) Einsprung von $82B9, $868E, $9702, $993F: 82A2: A9 00 LDA #$00 82A4: 85 40 STA $40 (keine sichtbare Verwendung) 82A6: 8D A4 02 STA $02A4 (Drivenummer ?) 82A9: 8D A3 02 STA $02A3 Anzahl Laufwerke = 0 (= 1 Laufwerk) 82AC: 20 AE 84 JSR $84AE ggf. Partition initialisieren 82AF: F0 05 BEQ $82B6 OK. ==> 82B1: A9 74 LDA #$74 74, DRIVE NOT READY 82B3: 20 7C 80 JSR $807C Ende Einsprung von $82AF: 82B6: 4C F6 81 JMP $81F6 Drive-LED-Flag setzen alle angegebenen Dateien im Directory suchen ($c44f) A: Filetabellen $e5-$f8 Filebeginn $0297-$02a1 $02a5: $ff: alle Files gefunden (kein Name enthaelt Wildcards) $00: - nicht alle Files wurden gefunden, oder - Files enthalten Wildcards (weitere Fundstellen sind moegl.) Einsprung von $87A2, $88D6, $A974, $B792, $B91E: 82B9: 20 A2 82 JSR $82A2 Partition initialisieren Einsprung von $82C8: 82BC: A9 00 LDA #$00 Flag fuer 'Suche nach belegten Eintraegen' 82BE: 85 73 STA $73 setzen 82C0: 20 24 84 JSR $8424 1. Dir-Eintrag holen 82C3: D0 0B BNE $82D0 gefunden ? ja, ==> Einsprung von $82E3: 82C5: CE A3 02 DEC $02A3 Anzahl der Laufwerke -1 = $ff 82C8: 10 F2 BPL $82BC (wird nie ausgefuehrt) 82CA: 60 RTS Einsprung von $82DC: 82CB: 20 89 84 JSR $8489 naechsten Dir-Eintrag holen 82CE: F0 10 BEQ $82E0 keiner mehr da ? ja, ==> Einsprung von $82C3, $82DE: 82D0: 20 27 83 JSR $8327 Eintrag mit gesuchten Eintraegen vergleichen 82D3: AD A5 02 LDA $02A5 noch nicht alle Dateien gefunden ? 82D6: F0 01 BEQ $82D9 ja, ==> 82D8: 60 RTS Einsprung von $82D6: 82D9: AD 6D 02 LDA $026D War der Eintrag ein gesuchter ? 82DC: 30 ED BMI $82CB nein, ==> 82DE: 10 F0 BPL $82D0 ja, ==> Einsprung von $82CE: 82E0: AD A5 02 LDA $02A5 Sind alle Dateien gefunden ? 82E3: F0 E0 BEQ $82C5 nein, (Ende) ==> 82E5: 60 RTS Dateien einzeln suchen ($c48b) A: n: 1: Keine Datei mehr gefunden; 0: Suche war erfolgreich Filetabellen $e5-$f8 Filebeginn $0297-$02a1 naechste Datei suchen (vorher den Direktory-Block neu einlesen) Einsprung von $8703: 82E6: 20 77 84 JSR $8477 naechsten Dir-Eintrag holen 82E9: F0 0E BEQ $82F9 noch eine Datei gefunden ? nein, ==> 82EB: D0 1C BNE $8309 ja ==> 1. Datei suchen Einsprung von $8301, $8695, $9705, $9945: 82ED: A9 00 LDA #$00 Flag fuer 'Suche nach belegten Eintraegen' 82EF: 85 73 STA $73 setzen 82F1: 20 24 84 JSR $8424 1. Directory-Eintrag suchen 82F4: D0 13 BNE $8309 gefunden ? ja, ==> 82F6: 8D A5 02 STA $02A5 a=0: Noch Dateien nicht gefunden (n=1 setzen und Ende) Einsprung von $82E9, $8307: 82F9: AD A5 02 LDA $02A5 Alle Dateien gefunden ? 82FC: D0 28 BNE $8326 ja, (endgueltig Ende der Suche)==> 82FE: CE A3 02 DEC $02A3 Anzahl der Laufwerke -1 = $ff 8301: 10 EA BPL $82ED (wird nie ausgefuehrt) 8303: 60 RTS n=1, Ende ==> naechste Datei suchen (Direktory-Block ist noch im Puffer) Einsprung von $8314, $8324, $8617: 8304: 20 89 84 JSR $8489 <-- naechsten Dir-Eintrag holen 8307: F0 F0 BEQ $82F9 keiner mehr da ? ja, ==> Einsprung von $82EB, $82F4: 8309: 20 27 83 JSR $8327 Eintrag mit gesuchten vergleichen 830C: AE 6D 02 LDX $026D War es ein gesuchter Eintrag ? 830F: 10 07 BPL $8318 ja, ==> 8311: AD A5 02 LDA $02A5 Existieren noch nicht gefundene Dateinamen? 8314: F0 EE BEQ $8304 ja, ==> 8316: D0 0E BNE $8326 nein, n=1, Ende ==> Einsprung von $830F: 8318: AD 33 02 LDA $0233 Wird ein bestimmter Filetyp gesucht ? 831B: F0 09 BEQ $8326 nein, (0 waere DEL) ==> 831D: B5 F4 LDA $F4,X Filetyp vergleichen 831F: 29 07 AND #$07 8321: CD 33 02 CMP $0233 8324: D0 DE BNE $8304 ungleich, ==> Einsprung von $82FC, $8316, $831B: 8326: 60 RTS File gefunden (n=0), Ende ==> Eintrag im Directory mit gesuchten Eintraegen vergleichen ($c4d8) Einsprung von $82D0, $8309: 8327: A2 FF LDX #$FF 8329: 8E 6D 02 STX $026D Flag fuer 'kein gesuchter Eintrag gefunden' 832C: E8 INX 832D: 8E A1 02 STX $02A1 Jokerflag loeschen 8330: 20 D7 83 JSR $83D7 pruefen, ob noch Dateien nicht gefunden 8333: F0 06 BEQ $833B wurden. ja, ==> Einsprung von $8339: 8335: 60 RTS Einsprung von $8344, $834B, $8362, $8368, $8383, $8421: 8336: 20 E2 83 JSR $83E2 naechste nicht gefundene Datei pruefen 8339: D0 FA BNE $8335 keine da ? ja, ==> Einsprung von $8333: 833B: A9 00 LDA #$00 Aktuelle Drivenummer 833D: 55 EF EOR $EF,X mit angegebener Drivenummer vergleichen 833F: 4A LSR 8340: 90 0B BCC $834D gleich, ==> 8342: 29 40 AND #$40 war eine Drivenummer angegeben ? 8344: F0 F0 BEQ $8336 ja, (naechste Datei) ==> 8346: A9 02 LDA #$02 (macht bei der 1581 keinen Sinn) 8348: CD A3 02 CMP $02A3 ist immer 0 ! 834B: F0 E9 BEQ $8336 wird nie ausgefuehrt Einsprung von $8340: 834D: BD 91 02 LDA $0291,X Position des Dateinamens holen 8350: AA TAX 8351: 20 26 85 JSR $8526 Laenge des Dateinamens ermitteln 8354: A0 03 LDY #$03 Dateiname steht ab der 3.Position 8356: 4C 6C 83 JMP $836C im Direktory-Eintrag Einsprung von $8376: 8359: BD 00 02 LDA $0200,X Zeichen aus Kommandozeile 835C: D1 64 CMP ($64),Y mit Zeichen aus Dir-Eintrag vergleichen 835E: F0 0A BEQ $836A gleich, ==> 8360: C9 3F CMP #$3F Joker '?' ? 8362: D0 D2 BNE $8336 nein, (Name nicht richtig) ==> 8364: B1 64 LDA ($64),Y Dateinamenende ? 8366: C9 A0 CMP #$A0 (LOAD"test?" findet kein "test") 8368: F0 CC BEQ $8336 ja, (Name nicht richtig) ==> Einsprung von $835E: 836A: E8 INX naechste Zeichen vergleichen 836B: C8 INY Einsprung von $8356: 836C: EC 90 02 CPX $0290 Dateinamenende erreicht ? 836F: B0 0A BCS $837B ja, ==> 8371: BD 00 02 LDA $0200,X Ist ein '*' an der aktuellen Position 8374: C9 2A CMP #$2A 8376: D0 E1 BNE $8359 nein, ==> 8378: 4C FA 83 JMP $83FA 1581: Zeichen hinter '*' pruefen Einsprung von $836F: 837B: C0 13 CPY #$13 max. Dateinamenlaenge (3+16) ? 837D: B0 06 BCS $8385 ja, ==> 837F: B1 64 LDA ($64),Y Auf Dateinamenende pruefen 8381: C9 A0 CMP #$A0 ($a0: Endkennzeichen) 8383: D0 B1 BNE $8336 nein, (Name nicht richtig) ==> Dateidaten der gefundenen Datei merken Einsprung von $837D, $841E: 8385: AE 30 02 LDX $0230 Nummer des gefundenen Dateinamens merken 8388: 8E 6D 02 STX $026D 838B: B5 F4 LDA $F4,X Jokerflag holen 838D: 29 80 AND #$80 und merken 838F: 8D A1 02 STA $02A1 (fuer uebergeordnete Routinen) 8392: AD 32 02 LDA $0232 Position und Dir-Block 8395: 95 EA STA $EA,X des Dateieintrages merken 8397: A5 4E LDA $4E [Parameter wird eigentlich in $71 8399: 95 E5 STA $E5,X uebergeben - na ja, egal] 839B: A0 00 LDY #$00 839D: B1 64 LDA ($64),Y Dateityp holen 839F: C8 INY 83A0: 48 PHA 83A1: 29 40 AND #$40 Scratch-Schutz merken 83A3: 85 40 STA $40 83A5: 68 PLA 83A6: 29 DF AND #$DF Scratch-Schutz ausblenden 83A8: 30 02 BMI $83AC ist Datei geschlossen ? ja, ==> 83AA: 09 20 ORA #$20 Dateityp mit '*'-Flag merken Einsprung von $83A8: 83AC: 29 27 AND #$27 83AE: 05 40 ORA $40 Scratch-Schutz einblenden 83B0: 85 40 STA $40 83B2: A9 80 LDA #$80 Flag fuer Joker holen 83B4: 35 F4 AND $F4,X 83B6: 05 40 ORA $40 Dateityp einblenden 83B8: 95 F4 STA $F4,X 83BA: B5 EF LDA $EF,X Drivenummer merken 83BC: 29 80 AND #$80 ['ORA Drivenummer' entfaellt] 83BE: 95 EF STA $EF,X b7=1: kein Laufwerk angegeben 83C0: B1 64 LDA ($64),Y Track merken 83C2: 9D 97 02 STA $0297,X 83C5: C8 INY 83C6: B1 64 LDA ($64),Y Sektor merken 83C8: 9D 9C 02 STA $029C,X 83CB: AD 6F 02 LDA $026F ist Recordlaenge gesetzt ? 83CE: D0 07 BNE $83D7 ja, ==> 83D0: A0 15 LDY #$15 Recordlaenge merken 83D2: B1 64 LDA ($64),Y 83D4: 8D 6F 02 STA $026F Prueft, ob alle Dateien gefunden worden sind ($c617) A: x: Nummer eines Dateinamens, der noch fehlt Einsprung von $8330, $83CE: 83D7: A9 FF LDA #$FF Flag: 'Alle Dateien der Kommandozeile im 83D9: 8D A5 02 STA $02A5 Directory gefunden' 83DC: AD 2F 02 LDA $022F Anzahl Dateinamen in Zaehler laden 83DF: 8D 30 02 STA $0230 alle Dateinamen testen Einsprung von $83F2, $8336: 83E2: CE 30 02 DEC $0230 <-- (naechsten Dateinamen pruefen) 83E5: 10 01 BPL $83E8 gibt es noch Dateien, nach denen gesucht 83E7: 60 RTS werden muss? nein, ==> Einsprung von $83E5: 83E8: AE 30 02 LDX $0230 Nummer des zu pruefenden Namens 83EB: B5 F4 LDA $F4,X Flags fuer Joker im Parameter 83ED: 30 05 BMI $83F4 b7=1: Joker vorhanden ? ja, (Dateiname kann mehrfach gefunden werden) ==> 83EF: BD 97 02 LDA $0297,X wurde Datei schon gefunden 83F2: D0 EE BNE $83E2 Ja, (Datei hat keinen Joker, also kann nur ein passender Eintrag existieren) ==> Einsprung von $83ED: 83F4: A9 00 LDA #$00 Flag: 'Noch nicht alle Dateien gefunden' 83F6: 8D A5 02 STA $02A5 merken 83F9: 60 RTS 1581: Zeichen hinter '*' vergleichen Einsprung von $8378: 83FA: 86 3B STX $3B Position des '*' merken 83FC: AE 90 02 LDX $0290 Position des Namen-Endes holen 83FF: CA DEX 8400: E4 3B CPX $3B = Position des '*' 8402: F0 1A BEQ $841E ja, ('*' ist letztes Zeichen) ==> 8404: A0 13 LDY #$13 max. Laenge des Dateinamens (+3: T&S, Typ) Einsprung von $840B: 8406: 88 DEY 8407: B1 64 LDA ($64),Y Ende des Dateinamens suchen 8409: C9 A0 CMP #$A0 840B: F0 F9 BEQ $8406 noch nicht gefunden, ==> in x und y stehen nun Endpositionen der zu vergleichenden Namen Einsprung von $841C: 840D: BD 00 02 LDA $0200,X Zeichen gleich ? 8410: D1 64 CMP ($64),Y 8412: F0 04 BEQ $8418 ja, ==> 8414: C9 3F CMP #$3F Joker '?' ? 8416: D0 09 BNE $8421 nein, (Name nicht richtig) ==> Einsprung von $8412: 8418: 88 DEY Zeichen rueckwaerts vergleichen 8419: CA DEX 841A: E4 3B CPX $3B bis zum '*' 841C: D0 EF BNE $840D noch nicht erreicht, ==> Einsprung von $8402: 841E: 4C 85 83 JMP $8385 Name Ok. ==> Einsprung von $8416: 8421: 4C 36 83 JMP $8336 Name nicht richtig, ==> naechsten Eintrag im Directory suchen : ($c5ac) E: $73 = 0 oder $73 <>1 und $72<>0 : belegten Eintrag suchen (bei der ersten Suche muss $73=0 gesetzt werden um den Rest muss man sich nicht kuemmern) $73 = 1 und $72=0 : freien Eintrag suchen (findet immer nur den ersten Eintrag) A: $72: Sektor, in dem der 1. freie Eintrag gefunden wurde $73: Position des freien Eintrages im Dir-Block $71 : Sektor des naechsten belegten Eintrages $0232: Position des Eintrages im Dir-Block z: 1: (BEQ) keinen Eintrag gefunden; 0: Suche erfolgreich Suche vorbereiten (1. Eintrag suchen) Einsprung von $82C0, $82F1, $95D0, $B26F: 8424: A0 00 LDY #$00 Zeiger auf den 1. Block, in dem sich ein 8426: 84 72 STY $72 freier Eintrag befindet, loeschen 8428: 88 DEY 8429: 8C 6D 02 STY $026D $ff: noch keinen Eintrag gefunden 842C: AD 2B 02 LDA $022B Directory Track merken 842F: 85 4D STA $4D als aktuelle Tracknummer und 8431: AD E5 01 LDA $01E5 1. Direktory-Sektor merken als 8434: 85 4E STA $4E aktuelle Sektornummer und als 8436: 8D A6 02 STA $02A6 naechster Verzeichnissektor 8439: 20 CF 93 JSR $93CF fuer SA 17 Lesekanal suchen, 1. Block lesen Eintrag suchen Einsprung von $849E: 843C: AD A6 02 LDA $02A6 Ist noch ein Verzeichnisblock vorhanden 843F: D0 01 BNE $8442 ja, ==> 8441: 60 RTS nein, z=1, Ende ==> Einsprung von $843F: 8442: A9 07 LDA #$07 8 Direktory-Eintraege (0-7) 8444: 8D 31 02 STA $0231 8447: A9 00 LDA #$00 1. Byte aus Dir-Puffer holen 8449: 20 50 94 JSR $9450 (>0: Es folgt noch ein Block) 844C: 8D A6 02 STA $02A6 und merken Einsprung von $8498: 844F: 20 42 94 JSR $9442 Pufferzeiger holen 8452: CE 31 02 DEC $0231 Anzahl der uebrigen Eintraege -1 8455: A0 00 LDY #$00 8457: B1 64 LDA ($64),Y Filetyp <> 0 (nicht geloescht) 8459: D0 14 BNE $846F ja, ==> 845B: A5 72 LDA $72 muss noch ein freier Eintrag gesucht werden? 845D: D0 2A BNE $8489 nein, (schon gefunden) ==> 845F: 20 79 9D JSR $9D79 T&S der aktuellen Datei holen 8462: A5 4E LDA $4E Sektornummer des Dir-Blocks merken 8464: 85 72 STA $72 (loescht gleichzeitig das Such-Flag) 8466: A5 64 LDA $64 Position des freien Eintrages merken 8468: A6 73 LDX $73 (z-Flag setzen, wenn ein belegter Eintrag 846A: 85 73 STA $73 gesucht wird) 846C: F0 1B BEQ $8489 ($73<>0): war freier Eintrag gesucht ? 846E: 60 RTS ja, z=0, Ende ==> belegten Eintrag gefunden Einsprung von $8459: 846F: A2 01 LDX #$01 $73=0: war ein belegter Eintrag gesucht ? 8471: E4 73 CPX $73 8473: D0 2C BNE $84A1 ja, ==> 8475: F0 12 BEQ $8489 nein, weitersuchen ==> Suche bei der letzten gefundenen Datei fortsetzen Einsprung von $82E6, $B2A7: 8477: AD 2B 02 LDA $022B <-- (Dir-Block neu lesen) 847A: 85 4D STA $4D Direktory-Track setzen 847C: A5 71 LDA $71 Block holen, in dem letzter Eintrag 847E: 85 4E STA $4E Eintrag gefunden wurde 8480: 20 CF 93 JSR $93CF fuer SA 17 Lesekanal suchen und Block lesen 8483: AD 32 02 LDA $0232 Zeiger auf letzten Dir-Eintrag holen 8486: 20 22 94 JSR $9422 Pufferzeiger setzen Einsprung von $845D, $846C, $8475, $82CB, $8304, $95F0: 8489: A9 FF LDA #$FF <-- (Dir ist noch im Puffer) 848B: 8D 6D 02 STA $026D $ff: noch keinen Eintrag gefunden 848E: AD 31 02 LDA $0231 Ist noch ein Eintrag im aktuellen Block ? 8491: 30 08 BMI $849B nein, ==> 8493: A9 20 LDA #$20 $20: Laenge eines Dir-Eintrages 8495: 20 38 91 JSR $9138 Pufferzeiger auf naechsten Eintrag setzen 8498: 4C 4F 84 JMP $844F und pruefen Einsprung von $8491: 849B: 20 AA 93 JSR $93AA naechsten Block lesen 849E: 4C 3C 84 JMP $843C Eintrag suchen Position der gefundenen Datei merken Einsprung von $8473: 84A1: A5 64 LDA $64 Zeiger auf den Eintrag merken 84A3: 8D 32 02 STA $0232 84A6: 20 79 9D JSR $9D79 T&S der aktuellen Datei holen 84A9: A5 4E LDA $4E Dir-Block merken, in dem der Eintrag 84AB: 85 71 STA $71 gefunden wurde 84AD: 60 RTS z=0, Ende ==> Testet auf Diskettenwechsel und initialisiert ggf. ($c63d) Einsprung von $82AC, $8627, $89E7, $8B23, $8B2F, $A956, $B781, $B8E3: 84AE: A5 2D LDA $2D Auto-Initialisierung ein ? 84B0: D0 31 BNE $84E3 nein, ==> 84B2: A9 01 LDA #$01 Wurde Diskette gewechselt ? 84B4: 24 25 BIT $25 (bzw. Lesefehler) 84B6: F0 2B BEQ $84E3 nein, ==> 84B8: 20 CF B0 JSR $B0CF physikalisches 1581-Format festlegen 84BB: 20 B3 B0 JSR $B0B3 ganze Diskette als Partition setzen 84BE: A9 80 LDA #$80 Job-Fehlerbehandlung ausschalten 84C0: 8D A8 02 STA $02A8 (wird automatisch zurueckgesetzt) 84C3: 20 DC 8E JSR $8EDC Verzeichnis-Blockheader suchen 84C6: A0 FF LDY #$FF Code fuer Drive-Error 84C8: C9 02 CMP #$02 ist Error $02,$03 oder $0f aufgetreten ? 84CA: F0 0A BEQ $84D6 ja, ==> 84CC: C9 03 CMP #$03 84CE: F0 06 BEQ $84D6 ja, ==> 84D0: C9 0F CMP #$0F 84D2: F0 02 BEQ $84D6 ja, ==> 84D4: A0 00 LDY #$00 nein, Code fuer Drive Ok. Einsprung von $84CA, $84CE, $84D2: 84D6: 98 TYA 84D7: 85 6E STA $6E Drive-Status setzen 84D9: D0 08 BNE $84E3 Fehler ? ja, (Ende) ==> 84DB: A9 80 LDA #$80 Job-Fehlerbehandlung ausschalten 84DD: 8D A8 02 STA $02A8 84E0: 20 03 8F JSR $8F03 Partition initialisieren Einsprung von $84B0, $84B6, $84D9: 84E3: 24 8A BIT $8A Burst-OR-Maske 84E5: 10 04 BPL $84EB b7=1: Fremdformat ? ja, ==> 84E7: A9 FF LDA #$FF Drive-Status setzen 84E9: 85 6E STA $6E Einsprung von $84E5: 84EB: A5 6E LDA $6E 84ED: 60 RTS Parameter aus dem INPUT-Puffer in Disk-Puffer kopieren ($c66e) E: a: max. Laenge des Parameters (Rest wird mit $a0 aufgefuellt) es werden max. 16 Zeichen kopiert (Rest ist immer $a0) x: Position des Parameters im INPUT-Puffer y: Zielpuffer Der Pufferzeiger muss auf den Zielbereich zeigen Einsprung von $88F7, $962E, $B39F: 84EE: 48 PHA 84EF: 20 26 85 JSR $8526 Laenge des Parameters feststellen 84F2: 20 08 85 JSR $8508 Parameter kopieren 84F5: 68 PLA 84F6: 38 SEC max. Laenge 84F7: ED 6C 02 SBC $026C - Parameterlaenge 84FA: AA TAX 84FB: F0 0A BEQ $8507 <=0 ? ja, ==> 84FD: 90 08 BCC $8507 84FF: A9 A0 LDA #$A0 Rest mit $a0 auffuellen Einsprung von $8505: 8501: 91 64 STA ($64),Y 8503: C8 INY 8504: CA DEX 8505: D0 FA BNE $8501 Einsprung von $84FB, $84FD: 8507: 60 RTS Parameter kopieren Einsprung von $84F2: 8508: 98 TYA 8509: 0A ASL Puffernummer * 2 850A: A8 TAY 850B: B9 BB 00 LDA $00BB,Y (Pufferzeiger holen) 850E: 85 64 STA $64 8510: B9 BC 00 LDA $00BC,Y 8513: 85 65 STA $65 8515: A0 00 LDY #$00 kopieren Einsprung von $8523: 8517: BD 00 02 LDA $0200,X 851A: 91 64 STA ($64),Y 851C: C8 INY 851D: F0 06 BEQ $8525 Pufferende, ==> 851F: E8 INX Kopieren, bis x hinter den Parameter zeigt 8520: EC 90 02 CPX $0290 ($0290: Zeiger hinter Parameter) 8523: 90 F2 BCC $8517 Einsprung von $851D: 8525: 60 RTS Laenge eines Parameters ermitteln ($c6a6) Sucht ab der x-ten Position nach ',' oder '=' E: x: Startposition des Parameters A: $0290: Ende des Parameters in der Befehlszeile $026c: Laenge des Parameters (max. 15) Einsprung von $8351, $84EF, $B853: 8526: A9 00 LDA #$00 8528: 8D 6C 02 STA $026C Parameterlaenge auf 0 setzen 852B: 8A TXA x-Register retten 852C: 48 PHA Einsprung von $8545: 852D: BD 00 02 LDA $0200,X ist das Zeichen ein Trennzeichen ? 8530: C9 2C CMP #$2C 8532: F0 13 BEQ $8547 ja, ==> 8534: C9 3D CMP #$3D 8536: F0 0F BEQ $8547 ja, ==> 8538: EE 6C 02 INC $026C Parameterlaenge + 1 853B: E8 INX naechstes Zeichen pruefen 853C: A9 0F LDA #$0F Parameter schon 15 Bytes lang ? 853E: CD 6C 02 CMP $026C 8541: 90 04 BCC $8547 ja, ==> 8543: E4 29 CPX $29 Kommandozeile zuende ? 8545: 90 E6 BCC $852D nein, ==> Einsprung von $8532, $8536, $8541: 8547: 8E 90 02 STX $0290 Ende des Parameters merken 854A: 68 PLA ($0290 zeigt auf Trennzeichen) 854B: AA TAX x-Register zurueckholen 854C: 60 RTS Directory-Zeile im Zwischenpuffer erzeugen ($c6ce) Einsprung von $B1D0: 854D: A5 52 LDA $52 aktuelle SA retten 854F: 48 PHA 8550: A5 50 LDA $50 aktuelle Kanalnummer retten 8552: 48 PHA 8553: 20 5D 85 JSR $855D Zeile erzeugen 8556: 68 PLA 8557: 85 50 STA $50 Kanalnummer und SA 8559: 68 PLA 855A: 85 52 STA $52 zurueckholen 855C: 60 RTS Einsprung von $8553: 855D: A9 11 LDA #$11 855F: 85 52 STA $52 Fuer die SA 17 (lesen) den internen Kanal 8561: 20 27 90 JSR $9027 zum Lesen holen 8564: 20 42 94 JSR $9442 Pufferzeiger holen 8567: AD 6D 02 LDA $026D Wurde ein Dateiname gefunden ? 856A: 10 05 BPL $8571 ja, ==> 856C: 20 6B 86 JSR $866B 'Blocks Free' ausgeben 856F: 18 CLC 8570: 60 RTS Einsprung von $856A: 8571: AD A4 02 LDA $02A4 Drivenummer ? [Diese Speicherzelle wird bei $82a6 auf 0 gesetzt, hier abgefragt und sonst nicht veraendert] 8574: F0 15 BEQ $858B (normalerweise immer) ==> Programm-Leiche 8576: CE A4 02 DEC $02A4 Drivenummer -1 8579: D0 03 BNE $857E =0 ? nein, ==> 857B: 4C 2D 80 JMP $802D 31, Syntax Error Einsprung von $8579: 857E: A9 00 LDA #$00 8580: 8D 8E 02 STA $028E Basic-Zeilennummer (Hi) =0 8583: 8D A4 02 STA $02A4 Drivenummer = 0 8586: 20 27 86 JSR $8627 Dir-Titel erzeugen 8589: 38 SEC 858A: 60 RTS Filenamen und Dateityp an die richtige Stelle im Puffer schreiben Einsprung von $8574: 858B: A2 18 LDX #$18 Endposition der Zeile (Position des '<') 858D: A0 1D LDY #$1D Position der Filelaenge (Hi) im Directory 858F: B1 64 LDA ($64),Y Laenge (Hi) holen 8591: 8D 8E 02 STA $028E und merken 8594: F0 02 BEQ $8598 = 0 ? ja, ==> 8596: A2 16 LDX #$16 >0: Die Dateilaenge ist also 3-stellig [Bei der 1581 koennen zwar auch 4-stellige Dateilaengen vorkommen, der Filename wird dann aber zu weit rechts ausgegeben.] Einsprung von $8594: 8598: 88 DEY 8599: B1 64 LDA ($64),Y Filelaenge (Lo) holen 859B: 8D 8D 02 STA $028D und merken 859E: E0 16 CPX #$16 Ist die Filelaenge > 255 (3-stellig) ? 85A0: F0 0A BEQ $85AC ja, ==> 85A2: C9 0A CMP #$0A < 10 (1-stellig) ? 85A4: 90 06 BCC $85AC ja, ==> 85A6: CA DEX 85A7: C9 64 CMP #$64 < 100 (2-stellig) ? 85A9: 90 01 BCC $85AC ja, ==> 85AB: CA DEX Dateilaenge: 100-255 Blocks (3-stellig) Einsprung von $85A0, $85A4, $85A9: 85AC: 20 1C 86 JSR $861C Dir-Zeilen-Puffer loeschen 85AF: B1 64 LDA ($64),Y y=0: Filetyp holen 85B1: 48 PHA 85B2: 0A ASL b6=1 (Scratch-Schutz) ? 85B3: 10 05 BPL $85BA nein, ==> 85B5: A9 3C LDA #$3C 85B7: 9D AD 02 STA $02AD,X '<' in Puffer schreiben Einsprung von $85B3: 85BA: 68 PLA 85BB: 29 0F AND #$0F Filetyp isolieren 85BD: A8 TAY 85BE: B9 B7 DB LDA $DBB7,Y 3. Buchstabe des Filetypes 85C1: 9D AC 02 STA $02AC,X in Puffer schreiben 85C4: CA DEX 85C5: B9 B1 DB LDA $DBB1,Y 2. Buchstabe des Filetypes 85C8: 9D AC 02 STA $02AC,X in Puffer schreiben 85CB: CA DEX 85CC: B9 AB DB LDA $DBAB,Y 1. Buchstabe des Filetypes 85CF: 9D AC 02 STA $02AC,X in Puffer schreiben 85D2: CA DEX 85D3: CA DEX File ordnungsgemaess geschlossen ? 85D4: B0 05 BCS $85DB ja, ==> 85D6: A9 2A LDA #$2A 85D8: 9D AD 02 STA $02AD,X '*' in Puffer schreiben Einsprung von $85D4: 85DB: A9 A0 LDA #$A0 ein Freiraum lassen 85DD: 9D AC 02 STA $02AC,X [Es wird 'Shift-Space' verwendet, damit auch bei 16 Zeichen langen Filenamen das 85E0: CA DEX zweite '"' an die richtige Stelle kommt.] 85E1: A0 12 LDY #$12 Filenamen kopieren Einsprung von $85EC: 85E3: B1 64 LDA ($64),Y 85E5: 9D AC 02 STA $02AC,X 85E8: CA DEX 85E9: 88 DEY 85EA: C0 03 CPY #$03 Anfang (T&S des Files) erreicht ? 85EC: B0 F5 BCS $85E3 nein, ==> Filenamen in '"' einschliessen 85EE: A9 22 LDA #$22 85F0: 9D AC 02 STA $02AC,X '"' am Namensanfang setzen Einsprung von $8601: 85F3: E8 INX 85F4: E0 20 CPX #$20 Zeilenende erreicht ? 85F6: B0 0B BCS $8603 ja, ==> 85F8: BD AC 02 LDA $02AC,X Zeichen aus Filenamen holen 85FB: C9 22 CMP #$22' = '"' ? 85FD: F0 04 BEQ $8603 ja, ==> 85FF: C9 A0 CMP #$A0 = 'Shift-Space' ? 8601: D0 F0 BNE $85F3 nein, ==> Einsprung von $85F6, $85FD: 8603: A9 22 LDA #$22' zweites '"' setzen 8605: 9D AC 02 STA $02AC,X vom '"' bis zum Zeilenende alle Zeichen 'entshiften' (b7 loeschen) Einsprung von $8615: 8608: E8 INX 8609: E0 20 CPX #$20 Zeilenende erreicht ? 860B: B0 0A BCS $8617 ja, ==> 860D: A9 7F LDA #$7F 860F: 3D AC 02 AND $02AC,X b7=0 8612: 9D AC 02 STA $02AC,X 8615: 10 F1 BPL $8608 immer ==> Einsprung von $860B: 8617: 20 04 83 JSR $8304 naechsten Dir-Eintrag holen 861A: 38 SEC 861B: 60 RTS Directoryzeilen-Puffer loeschen ($c7ac) Einsprung von $85AC, $862D, $866B: 861C: A0 1B LDY #$1B 861E: A9 20 LDA #$20 Puffer mit Spaces fuellen Einsprung von $8624: 8620: 99 AB 02 STA $02AB,Y 8623: 88 DEY 8624: D0 FA BNE $8620 8626: 60 RTS Directory-Titel erzeugen ($c7b7) Einsprung von $8586, $9942: 8627: 20 AE 84 JSR $84AE Laufwerk ggf. initialisieren 862A: 20 33 B6 JSR $B633 Verzeichnis-Header lesen 862D: 20 1C 86 JSR $861C Dir-Zeilen-Puffer loeschen 8630: A9 FF LDA #$FF 8632: 85 40 STA $40 8634: A9 00 LDA #$00 Basic-Zeilennummer (Drivenummer) = 0 8636: 8D 8D 02 STA $028D 8639: 8D 8E 02 STA $028E 863C: A6 6C LDX $6C aktuelle Puffernummer holen 863E: BD F1 01 LDA $01F1,X Pufferadresse holen 8641: 85 65 STA $65 8643: AD 77 DB LDA $DB77 Position des Disknamens holen 8646: 85 64 STA $64 8648: A0 16 LDY #$16 22 Bytes Disknamen+ID Einsprung von $8656: 864A: B1 64 LDA ($64),Y in Dir-Zeile kopieren 864C: C9 A0 CMP #$A0 864E: D0 02 BNE $8652 Shift-Spaces in Spaces umwandeln 8650: A9 20 LDA #$20 Einsprung von $864E: 8652: 99 AE 02 STA $02AE,Y 8655: 88 DEY 8656: 10 F2 BPL $864A 8658: A9 12 LDA #$12 RVS-ON an Pufferanfang setzen 865A: 8D AC 02 STA $02AC 865D: A9 22 LDA #$22 Filenamen in '"' einschliessen 865F: 8D AD 02 STA $02AD 8662: 8D BE 02 STA $02BE 8665: A9 20 LDA #$20 Zeichen vor der ID = 'Space' 8667: 8D BF 02 STA $02BF 866A: 60 RTS 'Blocks Free'-Meldung ausgeben ($c806) Einsprung von $856C: 866B: 20 1C 86 JSR $861C Ausgabepuffer loeschen 866E: A0 0B LDY #$0B Einsprung von $8677: 8670: B9 7C 86 LDA $867C,Y Meldung in Puffer kopieren 8673: 99 AC 02 STA $02AC,Y 8676: 88 DEY 8677: 10 F7 BPL $8670 8679: 4C 5B B6 JMP $B65B Freie Blocks als Basic-Zeilennummer merken 867C: 42 4C 4F 43 4B 53 20 46 blocks f 8684: 52 45 45 2E ree. Scratch ($c823) 8688: 20 70 82 JSR $8270 Dateityp feststellen ('S0:A*=U') 868B: 20 0B 82 JSR $820B alle Filenamen auf Drivenummer testen 868E: 20 A2 82 JSR $82A2 Drive initialisieren 8691: A9 00 LDA #$00 Zaehler fuer 'Files scratched' = 0 8693: 85 55 STA $55 8695: 20 ED 82 JSR $82ED 1. Datei suchen 8698: 30 6E BMI $8708 nicht gefunden, ==> Einsprung von $8706: 869A: 20 F5 9C JSR $9CF5 Ist das File gerade geoeffnet 869D: 90 64 BCC $8703 ja, ==> 869F: A0 00 LDY #$00 Filetyp holen 86A1: B1 64 LDA ($64),Y 86A3: 8D EE 01 STA $01EE und merken 86A6: 29 40 AND #$40 b6=1: Ist der Scratch-Schutz aktiv ? 86A8: D0 59 BNE $8703 ja, ==> 86AA: 20 3B 87 JSR $873B Filetyp = 0 setzen CBM-Dateien loeschen 86AD: AD EE 01 LDA $01EE Filetyp holen 86B0: 29 07 AND #$07 86B2: C9 05 CMP #$05 ist es eine Partition 86B4: D0 25 BNE $86DB nein, ==> 86B6: C8 INY 86B7: B1 64 LDA ($64),Y Start-T&S holen 86B9: 85 4D STA $4D 86BB: C8 INY 86BC: B1 64 LDA ($64),Y 86BE: 85 4E STA $4E 86C0: A0 1C LDY #$1C 86C2: B1 64 LDA ($64),Y Laenge der Partition holen 86C4: 8D EE 01 STA $01EE 86C7: C8 INY 86C8: B1 64 LDA ($64),Y 86CA: 8D ED 01 STA $01ED Einsprung von $86D6: 86CD: 20 B5 94 JSR $94B5 auf gueltigen Partition-Block pruefen 86D0: 20 46 B5 JSR $B546 Block in Bam freigeben 86D3: 20 EF B2 JSR $B2EF naechsten Block der Partition holen 86D6: D0 F5 BNE $86CD noch Blocks uebrig, ==> 86D8: 4C EE DB JMP $DBEE Bam speichern, Sprung nach $8701 File loeschen Einsprung von $86B4: 86DB: A0 13 LDY #$13 Side-Sektoren loeschen 86DD: B1 64 LDA ($64),Y 86DF: F0 0A BEQ $86EB sind Side-Sektoren vorhanden ? 86E1: 85 4D STA $4D ja, T&S merken 86E3: C8 INY 86E4: B1 64 LDA ($64),Y 86E6: 85 4E STA $4E 86E8: 20 13 87 JSR $8713 Blocks freigeben Einsprung von $86DF: 86EB: AE 6D 02 LDX $026D File loeschen 86EE: A9 20 LDA #$20 ist die Datei ordnungsgemaess geschlossen ? 86F0: 35 F4 AND $F4,X (b5=0) 86F2: D0 0D BNE $8701 nein, ('*'-File) ==> 86F4: BD 97 02 LDA $0297,X T&S des Files holen 86F7: 85 4D STA $4D 86F9: BD 9C 02 LDA $029C,X 86FC: 85 4E STA $4E 86FE: 20 13 87 JSR $8713 Datei verfolgen und Blocks freigeben Einsprung von $86F2, $DBF1: 8701: E6 55 INC $55 Anzahl 'Files scratched' +1 Einsprung von $869D, $86A8: 8703: 20 E6 82 JSR $82E6 naechste Datei suchen 8706: 10 92 BPL $869A gefunden, ==> Einsprung von $8698: 8708: A5 55 LDA $55 Anzahl 'Files scratched' fuer die Meldung 870A: 85 4D STA $4D als aktuelle Tracknummer merken 870C: A0 00 LDY #$00 Sektornummer =0 870E: A9 01 LDA #$01 01, Files scratched ,xx,00 8710: 4C 5D 80 JMP $805D File verfolgen und Blocks freigeben Einsprung von $86E8, $86FE, $9AE2: 8713: 20 46 B5 JSR $B546 1. Block des Files freigeben 8716: 20 CF 93 JSR $93CF Datei auf internem Lesekanal oeffnen Einsprung von $8738: 8719: A9 00 LDA #$00 Pufferzeiger auf 0 setzen 871B: 20 22 94 JSR $9422 871E: 20 9B 90 JSR $909B T&S des Folgeblocks holen und merken 8721: 85 4D STA $4D 8723: 20 9B 90 JSR $909B (Byte aus Puffer holen) 8726: 85 4E STA $4E 8728: A5 4D LDA $4D existiert ein Folgeblock ? 872A: D0 06 BNE $8732 ja, ==> 872C: 20 15 B5 JSR $B515 BAM abspeichern 872F: 4C 9E 91 JMP $919E Lesekanal freigeben Einsprung von $872A: 8732: 20 46 B5 JSR $B546 Folgeblock freigeben 8735: 20 AA 93 JSR $93AA Folgeblock lesen 8738: 4C 19 87 JMP $8719 File im Directory als geloescht kennzeichnen Einsprung von $86AA, $9780, $B2C1: 873B: A0 00 LDY #$00 Filetyp = 0 (DEL) setzen 873D: 98 TYA 873E: 91 64 STA ($64),Y 8740: 20 9A 9D JSR $9D9A Puffer schreiben 8743: 4C ED 94 JMP $94ED Jobausfuehrung ueberwachen Partition formatieren Einsprung von $B377: 8746: A5 90 LDA $90 Starttrack der Partition holen und merken 8748: 85 4D STA $4D 874A: A9 00 LDA #$00 und Sektor 0 merken (Partitionen muessen 874C: 85 4E STA $4E am 1. Sektor der Spur beginnen) 874E: 20 88 95 JSR $9588 T&S an DC uebergeben 8751: 20 CF B0 JSR $B0CF Physikalisches 1581-Format setzen 8754: A9 C0 LDA #$C0 'RESTORE_DV': Kopf auf Spur 0 setzen 8756: 20 9D 95 JSR $959D Aufruf des Controllers 8759: A4 9B LDY $9B altes Fuellbyte merken 875B: A9 00 LDA #$00 Blocks beim Formatieren mit $00 fuellen 875D: 85 9B STA $9B 875F: A9 F0 LDA #$F0 'FORMATDK_DV': Partition formatieren 8761: 20 9D 95 JSR $959D Controller aufrufen 8764: 84 9B STY $9B altes Fuellbyte zurueckholen 8766: C9 02 CMP #$02 Fehler ? 8768: 90 03 BCC $876D nein, ==> 876A: 4C 2D FF JMP $FF2D Job-Errorbehandlung ==> Einsprung von $8768: 876D: 60 RTS Copy ($c8f0) 876E: A9 00 LDA #$00 Flag: 'Bampuffer leer' setzen 8770: 8D 00 0A STA $0A00 8773: A9 1F LDA #$1F alle Kanaele freigeben 8775: 85 70 STA $70 8777: 20 99 80 JSR $8099 ':' suchen 877A: D0 03 BNE $877F gefunden 877C: 4C 7E 89 JMP $897E 31, SYNTAX ERROR Einsprung von $877A: 877F: 20 AC 80 JSR $80AC Eingabezeile pruefen 8782: 20 0B 82 JSR $820B Drivenummer(n) holen 8785: AD A2 02 LDA $02A2 Syntaxflag pruefen (Bedeutung: s. $db9c) 8788: 29 55 AND #$55 Ist ein ',' hinter dem '=' ? 878A: D0 0F BNE $879B ja, ==> 878C: AE 91 02 LDX $0291 878F: BD 00 02 LDA $0200,X beginnt der 1. Filename mit einem '*' ? 8792: C9 2A CMP #$2A 8794: D0 05 BNE $879B nein, ==> Einsprung von $87A0: 8796: A9 30 LDA #$30 30, Syntax Error 8798: 4C 7C 80 JMP $807C Einsprung von $878A, $8794: 879B: AD A2 02 LDA $02A2 Ist ein '*' in der Befehlszeile ? 879E: 29 D9 AND #$D9 87A0: D0 F4 BNE $8796 ja, ==> 87A2: 20 B9 82 JSR $82B9 alle angegebenen Files suchen 87A5: AD 2F 02 LDA $022F Anzahl der gefundenen Files 87A8: C9 03 CMP #$03 < 3 (also = 2) ? 87AA: 90 42 BCC $87EE ja, ==> File vor dem '=' mit 1. File hinter dem '=' vergleichen 87AC: A5 EF LDA $EF sind die Drivenummern gleich ? [Wenn keine 87AE: C5 F0 CMP $F0 Nummern angegeben werden, ist die eine $00 87B0: D0 3C BNE $87EE und die andere $80 !!!] nein, ==> 87B2: A5 EA LDA $EA Zeiger in Dir-Block gleich ? 87B4: C5 EB CMP $EB 87B6: D0 36 BNE $87EE nein, ==> 87B8: A5 E5 LDA $E5 Stehen beide Files im selben Dir-Block ? 87BA: C5 E6 CMP $E6 87BC: D0 30 BNE $87EE nein, ==> Neue Datei(en) an eine alte anhaengen (CONCAT) 87BE: 20 03 89 JSR $8903 pruefen, ob alle Files existieren 87C1: A9 01 LDA #$01 Zeiger auf das 1. File nach dem '=' setzen 87C3: 8D 30 02 STA $0230 87C6: 20 41 88 JSR $8841 File zum Lesen oeffnen 87C9: 20 5F 90 JSR $905F aktuellen Dateityp holen 87CC: B0 04 BCS $87D2 = REL-Datei, ==> 87CE: C9 02 CMP #$02 Wenn keine SEQ Datei, dann: 87D0: D0 05 BNE $87D7 Einsprung von $87CC: 87D2: A9 64 LDA #$64 64, File type mismatch 87D4: 20 7C 80 JSR $807C Einsprung von $87D0: 87D7: A9 12 LDA #$12 Auf internen Schreibkanal schalten 87D9: 85 52 STA $52 87DB: A5 B9 LDA $B9 internen Schreibkanal in 87DD: 85 BA STA $BA Lesekanal umwandeln 87DF: A9 FF LDA #$FF Lesekanal loeschen 87E1: 85 B9 STA $B9 [Nun ist das 1. File hinter dem '=' auf dem Schreibkanal zum Lesen geoeffnet. Bei dem Aufruf der Append-Funktion wird der benutzte Lesekanal automatisch wieder in einen Schreibkanal zurueckverwandelt.] 87E3: 20 CC 98 JSR $98CC Append: Dateiende suchen 87E6: A2 02 LDX #$02 mit 2. File nach dem '=' 87E8: 20 00 88 JSR $8800 'normales' COPY beginnen 87EB: 4C 4C 80 JMP $804C normales COPY Einsprung von $87AA, $87B0, $87B6, $87BC: 87EE: 20 F4 87 JSR $87F4 eigentliche Copy-Routine aufrufen 87F1: 4C 4C 80 JMP $804C Einsprung von $87EE: 87F4: 20 1E 89 JSR $891E existieren nur die Files hinter dem '=' ? (Rueckkehr nur bei 'Ja') 87F7: 20 E0 93 JSR $93E0 neues File anlegen 87FA: 20 AB 95 JSR $95AB und im Directory eintragen 87FD: AE 2E 02 LDX $022E 1. File nach dem '=' Einsprung von $87E8, $8838: 8800: 8E 30 02 STX $0230 als aktuelles File setzen 8803: 20 41 88 JSR $8841 File auf SA 17 zum Lesen oeffnen 8806: A9 11 LDA #$11 und aktivieren 8808: 85 52 STA $52 880A: 20 27 90 JSR $9027 (Kanalnummer holen) 880D: 20 5F 90 JSR $905F Filetyp holen 8810: D0 03 BNE $8815 kein REL-File, ==> 8812: 20 95 88 JSR $8895 REL-File zum Kopieren vorbereiten Einsprung von $8810: 8815: A9 08 LDA #$08 Flag 'EOI empfangen' loeschen 8817: 85 51 STA $51 8819: 4C 1F 88 JMP $881F Einsprung von $8827: 881C: 20 5C 8E JSR $8E5C Byte in Ziel-Datei schreiben Einsprung von $8819: 881F: 20 76 88 JSR $8876 Byte aus Quell-Datei holen 8822: A9 80 LDA #$80 b7=1: 'Dateiende' ? 8824: 20 E4 9C JSR $9CE4 (Dateistatus testen) 8827: F0 F3 BEQ $881C nein, ==> 8829: 20 5F 90 JSR $905F Filetyp holen 882C: F0 03 BEQ $8831 REL-Datei, ==> 882E: 20 5C 8E JSR $8E5C Byte in Zieldatei schreiben [Das Byte, das bei EOI zurueckgegeben wird, ist noch gueltig; bei REL-Dateien wurde bereits auf einen nicht existierenden Record zugegriffen.] Einsprung von $882C: 8831: AE 30 02 LDX $0230 naechstes File holen 8834: E8 INX 8835: EC 2F 02 CPX $022F noch eins vorhanden ? 8838: 90 C6 BCC $8800 ja, ==> 883A: A9 12 LDA #$12 Schreibkanal holen 883C: 85 52 STA $52 883E: 4C 9F 99 JMP $999F Ziel-Datei schliessen aktuelles File oeffnen ($c9fa) Einsprung von $87C6, $8803: 8841: AE 30 02 LDX $0230 Nummer des Files holen 8844: AD 2B 02 LDA $022B Directory-Track als aktuellen Track setzen 8847: 85 4D STA $4D 8849: B5 E5 LDA $E5,X Dir-Block mit Fileeintrag holen 884B: 85 4E STA $4E 884D: 20 CF 93 JSR $93CF SA 17 oeffnen und Dir-Block lesen 8850: AE 30 02 LDX $0230 8853: B5 EA LDA $EA,X Zeiger auf den Eintrag holen 8855: 20 22 94 JSR $9422 Pufferzeiger setzen 8858: AE 30 02 LDX $0230 885B: B5 F4 LDA $F4,X Dateityp holen und 885D: 29 07 AND #$07 885F: 8D 2D 02 STA $022D als aktuellen Dateitypen merken 8862: A9 00 LDA #$00 8864: 8D 6F 02 STA $026F Aktuelle Recordlaenge = 0 8867: 20 4D 98 JSR $984D File oeffnen und 1. Block lesen 886A: A0 01 LDY #$01 Pufferzeiger =1 886C: 20 5F 90 JSR $905F Dateityp auf REL-Datei testen 886F: F0 01 BEQ $8872 gleich, (Pufferzeiger =1) ==> 8871: C8 INY Zeiger =2 Einsprung von $886F: 8872: 98 TYA 8873: 4C 22 94 JMP $9422 Pufferzeiger setzen Byte aus aktueller Datei holen und auf Dateiende pruefen ($ca35) Einsprung von $881F, $A9D7, $A9F5: 8876: A9 11 LDA #$11 Internen Lesekanal setzen 8878: 85 52 STA $52 Einsprung von $98CC: 887A: 20 F4 92 JSR $92F4 Byte aus aktueller SA holen 887D: 85 54 STA $54 und merken 887F: A6 50 LDX $50 8881: BD 34 02 LDA $0234,X Kanalstatus testen 8884: 29 08 AND #$08 B3=0 (EOI) ? 8886: 85 51 STA $51 (EOI-Flag merken) 8888: D0 0A BNE $8894 nein, ==> 888A: 20 5F 90 JSR $905F aktuellen Filetyp auf REL-File 888D: F0 05 BEQ $8894 testen; gleich, ==> [EOI wird bei jedem Record-Ende gesetzt, deshalb muss das Flag: 'Record nicht vorhanden' (b7 im Dateistatus) getestet werden.] 888F: A9 80 LDA #$80 b7=1: Fileende-Flag setzen 8891: 20 D5 9C JSR $9CD5 Dateistatus setzen Einsprung von $8888, $888D: 8894: 60 RTS REL-File zum Kopieren vorbereiten ($ca53) Laenge der Quell-Datei ermitteln Einsprung von $8812: 8895: 20 5C A1 JSR $A15C Ende der Rel-Datei suchen 8898: 20 6E A5 JSR $A56E Super-Side-Sektor verwenden ? 889B: D0 04 BNE $88A1 nein, ==> 889D: AD 00 01 LDA $0100 Gruppennummer des Records merken 88A0: 48 PHA Einsprung von $889B: 88A1: A5 6A LDA $6A Position der T&S im Side-Sektor und 88A3: 48 PHA 88A4: A5 69 LDA $69 Side-Sektor-Nummer merken 88A6: 48 PHA Zieldatei um die erforderliche Laenge erweitern 88A7: A9 12 LDA #$12 Zieldatei oeffnen 88A9: 85 52 STA $52 88AB: 20 42 90 JSR $9042 Kanal zum Schreiben holen 88AE: 20 38 A4 JSR $A438 Parameter des letzten Records merken 88B1: 85 6B STA $6B a=0: Position des Records loeschen 88B3: 68 PLA Side-Sektornummer zurueckholen 88B4: 85 69 STA $69 88B6: 68 PLA Position der T&S im Side-Sektor zurueckholen 88B7: 85 6A STA $6A 88B9: 20 6E A5 JSR $A56E Super-Side-Sektor verwenden ? 88BC: D0 04 BNE $88C2 nein, ==> 88BE: 68 PLA 88BF: 8D 00 01 STA $0100 Gruppennummer zurueckholen Einsprung von $88BC: 88C2: 4C DC A2 JMP $A2DC Datensaetze an REL-File anhaengen DOS 2 RENAME ($ca88) 88C5: 20 0B 82 JSR $820B Drivenummer(n) testen 88C8: A5 F0 LDA $F0 Drivenummer des 2. Files 88CA: 29 01 AND #$01 88CC: 85 F0 STA $F0 88CE: C5 EF CMP $EF = Drivenummer des 1. Files ? 88D0: F0 02 BEQ $88D4 ja, ==> 88D2: 09 80 ORA #$80 Flag fuer unbestimmte Drivenummer setzen Einsprung von $88D0: 88D4: 85 EF STA $EF 88D6: 20 B9 82 JSR $82B9 alle angegebenen Dateien suchen 88D9: 20 1E 89 JSR $891E Existiert nur der 2. Name schon ? 88DC: A5 E6 LDA $E6 (Rueckkehr nur bei Ja) 88DE: 85 4E STA $4E 88E0: 20 94 9D JSR $9D94 Dir-Block mitdem gesuchten Eintrag einlesen 88E3: 20 ED 94 JSR $94ED Job abwarten 88E6: A5 EB LDA $EB Zeiger auf Dateieintrag 88E8: 18 CLC 88E9: 69 03 ADC #$03 +3 (Typ,T&S beruecksichtigen) 88EB: 20 22 94 JSR $9422 Pufferzeiger setzen 88EE: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen 88F1: A8 TAY 88F2: AE 91 02 LDX $0291 Position des neuen Dateinamens 88F5: A9 10 LDA #$10 und Maximallaenge holen 88F7: 20 EE 84 JSR $84EE Namen kopieren und mit $a0 auffuellen 88FA: 20 9A 9D JSR $9D9A Puffer schreiben 88FD: 20 ED 94 JSR $94ED Job abwarten 8900: 4C 4C 80 JMP $804C aktuellen Filetyp ermitteln und pruefen, ob alle Files nach dem '=' existieren ($cacc) Einsprung von $87BE, $891E: 8903: A5 F5 LDA $F5 Dateityp des 1. Files hinter dem '=' holen 8905: 29 07 AND #$07 8907: 8D 2D 02 STA $022D und als aktuellen Filetyp merken 890A: AE 2F 02 LDX $022F vom letzten Fileeintrag bis zum Einsprung von $8916: 890D: CA DEX 890E: EC 2E 02 CPX $022E 1. Fileeintrag nach dem '=' 8911: 90 0A BCC $891D ( fertig, ==> ) 8913: BD 97 02 LDA $0297,X Tracknummer des aktuellen Files holen 8916: D0 F5 BNE $890D >0 (File existiert), ==> 8918: A9 62 LDA #$62 891A: 4C 7C 80 JMP $807C 62, File not found Einsprung von $8911: 891D: 60 RTS pruefen, ob alle Files vor dem '=' nicht existieren und alle Files nach dem '=' existieren ($cae7) Einsprung von $87F4, $88D9: 891E: 20 03 89 JSR $8903 existieren Files nach dem '=' ? Einsprung von $892C: 8921: BD 97 02 LDA $0297,X ja; Tracknummer der Files vor dem '=' =0 ? 8924: F0 05 BEQ $892B ja, ==> 8926: A9 63 LDA #$63 8928: 4C 7C 80 JMP $807C 63, File exists Einsprung von $8924: 892B: CA DEX naechstes File pruefen 892C: 10 F3 BPL $8921 noch eines vorhanden, ==> 892E: 60 RTS Memory-Befehle ($caf8) 892F: AD 01 02 LDA $0201 Zeichen hinter M 8932: C9 2D CMP #$2D <> '-' 8934: D0 48 BNE $897E ja, 31, Syntax Error ==> 8936: AD 03 02 LDA $0203 Adresse hinter m-x Befehl holen 8939: 85 40 STA $40 893B: AD 04 02 LDA $0204 893E: 85 41 STA $41 8940: A0 00 LDY #$00 8942: AD 02 02 LDA $0202 Zeichen hinter dem '-' pruefen: 8945: C9 52 CMP #$52 8947: F0 0B BEQ $8954 M-R, ==> 8949: C9 57 CMP #$57 894B: F0 36 BEQ $8983 M-W, ==> 894D: C9 45 CMP #$45 894F: D0 2D BNE $897E 31, Syntax Error Memory-Execute 8951: 6C 40 00 JMP ($0040) Memory-Read Einsprung von $8947: 8954: B1 40 LDA ($40),Y 1. Datenbyte holen und merken 8956: 85 54 STA $54 8958: A5 29 LDA $29 Laenge der Kommandozeile < 6 ? 895A: C9 06 CMP #$06 ('m-r',lo,hi) 895C: 90 1A BCC $8978 ja, ==> 895E: AE 05 02 LDX $0205 Anzahl der zu sendenden Bytes holen 8961: CA DEX -1 (1. Byte ist bereits gelesen) 8962: F0 14 BEQ $8978 = 0 ? ja, ==> 8964: 8A TXA Anzahl zu sendender Bytes + 8965: 18 CLC 8966: 65 40 ADC $40 Adresse des 1. Bytes 8968: E6 40 INC $40 (1. Byte ist gelesen) 896A: 8D 48 02 STA $0248 = Endadresse (Lo) 896D: A5 40 LDA $40 Adresse des auszugebenden Speicherbereiches 896F: 85 CF STA $CF in den Fehlerkanal-Pufferzeiger kopieren 8971: A5 41 LDA $41 8973: 85 D0 STA $D0 8975: 4C 9F 93 JMP $939F Byte zur Ausgabe bereitstellen Einsprung von $895C, $8962: 8978: 20 27 90 JSR $9027 Kanal zum Lesen holen 897B: 4C 96 93 JMP $9396 auf Fehlerpuffer zurueckschalten Einsprung von $8934, $894F, $877C: 897E: A9 31 LDA #$31 31, Syntax Error 8980: 4C 7C 80 JMP $807C Memory-Write Einsprung von $894B, $898C: 8983: B9 06 02 LDA $0206,Y 'm-w',lo,hi,anz,d1,d2,.. 8986: 91 40 STA ($40),Y (d1 liegt bei $0206) 8988: C8 INY 8989: CC 05 02 CPY $0205 (anz liegt bei $0205) 898C: 90 F5 BCC $8983 alle Bytes kopieren 898E: 60 RTS User-Befehle ($cb5c) 898F: AC 01 02 LDY $0201 u0-Befehle ? 8992: C0 30 CPY #$30 8994: D0 36 BNE $89CC nein ==> 8996: A5 29 LDA $29 'u0' ? 8998: C9 03 CMP #$03 899A: 90 27 BCC $89C3 ja, Tabelle $ffea aktivieren ==> 899C: 78 SEI 'u0...' 899D: AD 02 02 LDA $0202 Befehl holen 89A0: 85 7C STA $7C und merken 89A2: 29 1F AND #$1F b0-4: Befehlsnummer 89A4: AA TAX 89A5: 0A ASL 16-Bit Index 89A6: A8 TAY 89A7: B9 36 DB LDA $DB36,Y Sprungadresse des Userbefehls holen 89AA: 85 46 STA $46 89AC: B9 37 DB LDA $DB37,Y 89AF: 85 47 STA $47 89B1: 20 F6 81 JSR $81F6 Drive-LED einschalten 89B4: A5 76 LDA $76 b2=0: Burst-Clock Zustand loeschen 89B6: 29 FB AND #$FB 89B8: 85 76 STA $76 89BA: 20 C0 89 JSR $89C0 Userbefehl aufrufen 89BD: 4C 4C 80 JMP $804C DOS-Meldung ausgeben Einsprung von $89BA: 89C0: 6C 46 00 JMP ($0046) Einsprung von $899A, $B065: 89C3: A9 EA LDA #$EA Standardtabelle fuer u1-u: ($ffea) setzen 89C5: 85 33 STA $33 89C7: A9 FF LDA #$FF 89C9: 85 34 STA $34 Burst-Befehle $18,$19: (RTS) 89CB: 60 RTS USER-Befehle '1' - ':' aufrufen Einsprung von $8994: 89CC: 20 D2 89 JSR $89D2 'u1' - 'u:' aufrufen 89CF: 4C 4C 80 JMP $804C Einsprung von $89CC: 89D2: 88 DEY Beginn mit 1 (nicht 0) 89D3: 98 TYA 89D4: 29 0F AND #$0F 89D6: 0A ASL 89D7: A8 TAY Adresse holen 89D8: B1 33 LDA ($33),Y 89DA: 85 46 STA $46 89DC: C8 INY 89DD: B1 33 LDA ($33),Y 89DF: 85 47 STA $47 89E1: 6C 46 00 JMP ($0046) und anspringen '#', oeffnen eines Direktzugriffkanals ($cb84) Einsprung von $96D3: 89E4: A5 52 LDA $52 aktuelle SA merken 89E6: 48 PHA 89E7: 20 AE 84 JSR $84AE ggf. Drive initialisieren 89EA: 68 PLA 89EB: 85 52 STA $52 SA zurueckholen 89ED: A6 29 LDX $29 89EF: CA DEX nur '#' ? 89F0: D0 0D BNE $89FF '#x' ==> 89F2: A9 01 LDA #$01 89F4: 20 5A 91 JSR $915A Kanal oeffnen und 1 Puffer belegen 89F7: 4C 35 8A JMP $8A35 Einsprung von $8A09, $8A19: 89FA: A9 70 LDA #$70 70, no Channel 89FC: 4C 7C 80 JMP $807C Einsprung von $89F0: 89FF: A0 01 LDY #$01 Zeiger auf 2. Zeichen im INPUT-Puffer 8A01: 20 AC 8A JSR $8AAC setzen und Zahl holen 8A04: AE 9C 02 LDX $029C Puffernummer >= 8 ? 8A07: E0 08 CPX #$08 8A09: B0 EF BCS $89FA ja, ==> 8A0B: A9 00 LDA #$00 Pruefen, ob Puffer frei ist 8A0D: 85 40 STA $40 8A0F: 38 SEC 1-Bit x-mal shiften Einsprung von $8A13: 8A10: 26 40 ROL $40 8A12: CA DEX bis gewuenschte Position erreicht ist 8A13: 10 FB BPL $8A10 8A15: A5 40 LDA $40 und entsprechendes Bit der Pufferbelegung 8A17: 25 6D AND $6D testen; ist das Bit=1, dann ist der 8A19: D0 DF BNE $89FA Puffer belegt: 70, no Channel ==> 8A1B: A5 40 LDA $40 8A1D: 05 6D ORA $6D Bit setzen und dadurch Puffer belegen 8A1F: 85 6D STA $6D 8A21: A9 00 LDA #$00 8A23: 20 5A 91 JSR $915A Lesekanal oeffnen und keinen Puffer belegen 8A26: A6 50 LDX $50 8A28: AD 9C 02 LDA $029C Puffernummer holen 8A2B: 95 D1 STA $D1,X Puffer dem Kanal zuordnen 8A2D: AA TAX 8A2E: A9 00 LDA #$00 Jobcodes des Puffers loeschen 8A30: 95 02 STA $02,X 8A32: 9D 72 02 STA $0272,X Einsprung von $89F7: 8A35: A6 52 LDX $52 8A37: B5 A8 LDA $A8,X b76=01: Kanal zum Lesen/Schreiben oeffnen 8A39: 09 40 ORA #$40 8A3B: 95 A8 STA $A8,X in Sekundaeradressentabelle setzen 8A3D: A4 50 LDY $50 8A3F: A9 FF LDA #$FF Anzahl gueltige Bytes = 256 8A41: 99 42 02 STA $0242,Y (der ganze Puffer) 8A44: A9 89 LDA #$89 Kanalstatus: Schreiben, Lesen, kein EOI 8A46: 99 34 02 STA $0234,Y 8A49: B9 D1 00 LDA $00D1,Y Puffernummer fuer Ausgabe 8A4C: 99 3B 02 STA $023B,Y bereitstellen 8A4F: 0A ASL 16-Bit Index 8A50: AA TAX 8A51: A9 01 LDA #$01 Pufferzeiger auf 2. Byte setzen 8A53: 95 BB STA $BB,X (wegen Blocklaenge bei B-R, B-W) 8A55: A9 0E LDA #$0E b1-3: Dateityp $07: Direktzugriff 8A57: 99 F9 00 STA $00F9,Y 8A5A: 4C 4C 80 JMP $804C Block-Befehle ($cc1b) 8A5D: A0 00 LDY #$00 Am Zeilenanfang beginnen 8A5F: A2 00 LDX #$00 Anzahl gefundener ',' =0 8A61: A9 2D LDA #$2D 8A63: 20 1C 81 JSR $811C '-' suchen 8A66: D0 0A BNE $8A72 gefunden, ==> Einsprung von $8A82: 8A68: A9 31 LDA #$31 31, SYNTAX ERROR 8A6A: 4C 7C 80 JMP $807C Einsprung von $8A73, $8ACE: 8A6D: A9 30 LDA #$30 30, SYNTAX ERROR 8A6F: 4C 7C 80 JMP $807C Einsprung von $8A66: 8A72: 8A TXA ',' gefunden ? 8A73: D0 F8 BNE $8A6D ja, ==> 8A75: A2 09 LDX #$09 'b-x' 8A77: B9 00 02 LDA $0200,Y mit 'afrwepRW?*' vergleichen Einsprung von $8A80: 8A7A: DD 61 8C CMP $8C61,X 8A7D: F0 05 BEQ $8A84 gefunden, ==> 8A7F: CA DEX 8A80: 10 F8 BPL $8A7A noch nicht gefunden, ==> 8A82: 30 E4 BMI $8A68 gar nicht gefunden, ==> Einsprung von $8A7D: 8A84: 8A TXA Block-Befehlsnummer 8A85: 09 80 ORA #$80 +$80 (Kennzeichen fuer Block-Befehl) 8A87: 8D 2A 02 STA $022A Befehlsnummer speichern 8A8A: 20 9F A8 JSR $8A9F Blockparamerter holen 8A8D: AD 2A 02 LDA $022A aktuelle Befefehlsnummer holen 8A90: 0A ASL 8A91: AA TAX 8A92: BD 6C 8C LDA $8C6C,X Befehlsadresse holen 8A95: 85 41 STA $41 8A97: BD 6B 8C LDA $8C6B,X 8A9A: 85 40 STA $40 8A9C: 6C 40 00 JMP ($0040) Block-Befehl aufrufen ==> - Parameter der Block-Befehle holen ($cc7c) - Einsprung von $8A8A, $8B9A, $8BD7: 8A9F: A0 00 LDY #$00 Zeile vom Anfang an pruefen 8AA1: A2 00 LDX #$00 Anzahl gefundener Kommas = 0 8AA3: A9 3A LDA #$3A 8AA5: 20 1C 81 JSR $811C Eingabezeile bis zum ':' pruefen 8AA8: D0 02 BNE $8AAC ':' gefunden ? ja, ==> 8AAA: A0 03 LDY #$03 Zeiger hinter 'b-x' setzen Einsprung von $8AA8, $8ABE, $8A01: 8AAC: B9 00 02 LDA $0200,Y Zeichen aus Input-Puffer 8AAF: C9 20 CMP #$20 mit gueltigen Trennzeichen 8AB1: F0 08 BEQ $8ABB vergleichen 8AB3: C9 1D CMP #$1D , , ',' 8AB5: F0 04 BEQ $8ABB 8AB7: C9 2C CMP #$2C aktuelles Zeichen ist kein Trennzeichen, 8AB9: D0 06 BNE $8AC1 Zeichen gehoert also zum Parameter, ==> Einsprung von $8AB1, $8AB5, $8ACC: 8ABB: C8 INY naechstes Zeichen 8ABC: C4 29 CPY $29 Zeilenende ? 8ABE: 90 EC BCC $8AAC nein, ==> 8AC0: 60 RTS Ende Einsprung von $8AB9: 8AC1: 20 D0 8A JSR $8AD0 ASCII-Wert in HEX-Wert umwandeln 8AC4: EE 2E 02 INC $022E naechsten Parameterspeicher waehlen 8AC7: AC 30 02 LDY $0230 Zeiger in Zeile zurueckholen 8ACA: E0 04 CPX #$04 Anzahl Dezimalstellen >= 4 ? 8ACC: 90 ED BCC $8ABB nein, ==> 8ACE: B0 9D BCS $8A6D 30, Syntax Error ASCII-Werte aus dem Input-Puffer in HEX-Werte umwandeln und in der Parameter-Tabelle ablegen ($cca1) Einsprung von $8AC1: 8AD0: A9 00 LDA #$00 Zwischenspeicher loeschen fuer 3 Ziffern 8AD2: 85 40 STA $40 (ASCII-Zahl) 8AD4: 85 41 STA $41 ($42 wird spaeter sowieso ueberschrieben) 8AD6: 85 43 STA $43 Hi-Byte des Ergebnisses =0 8AD8: A2 FF LDX #$FF Zaehler fuer Wertigkeit der Ziffer Einsprung von $8AF6: 8ADA: B9 00 02 LDA $0200,Y Zeichen aus Kommandozeile holen 8ADD: C9 40 CMP #$40 ist Zeichen eine Ziffer ? 8ADF: B0 17 BCS $8AF8 [' :;<=>? ' werden als Ziffern 8AE1: C9 30 CMP #$30 10-15 gerechnet; '2<' entspricht 8AE3: 90 13 BCC $8AF8 dem Block 32 (2*10+12)] 8AE5: 29 0F AND #$0F ja, 8AE7: 48 PHA Wert der Ziffer merken 8AE8: A5 41 LDA $41 Alte Zahl * 10 8AEA: 85 42 STA $42 8AEC: A5 40 LDA $40 8AEE: 85 41 STA $41 8AF0: 68 PLA + Ziffer 8AF1: 85 40 STA $40 8AF3: C8 INY Zeiger auf naechstes Zeichen 8AF4: C4 29 CPY $29 setzen; Zeilenende ? 8AF6: 90 E2 BCC $8ADA nein, ==> Einsprung von $8ADF, $8AE3: 8AF8: 8C 30 02 STY $0230 Zeiger in Kommandozeile merken ungepackte BCD-Zahl (1 Ziffer / Byte) in Binaerzahl wandeln 8AFB: 18 CLC 8AFC: A9 00 LDA #$00 Ergebnis (Lo) =0 Einsprung von $8B06: 8AFE: E8 INX naechste Ziffer nehmen 8AFF: E0 03 CPX #$03 alle 3 Stellen fertig ? 8B01: B0 0F BCS $8B12 ja, ==> 8B03: B4 40 LDY $40,X Ziffer holen; y-mal den Wert der Ziffer Einsprung von $8B0B, $8B10: 8B05: 88 DEY zum Ergebnis addieren 8B06: 30 F6 BMI $8AFE < 0, (naechste Ziffer holen) ==> 8B08: 7D 20 8B ADC $8B20,X Wertigkeit der Ziffer addieren 8B0B: 90 F8 BCC $8B05 kein Uebertrag, ==> 8B0D: 18 CLC Uebertrag addieren 8B0E: E6 43 INC $43 8B10: D0 F3 BNE $8B05 immer ==> Einsprung von $8B01: 8B12: 48 PHA Ergebnis in den Parameterspeicher 8B13: AE 2E 02 LDX $022E uebernehmen 8B16: A5 43 LDA $43 8B18: 9D 97 02 STA $0297,X Hi-Byte 8B1B: 68 PLA 8B1C: 9D 9C 02 STA $029C,X Lo-Byte 8B1F: 60 RTS 8B20: 01 0A 64 1,10,100 Wertigkeit der Ziffern Block-Free ($ccf5) 8B23: 20 AE 84 JSR $84AE auf Diskettenwechsel testen 8B26: 20 32 8C JSR $8C32 Block-Parameter holen und testen 8B29: 20 46 B5 JSR $B546 Block freigeben 8B2C: 4C 50 80 JMP $8050 Block-Allocate ($cd03) 8B2F: 20 AE 84 JSR $84AE Auf Diskettenwechsel testen 8B32: 20 32 8C JSR $8C32 Blockparameter holen 8B35: A5 4E LDA $4E Sektornummer merken 8B37: 48 PHA 8B38: 20 46 B7 JSR $B746 naechsten freien Block auf dem Track suchen 8B3B: F0 0B BEQ $8B48 kein Block frei, ==> 8B3D: 68 PLA mit altem Sektor vergleichen 8B3E: C5 4E CMP $4E Ist der freie Sektor der gewuenschte ? 8B40: D0 19 BNE $8B5B nein, ==> 8B42: 20 72 B5 JSR $B572 Block belegen 8B45: 4C 50 80 JMP $8050 00, ok,00,00 ==> Einsprung von $8B3B: 8B48: 68 PLA Einsprung von $8B59: 8B49: A9 00 LDA #$00 mit Sektor 0 beginnen 8B4B: 85 4E STA $4E 8B4D: E6 4D INC $4D naechsten Track probieren 8B4F: A5 4D LDA $4D ist maximale Tracknummer + 1 erreicht ? 8B51: CD 2C 02 CMP $022C 8B54: B0 0A BCS $8B60 ja, ==> 8B56: 20 46 B7 JSR $B746 einen freien Block auf dem Track suchen 8B59: F0 EE BEQ $8B49 nicht gefunden, ==> Einsprung von $8B40: 8B5B: A9 65 LDA #$65 65, no Block,tt,ss 8B5D: 20 3F FF JSR $FF3F CMDERR-Ende Einsprung von $8B54: 8B60: A9 65 LDA #$65 65, no Block,00,00 8B62: 20 7C 80 JSR $807C T&S=0, Ende Block-Read-Parameter pruefen und Block lesen ($cd36) Einsprung von $8B71, $8BE3: 8B65: 20 2F 8C JSR $8C2F Parameter testen 8B68: 4C BD 93 JMP $93BD Block lesen Byte aus Puffer holen ($cd3c) Einsprung von $8B79: 8B6B: 20 69 90 JSR $9069 Puffernummer holen 8B6E: A1 BB LDA ($BB,X) 8B70: 60 RTS Block lesen und Pufferzeiger setzen ($cd42) Einsprung von $8B85, $8B9D: 8B71: 20 65 8B JSR $8B65 Block lesen Einsprung von $8B94: 8B74: A9 00 LDA #$00 Pufferzeiger auf 0 8B76: 20 22 94 JSR $9422 (Blocklaenge ist im 1. Byte) 8B79: 20 6B 8B JSR $8B6B Byte (Blocklaenge) holen 8B7C: 99 42 02 STA $0242,Y und Blockende setzen 8B7F: A9 89 LDA #$89 Kanal zum Lesen und Schreiben freigeben 8B81: 99 34 02 STA $0234,Y Kanalstatus setzen 8B84: 60 RTS Block-Read ($cd56) 8B85: 20 71 8B JSR $8B71 Block lesen, Pufferzeiger setzen 8B88: 20 48 93 JSR $9348 Byte nach der Blocklaenge zur Ausgabe 8B8B: 4C 4C 80 JMP $804C bereitstellen Super-Read 8B8E: 20 44 8C JSR $8C44 Parameter holen, NICHT testen 8B91: 20 BD 93 JSR $93BD Block lesen 8B94: 20 74 8B JSR $8B74 Pufferzeiger setzen 8B97: 4C A0 8B JMP $8BA0 1. Byte zur Ausgabe bereitstellen u1 ($cd5f) 8B9A: 20 9F 8A JSR $8A9F Kanal oeffnen, Parameter holen 8B9D: 20 71 8B JSR $8B71 Block einlesen Einsprung von $8B97: 8BA0: B9 42 02 LDA $0242,Y Anzahl zu uebertragender Bytes [dies ist ja das 1. Byte des gelesenen Blocks !] 8BA3: 99 3B 02 STA $023B,Y in Ausgabepuffer (als Datenbyte) schreiben 8BA6: A9 FF LDA #$FF Blocklaenge setzen (ganzen Block ausgeben) 8BA8: 99 42 02 STA $0242,Y 8BAB: 4C 4C 80 JMP $804C Block-Write ($cd73) 8BAE: 20 2F 8C JSR $8C2F Kanal oeffnen, Parameter holen 8BB1: 20 42 94 JSR $9442 Pufferzeiger holen 8BB4: A8 TAY 8BB5: 88 DEY auf letztes benutztes Byte setzen 8BB6: C9 02 CMP #$02 Pufferzeiger <=2 ? 8BB8: B0 02 BCS $8BBC nein, ==> 8BBA: A0 01 LDY #$01 Puffer muss mindestens 1 Datenbyte enthalten Einsprung von $8BB8: 8BBC: A9 00 LDA #$00 8BBE: 20 22 94 JSR $9422 Pufferzeiger auf 0 setzen 8BC1: 98 TYA 8BC2: 20 B1 8E JSR $8EB1 Byte in Puffer schreiben 8BC5: 8A TXA Puffernummer merken 8BC6: 48 PHA 8BC7: 20 C1 93 JSR $93C1 Puffer auf Disk schreiben 8BCA: 68 PLA 8BCB: AA TAX Puffernummer zurueckholen 8BCC: A4 50 LDY $50 8BCE: 4C 09 8C JMP $8C09 Byte fuer Ausgabe bereitstellen Super-Write 8BD1: 20 44 8C JSR $8C44 Parameter holen, NICHT testen 8BD4: 4C DD 8B JMP $8BDD Puffer schreiben u2 ($cd97) 8BD7: 20 9F 8A JSR $8A9F Parameter holen 8BDA: 20 2F 8C JSR $8C2F Kanal oeffnen, Parameter auswerten Einsprung von $8BD4: 8BDD: 20 C1 93 JSR $93C1 Puffer schreiben 8BE0: 4C 4C 80 JMP $804C Block-Execute ($cda3) 8BE3: 20 65 8B JSR $8B65 Parameter testen, Block lesen 8BE6: A9 00 LDA #$00 Lo-Byte der Startadresse merken 8BE8: 85 40 STA $40 8BEA: A6 6C LDX $6C Adresse des aktuellen Puffers holen 8BEC: BD F1 01 LDA $01F1,X 8BEF: 85 41 STA $41 und als Hi-Byte der Startadresse merken 8BF1: 20 F7 8B JSR $8BF7 Ruecksprungadresse auf dem Stack merken 8BF4: 4C 4C 80 JMP $804C Einsprung von $8BF1: 8BF7: 6C 40 00 JMP ($0040) Programm aufrufen Block-Pointer ($cdbd) 8BFA: 20 0F 8C JSR $8C0F Kanal oeffnen 8BFD: A5 6C LDA $6C aktuelle Puffernummer holen 8BFF: 0A ASL auf 2-Byte-Tabelle umrechnen 8C00: AA TAX 8C01: AD 9D 02 LDA $029D neuen Wert fuer den Pufferzeiger holen 8C04: 95 BB STA $BB,X und setzen 8C06: 20 69 90 JSR $9069 Kanal und Puffernummer holen Einsprung von $8BCE: 8C09: 20 4A 93 JSR $934A Byte fuer Ausgabe bereitstellen 8C0C: 4C 4C 80 JMP $804C Kanal oeffnen ($cdd2) Einsprung von $8BFA, $8C2F, $8C44: 8C0F: A6 67 LDX $67 Parameternummer holen (1 Parameter=1 Byte) 8C11: E6 67 INC $67 auf naechsten Parameter schalten 8C13: BD 9C 02 LDA $029C,X Wert aus Kommandozeile 8C16: A8 TAY (SA des Direktzugriffkanals) 8C17: 88 DEY 8C18: 88 DEY >=2 und <=14 ? 8C19: C0 0D CPY #$0D 8C1B: 90 05 BCC $8C22 ja, ==> Einsprung von $8C27: 8C1D: A9 70 LDA #$70 8C1F: 4C 7C 80 JMP $807C 70, No Channel Einsprung von $8C1B: 8C22: 85 52 STA $52 als aktuelle SA merken 8C24: 20 27 90 JSR $9027 Kanalnummer holen 8C27: B0 F4 BCS $8C1D Kanal in Ordnung ? nein, ==> 8C29: 20 11 9F JSR $9F11 aktiven Puffer holen 8C2C: 85 6C STA $6C und merken 8C2E: 60 RTS Kanal oeffnen, Blockparameter holen und testen ($cdf2) Einsprung von $8B65, $8BAE, $8BDA: 8C2F: 20 0F 8C JSR $8C0F Kanal oeffnen Einsprung von $8B26, $8B32: 8C32: A6 67 LDX $67 Parameternummer holen 8C34: BD 9E 02 LDA $029E,X T&S des angeforderten Blocks holen 8C37: 85 4E STA $4E 8C39: BD 9D 02 LDA $029D,X 8C3C: 85 4D STA $4D 8C3E: 20 B5 94 JSR $94B5 auf gueltigen Block pruefen 8C41: 4C F6 81 JMP $81F6 Drive-LED einschalten Kanal oeffnen, Blockparameter holen und NICHT testen Einsprung von $8B8E, $8BD1: 8C44: 20 0F 8C JSR $8C0F Kanal oeffnen 8C47: A6 67 LDX $67 8C49: BD 9E 02 LDA $029E,X T&S des angeforderten Blocks holen 8C4C: 85 4E STA $4E 8C4E: BD 9D 02 LDA $029D,X 8C51: 85 4D STA $4D 8C53: 20 F6 81 JSR $81F6 Drive-LED einschalten 8C56: A9 40 LDA #$40 T&S nicht pruefen 8C58: 8D A8 02 STA $02A8 8C5B: 60 RTS Puffer allokieren E: a: b0-7: 1-Bits: zu belegende Puffer Einsprung von $FF66: 8C5C: 05 6D ORA $6D entsprechendes Bit setzen 8C5E: 85 6D STA $6D 8C60: 60 RTS Block-Befehle und Adressen ($cc5d) 8C61: 41 46 52 57 45 50 D2 D7 'afrwepRW' 8C69: 3F 2A '?*' 8C6B: 2F 8B $8B2F Allocate 8C6D: 23 8B $8B23 Free 8C6F: 85 8B $8B85 Read 8C71: AE 8B $8BAE Write 8C73: E3 8B $8BE3 Execute 8C75: FA 8B $8BFA Pointer 8C77: 8E 8B $8B8E Super-Read 8C79: D1 8B $8BD1 Super-Write 8C7B: 7F 8C $8C7F Hard & Software 8C7D: 84 8C $8C84 Widmung 8C7F: A9 79 LDA #$79 Hard & Software 8C81: 4C 67 A8 JMP $A867 8C84: A9 7A LDA #$7A Widmung 8C86: 4C 67 A8 JMP $A867 Position des Records berechnen ($ce0e) Einsprung von $A1ED, $A2D9, $A420: 8C89: 20 C1 8C JSR $8CC1 Bytes bis zum gesuchten Record berechnen 8C8C: 20 06 8D JSR $8D06 x/254 8C8F: A5 60 LDA $60 Rest merken 8C91: 85 6B STA $6B = gesuchte Position im Datenblock 8C93: 20 09 8D JSR $8D09 x/120 = Side-Sektor-Nummer 8C96: E6 6B INC $6B Datenbereich faengt bei Byte 2 an 8C98: E6 6B INC $6B 8C9A: 20 6E A5 JSR $A56E wird Super-Side-Sektor verwendet? 8C9D: F0 0D BEQ $8CAC ja, ==> 1541-kompatible REL-Datei 8C9F: A5 5B LDA $5B Side-Sektor-Nummer merken 8CA1: 85 69 STA $69 8CA3: A5 60 LDA $60 Rest: Nummer des Datenblocks im Side-Sektor 8CA5: 0A ASL * 2 (2-Byte Tabelle: T&S) 8CA6: 18 CLC Die Tabelle mit den T&S der Datenblocks 8CA7: 69 10 ADC #$10 faengt an der Position 16 im Side-Sektor an 8CA9: 85 6A STA $6A Zeiger auf T&S des Datenblocks 8CAB: 60 RTS 1581-REL-Datei mit Super-Side-Sektor Einsprung von $8C9D: 8CAC: A5 60 LDA $60 Rest: Nummer des Datenblocks im Side-Sektor 8CAE: 0A ASL 8CAF: 18 CLC Die 2-Byte Tabelle 8CB0: 69 10 ADC #$10 faengt an Position 16 an 8CB2: 85 6A STA $6A Zeiger auf T&S des Datenblocks 8CB4: 20 0C 8D JSR $8D0C x/6 = Gruppe des Side-Sektors 8CB7: A5 60 LDA $60 Rest merken (Nummer des Side-Sektors) 8CB9: 85 69 STA $69 8CBB: A5 5B LDA $5B Gruppennummer merken 8CBD: 8D 00 01 STA $0100 8CC0: 60 RTS Zahl der Bytes bis zum gesuchten Record berechnen ($ce2c) (Recordnummer * Recordlaenge + Position im Record) Einsprung von $8C89: 8CC1: 20 38 8D JSR $8D38 Rechenregister 1 loeschen 8CC4: 85 62 STA $62 Recordnummer in Rechenregister 2 schreiben 8CC6: A6 50 LDX $50 8CC8: BD 49 02 LDA $0249,X (aktuelle Recordnummer Lo) 8CCB: 85 60 STA $60 8CCD: BD 50 02 LDA $0250,X (Hi) 8CD0: 85 61 STA $61 8CD2: D0 04 BNE $8CD8 Recordnummer = 0 ? 8CD4: A5 60 LDA $60 8CD6: F0 0B BEQ $8CE3 ja, ==> Einsprung von $8CD2: 8CD8: A5 60 LDA $60 Recordnummer -1 nehmen 8CDA: 38 SEC 8CDB: E9 01 SBC #$01 8CDD: 85 60 STA $60 8CDF: B0 02 BCS $8CE3 8CE1: C6 61 DEC $61 Einsprung von $8CD6, $8CDF: 8CE3: BD 5E 02 LDA $025E,X Recordlaenge holen 24*8-Bit-Multiplikationsroutine ($ce4e) Rechnung: Reg1 = Reg2 * a + ($68) 8CE6: 85 40 STA $40 [Die Bits in $40 werden der Reihe nach Einsprung von $8CF4: 8CE8: 46 40 LSR $40 getestet (Lo-Bit zuerst). 8CEA: 90 03 BCC $8CEF Ist das Bit gesetzt, 8CEC: 20 4C 8D JSR $8D4C dann wird Reg2 zu Reg1 addiert. Einsprung von $8CEA: 8CEF: 20 44 8D JSR $8D44 Danach wird Reg2 *2 genommen und der 8CF2: A5 40 LDA $40 Vorgang wiederholt, bis kein 1-Bit mehr in 8CF4: D0 F2 BNE $8CE8 $40 ist. Reg2 wird also fuer Bit1 *1, fuer Bit2 *2, ... und fuer Bit7 *128 genommen (entsprechend der Wertigkeit der Bits).] 8CF6: A5 68 LDA $68 ($68) zu Reg1 addieren 8CF8: 18 CLC [In $68 steht normalerweise die aktuelle 8CF9: 65 5B ADC $5B Position im Record] 8CFB: 85 5B STA $5B 8CFD: 90 06 BCC $8D05 1. Uebertrag ? nein, ==> 8CFF: E6 5C INC $5C 8D01: D0 02 BNE $8D05 2. Uebertrag ? nein, ==> 8D03: E6 5D INC $5D Einsprung von $8CFD, $8D01: 8D05: 60 RTS 24/8-Bit-Divisionsroutine ($ce71) [Der Vergleich mit dem 1541-ROM lohnt sich ...] Einsprung von $8C8C: 8D06: A9 FE LDA #$FE x/254 (Sektorlaenge) 8D08: 2C B $2C Einsprung von $8C93: 8D09: A9 78 LDA #$78 x/120 (Blocks pro Side-Sektor) 8D0B: 2C B $2C Einsprung von $8CB4: 8D0C: A9 06 LDA #$06 x/6 (Side-Sektoren pro Gruppe) E: $5b-$5d: Divident a : Divisor A: $5b-$5d: Quotient $60 : Rest 8D0E: 85 40 STA $40 <-- (x/a) 8D10: A9 00 LDA #$00 9-Bit Rest-Register loeschen 8D12: 85 60 STA $60 8D14: 85 61 STA $61 8D16: A2 18 LDX #$18 (24-Bit) Einsprung von $8D35: 8D18: 06 5B ASL $5B Divident ins Restregister schieben 8D1A: 26 5C ROL $5C [Der Divident wird so lange in das 8D1C: 26 5D ROL $5D Rest-Register geschoben (Hi-Bit voran), 8D1E: 26 60 ROL $60 bis der Inhalt des Rest-Registers 8D20: 26 61 ROL $61 mindestens so gross ist wie der Divisor. 8D22: A5 60 LDA $60 In diesem Fall wird dann der Divisor vom 8D24: 38 SEC Rest-Register abgezogen und das ent- 8D25: E5 40 SBC $40 sprechende Bit im Ergebnisspeicher ge- 8D27: A8 TAY setzt. Um drei Shift-Befehle zu sparen, 8D28: A5 61 LDA $61 werden Divident und Quotient im selben 8D2A: E9 00 SBC #$00 Register gespeichert.] 8D2C: 90 06 BCC $8D34 Rest gross genug (>=Divisor) ? 8D2E: E6 5B INC $5B ja, Bit im Ergebnis setzen (B0 war ja 0) 8D30: 85 61 STA $61 Restregister setzen 8D32: 84 60 STY $60 [Bei einer Division durch 0 werden alle Einsprung von $8D2C: 8D34: CA DEX Bits des Ergebnisses =1 und der Rest ist 8D35: D0 E1 BNE $8D18 gleich den zwei niederwertigen Bytes des 8D37: 60 RTS Dividenden.] Rechenregister 1 loeschen ($ced9) Einsprung von $8CC1, $9E97: 8D38: A9 00 LDA #$00 8D3A: 85 5B STA $5B 8D3C: 85 5C STA $5C 8D3E: 85 5D STA $5D 8D40: 60 RTS Rechenregister 2 *2 bzw. *4 ($cee2) 8D41: 20 44 8D JSR $8D44 <-- * 4 Einsprung von $8D41, $8CEF: 8D44: 18 CLC <-- * 2 8D45: 26 60 ROL $60 8D47: 26 61 ROL $61 8D49: 26 62 ROL $62 8D4B: 60 RTS Rechenregister addieren ($ceed) Einsprung von $8CEC, $9ED0: 8D4C: 18 CLC 24-Bit Addition 8D4D: A2 FD LDX #$FD $5b=$5b+$60 Einsprung von $8D56: 8D4F: B5 5E LDA $5E,X Wrap-Around-Effekt beachten !!! 8D51: 75 63 ADC $63,X (Wert im x-Register als negative Zahl 8D53: 95 5E STA $5E,X betrachten) 8D55: E8 INX 8D56: D0 F7 BNE $8D4F 8D58: 60 RTS Feststellen, welcher Kanal schon am laengsten inaktiv ist (legt Reihenfolge fest fuer das 'Stehlen' von Puffern) ($cefa) Tabelle initialisieren Einsprung von $8D76, $B068: 8D59: A2 00 LDX #$00 Bereich von $df-$e4 Einsprung von $8D61: 8D5B: 8A TXA mit 0-5 fuellen 8D5C: 95 DF STA $DF,X 8D5E: E8 INX 8D5F: E0 05 CPX #$05 8D61: D0 F8 BNE $8D5B 8D63: A9 05 LDA #$05 [bei der 1581 unnoetig, 8D65: 95 DF STA $DF,X bei der 1541 wurde der Bereich 8D67: 60 RTS mit 0-3, 6 gefuellt.] Aktuelle Kanalnummer ans Tabellenende ruecken Einsprung von $8D7D, $8E3C: 8D68: A0 05 LDY #$05 <-- regulaerer Einsprung 8D6A: A6 50 LDX $50 aktuelle Kanalnummer holen Einsprung von $8D79: 8D6C: B9 DF 00 LDA $00DF,Y alte Nummer aus der Tebelle merken 8D6F: 96 DF STX $DF,Y und durch die neue ersetzen 8D71: C5 50 CMP $50 ist die Kanalnummer gefunden ? 8D73: F0 07 BEQ $8D7C ja, (Ende) ==> 8D75: 88 DEY War die Kanalnummer nicht in der Tabelle, 8D76: 30 E1 BMI $8D59 wird diese neu initialisiert 8D78: AA TAX Kanalnummer nach x 8D79: 4C 6C 8D JMP $8D6C naechste Kanalnummer verschieben ==> Einsprung von $8D73: 8D7C: 60 RTS Puffer wechseln im Zwei-Puffer-Betrieb ($cf1e) ggf. wird, wenn ein Puffer 'gestohlen' wurde, ein neuer Puffer gesucht und mit den benoetigten Daten gefuellt. Einsprung von $8FF2, $8FFB, $90AF, $90DA, $9101, $912D, $99CB, $9A47, $9A6F, $9FCA, $9FDD, $9FF2, $9FF8, $A11E, $A12B, $A12E, $A24C, $A25B, $A261, $A394, $A3A6, $A423, $A45C, $A4FA, $A544: 8D7D: 20 68 8D JSR $8D68 Kanalnummer ans Tabellenende 8D80: A6 50 LDX $50 8D82: B5 D1 LDA $D1,X 1. Puffer inaktiv ? 8D84: 30 02 BMI $8D88 Ja, ==> 8D86: B5 D8 LDA $D8,X 2. Puffer unbelegt ? Einsprung von $8D84: 8D88: C9 FF CMP #$FF (bzw. 1. Puffer unbelegt ?) 8D8A: F0 18 BEQ $8DA4 Ja, neuen Puffer suchen ==> 8D8C: B5 D1 LDA $D1,X Aktiven Puffer wechseln 8D8E: 49 80 EOR #$80 dazu: 8D90: 95 D1 STA $D1,X 1. Puffer umschalten, 8D92: 48 PHA 8D93: B5 D8 LDA $D8,X 2. Puffer umschalten 8D95: 49 80 EOR #$80 8D97: 95 D8 STA $D8,X 8D99: A8 TAY 8D9A: 68 PLA Aktiven Puffer nach A 8D9B: 10 01 BPL $8D9E 1. Puffer aktiv, dann ==> 8D9D: 98 TYA 2. Puffer ist aktiv Einsprung von $8D9B: 8D9E: 29 BF AND #$BF 8DA0: AA TAX 8DA1: 4C ED 94 JMP $94ED Alten Job abwarten, Ende ==> Ersatz fuer gestohlenen Puffer suchen Einsprung von $8D8A: 8DA4: B5 D1 LDA $D1,X 1. Puffer aktiv ? 8DA6: 10 02 BPL $8DAA ja, ==> 8DA8: B5 D8 LDA $D8,X [Das Ergebnis wurde bei der 1541 fuer die Einsprung von $8DA6: 8DAA: 29 BF AND #$BF Drivenummerabfrage verwendet, die bei der 8DAC: A8 TAY 1581 nicht mehr existiert.] 8DAD: 20 04 92 JSR $9204 Puffer suchen 8DB0: 10 05 BPL $8DB7 gefunden, dann ==> 8DB2: A9 70 LDA #$70 70, NO CHANNEL 8DB4: 4C 7C 80 JMP $807C Einsprung von $8DB0: 8DB7: A6 50 LDX $50 aktuelle Kanalnummer holen 8DB9: 09 80 ORA #$80 neuen Puffer inaktiv setzen 8DBB: B4 D1 LDY $D1,X Wenn 1. Puffer inaktiv, dann 8DBD: 10 04 BPL $8DC3 1. Puffer neubesetzen 8DBF: 95 D1 STA $D1,X 8DC1: 30 02 BMI $8DC5 immer ==> Einsprung von $8DBD: 8DC3: 95 D8 STA $D8,X ansonsten 2. Puffer neubesetzen Pufferinhalt wieder herstellen Einsprung von $8DC1: 8DC5: A5 4D LDA $4D aktuelle T&S retten 8DC7: 48 PHA 8DC8: A5 4E LDA $4E 8DCA: 48 PHA 8DCB: A9 01 LDA #$01 Sektornummer aus Puffer holen 8DCD: 85 42 STA $42 (s. $9450) 8DCF: B5 D1 LDA $D1,X aktiven Puffer holen 8DD1: 10 02 BPL $8DD5 8DD3: B5 D8 LDA $D8,X Einsprung von $8DD1: 8DD5: 29 BF AND #$BF 8DD7: A8 TAY 8DD8: B9 F1 01 LDA $01F1,Y Pufferadresse holen 8DDB: 85 43 STA $43 8DDD: A0 00 LDY #$00 8DDF: B1 42 LDA ($42),Y Byte holen 8DE1: 85 4E STA $4E als aktuelle Sektornummer merken 8DE3: A9 00 LDA #$00 Tracknummer holen 8DE5: 85 42 STA $42 [Vergleichen Sie diesen Absatz mit dem 8DE7: B5 D1 LDA $D1,X davor. Hier hat doch irgend jemand ganz 8DE9: 10 02 BPL $8DED offensicht lich mit einer 'Suchen und 8DEB: B5 D8 LDA $D8,X Ersetzen'-Funktion oder 'Macro'-Funkton Einsprung von $8DE9: 8DED: 29 BF AND #$BF Unterprogramm-Aufrufe durch die ent- 8DEF: A8 TAY sprechenden Routinen ersetzt (um das DOS 8DF0: B9 F1 01 LDA $01F1,Y zu beschleunigen). Dabei haette hier ein 8DF3: 85 43 STA $43 einfaches 'dec $42' gleiche Dienste tun 8DF5: A0 00 LDY #$00 koennen.] 8DF7: B1 42 LDA ($42),Y Byte aus Puffer holen 8DF9: 85 4D STA $4D als aktuelle Tracknummer merken 8DFB: F0 2A BEQ $8E27 letzter Block ? ja, ==> 8DFD: 20 5F 90 JSR $905F Aktuellen Filetyp holen 8E00: F0 0B BEQ $8E0D REL-File ? ja, ==> 8E02: 20 E9 9C JSR $9CE9 Ist Jobcode = $90 (schreiben) ? [Ein geschriebener Puffer muss ja nicht mehr eingelesen werden.] 8E05: D0 06 BNE $8E0D nein, ==> 8E07: 20 4D 8E JSR $8E4D Aktiven Puffer wechseln 8E0A: 4C 1E 8E JMP $8E1E Einsprung von $8E00, $8E05: 8E0D: A6 50 LDX $50 Aktiven Puffer wechseln 8E0F: B5 D1 LDA $D1,X 8E11: 49 80 EOR #$80 8E13: 95 D1 STA $D1,X 8E15: B5 D8 LDA $D8,X 8E17: 49 80 EOR #$80 8E19: 95 D8 STA $D8,X 8E1B: 20 94 9D JSR $9D94 Lesejob aufrufen Einsprung von $8E0A: 8E1E: 68 PLA 8E1F: 85 4E STA $4E T&S zurueckholen 8E21: 68 PLA 8E22: 85 4D STA $4D 8E24: 4C 30 8E JMP $8E30 Einsprung von $8DFB: 8E27: 68 PLA T&S zurueckholen 8E28: 85 4E STA $4E 8E2A: 68 PLA 8E2B: 85 4D STA $4D 8E2D: 20 4D 8E JSR $8E4D aktiven Puffer wechseln Einsprung von $8E24: 8E30: 20 11 9F JSR $9F11 aktiven Puffer holen 8E33: AA TAX 8E34: 4C ED 94 JMP $94ED Jobausfuehrung abwarten Falls dem Kanal ein Puffer fehlt, einen neuen zuordnen ($cf7b) Einsprung bei $8e3c Einsprung von $8E47: 8E37: A9 70 LDA #$70 70, No Channel 8E39: 4C 7C 80 JMP $807C 8E3C: 20 68 8D JSR $8D68 <-- Kanalnummer ans Tabellenende 8E3F: 20 33 9F JSR $9F33 Besitzt Kanal nur einen Puffer 8E42: D0 08 BNE $8E4C nein, ==> 8E44: 20 04 92 JSR $9204 neuen Puffer suchen 8E47: 30 EE BMI $8E37 keinen gefunden ? ja, ==> 8E49: 4C 3E 9F JMP $9F3E Dem Kanal neuen Puffer zuordnen Einsprung von $8E42: 8E4C: 60 RTS Aktiven Puffer wechseln ($cf8c) Einsprung von $8E07, $8E2D: 8E4D: A6 50 LDX $50 8E4F: B5 D1 LDA $D1,X 1. Puffer umschalten 8E51: 49 80 EOR #$80 8E53: 95 D1 STA $D1,X 8E55: B5 D8 LDA $D8,X 2. Puffer umschalten 8E57: 49 80 EOR #$80 8E59: 95 D8 STA $D8,X 8E5B: 60 RTS Byte ueber internen Schreibkanal in Puffer schreiben ($cf9b) Einsprung von $881C, $882E: 8E5C: A2 12 LDX #$12 SA 18: interner Schreibkanal 8E5E: 86 52 STX $52 8E60: 20 42 90 JSR $9042 Schreibkanal holen 8E63: 20 F6 81 JSR $81F6 Drive-LED einschalten 8E66: 20 5F 90 JSR $905F aktuellen Filetyp holen 8E69: 90 05 BCC $8E70 'normale' Datei ?, ==> 8E6B: A9 20 LDA #$20 b5=0: 'Record noch nicht voll' 8E6D: 20 DB 9C JSR $9CDB Status loeschen Einsprung von $8E69: 8E70: A5 52 LDA $52 [= $12, oder ? (Einsprung nur bei $8e5c)] 8E72: C9 0F CMP #$0F 8E74: F0 23 BEQ $8E99 8E76: D0 08 BNE $8E80 Byte ausgeben ==> Byte in aktuelle Datei schreiben ($cfb7) [Diese Routine wird immer dann aufgerufen, wenn Daten ueber den seriellen Bus an das Diskettenlaufwerk gesendet werden. Dabei ist es egal, ob es sich um: - Daten fuer eine Datei, oder - den Filenamen der Datei, oder um - Diskettenkommandos handelt. In den beiden letzten Faellen wird das Befehlsmodus-Flag gesetzt. Dadurch wird nach der Uebertragung der Befehl automatisch analysiert bzw. die Datei geoeffnet (s.$8004).] Einsprung von $AED3: 8E78: A5 53 LDA $53 SA vom BUS 8E7A: 29 8F AND #$8F b7=1: SA oeffnen ? oder 8E7C: C9 0F CMP #$0F Byte in Kommandokanal schreiben ? 8E7E: B0 19 BCS $8E99 ja, ==> Einsprung von $8E76: 8E80: 20 5F 90 JSR $905F aktuellen Filetyp holen 8E83: B0 05 BCS $8E8A Rel-Datei oder Direktzugriff, ==> 8E85: A5 54 LDA $54 empfangenes Byte holen 8E87: 4C 12 91 JMP $9112 Byte in die Datei schreiben Einsprung von $8E83: 8E8A: D0 03 BNE $8E8F REL-Datei ? 8E8C: 4C 33 A0 JMP $A033 ja, Byte in Record schreiben Einsprung von $8E8A: 8E8F: A5 54 LDA $54 Byte holen 8E91: 20 B1 8E JSR $8EB1 Byte in Puffer schreiben 8E94: A4 50 LDY $50 8E96: 4C 4A 93 JMP $934A naechstes Byte zur Ausgabe bereitstellen Einsprung von $8E7E, $8E74: 8E99: A9 05 LDA #$05 Kommando-Kanalnumer setzen 8E9B: 85 50 STA $50 8E9D: 20 42 94 JSR $9442 Pufferzeiger holen 8EA0: C9 2A CMP #$2A Puffer voll ? 8EA2: F0 05 BEQ $8EA9 ja, ==> 8EA4: A5 54 LDA $54 empfangenes Byte holen und 8EA6: 20 B1 8E JSR $8EB1 in (Kommando-) Puffer schreiben Einsprung von $8EA2: 8EA9: A5 51 LDA $51 EOI-Flag testen 8EAB: F0 01 BEQ $8EAE Datenende, ==> 8EAD: 60 RTS Einsprung von $8EAB: 8EAE: E6 7B INC $7B Befehlsmodus-Flag setzen 8EB0: 60 RTS Byte in Puffer schreiben, Pufferzeiger erhoehen ($cff1) Einsprung von $8BC2, $8E91, $8EA6, $9112, $9122, $9127, $9402, $9407, $9415, $941A, $941F, $9613, $961A, $9621, $9A3D, $9A62, $9A66, $B19C, $B1A1, $B1A6, $B1A9, $B1AF, $B1B4, $B1C5, $B1CA, $B1CD, $B1D8, $B1DE, $B1E6, $B204, $B20A, $B21B, $B21E, $B221, $B23C, $B8C5: 8EB1: 48 PHA Byte merken 8EB2: 20 11 9F JSR $9F11 Puffer holen 8EB5: 10 06 BPL $8EBD 8EB7: 68 PLA Kein Puffer gefunden 8EB8: A9 61 LDA #$61 61, FILE NOT OPEN 8EBA: 4C 7C 80 JMP $807C Einsprung von $8EB5, $9CD0: 8EBD: 0A ASL (Puffernummer) 8EBE: AA TAX 8EBF: 68 PLA Byte zurueckholen 8EC0: 81 BB STA ($BB,X) Byte in Puffer schreiben 8EC2: F6 BB INC $BB,X Pufferzeiger erhoehen 8EC4: 60 RTS Initialize ($d005) 8EC5: 20 85 80 JSR $8085 Drivenummer holen 8EC8: 20 CF B0 JSR $B0CF Phy. Format einer 1581-Disk einstellen 8ECB: 20 B3 B0 JSR $B0B3 Ganze Diskette als Partition waehlen 8ECE: 20 03 8F JSR $8F03 Partition initialisieren 8ED1: 2C FB 01 BIT $01FB Ist Autoboot aktiv ? 8ED4: 50 03 BVC $8ED9 Nein ==> 8ED6: 4C 38 A9 JMP $A938 JCBMBOOT aufrufen ==> Einsprung von $8ED4: 8ED9: 4C 4C 80 JMP $804C Blockheader des Verzeichnisheaders suchen und Schreibschutz pruefen ($d00e [mit etwas Phantasie...]) Einsprung von $84C3, $8F14: 8EDC: 20 04 92 JSR $9204 Puffer suchen 8EDF: 85 6C STA $6C und merken 8EE1: AA TAX 8EE2: 20 35 92 JSR $9235 Puffer wieder freigeben [Puffer wird nur waehrend der Initiali- sierung gebraucht. In der Zeit kann sowieso keine andere Routine Puffer suchen.] 8EE5: A2 00 LDX #$00 8EE7: 86 4E STX $4E Sector 0 8EE9: AE 2B 02 LDX $022B Directory-Track anwaehlen 8EEC: 86 4D STX $4D 8EEE: 20 88 95 JSR $9588 T&S an DC uebergeben 8EF1: A9 B0 LDA #$B0 SEEKHD_DV: Suchen eines Sectors 8EF3: 20 E4 94 JSR $94E4 Job ausfuehren 8EF6: A6 6C LDX $6C Puffernummer wieder holen 8EF8: 48 PHA 8EF9: A9 B6 LDA #$B6 DETWP_DV: Schreibschutz pruefen 8EFB: 20 9D 95 JSR $959D Controller aufrufen 8EFE: 8D FA 01 STA $01FA und Zustand merken 8F01: 68 PLA 8F02: 60 RTS Partition initialisieren ($d042) Einsprung von $84E0, $8ECE, $96DB, $A7EA, $B265, $B383, $B42F, $B7FD, $BCCB, $BEEA: 8F03: AD FB 01 LDA $01FB Autoboot aus 8F06: 29 BF AND #$BF 8F08: 8D FB 01 STA $01FB 8F0B: A5 8A LDA $8A OR-Maske fuer Burststatus 8F0D: 09 80 ORA #$80 b7=1: Fremdformat 8F0F: 85 8A STA $8A 8F11: 20 6E 92 JSR $926E SA 0-14 freigeben 8F14: 20 DC 8E JSR $8EDC Blockheader des Verzeichnis-Headers suchen 8F17: C9 02 CMP #$02 8F19: B0 06 BCS $8F21 Fehler, ==> 8F1B: A5 91 LDA $91 Sektorengroesse 8F1D: C9 02 CMP #$02 =2 (512 Bytes) ? 8F1F: F0 03 BEQ $8F24 ja, ==> Einsprung von $8F19: 8F21: 4C B9 8F JMP $8FB9 Fehler bzw. kein 1581-Format Einsprung von $8F1F: 8F24: 20 DE 94 JSR $94DE Block lesen 8F27: A5 6C LDA $6C Puffernummer holen 8F29: 0A ASL 8F2A: AA TAX 8F2B: A9 01 LDA #$01 Folgesektor holen 8F2D: 95 BB STA $BB,X 8F2F: A1 BB LDA ($BB,X) als 1. Sektor des Verzeichnisses merken 8F31: 8D E5 01 STA $01E5 8F34: A9 02 LDA #$02 Diskettenversionsnummer 8F36: 95 BB STA $BB,X (Formatkennzeichen) merken 8F38: A1 BB LDA ($BB,X) 8F3A: 85 6F STA $6F 8F3C: A9 00 LDA #$00 BAM-Puffer als leer kennzeichnen 8F3E: 8D 00 0A STA $0A00 8F41: 20 4F B6 JSR $B64F BAM einlesen 8F44: A9 00 LDA #$00 8F46: 85 25 STA $25 Flag 'Diskettenwechsel' loeschen 8F48: 85 6E STA $6E Drivestatus loeschen 8F4A: A0 02 LDY #$02 8F4C: B1 31 LDA ($31),Y Diskettenversionsnummer in Byte 2 der BAM 8F4E: CD EB 01 CMP $01EB = 1581-Nummer (normalerweise 'd') ? 8F51: D0 66 BNE $8FB9 nein, ==> 8F53: C8 INY 8F54: B1 31 LDA ($31),Y und steht in Byte 3 ihr Komplement ? 8F56: 49 FF EOR #$FF 8F58: CD EB 01 CMP $01EB 8F5B: D0 5C BNE $8FB9 nein, ==> 8F5D: A5 8A LDA $8A Flag fuer Fremdformat in der Burst-OR-Maske 8F5F: 29 7F AND #$7F loeschen 8F61: 85 8A STA $8A 8F63: A0 04 LDY #$04 8F65: B1 31 LDA ($31),Y ID1 8F67: 85 1D STA $1D 8F69: C8 INY 8F6A: B1 31 LDA ($31),Y ID2 8F6C: 85 1E STA $1E 8F6E: C8 INY 8F6F: B1 31 LDA ($31),Y E/A-Byte 8F71: 85 8D STA $8D 8F73: 29 20 AND #$20 Flag 'Superside-Sektor verwenden' 8F75: 8D 01 01 STA $0101 (b5=0) merken 8F78: C8 INY 8F79: B1 31 LDA ($31),Y Autoboot-Byte 8F7B: 10 08 BPL $8F85 aus, ==> 8F7D: AD FB 01 LDA $01FB Autoboot einschalten 8F80: 09 40 ORA #$40 8F82: 8D FB 01 STA $01FB Anzahl freier Blocks in Partition berechnen Einsprung von $8F7B, $B512: 8F85: A5 4D LDA $4D Aktuelle Tracknummer merken 8F87: 48 PHA 8F88: A2 00 LDX #$00 Anfangen mit 0 Blocks frei 8F8A: 8E A9 02 STX $02A9 8F8D: 8E AA 02 STX $02AA 8F90: A6 90 LDX $90 Starttrack der Partition 8F92: 24 B $24 Einsprung von $8F99, $8FAC, $8FB1: 8F93: E8 INX 8F94: 86 4D STX $4D 8F96: EC 2B 02 CPX $022B Dir-Track ? 8F99: F0 F8 BEQ $8F93 ja, ==> 8F9B: EC 2C 02 CPX $022C letzter Track + 1 ? 8F9E: B0 13 BCS $8FB3 ja, ==> 8FA0: 20 BD B5 JSR $B5BD BAM-Zeiger auf aktuelles Bitmuster setzen 8FA3: B1 31 LDA ($31),Y Freie Blocks des Tracks 8FA5: 18 CLC 8FA6: 6D A9 02 ADC $02A9 addieren 8FA9: 8D A9 02 STA $02A9 8FAC: 90 E5 BCC $8F93 kein Uebertrag, ==> 8FAE: EE AA 02 INC $02AA 8FB1: D0 E0 BNE $8F93 immer ==> Einsprung von $8F9E: 8FB3: 68 PLA Aktuelle Tracknummer zurueckholen 8FB4: 85 4D STA $4D 8FB6: A2 00 LDX #$00 8FB8: 60 RTS kein 1581-Diskettenformat Einsprung von $8F21, $8F51, $8F5B: 8FB9: A2 03 LDX #$03 Verzeichnis-Folgesektor 8FBB: 8E E5 01 STX $01E5 8FBE: A2 C0 LDX #$C0 E/A-Byte: b6: CRC-Test ein; b7:Verify ein 8FC0: 86 8D STX $8D b5=0: Super-Side-Sektoren verwenden 8FC2: A2 00 LDX #$00 Flags fuer REL-Datei loeschen 8FC4: 8E 01 01 STX $0101 8FC7: 86 25 STX $25 Flag fuer Diskettenwechsel loeschen 8FC9: 86 6E STX $6E Drivestatus loeschen 8FCB: 8E A9 02 STX $02A9 keine freien Blocks 8FCE: 8E AA 02 STX $02AA 8FD1: 86 1D STX $1D ID loeschen 8FD3: 86 1E STX $1E 8FD5: 60 RTS DOS 3 Block einlesen und Folgeblock merken ($d09b) E: $50 : Kanalnummer $4d,$4e: T&S A: $4d,$4e: T&S des Folgeblocks (Fileende: $4d=0, $4e=Anzahl der gueltigen Zeichen) Einsprung von $8FEA, $9B1C: 8FD6: 20 85 95 JSR $9585 T&S an DC 8FD9: 20 FE 8F JSR $8FFE Befehl (lesen) an DC 8FDC: 20 ED 94 JSR $94ED Jobausfuehrung ueberwachen Folgeblock merken 8FDF: 20 71 90 JSR $9071 1. Byte aus Puffer holen 8FE2: 85 4D STA $4D 8FE4: 20 71 90 JSR $9071 2. Byte 8FE7: 85 4E STA $4E 8FE9: 60 RTS Block (und ggf. Folgeblock) im 2-Puffer-Modus lesen ($d0af) Einsprung von $A270: 8FEA: 20 D6 8F JSR $8FD6 Block lesen 8FED: A5 4D LDA $4D Folgeblock ? 8FEF: D0 01 BNE $8FF2 ja, ==> 8FF1: 60 RTS Einsprung von $8FEF: 8FF2: 20 7D 8D JSR $8D7D Puffer suchen bzw. wechseln 8FF5: 20 85 95 JSR $9585 T&S an DC uebergeben 8FF8: 20 FE 8F JSR $8FFE Befehl 'Block-lesen' an DC uebergeben [Die Jobausfuehrung wird nicht abgewartet. Fruehere Laufwerke konnten so den Block 'im Hintergrund' einlesen.] 8FFB: 4C 7D 8D JMP $8D7D Auf 1. Puffer zurueckschalten ??? Einsprung von $8FD9, $8FF8, $90FE: 8FFE: A9 80 LDA #$80 <-- Jobcode 'Block lesen' 9000: D0 02 BNE $9004 Einsprung von $912A, $940A, $9A69: 9002: A9 90 LDA #$90 <-- Jobcode 'Block schreiben' Einsprung von $9000: 9004: 85 28 STA $28 zwischenspeichern 9006: 20 11 9F JSR $9F11 Puffer holen 9009: AA TAX 900A: 20 71 94 JSR $9471 T&S auf Gueltigkeit pruefen, und Job aufrufen 900D: 8A TXA 900E: 48 PHA 900F: 0A ASL Puffernummer *2 9010: AA TAX 9011: A9 00 LDA #$00 Pufferzeiger initialisieren 9013: 95 BB STA $BB,X 9015: 20 5F 90 JSR $905F Filetyp holen 9018: C9 04 CMP #$04 REL-Datei ? 901A: B0 08 BCS $9024 ja, ==> 901C: FE 49 02 INC $0249,X Dateilaenge +1 901F: D0 03 BNE $9024 9021: FE 50 02 INC $0250,X Einsprung von $901A, $901F: 9024: 68 PLA Puffernummer zurueckholen 9025: AA TAX 9026: 60 RTS Kanal zum Lesen holen und pruefen ($d0eb) E: $52 : Sekundaeradresse a: $50, x: Kanalnummer Einsprung von $8561, $880A, $8978, $8C24, $92F4, $97BB, $9D79, $A1A9, $A828, $AD5D: 9027: A5 52 LDA $52 aktuelle Sekundaeradresse 9029: C9 13 CMP #$13 >18 902B: 90 02 BCC $902F nein, ==> 902D: 29 0F AND #$0F ja, auf 15 begrenzen Einsprung von $902B: 902F: C9 0F CMP #$0F Kommandokanal ? 9031: D0 02 BNE $9035 9033: A9 10 LDA #$10 ja, Kanal 16 (Fehlerkanal) benutzen Einsprung von $9031: 9035: AA TAX 9036: 38 SEC entsprechende Kanalnummer aus 9037: B5 A8 LDA $A8,X Sekundaeradressentabelle holen 9039: 30 06 BMI $9041 b7=1: Schreibkanal ? ja, ==> 903B: 29 0F AND #$0F Kanalnummer isolieren 903D: 85 50 STA $50 und als aktuellen Kanal merken 903F: AA TAX 9040: 18 CLC Einsprung von $9039: 9041: 60 RTS Kanal zum Schreiben holen und pruefen ($d107) E: $52 : Sekundaeradresse A: $50, x: Kanalnummer Einsprung von $88AB, $8E60, $99B7, $9B0A, $A82E, $AEB9: 9042: A5 52 LDA $52 Sekundaeradresse holen 9044: C9 13 CMP #$13 >18 ? 9046: 90 02 BCC $904A 9048: 29 0F AND #$0F ja, auf 15 begrenzen Einsprung von $9046: 904A: AA TAX entsprechende Kanalnummer aus 904B: B5 A8 LDA $A8,X Sekundaeradressentabelle holen 904D: A8 TAY 904E: 0A ASL 904F: 90 0A BCC $905B b7=1: Schreibkanal ? nein, ==> 9051: 30 0A BMI $905D b76=11: (ungueltig) ? ja, ==> Einsprung von $905B: 9053: 98 TYA Schreib- bzw. Schreib/Lesekanal 9054: 29 0F AND #$0F Kanalnummer isolieren 9056: 85 50 STA $50 und als aktuelle Kanalnummer merken 9058: AA TAX 9059: 18 CLC O.k. Flag 905A: 60 RTS Einsprung von $904F: 905B: 30 F6 BMI $9053 b76=01: Schreib/Lesekanal? ja,==> Einsprung von $9051: 905D: 38 SEC Fehlerflag setzen 905E: 60 RTS Aktuellen Filetyp holen ($d125) Einsprung von $87C9, $880D, $8829, $886C, $888A, $8DFD, $8E66, $8E80, $9015, $9305, $931A, $9333, $99AC, $9AA5, $A1B8, $A831: 905F: A6 50 LDX $50 aktuelle Kanalnummer 9061: B5 F9 LDA $F9,X und den Dateityp holen 9063: 4A LSR Drivenummer entfernen 9064: 29 07 AND #$07 Dateityp isolieren 9066: C9 04 CMP #$04 Relative Datei ? 9068: 60 RTS Kanal- und Puffernummer holen ($d12f) A: x: Puffernummer *2 y: Kanalnummer Einsprung von $8B6B, $8C06, $933A, $9F9E, $A0AD, $A0C6, $A0E4: 9069: 20 11 9F JSR $9F11 aktuellen Puffer holen 906C: 0A ASL * 2 (Index in Pufferzeigertabelle 906D: AA TAX mit 2 Byte pro Zeiger) 906E: A4 50 LDY $50 aktuelle Kanalnummer 9070: 60 RTS Byte aus aktuellem Puffer holen ($d137) E: $50: Kanalnummer A: a : aktuelles Byte z : 1: Blockende Einsprung von $8FDF, $8FE4, $909B, $90CC, $90D5, $9107, $938F, $994B, $9DD3, $9DD8, $B245, $B2D5, $B2DA: 9071: A6 50 LDX $50 Kanal- und Puffernummer holen 9073: B5 D1 LDA $D1,X [Dies entspricht exakt der Routine $9069. 9075: 10 02 BPL $9079 Bei der 1541 stand hier nur ein JSR 9077: B5 D8 LDA $D8,X dorthin. Diese Version spart Einsprung von $9075: 9079: 29 BF AND #$BF 2 x JSR, 2 x RTS (2x6 + 2x6 = 24 Takte) 907B: 0A ASL fuer jedes gelesene Byte 907C: AA TAX = 0.6 sec bei 202 Blocks.] 907D: A4 50 LDY $50 907F: B9 42 02 LDA $0242,Y Zeiger auf Pufferende = 0 ? 9082: F0 12 BEQ $9096 (nicht letzter Block) ja, ==> Byte aus letztem Block einer Datei holen 9084: A1 BB LDA ($BB,X) Byte holen 9086: 48 PHA 9087: B5 BB LDA $BB,X Dateiende ? 9089: D9 42 02 CMP $0242,Y 908C: D0 04 BNE $9092 nein, ==> 908E: A9 FF LDA #$FF Pufferzeiger auf 0 setzen 9090: 95 BB STA $BB,X ($ff wegen inc bb,x (setzt das z-Flag)) Einsprung von $908C: 9092: 68 PLA 9093: F6 BB INC $BB,X Pufferzeiger erhoehen 9095: 60 RTS Byte aus allen anderen Bloecken einer Datei holen Einsprung von $9082: 9096: A1 BB LDA ($BB,X) Byte holen 9098: F6 BB INC $BB,X Pufferzeiger erhoehen 909A: 60 RTS Byte aus aktueller Datei holen ($d156) Es wird der Zwei-Puffer-Modus verwendet. Dieser bringt bei der 1581 keinen Vorteil (sondern nur den Nachteil, dass 2 Puffer gebraucht werden). E: $50 : Kanalnummer A: $0234+KN: Kanalstatus a : Byte aus der Datei Byte aus aktuellem Puffer holen Einsprung von $871E, $8723, $935C, $93B9, $9B8D: 909B: 20 71 90 JSR $9071 Byte holen 909E: D0 66 BNE $9106 Blockende ? nein, ==> 90A0: 85 54 STA $54 Datenbyte zwischenspeichern 90A2: B9 42 02 LDA $0242,Y Dateiende ? 90A5: F0 08 BEQ $90AF nein, ==> 90A7: A9 80 LDA #$80 b7=1: Lesekanal; b3=0: EOI-Flag setzen 90A9: 99 34 02 STA $0234,Y Kanalstatus setzen 90AC: A5 54 LDA $54 90AE: 60 RTS T&S des uebernaechsten Blocks holen Einsprung von $90A5: 90AF: 20 7D 8D JSR $8D7D Puffer umschalten (er enthaelt bereits den 90B2: A9 00 LDA #$00 Folgeblock) 90B4: 85 40 STA $40 90B6: A6 50 LDX $50 90B8: B5 D1 LDA $D1,X Aktuellen Puffer holen 90BA: 10 02 BPL $90BE 90BC: B5 D8 LDA $D8,X Einsprung von $90BA: 90BE: 29 BF AND #$BF 90C0: 0A ASL 90C1: AA TAX 90C2: B5 BC LDA $BC,X Pufferzeiger setzen 90C4: 85 65 STA $65 90C6: A5 40 LDA $40 = 0 90C8: 95 BB STA $BB,X 90CA: 85 64 STA $64 90CC: 20 71 90 JSR $9071 1. Byte aus Puffer holen 90CF: C9 00 CMP #$00 Ist es der letzter Block der Datei ? 90D1: F0 34 BEQ $9107 ja, ==> 90D3: 85 4D STA $4D Folgetrack merken 90D5: 20 71 90 JSR $9071 2. Byte holen 90D8: 85 4E STA $4E Folgesektor merken 90DA: 20 7D 8D JSR $8D7D Puffer wieder zurueckschalten oebernaechsten Block einlesen 90DD: A6 50 LDX $50 Was soll das ? 90DF: B5 D1 LDA $D1,X Puffer holen, die erste 90E1: 10 02 BPL $90E5 90E3: B5 D8 LDA $D8,X Einsprung von $90E1: 90E5: 29 BF AND #$BF 90E7: AA TAX [Hier ist eine Laufwerksnummernabfrage entfallen] Puffer holen, die zweite 90E8: A6 50 LDX $50 Kanalnummer holen 90EA: B5 D1 LDA $D1,X Aktiven Puffer holen 90EC: 10 02 BPL $90F0 (wenn erster nicht aktiv, dann zweiten 90EE: B5 D8 LDA $D8,X Puffer holen) Einsprung von $90EC: 90F0: 29 BF AND #$BF 90F2: 0A ASL 2-Byte-Tabelle 90F3: A8 TAY 90F4: A5 4D LDA $4D T&S des Folgeblocks in Jobpuffer schreiben 90F6: 99 0B 00 STA $000B,Y 90F9: A5 4E LDA $4E 90FB: 99 0C 00 STA $000C,Y 90FE: 20 FE 8F JSR $8FFE Block einlesen 9101: 20 7D 8D JSR $8D7D Puffer wieder umschalten 9104: A5 54 LDA $54 Datenbyte zurueckholen Einsprung von $909E: 9106: 60 RTS Letzten Dateiblock behandeln Einsprung von $90D1: 9107: 20 71 90 JSR $9071 Blocklaenge holen 910A: A4 50 LDY $50 und als Blocklaenge des aktuellen 910C: 99 42 02 STA $0242,Y Kanals merken 910F: A5 54 LDA $54 Datenbyte zurueckholen 9111: 60 RTS Schreiben eines Bytes in eine Datei im 2-Puffer Modus. ($d19d) Ist der Puffer voll, wird der naechste freie Sektor gesucht, der volle Block abgespeichert und auf den anderen Puffer geschaltet. In frueheren Laufwerken konnte so der Puffer 'im Hintergrund' abgespeichert werden. Einsprung von $8E87: 9112: 20 B1 8E JSR $8EB1 Byte in Puffer schreiben 9115: F0 01 BEQ $9118 Puffer voll ? 9117: 60 RTS nein ==> Einsprung von $9115, $98DF: 9118: 20 68 B6 JSR $B668 Folgeblock suchen und in der BAM belegen 911B: A9 00 LDA #$00 911D: 20 22 94 JSR $9422 Pufferzeiger auf 0 setzen 9120: A5 4D LDA $4D Sektorverkettung setzen: 9122: 20 B1 8E JSR $8EB1 Tracknummer in Puffer schreiben 9125: A5 4E LDA $4E Sektornummer schreiben 9127: 20 B1 8E JSR $8EB1 912A: 20 02 90 JSR $9002 Block schreiben 912D: 20 7D 8D JSR $8D7D Puffer wechseln 9130: 20 85 95 JSR $9585 T&S in Jobspeicher schreiben 9133: A9 02 LDA #$02 Pufferzeiger hinter die Verkettungs-Bytes 9135: 4C 22 94 JMP $9422 setzen Erhoehen des aktuellen Pufferzeigers ($d1c6) E: a : Wert, der zum Pufferzeiger addiert werden soll $50: aktuelle Kanalnummer Einsprung von $8495: 9138: 85 40 STA $40 Wert merken 913A: 20 42 94 JSR $9442 Pufferzeiger holen 913D: 18 CLC a: Pufferzeiger Lo 913E: 65 40 ADC $40 und angegebenen Wert hinzuaddieren 9140: 95 BB STA $BB,X Pufferzeiger setzen 9142: 85 64 STA $64 9144: 60 RTS Autoboot bei Warmstart ein/aus c=1 : ein c=0 : aus Einsprung von $FF60: 9145: AD FB 01 LDA $01FB Autoboot-Flag loeschen 9148: 29 7F AND #$7F 914A: 8D FB 01 STA $01FB 914D: A9 00 LDA #$00 914F: 6A ROR c-Flag nach b7 schieben 9150: 0D FB 01 ORA $01FB Autoboot-Flag entsprechend setzen 9153: 8D FB 01 STA $01FB 9156: 60 RTS Kanal oeffnen und entsprechende Zahl Puffer zuordnen ($d1df) E: a : Anzahl der Puffer (0, 1, oder 2 Puffer) $52: Sekundaeradresse A: $50: neue Kanalnummer Wenn kein Kanal oder Puffer gefunden wird, erfolgt kein Ruecksprung in die aufrufende Routine Einsprung von $9BC8: 9157: 38 SEC <-- Schreibkanal suchen 9158: B0 01 BCS $915B Einsprung von $89F4, $8A23, $9B0F, $B182: 915A: 18 CLC <-- Lesekanal suchen Einsprung von $9158: 915B: 08 PHP 915C: 85 40 STA $40 Anzahl der gesuchten Puffer merken 915E: 20 9E 91 JSR $919E Kanal freigeben 9161: 20 DB 92 JSR $92DB freien Kanal suchen 9164: 85 50 STA $50 und als aktuellen Kanal merken 9166: A6 52 LDX $52 Sekundaeradresse holen 9168: 28 PLP 9169: 90 02 BCC $916D Lesekanal ? ja, ==> 916B: 09 80 ORA #$80 b76=10: Flag: Schreibkanal Einsprung von $9169: 916D: 95 A8 STA $A8,X Kanal der SA zuordnen 916F: 29 3F AND #$3F 9171: A8 TAY 9172: A9 FF LDA #$FF Pufferzuordnung loeschen 9174: 99 D1 00 STA $00D1,Y 1. Puffer 9177: 99 D8 00 STA $00D8,Y 2. Puffer 917A: 99 65 02 STA $0265,Y SS-Puffer 917D: C6 40 DEC $40 Soll ein Puffer gesucht werden ? 917F: 30 1C BMI $919D nein, ==> 9181: 20 04 92 JSR $9204 freien Puffer suchen 9184: 10 08 BPL $918E Puffer gefunden ? ja, ==> Einsprung von $9198, $9B44, $9BFC: 9186: 20 CE 91 JSR $91CE Puffer wieder freigeben 9189: A9 70 LDA #$70 70, no Channel 918B: 4C 7C 80 JMP $807C Einsprung von $9184: 918E: 99 D1 00 STA $00D1,Y 1. Puffer merken 9191: C6 40 DEC $40 noch einen Puffer suchen ? 9193: 30 08 BMI $919D nein, ==> 9195: 20 04 92 JSR $9204 freien Puffer suchen 9198: 30 EC BMI $9186 keinen Puffer gefunden ? ja, ==> 919A: 99 D8 00 STA $00D8,Y 2. Puffer merken Einsprung von $917F, $9193: 919D: 60 RTS Freigeben einer SA ausser der des Kommandokanals; Puffer freigeben ($d227) Schreib-/Lesekanaele ausser dem Kommandokanal schliessen E: $52: Sekundaeradresse, die geschlossen werden soll Einsprung von $872F, $915E, $9266, $9289, $9438, $943F, $9965, $99C5, $9A02, $A838, $B2E3: 919E: A5 52 LDA $52 Sekundaeradresse holen 91A0: C9 0F CMP #$0F Kommandokanal nicht 91A2: D0 01 BNE $91A5 schliessen 91A4: 60 RTS Einsprung von $91A2: 91A5: A6 52 LDX $52 Aktuelle SA holen 91A7: B5 A8 LDA $A8,X Zugehoerige Kanalnummer holen 91A9: C9 FF CMP #$FF 'Kanal unbenutzt' ? 91AB: F0 20 BEQ $91CD ja, ==> 91AD: 29 3F AND #$3F Kanalnummer isolieren 91AF: 85 50 STA $50 Als aktuelle Kanalnummer merken 91B1: A9 FF LDA #$FF SA als unbenutzt kennzeichnen 91B3: 95 A8 STA $A8,X SA freigeben 91B5: A6 50 LDX $50 Kanalnummer wieder holen 91B7: A9 00 LDA #$00 Kanalstatus loeschen 91B9: 9D 34 02 STA $0234,X 91BC: 20 CE 91 JSR $91CE Puffer und Zuordnung freigeben 91BF: A6 50 LDX $50 91C1: A9 01 LDA #$01 Entsprechendes Bit der Kanaltabelle setzen Einsprung von $91C7: 91C3: CA DEX und damit den Kanal freigeben 91C4: 30 03 BMI $91C9 91C6: 0A ASL Bit an die richtige Stelle 91C7: D0 FA BNE $91C3 schieben Einsprung von $91C4: 91C9: 05 70 ORA $70 Bit setzen 91CB: 85 70 STA $70 Einsprung von $91AB: 91CD: 60 RTS Puffer und dessen Kanalzuordnung freigeben ($d25a) Einsprung von $9186, $91BC: 91CE: A6 50 LDX $50 aktuelle Kanalnummer holen 91D0: B5 D1 LDA $D1,X 1. Puffer pruefen 91D2: C9 FF CMP #$FF kein Puffer zugeordnet ? 91D4: F0 09 BEQ $91DF ja, ==> 91D6: 48 PHA 91D7: A9 FF LDA #$FF Pufferzuordnung loeschen 91D9: 95 D1 STA $D1,X 91DB: 68 PLA 91DC: 20 52 92 JSR $9252 Puffer freigeben Einsprung von $91D4: 91DF: A6 50 LDX $50 91E1: B5 D8 LDA $D8,X 2. Puffer pruefen 91E3: C9 FF CMP #$FF kein Puffer zugeordnet ? 91E5: F0 09 BEQ $91F0 91E7: 48 PHA 91E8: A9 FF LDA #$FF Pufferzuordnung loeschen 91EA: 95 D8 STA $D8,X 91EC: 68 PLA 91ED: 20 52 92 JSR $9252 Puffer freigeben Einsprung von $91E5: 91F0: A6 50 LDX $50 91F2: BD 65 02 LDA $0265,X Side-Sektor-Puffer pruefen 91F5: C9 FF CMP #$FF kein Puffer zugeordnet ? 91F7: F0 0A BEQ $9203 91F9: 48 PHA 91FA: A9 FF LDA #$FF Pufferzuordnung loeschen 91FC: 9D 65 02 STA $0265,X 91FF: 68 PLA 9200: 4C 52 92 JMP $9252 Puffer freigeben Einsprung von $91F7: 9203: 60 RTS Suchen eines freien oder inaktiven Puffers ($d28e) A: a,x: Puffernummer (>$7f: kein Puffer gefunden) Einsprung von $8DAD, $8E44, $8EDC, $9181, $9195, $9B3F, $9BF7: 9204: 98 TYA 9205: 48 PHA 9206: 20 28 92 JSR $9228 Puffer suchen 9209: 10 06 BPL $9211 gefunden ? ja, ==> 920B: 20 91 92 JSR $9291 Puffer 'stehlen' [ganz legal...] 920E: AA TAX erfolgreich ? 920F: 30 13 BMI $9224 nein, ==> Einsprung von $9209, $9213: 9211: B5 02 LDA $02,X Jobausfuehrung abwarten 9213: 30 FC BMI $9211 9215: A9 00 LDA #$00 Jobspeicher loeschen 9217: 95 02 STA $02,X 9219: 9D 72 02 STA $0272,X 921C: 8A TXA Puffernummer * 2 921D: 0A ASL 921E: A8 TAY 921F: A9 02 LDA #$02 Pufferzeiger initialisieren 9221: 99 BB 00 STA $00BB,Y Einsprung von $920F: 9224: 68 PLA 9225: A8 TAY 9226: 8A TXA Puffernummer merken 9227: 60 RTS Suchen und belegen eines freien Puffers ($d2ba) A: a,x: Puffernummer ($ff: kein Puffer gefunden) Einsprung von $9206: 9228: A2 07 LDX #$07 Bit suchen, das 0 ist (= freier Puffer) Einsprung von $9232: 922A: A5 6D LDA $6D 922C: 3D EA B5 AND $B5EA,X 922F: F0 04 BEQ $9235 Position in x 9231: CA DEX 9232: 10 F6 BPL $922A 9234: 60 RTS kein freier Puffer Einsprung von $922F, $8EE2: 9235: A5 6D LDA $6D Puffer belegen 9237: 5D EA B5 EOR $B5EA,X 923A: 85 6D STA $6D 923C: 8A TXA 923D: 60 RTS einen inaktiven Puffer eines Kanals freigeben ($d2da) Programmleiche 923E: A6 50 LDX $50 Kanalnummer 9240: B5 D1 LDA $D1,X zugehoerigen 1.Puffer holen 9242: 30 04 BMI $9248 Puffer inaktiv, dann ==> 9244: B5 D8 LDA $D8,X 2.Puffer holen 9246: 10 19 BPL $9261 Puffer auch aktiv, dann ==> Einsprung von $9242: 9248: C9 FF CMP #$FF ist kein Puffer zugeordnet ? 924A: F0 15 BEQ $9261 ja, ==> 924C: 48 PHA Puffernummer merken 924D: A9 FF LDA #$FF 1.Puffer freigeben [auch, wenn der 2.Puffer 924F: 95 D1 STA $D1,X der inaktive ist ! Dies ist ein schwerer 9251: 68 PLA Programmfehler, der sich nur deshalb nicht auswirkt, weil dieser Teil der Routine nie nie aufgerufen wird . (Im 1541-DOS ist die die Routine Ok. und wird auch verwendet.)] Puffer freigeben <-- Einsprung E: a: Puffernummer Einsprung von $91DC, $91ED, $9200: 9252: 29 0F AND #$0F Puffernummer isolieren 9254: A8 TAY und Puffer freigeben 9255: C8 INY durch Loeschen des entsprechenden Bits 9256: A2 08 LDX #$08 Einsprung von $925F: 9258: 66 6D ROR $6D ROR, bis die Bits wieder an der alten 925A: 88 DEY Position sind 925B: D0 01 BNE $925E an der gesuchten Position durch 925D: 18 CLC CLC das entsprechende Bit loeschen Einsprung von $925B: 925E: CA DEX 925F: 10 F7 BPL $9258 weiterschieben, ==> Einsprung von $9246, $924A: 9261: 60 RTS Kanaele der Sekundaeradressen 1-14 freigeben ($d307) Einsprung von $B371, $B7FA: 9262: A9 0E LDA #$0E mit sa=14 anfangen 9264: 85 52 STA $52 Einsprung von $926B: 9266: 20 9E 91 JSR $919E Kanal freigeben 9269: C6 52 DEC $52 naechste SA 926B: D0 F9 BNE $9266 926D: 60 RTS Die SA 0-14 des Laufwerks 0 freigeben Einsprung von $8F11, $B13B: 926E: A9 0E LDA #$0E Beginn mit Sekundaeradresse 14 9270: 85 52 STA $52 Einsprung von $928E: 9272: A6 52 LDX $52 zugehoerige Kanalnummer holen 9274: B5 A8 LDA $A8,X 9276: C9 FF CMP #$FF kein Kanal zugeordnet ? 9278: F0 12 BEQ $928C ja, naechste SA freigeben 927A: 29 3F AND #$3F Kanalnummer isolieren 927C: 85 50 STA $50 927E: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen 9281: AA TAX 9282: BD 72 02 LDA $0272,X Zwischenspeicher fuer Jobcodes 9285: 29 01 AND #$01 Drivenummer (ist immer 0) 9287: D0 03 BNE $928C (wird nie ausgefuehrt) 9289: 20 9E 91 JSR $919E SA freigeben Einsprung von $9278, $9287: 928C: C6 52 DEC $52 naechste SA freigeben 928E: 10 E2 BPL $9272 9290: 60 RTS 'Stehlen' eines inaktiven Puffers ($d339) A: a: gestohlener Puffer ($ff: kein Puffer gefunden) [Wenn alle Puffer belegt sind, und trotzdem noch ein Puffer benoetigt wird, kann mit dieser Routine ein 'inaktiver Puffer' freigegeben werden. Inaktive Puffer enthalten normalerweise: - Daten, die von der 2-Puffer-Automatik im Voraus geladen worden sind, und die noch nicht sofort gebraucht werden (Diese Daten muessen spaeter ein zweites Mal geladen werden), - oder Daten, die abgespeichert werden sollen, sobald der Schreib-/Lese- kopf positioniert worden ist (In diesem Fall muss man nur den Schreib- vorgang abwarten). Dieses Konzept ist bei der 1581 jedoch nicht mehr sinnvoll, da das DOS so lange fast voellig angehalten wird, bis alle Schreib-/Lesejobs erledigt sind und das Laden und Speichern deshalb nicht mehr im Hintergrund geschieht.] Einsprung von $920B: 9291: A5 40 LDA $40 Zwischenspeicher merken 9293: 48 PHA 9294: A0 00 LDY #$00 Einsprung von $92B0: 9296: B6 DF LDX $DF,Y am laengsten nicht benutzte Kanaele zuerst 9298: B5 D1 LDA $D1,X testen 929A: 10 04 BPL $92A0 1. Puffer aktiv, dann ==> 929C: C9 FF CMP #$FF besitzt Kanal einen 1. Puffer ? 929E: D0 16 BNE $92B6 ja, versuchen zu 'stehlen' ==> Einsprung von $929A, $92CB: 92A0: 8A TXA 92A1: 18 CLC 92A2: 69 08 ADC #$08 2. Puffer testen 92A4: AA TAX 92A5: B5 D1 LDA $D1,X 92A7: 10 04 BPL $92AD Puffer aktiv, dann ==> 92A9: C9 FF CMP #$FF besitze Kanal einen 2. Puffer ? 92AB: D0 09 BNE $92B6 ja, versuchen zu 'stehlen' ==> Einsprung von $92A7, $92CD: 92AD: C8 INY naechsten Kanal versuchen 92AE: C0 06 CPY #$06 92B0: 90 E4 BCC $9296 92B2: A2 FF LDX #$FF keinen 'stehlbaren' Puffer gefunden 92B4: D0 20 BNE $92D6 immer ==> Versuchen, den gefundenen Puffer zu stehlen Einsprung von $929E, $92AB: 92B6: 86 40 STX $40 Kanalnummer (ggf. +8: 2. Puffer) merken 92B8: 29 3F AND #$3F Puffernummer isolieren 92BA: AA TAX Einsprung von $92BD: 92BB: B5 02 LDA $02,X evtl. Job abwarten 92BD: 30 FC BMI $92BB 92BF: C9 02 CMP #$02 ist ein Fehler aufgetreten ? 92C1: 90 0C BCC $92CF nein, ==> 92C3: C9 0F CMP #$0F 92C5: F0 08 BEQ $92CF Drive not ready ?, ==> 92C7: A6 40 LDX $40 Lesefehler, naechsten Puffer probieren 92C9: E0 08 CPX #$08 weitermachen bei: 92CB: 90 D3 BCC $92A0 2. Puffer, ==> 92CD: B0 DE BCS $92AD 1. Puffer, naechster Kanal (bzw. Ende) ==> Einsprung von $92C1, $92C5: 92CF: A4 40 LDY $40 Puffer freigeben 92D1: A9 FF LDA #$FF 92D3: 99 D1 00 STA $00D1,Y Einsprung von $92B4: 92D6: 68 PLA Zwischenspeicher zurueckholen 92D7: 85 40 STA $40 92D9: 8A TXA gefundenen Puffer nach A 92DA: 60 RTS Freien Kanal suchen ($d37f) Einsprung von $9161: 92DB: A0 00 LDY #$00 Byte ($70) nach einem gesetzten Bit 92DD: A9 01 LDA #$01 durchsuchen Einsprung von $92E5: 92DF: 24 70 BIT $70 (der entsprechende Kanal ist frei) 92E1: D0 09 BNE $92EC Kanal gefunden, ==> 92E3: C8 INY Kanalnummer +1 92E4: 0A ASL naechstes Bit probieren 92E5: D0 F8 BNE $92DF noch ein Bit zu ueberpruefen, ==> 92E7: A9 70 LDA #$70 70, NO CHANNEL 92E9: 4C 7C 80 JMP $807C Einsprung von $92E1: 92EC: 49 FF EOR #$FF entsprechendes Bit loeschen 92EE: 25 70 AND $70 und dadurch den Kanal belegen 92F0: 85 70 STA $70 92F2: 98 TYA Kanalnummer nach A 92F3: 60 RTS Byte fuer beliebige SA holen ($d39b) E: $52: Aktuelle SA A: a : Byte aus Puffer Einsprung von $887A: 92F4: 20 27 90 JSR $9027 Kanal holen 92F7: 20 F6 81 JSR $81F6 Drive-LED einschalten 92FA: 20 03 93 JSR $9303 Byte aus Kanal holen 92FD: A6 50 LDX $50 92FF: BD 3B 02 LDA $023B,X Byte aus Ausgabepuffer holen 9302: 60 RTS Byte aus beliebigem Kanal holen ($d3aa) Diese Routine wird von DOS jedesmal aufgerufen, wenn ein Byte zum Computer uebertragen werden soll. Es werden sowohl Daten aus 'normalen' Dateien gelesen, als auch Daten aus dem Directory, aus REL-Dateien, oder Direktzugriffen ('#'). E: $50: aktueller Kanal A: Byte im Ausgabepuffer $023b+KN (Kanalnummer $50) Kanalstatus $0234+KN [kleiner Zeitvergleich: Die Routine benoetigt ca. 140 Taktzyklen, um bei LOAD ein Byte zu holen, bei SA 2-14 (PRG,SEQ,USR) sind es ca. 162 Zyklen. Dies entspricht bei 202 Blocks einer Zeit von 3,6 - 4,2 sec. Wenn ein Block nachgeladen werden muss, werden ca. 910 Taktzyklen zusaetzlich gebraucht (reiner DOS-Aufwand, ohne Controllerprogramm) = 0,1 sec. bei 202 Blocks. Um die reale Geschwindigkeit der Routine zu testen, verwenden wir den Append-Befehl (SA=2). Der Vorgang dauert bei 202 Blocks 12 sec. Er selbst benoetigt ca. 130 Zyklen pro Byte (= 3,3 sec). Also braucht diese Routine tatsaechlich ca. 8,7 sec. fuer 202 Blocks. Wir hatten aber nur 4,3 sec. (4,2 + 0,1) ausgerechnet. Die restlichen 4,4 sec. werden verbraucht: - vom Controller (min. 3,0 sec): - Lesen der benoetigten Spuren (mindestens 2,8 sec.): - 11 x ersten Blockheader finden ( = 0,1 sec.), - 11 x 2 folgende Datenbereiche ueberlesen ( = 0,4 sec.) - 11 Spuren lesen bei 5 Umdrehungen/sec. ( = 2,2 sec.), - Positionieren der Schreib-/Lesekoepfe (ca. 0,3 sec.), - vom Controller-Programm (min. 0,5 sec.): - Abfragen der Jobspeicher: 266 Takte x 1200 (Timer-IRQ) + 180 Takte x 202 x 4 (BRK) (ca. 0,2 sec.), - Kopieren der Daten vom Cache in den DOS-Puffer (0,3 sec.). Die restlichen 0.9 sec. verteilen sich auf die vielen verschiedenen kleineren Routinen (Log. in Phy. Format umwandeln, ...). (Die angegebenen Zeiten sind uebrigens alle 'Mindest-Zeiten'.)] Einsprung von $92FA, $AE35: 9303: A6 50 LDX $50 9305: 20 5F 90 JSR $905F Filetyp holen 9308: D0 03 BNE $930D kein Rel-File, ==> 930A: 4C A6 A0 JMP $A0A6 Byte aus Record-Puffer holen Einsprung von $9308: 930D: A5 52 LDA $52 SA = 15 ? 930F: C9 0F CMP #$0F 9311: F0 5D BEQ $9370 ja, Fehlermeldung bzw. M-R-Byte holen 9313: BD 34 02 LDA $0234,X Kanalstatus holen 9316: 29 08 AND #$08 EOI gesetzt ? 9318: D0 15 BNE $932F nein, ==> 931A: 20 5F 90 JSR $905F Filetyp holen 931D: C9 07 CMP #$07 Direktzugriff ? 931F: D0 08 BNE $9329 nein, ==> 9321: A9 89 LDA #$89 b7=1: Lesen und b0=1: Schreiben ermoeglichen 9323: 9D 34 02 STA $0234,X b4=1: EOI loeschen 9326: 4C 3A 93 JMP $933A 1. Byte zur Ausgabe bereitstellen Einsprung von $931F: 9329: A9 00 LDA #$00 Kanal verriegeln (weder Lesen noch 932B: 9D 34 02 STA $0234,X Schreiben ist gesetzt) 932E: 60 RTS Einsprung von $9318: 932F: A5 52 LDA $52 SA=0: LOAD ? 9331: F0 32 BEQ $9365 ja, ==> 9333: 20 5F 90 JSR $905F Filetyp holen 9336: C9 04 CMP #$04 <4 (SEQ,PRG,USR) 9338: 90 22 BCC $935C ja, ==> Byte aus Direktzugriffskanal holen Einsprung von $9326: 933A: 20 69 90 JSR $9069 Kanal- und Puffernummer holen 933D: B5 BB LDA $BB,X Pufferende erreicht ? 933F: D9 42 02 CMP $0242,Y 9342: D0 04 BNE $9348 nein, ==> 9344: A9 00 LDA #$00 Zeiger auf Pufferanfang setzen (1. Byte 9346: 95 BB STA $BB,X ueberlesen (es enthaelt die Blocklaenge bei M-R bzw. M-W)) Einsprung von $9342, $8B88: 9348: F6 BB INC $BB,X Pufferzeiger erhoehen Einsprung von $8C09, $8E96: 934A: A1 BB LDA ($BB,X) Byte aus Puffer holen 934C: 99 3B 02 STA $023B,Y und in Ausgabepuffer schreiben 934F: B5 BB LDA $BB,X Pufferende erreicht ? 9351: D9 42 02 CMP $0242,Y 9354: D0 05 BNE $935B nein, ==> 9356: A9 81 LDA #$81 b4=0: EOI ausgeben 9358: 99 34 02 STA $0234,Y Einsprung von $9354: 935B: 60 RTS Byte aus PRG-/SEQ-/USR-Dateien holen Einsprung von $9338, $9368: 935C: 20 9B 90 JSR $909B Byte holen (im 2-Puffer-Modus) Einsprung von $936D: 935F: A6 50 LDX $50 9361: 9D 3B 02 STA $023B,X und in Ausgabepuffer schreiben 9364: 60 RTS Einsprung von $9331: 9365: AD 6E 02 LDA $026E <-- SA=0: DIRECTORY-Modus aktiv ? 9368: F0 F2 BEQ $935C nein, ==> 936A: 20 45 B2 JSR $B245 Byte aus Directory holen 936D: 4C 5F 93 JMP $935F und zur Ausgabe bereitstellen Fehlerkanal auslesen bzw M-R-Befehl ($d414) Einsprung von $9311: 9370: 20 42 94 JSR $9442 Pufferzeiger holen 9373: C9 CF CMP #$CF = $02cf (Pufferanfang) ? 9375: D0 18 BNE $938F nein, Byte holen ==> 9377: A5 65 LDA $65 9379: C9 02 CMP #$02 937B: D0 12 BNE $938F nein, Byte holen ==> 937D: A9 0D LDA #$0D ja, CR ausgeben 937F: 85 54 STA $54 [Diese Abfrage fuehrt dazu, dass die neue Fehlermeldung bereitge stellt wird, wenn die alte ausgegeben worden ist. Die Fehlermeldung wird aber auch dann bereitgestellt, wenn man mit dem M-R Befehl versucht, ueber den Fehlerpuffer-Anfang zu lesen. Dann wird der M-R einfach abgebrochen.] Ok-Meldung bereitstellen 9381: 20 E5 81 JSR $81E5 LEDs ausschalten 9384: A9 00 LDA #$00 9386: 20 67 A8 JSR $A867 '00, OK,00,00'-Meldung bereitstellen 9389: C6 CF DEC $CF 938B: A9 80 LDA #$80 EOI setzen 938D: D0 12 BNE $93A1 immer ==> Einsprung von $9375, $937B: 938F: 20 71 90 JSR $9071 Byte aus aktuellem Puffer holen 9392: 85 54 STA $54 und merken 9394: D0 09 BNE $939F Pufferende erreicht ? [Leider ist das z-Flag nicht nur am Pufferende gesetzt, sondern generell, wenn eine Seitengrenze uebersprungen wird, da das Hi-Byte der Pufferadresse nicht beruecksichtigt wird. Dies ist bei 'normalen' Puffern auch ganz in Ordnung. Beim M-R Befehl tritt jedoch ein Fehler auf, da bei ihm der Ausgabepuffer auch ueber Seitengrenzen gehen kann. In einem solchen Fall wird einfach wieder auf Fehlerausgabe umgeschaltet.] Fehlerausgabe initialisieren Einsprung von $897B: 9396: A9 CF LDA #$CF Fehler-Pufferzeiger auf $02cf setzen 9398: 20 22 94 JSR $9422 Pufferzeiger Lo auf $cf setzen 939B: A9 02 LDA #$02 Pufferzeiger Hi auf $02 setzen 939D: 95 BC STA $BC,X Einsprung von $9394, $8975: 939F: A9 88 LDA #$88 b3=1: EOI-Flag loeschen Einsprung von $938D: 93A1: 8D 3A 02 STA $023A b7=1: auf Ausgabe (Lesen) schalten 93A4: A5 54 LDA $54 Datenbyte holen 93A6: 8D 41 02 STA $0241 und in Ausgabepuffer schreiben 93A9: 60 RTS Lesen des naechsten Blocks ($d44d) Einsprung von $849B, $8735, $B2E9: 93AA: 20 11 9F JSR $9F11 Puffernummer holen 93AD: 0A ASL 93AE: AA TAX 93AF: A9 00 LDA #$00 93B1: 95 BB STA $BB,X Pufferzeiger auf 0 93B3: A1 BB LDA ($BB,X) Folgetracknummer holen 93B5: F0 05 BEQ $93BC =0 (Fileende), ==> 93B7: D6 BB DEC $BB,X Zeiger auf letztes Byte im Block setzen 93B9: 4C 9B 90 JMP $909B naechstes Byte holen (und damit den Einsprung von $93B5: 93BC: 60 RTS den Folgeblock einlesen) Lesen/Schreiben des aktuellen Puffers ($d460) E: $6c : Puffernummer $4d,$4e: T&S Einsprung von $8B68, $8B91, $95E1, $9A90: 93BD: A9 80 LDA #$80 <-- Puffer lesen 93BF: D0 02 BNE $93C3 Einsprung von $8BC7, $8BDD, $9656, $97E7, $9837, $B3F0, $B408: 93C1: A9 90 LDA #$90 <-- Puffer schreiben Einsprung von $93BF: 93C3: 85 28 STA $28 93C5: A5 6C LDA $6C Puffernummer holen 93C7: 20 88 95 JSR $9588 T&S an Controller uebergeben 93CA: A6 6C LDX $6C Puffernummer holen 93CC: 4C E8 94 JMP $94E8 Puffer lesen/schreiben Datei auf internem Lesekanal oeffnen, Puffer belegen und 1. Block lesen ($d475) Einsprung von $8439, $8480, $8716, $884D, $B2CD: 93CF: A9 01 LDA #$01 <-- sequentielle Datei Einsprung von $A991: 93D1: 8D 2D 02 STA $022D <-- a: Filetyp 93D4: A9 11 LDA #$11 SA 17: interne Lese-Adresse 93D6: 85 52 STA $52 93D8: 20 0D 9B JSR $9B0D Kanal suchen und 1. Block lesen 93DB: A9 02 LDA #$02 Puffer-Zeiger auf 1. Datenbyte setzen 93DD: 4C 22 94 JMP $9422 Datei auf internem Schreibkanal oeffnen, 1. T&S des Datenblocks und ggf. des 1. Side-Sektors holen ($d486) Einsprung von $87F7: 93E0: A9 12 LDA #$12 SA 18: interne Schreib-Adresse 93E2: 85 52 STA $52 93E4: 4C C3 9B JMP $9BC3 Kanal suchen, File anlegen Neuen Block an das Directory anhaengen ($d48d) Einsprung von $95F5: 93E7: 20 79 9D JSR $9D79 T&S der aktuellen Datei holen 93EA: A9 01 LDA #$01 nur eine Suchphase ausfuehren (s. $b668) 93EC: 85 40 STA $40 93EE: A5 2E LDA $2E Sektorversatz merken 93F0: 48 PHA 93F1: A9 01 LDA #$01 Sektorversatz auf 1 setzen 93F3: 85 2E STA $2E 93F5: 20 75 B6 JSR $B675 freien Block suchen 93F8: 68 PLA 93F9: 85 2E STA $2E alten Sektorversatz zurueckholen 93FB: A9 00 LDA #$00 Pufferzeiger auf Verkettungsbytes setzen 93FD: 20 22 94 JSR $9422 9400: A5 4D LDA $4D T&S des Folgeblocks im aktuellen Block 9402: 20 B1 8E JSR $8EB1 eintragen 9405: A5 4E LDA $4E 9407: 20 B1 8E JSR $8EB1 940A: 20 02 90 JSR $9002 alten Directory-Block schreiben 940D: 20 ED 94 JSR $94ED Jobausfuehrung pruefen 9410: A9 00 LDA #$00 9412: 20 22 94 JSR $9422 Pufferzeiger auf 0 setzen Einsprung von $9418: 9415: 20 B1 8E JSR $8EB1 Puffer mit $00 fuellen 9418: D0 FB BNE $9415 (z=1: Puffer voll) 941A: 20 B1 8E JSR $8EB1 Kennzeichen fuer 'letzter Sektor' 941D: A9 FF LDA #$FF und aktuelle Blocklaenge setzen 941F: 4C B1 8E JMP $8EB1 [Die ist im Directory immer 255.] Pufferzeiger auf bestimmten Wert setzen ($d4c8) E: a : neuer Pufferzeiger $50: Kanalnummer Einsprung von $8486, $871B, $8855, $8873, $88EB, $8B76, $8BBE, $911D, $9135, $9398, $93DD, $93FD, $9412, $9606, $97C1, $98E4, $9A5F, $9B84, $9C62, $9DD0, $9F7B, $9FCF, $A212, $A48A, $A4B7, $A4D5, $A526, $A556, $B187, $B2D2: 9422: 85 40 STA $40 Pufferzeiger Lo merken 9424: 20 11 9F JSR $9F11 Puffernummer holen 9427: 0A ASL 9428: AA TAX 9429: B5 BC LDA $BC,X Pufferzeiger Hi setzen 942B: 85 65 STA $65 942D: A5 40 LDA $40 Pufferzeiger Lo setzen 942F: 95 BB STA $BB,X 9431: 85 64 STA $64 9433: 60 RTS interne Schreib-/Lesekanaele freigeben ($d4da) Einsprung von $806E, $9968, $A7FE: 9434: A9 11 LDA #$11 Lesekanal der SA 17 9436: 85 52 STA $52 9438: 20 9E 91 JSR $919E freigeben 943B: A9 12 LDA #$12 Schreibkanal der SA 18 943D: 85 52 STA $52 943F: 4C 9E 91 JMP $919E freigeben ---------------------------------- Pufferzeiger des aktiven Puffers holen ($d4e8) E: $50 : Kanalnummer A: $64-$65: Pufferzeiger a : Pufferzeiger Lo ---------------------------------- Einsprung von $844F, $8564, $8BB1, $8E9D, $913A, $9370, $9A34, $9A40, $9F69, $A113, $A13A: 9442: 20 11 9F JSR $9F11 Aktiven Puffer holen Einsprung von $9E7A: 9445: 0A ASL <-- Zeiger des Puffers a holen 9446: AA TAX 9447: B5 BC LDA $BC,X Pufferzeiger nach $64-$65 9449: 85 65 STA $65 944B: B5 BB LDA $BB,X 944D: 85 64 STA $64 944F: 60 RTS Holt Byte aus aktuellem Puffer ($d4f6) E: a : Position im Puffer $50: aktuelle Kanalnummer A: a : Byte aus Puffer Einsprung von $8449, $9F8F, $A37C: 9450: 85 42 STA $42 Index in Puffer 9452: 20 11 9F JSR $9F11 aktuellen Puffer holen 9455: AA TAX 9456: BD F1 01 LDA $01F1,X Hi-Byte der Pufferadresse holen 9459: 85 43 STA $43 945B: A0 00 LDY #$00 Byte aus Puffer holen 945D: B1 42 LDA ($42),Y 945F: 60 RTS Prueft auf Diskettenwechsel und stellt ggf. das 1581-Format ein Einsprung von $FF69: 9460: A9 01 LDA #$01 Diskettenwechsel ? 9462: 24 25 BIT $25 9464: F0 0A BEQ $9470 nein, ==> 9466: 49 01 EOR #$01 Flag loeschen 9468: 85 25 STA $25 946A: 20 CF B0 JSR $B0CF Physikalisches 1581-Format einstellen 946D: 4C B3 B0 JMP $B0B3 Ganze Diskette als Partition setzen Einsprung von $9464: 9470: 60 RTS T&S auf Gueltigkeit pruefen ($d506) ggf. Formatkennzeichen pruefen, Jobcode setzen und Controller aufrufen E: x : Puffernummer $28: Jobcode Einsprung von $900A, $9DCB: 9471: A5 28 LDA $28 Zwischenspeicher fuer Jobcode merken Einsprung von $94EA: 9473: 48 PHA 9474: 86 6C STX $6C aktuelle Puffernummer merken 9476: 2C A8 02 BIT $02A8 b6=1: T&S Pruefung abgeschaltet ? 9479: 70 58 BVS $94D3 ja, ==> 947B: 8A TXA Index fuer 16-Bit Tabelle berechnen 947C: 0A ASL 947D: AA TAX 947E: B5 0C LDA $0C,X Sektornummer merken 9480: 85 28 STA $28 9482: B5 0B LDA $0B,X Tracknummer 9484: F0 1A BEQ $94A0 = 0 ? ja, (Fehler) ==> 9486: CD 2C 02 CMP $022C > letzter Track der Partition ? 9489: B0 15 BCS $94A0 ja, (Fehler) ==> 948B: 68 PLA Jobcode holen 948C: 48 PHA 948D: C9 90 CMP #$90 'Schreiben' ? 948F: D0 42 BNE $94D3 nein, ==> [Anscheinend wird die Sektor- nummer nur bei Schreibjobs geprueft ?!] 9491: A5 6F LDA $6F Formatkennzeichen 9493: CD EB 01 CMP $01EB = 1581-Formatkennzeichen ? 9496: D0 33 BNE $94CB nein, ==> 9498: A5 75 LDA $75 Anzahl der Sektoren pro Track 949A: C5 28 CMP $28 mit Sektornummer vergleichen 949C: F0 02 BEQ $94A0 gleich, dann Fehler ==> 949E: B0 33 BCS $94D3 groesser, dann Ok. ==> Einsprung von $9484, $9489, $949C: 94A0: 20 A8 94 JSR $94A8 T&S aus Jobpuffer holen Einsprung von $94B7, $94BC, $94C0, $94C6, $94C8: 94A3: A9 66 LDA #$66 66, Illegal Track or Sector 94A5: 4C 3F FF JMP $FF3F Track und Sektor aus Jobpuffer holen und als aktuelle T&S merken ($d552) E: $6c : Puffernummer a: $4d, $4e: T&S aus dem Jobpuffer Einsprung von $94A0, $94CB: 94A8: A5 6C LDA $6C Puffernummer 94AA: 0A ASL * 2 94AB: AA TAX 94AC: B5 0B LDA $0B,X T&S holen 94AE: 85 4D STA $4D 94B0: B5 0C LDA $0C,X 94B2: 85 4E STA $4E 94B4: 60 RTS Auf gueltigen Block (T&S) pruefen ($d55f) E: $4d,$4e: zu pruefende T&S Einsprung von $86CD, $8C3E, $B2C7, $B33C, $B7CA, $B81F, $B885, $B8A5: 94B5: A5 4D LDA $4D Spurnummer = 0 ? 94B7: F0 EA BEQ $94A3 94B9: CD 2C 02 CMP $022C oder >= Partition-Ende ? 94BC: B0 E5 BCS $94A3 94BE: C5 90 CMP $90 oder < Partition-Anfang ? 94C0: 90 E1 BCC $94A3 alles ungueltig, ==> 94C2: A5 75 LDA $75 Sektornummer 94C4: C5 4E CMP $4E >= max. Sektornummer ? 94C6: F0 DB BEQ $94A3 94C8: 90 D9 BCC $94A3 ja, ungueltig, ==> 94CA: 60 RTS T&S im gueltigen Bereich Meldung fuer falsches Formatkennzeichen ausgeben ($d572) Einsprung von $9496, $B38D: 94CB: 20 A8 94 JSR $94A8 T&S holen 94CE: A9 73 LDA #$73 73, Copyright CBM ... 94D0: 4C 3F FF JMP $FF3F Job setzen und Controller aufrufen ($d57a) Aufruf mit JMP E: $6c: Puffernummer PHA: Jobcode Einsprung von $9479, $948F, $949E: 94D3: A6 6C LDX $6C Puffernummer holen 94D5: 68 PLA 94D6: 85 28 STA $28 Jobcode abspeichern 94D8: 9D 72 02 STA $0272,X 94DB: 4C 9D 95 JMP $959D Controller aufrufen Schreib-/Lesejobs pruefen und Durchfuehrung abwarten ($d586) E: $6c: Puffernummer Einsprung von $8F24, $B602, $B60C, $B63D: 94DE: A9 80 LDA #$80 <-- Lesejobs 94E0: D0 02 BNE $94E4 Einsprung von $B61D, $B627: 94E2: A9 90 LDA #$90 <-- Schreibjobs <-- sonstige Jobs (Jobcode in a) Einsprung von $94E0, $8EF3, $A59E, $A5F6: 94E4: A6 6C LDX $6C Puffernummer holen Einsprung von $9B04: 94E6: 85 28 STA $28 Jobcode merken Einsprung von $93CC, $9E72: 94E8: A5 28 LDA $28 94EA: 20 73 94 JSR $9473 Job aufrufen und Ausfuehrung abwarten Einsprung von $8743, $88E3, $88FD, $8DA1, $8E34, $8FDC, $940D, $9A6C, $9B63, $9C55, $9C79, $9D36, $9FDA, $9FE8, $A41A, $A4BD, $A4F7, $A53B, $BFE0: 94ED: 20 F8 94 JSR $94F8 Job auf korrekte Durchfuehrung pruefen und ggf. Fehler behandeln 94F0: 48 PHA Jobrueckmeldung merken 94F1: A9 00 LDA #$00 Fehlerunterdrueckung aufheben 94F3: 8D A8 02 STA $02A8 94F6: 68 PLA Jobrueckmeldung zurueckholen 94F7: 60 RTS Job auf fehlerfreie Durchfuehrung pruefen ($d5a6) E: x: Puffernummer Test auf Fehler, bei denen mehrere Versuche keine Besserung bringen koennen Einsprung von $94ED: 94F8: 20 98 95 JSR $9598 Controller aufrufen 94FB: C9 02 CMP #$02 kein Fehler ? (0 oder 1) 94FD: 90 19 BCC $9518 ja, Ok. Ende ==> 94FF: C9 08 CMP #$08 Schreibschutzfehler ? 9501: F0 0C BEQ $950F ja, ==> 9503: C9 0B CMP #$0B Falsche ID ? 9505: F0 08 BEQ $950F ja, ==> 9507: C9 03 CMP #$03 keine Adressmarke gefunden ? 9509: F0 04 BEQ $950F ja, ==> 950B: C9 0F CMP #$0F keine Diskette eingelegt ? 950D: D0 0B BNE $951A nein, ==> Einsprung von $9501, $9505, $9509: 950F: 24 81 BIT $81 Burst-Fehlerunterdrueckung ? 9511: 30 05 BMI $9518 ja, ==> 9513: 2C A8 02 BIT $02A8 DOS-Fehlerunterdrueckung ? 9516: 10 17 BPL $952F nein, ==> Einsprung von $94FD, $9511: 9518: 18 CLC ja: Fehler kommentarlos hinnehmen 9519: 60 RTS Mehrere Leseversuche unternehmen, ggf. Spur 0 anfahren Einsprung von $950D: 951A: 98 TYA 951B: 48 PHA 951C: 20 64 95 JSR $9564 Mehrere Versuche durchfuehren 951F: C9 02 CMP #$02 kein Fehler mehr ? 9521: 90 37 BCC $955A ja, ==> 9523: 24 30 BIT $30 b7=0: Kopf auf Spur 0 fahren ? 9525: 10 12 BPL $9539 ja, ==> Einsprung von $954D: 9527: 68 PLA Stack restaurieren [enthielt ein gerettetes y-Reg. Der Wert hat nichts mit Jobcodes zu tun, trotzdem 9528: C9 90 CMP #$90 wird mit $90: Jobcode zum Schreiben ver- 952A: D0 03 BNE $952F glichen - ein Fehler bei der Veraenderung 952C: 9D 72 02 STA $0272,X des 1541-DOS; wird bei der 1581 aber sowieso nicht mehr benoetigt] Einsprung von $9516, $952A, $955C, $C015: 952F: A9 00 LDA #$00 Fehlerpruefung einschalten 9531: 8D A8 02 STA $02A8 [Fehlerunterdrueckung wird nicht beachtet !] 9534: B5 02 LDA $02,X Fehlernummer holen 9536: 20 2D FF JSR $FF2D Error-Routine des Controllers Kopf auf Spur 0 fahren und Job nochmal probieren Einsprung von $9525: 9539: 24 81 BIT $81 Burst-Fehlerunterdrueckung ? 953B: 30 21 BMI $955E ja, ==> 953D: 2C A8 02 BIT $02A8 DOS-Fehlerunterdrueckung ? 9540: 30 1C BMI $955E ja, ==> 9542: 48 PHA a enthaelt letzte Job-RoeCK-meldung 9543: A9 C0 LDA #$C0 RESTORE_DV 9545: 20 9D 95 JSR $959D Aufruf des Controllers 9548: 20 64 95 JSR $9564 Schreib-/Lesejob ausfuehren 954B: C9 02 CMP #$02 Fehler ? 954D: B0 D8 BCS $9527 ja, ==> 954F: 68 PLA vorletzte Job-RoeCK-meldung holen 9550: C9 90 CMP #$90 (ist immer < $10) 9552: D0 0A BNE $955E also immer ==> 9554: 9D 72 02 STA $0272,X wird nie aufgerufen 9557: 20 64 95 JSR $9564 " Einsprung von $9521: 955A: C9 02 CMP #$02 " 955C: B0 D1 BCS $952F " Einsprung von $953B, $9540, $9552: 955E: 68 PLA y-Register zurueckholen 955F: A8 TAY 9560: B5 02 LDA $02,X Jobrueckmeldung holen 9562: 18 CLC Ok. Ende 9563: 60 RTS mehrere Schreib-/Leseversuche ausfuehren Einsprung von $951C, $9548, $9557: 9564: A5 30 LDA $30 Anzahl der Leseversuche nach y 9566: 29 3F AND #$3F 9568: A8 TAY Einsprung von $957A, $C023: 9569: A5 79 LDA $79 LED-Blinken aktivieren 956B: 09 20 ORA #$20 956D: 85 79 STA $79 956F: BD 72 02 LDA $0272,X Jobcode holen 9572: 20 9D 95 JSR $959D Job nochmals ausfuehren 9575: C9 02 CMP #$02 Fehler 9577: 90 03 BCC $957C nein, => 9579: 88 DEY naechster Versuch ? 957A: D0 ED BNE $9569 ja, ==> Einsprung von $9577: 957C: 48 PHA Jobrueckmeldung merken 957D: A5 79 LDA $79 LED-Blinken aus 957F: 29 DF AND #$DF 9581: 85 79 STA $79 9583: 68 PLA Jobrueckmeldung in A 9584: 60 RTS T&S an DC uebergeben ($d6d0) E: $50: Kanalnummer Einsprung von $8FD6, $8FF5, $9130, $9BCB, $9DB8, $A397, $A3A9: 9585: 20 11 9F JSR $9F11 Puffernummer holen Einsprung von $874E, $8EEE, $93C7, $9B5D, $9C19, $9E6D, $A59A, $A5F1, $B64C, $BDD3, $BFF3: 9588: 0A ASL <-- a: Puffernummer 9589: A8 TAY 958A: A5 4D LDA $4D T&S in entsprechenden 958C: 99 0B 00 STA $000B,Y Jobspeicher schreiben 958F: A5 4E LDA $4E 9591: 99 0C 00 STA $000C,Y 9594: A9 00 LDA #$00 9596: AA TAX 9597: 60 RTS Aufruf des Controllers A: a: Jobrueckmeldung E: x: Puffernummer Einsprung von $94F8: 9598: 08 PHP <-- i-Flag retten 9599: 58 CLI i-Flag loeschen 959A: 4C A1 95 JMP $95A1 E: a: Jobcode x: Puffernummer Einsprung von $8756, $8761, $8EFB, $94DB, $9545, $9572, $B0A2, $B0AB, $BCDE, $BDD8, $BDDD, $BE26, $BE3A, $BE3F, $BE4E, $BF2A, $BF56, $BFBB, $BFDD, $DBF4, $DBFD, $FF54: 959D: 08 PHP <-- i-Flag retten 959E: 58 CLI i-Flag loeschen 959F: 95 02 STA $02,X Jobcode fuer Puffer x setzen Einsprung von $959A: 95A1: 00 BRK Jobschleife aufrufen 95A2: EA NOP [BRK ist ein 2-Byte-Befehl!] Einsprung von $95A5: 95A3: B5 02 LDA $02,X warten, bis Controller fertig ist 95A5: 30 FC BMI $95A3 95A7: 28 PLP i-Flag zurueckholen 95A8: B5 02 LDA $02,X Status lesen 95AA: 60 RTS Neue Datei im Directory eintragen ($d6e4) Einsprung von $87FA, $9893, $B89F: 95AB: A5 52 LDA $52 aktuelle SA und 95AD: 48 PHA 95AE: A5 50 LDA $50 aktuelle Kanalnummer merken 95B0: 48 PHA freien Eintrag suchen 95B1: A5 4E LDA $4E aktuelle T&S merken 95B3: 48 PHA 95B4: A5 4D LDA $4D 95B6: 48 PHA 95B7: A9 11 LDA #$11 internen Lesekanal oeffnen, 95B9: 85 52 STA $52 aktuellen Puffer holen und 95BB: 20 79 9D JSR $9D79 T&S des geladenen Blocks holen 95BE: AD 2D 02 LDA $022D aktuellen Dateityp merken 95C1: 48 PHA 95C2: A6 6C LDX $6C Puffernummer 95C4: A5 EF LDA $EF Drivenummer des Files 95C6: 5D 72 02 EOR $0272,X mit Drivenummer des Jobs vergleichen 95C9: 4A LSR 95CA: 90 0B BCC $95D7 gleich, ==> Das Verzeichnis des falschen Laufwerks ist geoeffnet 95CC: A2 01 LDX #$01 Flag: '1. freien Eintrag finden' setzen 95CE: 86 73 STX $73 95D0: 20 24 84 JSR $8424 und Eintrag suchen 95D3: F0 20 BEQ $95F5 keinen freier Eintrag, ==> 95D5: D0 2D BNE $9604 Das richtige Verzeichnis ist geoeffnet Einsprung von $95CA: 95D7: A5 72 LDA $72 1. Dir-Block mit freiem Eintrag 95D9: F0 11 BEQ $95EC noch nicht gefunden ?, ==> 95DB: C5 4E CMP $4E ist der Block bereits geladen ? 95DD: F0 25 BEQ $9604 ja, ==> 95DF: 85 4E STA $4E 95E1: 20 BD 93 JSR $93BD Dir-Block in den aktuellen Puffer einlesen 95E4: 4C 04 96 JMP $9604 Einsprung von $95FC: 95E7: A9 72 LDA #$72 72, Disk full 95E9: 20 7C 80 JSR $807C Einsprung von $95D9: 95EC: A9 01 LDA #$01 Flag: '1. freien Eintrag finden' setzen 95EE: 85 73 STA $73 95F0: 20 89 84 JSR $8489 und Suche fortsetzen 95F3: D0 0F BNE $9604 freien Eintrag gefunden, ==> Im Directory ist kein Eintrag mehr frei, Directory erweitern Einsprung von $95D3: 95F5: 20 E7 93 JSR $93E7 neuen Dir-Block anhaengen 95F8: A5 4E LDA $4E Sektornummer < 3 ? 95FA: C9 03 CMP #$03 95FC: 90 E9 BCC $95E7 ja, (Direktory ist voll) ==> 95FE: 85 72 STA $72 1. Eintrag des neuen Blocks fuer den 9600: A9 02 LDA #$02 Filenamen verwenden (beginnt hinter der 9602: 85 73 STA $73 Blockverkettung) File im Directory an der freien Stelle eintragen Einsprung von $95D5, $95DD, $95E4, $95F3: 9604: A5 73 LDA $73 Pufferzeiger auf den freien Eintrag setzen 9606: 20 22 94 JSR $9422 9609: 68 PLA Aktuellen Dateityp zurueckholen 960A: 8D 2D 02 STA $022D 960D: C9 04 CMP #$04 Dateityp = REL-Datei ? 960F: D0 02 BNE $9613 nein, ==> 9611: 09 80 ORA #$80 Flag: 'Datei geschlossen' setzen Einsprung von $960F: 9613: 20 B1 8E JSR $8EB1 Dateityp in Puffer schreiben 9616: 68 PLA 9617: 8D 97 02 STA $0297 T&S merken 961A: 20 B1 8E JSR $8EB1 und in Puffer schreiben 961D: 68 PLA 961E: 8D 9C 02 STA $029C 9621: 20 B1 8E JSR $8EB1 9624: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen 9627: A8 TAY 9628: AD 91 02 LDA $0291 Position des Filenamens holen 962B: AA TAX 962C: A9 10 LDA #$10 Maximale Filenamenlaenge setzen 962E: 20 EE 84 JSR $84EE Filenamen in Puffer kopieren 9631: A0 10 LDY #$10 9633: A9 00 LDA #$00 Rest des Eintrags (11 Bytes) loeschen Einsprung von $963A: 9635: 91 64 STA ($64),Y [$64 zeigt auf das 3. Byte des Eintrages; 9637: C8 INY y= 16..27 - Also werden die Bytes 19-29 9638: C0 1B CPY #$1B geloescht.] 963A: 90 F9 BCC $9635 963C: AD 2D 02 LDA $022D Dateityp = REL-Datei ? 963F: C9 04 CMP #$04 9641: D0 13 BNE $9656 nein, ==> 9643: A0 10 LDY #$10 9645: AD 70 02 LDA $0270 T&S des (Super-)Side-Sektors eintragen 9648: 91 64 STA ($64),Y 964A: C8 INY 964B: AD 71 02 LDA $0271 964E: 91 64 STA ($64),Y 9650: C8 INY 9651: AD 6F 02 LDA $026F Datensatzlaenge eintragen 9654: 91 64 STA ($64),Y Einsprung von $9641: 9656: 20 C1 93 JSR $93C1 Puffer schreiben 9659: 68 PLA 965A: 85 50 STA $50 Kanalnummer und 965C: AA TAX 965D: 68 PLA 965E: 85 52 STA $52 SA zurueckholen T&S des Eintrages dem Kanal und der Dateitabelle zuordnen 9660: A5 72 LDA $72 Dir-Block merken 9662: 85 E5 STA $E5 9664: 9D 7D 02 STA $027D,X 9667: A5 73 LDA $73 Position im Dir-Block merken 9669: 85 EA STA $EA 966B: 9D 84 02 STA $0284,X 966E: AD 2D 02 LDA $022D Dateityp merken 9671: 85 F4 STA $F4 9673: A9 00 LDA #$00 Drivenummer (immer 0) merken 9675: 85 EF STA $EF 9677: 60 RTS Datei mit SA 0-14 oeffnen ($d7b4) Geoeffnet werden: - 'normale' Dateien im Zweipuffer-Betrieb, - '*' (alte Datei), - '@' (Save & Replace), - Append und Modify werden unterstuetzt - relative Dateien, - Direktory ('$') mit und ohne Formatierung, - Direktzugriffe ('#'). Einsprung von $8015: 9678: A5 52 LDA $52 SA merken 967A: 85 7A STA $7A 967C: 20 65 81 JSR $8165 Kommandozeilenende feststellen 967F: 8E 2A 02 STX $022A und merken letzte Datei wieder oeffnen ? 9682: AE 00 02 LDX $0200 1. Zeichen aus der Kommandozeile holen 9685: A5 7A LDA $7A SA holen 9687: D0 27 BNE $96B0 SA<>0, ==> 9689: E0 2A CPX #$2A ist 1. Zeichen ein '*' ? 968B: D0 23 BNE $96B0 nein, ==> 968D: A5 4C LDA $4C Starttrack der Datei holen 968F: F0 45 BEQ $96D6 keine Datei gespeichert, ==> 9691: 85 4D STA $4D 9693: A9 00 LDA #$00 Drivenummer setzen 9695: 85 EF STA $EF 9697: A9 02 LDA #$02 Dateityp auf PRG setzen 9699: 85 F4 STA $F4 969B: AD 8B 02 LDA $028B Startsektor setzen 969E: 85 4E STA $4E 96A0: 20 F6 81 JSR $81F6 Drive-LED einschalten 96A3: 20 0D 9B JSR $9B0D Kanal suchen, 1. Block lesen 96A6: A9 04 LDA #$04 Dateityp auf PRG setzen Einsprung von $96CC: 96A8: A6 50 LDX $50 96AA: 99 F9 00 STA $00F9,Y 96AD: 4C 4C 80 JMP $804C Directory oeffnen Einsprung von $9687, $968B: 96B0: E0 24 CPX #$24 Directory oeffnen ? 96B2: D0 1B BNE $96CF nein, ==> 96B4: A5 7A LDA $7A SA>0 ? 96B6: D0 03 BNE $96BB ja, ==> 96B8: 4C F7 98 JMP $98F7 Directory ausgeben Verzeichnis unformatiert ausgeben Einsprung von $96B6: 96BB: 20 85 80 JSR $8085 Drivenummer suchen, Drive-LED einschalten 96BE: AD 2B 02 LDA $022B T&S des Verzeichnisheaders 96C1: 85 4D STA $4D als Dateianfang setzen 96C3: A9 00 LDA #$00 96C5: 85 4E STA $4E 96C7: 20 0D 9B JSR $9B0D Kanal suchen, 1. Block lesen 96CA: A9 02 LDA #$02 Dateityp auf SEQ setzen 96CC: 4C A8 96 JMP $96A8 Direktzugriffskanal oeffnen Einsprung von $96B2: 96CF: E0 23 cpx #'# Filename ='#23? 96D1: D0 0B BNE $96DE nein, ==> 96D3: 4C E4 89 JMP $89E4 Direktzugriffskanal oeffnen LOAD"*", wenn noch kein File vorher geoeffnet worden war Einsprung von $968F: 96D6: A9 02 LDA #$02 Dateityp auf PRG setzen 96D8: 8D 33 02 STA $0233 96DB: 20 03 8F JSR $8F03 Partition initialisieren Dateinamen und Zugriffsart feststellen; Datei suchen Einsprung von $96D1: 96DE: 20 99 80 JSR $8099 Eingabezeile bis zum ':' auswerten 96E1: D0 04 BNE $96E7 ':' gefunden, ==> 96E3: A2 00 LDX #$00 Anzahl gefundener Kommas = 0 96E5: F0 0C BEQ $96F3 immer, ==> Einsprung von $96E1: 96E7: 8A TXA Wurde vor dem ':' ein Komma gefunden ? 96E8: F0 05 BEQ $96EF nein, ==> 96EA: A9 30 LDA #$30 30, Syntax Error 96EC: 4C 7C 80 JMP $807C Einsprung von $96E8: 96EF: 88 DEY War der ':' das 1. Zeichen 96F0: F0 01 BEQ $96F3 (LOAD":xxx") ? ja, ==> 96F2: 88 DEY y -2: Position der Drivenummer Einsprung von $96E5, $96F0: 96F3: 8C 91 02 STY $0291 Position der Drivenummer merken 96F6: A9 8D LDA #$8D nach suchen 96F8: 20 1C 81 JSR $811C Rest der Befehlszeile auswerten 96FB: E8 INX x: Anzahl Kommas +1 = 96FC: 8E 2F 02 STX $022F Anzahl gefundener Parameter merken 96FF: 20 FD 81 JSR $81FD Laufwerksnummer holen 9702: 20 A2 82 JSR $82A2 Drive initialisieren, LED einschalten 9705: 20 ED 82 JSR $82ED Datei suchen 9708: A2 00 LDX #$00 970A: 8E 6F 02 STX $026F aktuelle Recordlaenge =0 970D: 8E A7 02 STX $02A7 Default Zugriffsmodus 9710: 8E 2D 02 STX $022D aktuellen Dateityp loeschen 9713: E8 INX x=1 9714: EC 2E 02 CPX $022E = Anzahl der Parameter ? 9717: B0 10 BCS $9729 ja, (open x,y,z,"BSP") ==> 9719: 20 AB 98 JSR $98AB Filetyp oder Zugriffsart holen 971C: E8 INX x=2 971D: EC 2E 02 CPX $022E = Anzahl der Parameter ? 9720: B0 07 BCS $9729 ja, (open x,y,z,"BSP,S" oder open x,y,z,"BSP,R") ==> 9722: C0 04 CPY #$04 Ist Parameter der Filetyp 'L' (REL-Datei) ? 9724: F0 38 BEQ $975E ja, ==> 9726: 20 AB 98 JSR $98AB Filetyp oder Zugriffsart holen (open x,y,z,"BSP,S,R") Einsprung von $9717, $9720, $976A, $9771: 9729: A6 7A LDX $7A SA zurueckholen 972B: 86 52 STX $52 972D: E0 02 CPX #$02 SA>=2 (also nicht LOAD/SAVE) ? 972F: B0 0D BCS $973E ja, ==> 9731: 8E A7 02 STX $02A7 Modus bei LOAD/SAVE durch die SA ermitteln 9734: AD 2D 02 LDA $022D Wurde ein Filetyp angegeben 9737: D0 1B BNE $9754 ja, ==> 9739: A9 02 LDA #$02 Filetyp PRG setzen 973B: 8D 2D 02 STA $022D Einsprung von $972F: 973E: AD 2D 02 LDA $022D Wurde bereits ein Filetyp festgelegt ? 9741: D0 11 BNE $9754 ja, ==> 9743: A5 F4 LDA $F4 Typ des gefundenen Files als aktuellen Typ 9745: 29 07 AND #$07 uebernehmen 9747: 8D 2D 02 STA $022D 974A: AD 97 02 LDA $0297 Tracknummer des 1. Blocks holen 974D: D0 05 BNE $9754 >0 (File wurde gefunden), ==> 974F: A9 01 LDA #$01 Filetyp SEQ festlegen (wenn kein File 9751: 8D 2D 02 STA $022D gefunden wurde, kann auch der Typ nicht uebernommen werden) Einsprung von $9737, $9741, $974D: 9754: AD A7 02 LDA $02A7 Zugriffsart 'Write' festgelegt ? 9757: C9 01 CMP #$01 9759: F0 18 BEQ $9773 ja, (File zum Schreiben oeffnen) ==> 975B: 4C ED 97 JMP $97ED File zum Lesen oeffnen REL-Datei oeffnen Einsprung von $9724: 975E: BC 91 02 LDY $0291,X Position des 3. Parameters holen 9761: B9 00 02 LDA $0200,Y Recordlaenge aus Kommandozeile holen 9764: 8D 6F 02 STA $026F und merken 9767: AD 97 02 LDA $0297 Tracknummer des 1. Blocks holen 976A: D0 BD BNE $9729 > 0 (REL-Datei gefunden), ==> 976C: A9 01 LDA #$01 Zugriffsart 'Schreiben' festlegen 976E: 8D A7 02 STA $02A7 (damit die Datei angelegt wird) 9771: D0 B6 BNE $9729 ==> File zum Schreiben oeffnen ($d8c6) Einsprung von $9759: 9773: A5 F4 LDA $F4 b7=1: Jokerflag gesetzt ? 9775: 29 80 AND #$80 (z.B.: SAVE"@:BEISP*",ga) 9777: AA TAX 9778: D0 14 BNE $978E ja, ==> 977A: A9 20 LDA #$20 b5=1: File nicht geschlossen ? 977C: 24 F4 BIT $F4 977E: F0 06 BEQ $9786 nein ==> [Ja: In diesem Fall existiert bereits ein File mit dem geforderten Namen, das aber nicht ordnungsgemaess geschlosen worden ist. Dieses muss erst geloescht werden, bevor das neue File angelegt wird.] 9780: 20 3B 87 JSR $873B altes File als geloescht kennzeichnen 9783: 4C 90 98 JMP $9890 neues File anlegen Einsprung von $977E: 9786: AD 97 02 LDA $0297 File bereits vorhanden (Tracknummer >0) ? 9789: D0 03 BNE $978E ja, ==> 978B: 4C 90 98 JMP $9890 neues File anlegen Einsprung von $9778, $9789: 978E: AD 00 02 LDA $0200 1. Zeichen aus Befehlszeile holen 9791: C9 40 CMP #$40 SAVE & REPLACE ? 9793: F0 0D BEQ $97A2 ja, ==> 9795: 8A TXA Jokerflag gesetzt (SAVE"BEISP*",ga) ? 9796: D0 05 BNE $979D ja, (Fehler) ==> 9798: A9 63 LDA #$63 63, FILE EXISTS 979A: 4C 7C 80 JMP $807C Einsprung von $9796: 979D: A9 33 LDA #$33 33, SYNTAX ERROR 979F: 4C 7C 80 JMP $807C DOS 4 Oeffnen eines Files mit Ueberschreiben ($d8f5) Einsprung von $9793: 97A2: A5 F4 LDA $F4 Dateityp des 1. Files holen 97A4: 29 07 AND #$07 (B0-2: Dateityp) 97A6: CD 2D 02 CMP $022D und mit Dateityp des gefundenen Files 97A9: D0 67 BNE $9812 vergleichen; ungleich ? ja, (Fehler) ==> 97AB: C9 04 CMP #$04 Ist es eine REL-Datei ? 97AD: F0 63 BEQ $9812 ja, ==> 97AF: 20 C3 9B JSR $9BC3 File zum Schreiben oeffnen 97B2: A5 50 LDA $50 Kanalnummer merken 97B4: 8D 8C 02 STA $028C 97B7: A9 11 LDA #$11 17: SA des internen Lesekanals 97B9: 85 52 STA $52 97BB: 20 27 90 JSR $9027 Kanal zum Lesen holen 97BE: AD 32 02 LDA $0232 Pufferzeiger auf den Dir-Eintrag setzen 97C1: 20 22 94 JSR $9422 97C4: A0 00 LDY #$00 97C6: B1 64 LDA ($64),Y 97C8: 09 20 ORA #$20 b5=1: Flag 'File wird ersetzt' im Directory 97CA: 91 64 STA ($64),Y setzen 97CC: A0 1A LDY #$1A 97CE: A5 4D LDA $4D T&S des neuen Files merken 97D0: 91 64 STA ($64),Y 97D2: C8 INY 97D3: A5 4E LDA $4E 97D5: 91 64 STA ($64),Y 97D7: AE 8C 02 LDX $028C Kanalnummer des Files holen 97DA: A5 E5 LDA $E5 Direktory-Block 97DC: 9D 7D 02 STA $027D,X merken 97DF: A5 EA LDA $EA Position des Fileeintrages im Dir-Block 97E1: 9D 84 02 STA $0284,X in Kanaltabelle merken 97E4: 20 79 9D JSR $9D79 T&S setzen 97E7: 20 C1 93 JSR $93C1 Directory-Block schreiben 97EA: 4C 96 98 JMP $9896 T&S des neuen Files merken ('*') Zugriffsart feststellen und File zum Lesen oeffnen ($d940) Einsprung von $975B: 97ED: AD 97 02 LDA $0297 Tracknummer des 1. Blocks holen 97F0: D0 05 BNE $97F7 > 0 (File gefunden) ? ja, ==> 97F2: A9 62 LDA #$62 62, File not found 97F4: 4C 7C 80 JMP $807C Einsprung von $97F0: 97F7: AD A7 02 LDA $02A7 Ist die Zugriffsart = 'M' (Modify) ? 97FA: C9 03 CMP #$03 97FC: F0 0B BEQ $9809 ja, ==> 97FE: A9 20 LDA #$20 b5=1: ist die Datei offen ? 9800: 24 F4 BIT $F4 9802: F0 05 BEQ $9809 nein, ==> 9804: A9 60 LDA #$60 60, Write File open 9806: 4C 7C 80 JMP $807C Einsprung von $97FC, $9802: 9809: A5 F4 LDA $F4 Typ der Datei 980B: 29 07 AND #$07 980D: CD 2D 02 CMP $022D = gesuchter Typ ? 9810: F0 05 BEQ $9817 ja, ==> Einsprung von $9825, $97A9, $97AD: 9812: A9 64 LDA #$64 64, File type mismatch 9814: 4C 7C 80 JMP $807C Einsprung von $9810: 9817: A0 00 LDY #$00 Anzahl der Dateinamen = 1 9819: 8C 30 02 STY $0230 981C: AE A7 02 LDX $02A7 Zugriffsart holen 981F: E0 02 CPX #$02 = Append ? 9821: D0 1A BNE $983D nein, ==> 9823: C9 04 CMP #$04 Filetyp = REL ? 9825: F0 EB BEQ $9812 ja, (Fehler) ==> 9827: B1 64 LDA ($64),Y b7=0: Flag 'File offen' im Directory setzen 9829: 29 4F AND #$4F 982B: 91 64 STA ($64),Y 982D: A5 52 LDA $52 aktuelle SA merken 982F: 48 PHA 9830: A9 11 LDA #$11 internen Lesekanal aktivieren 9832: 85 52 STA $52 9834: 20 79 9D JSR $9D79 T&S der aktuellen Datei holen 9837: 20 C1 93 JSR $93C1 Puffer schreiben 983A: 68 PLA 983B: 85 52 STA $52 SA zurueckholen Einsprung von $9821: 983D: 20 4D 98 JSR $984D File zum Lesen oeffnen 9840: AD A7 02 LDA $02A7 Zugriffsart 9843: C9 02 CMP #$02 = Append ? 9845: D0 4F BNE $9896 nein, ==> 9847: 20 CC 98 JSR $98CC Append-Befehl aufrufen 984A: 4C 4C 80 JMP $804C Oeffnen eines Files zum Lesen ($d9a0) Einsprung von $8867, $983D: 984D: A0 13 LDY #$13 984F: B1 64 LDA ($64),Y T&S des (Super-)Side-Sektors holen 9851: 8D 70 02 STA $0270 9854: C8 INY 9855: B1 64 LDA ($64),Y 9857: 8D 71 02 STA $0271 985A: C8 INY 985B: B1 64 LDA ($64),Y Recordlaenge holen 985D: AE 6F 02 LDX $026F 9860: 8D 6F 02 STA $026F und merken 9863: 8A TXA war eine Recordlaenge angegeben ? 9864: F0 0A BEQ $9870 nein, ==> 9866: CD 6F 02 CMP $026F Laengen gleich ? 9869: F0 05 BEQ $9870 ja, ==> 986B: A9 50 LDA #$50 986D: 20 7C 80 JSR $807C 50, Record not present ==> Einsprung von $9864, $9869: 9870: AE 30 02 LDX $0230 aktuelle Filenummer 9873: BD 97 02 LDA $0297,X T&S des 1. Datenblocks holen 9876: 85 4D STA $4D (stehen bereits in der Filetabelle) 9878: BD 9C 02 LDA $029C,X 987B: 85 4E STA $4E 987D: 20 0D 9B JSR $9B0D 1.Block (+ Side-Sektor) lesen 9880: A4 50 LDY $50 Kanalnummer und 9882: AE 30 02 LDX $0230 Dateinamen-Nummer holen 9885: B5 E5 LDA $E5,X Position des Eintrages im Directory fuer 9887: 99 7D 02 STA $027D,Y aktuellen Kanal merken 988A: B5 EA LDA $EA,X und Dir-Block des Eintrages merken 988C: 99 84 02 STA $0284,Y 988F: 60 RTS neues File anlegen und zum Schreiben oeffnen ($d9e3) Einsprung von $9783, $978B: 9890: 20 C3 9B JSR $9BC3 File anlegen und zum Schreiben oeffnen 9893: 20 AB 95 JSR $95AB Datei im Directory eintragen T&S eines Files holen und fuer 'LOAD "*",8' merken ($d9ef) Einsprung von $97EA, $9845: 9896: A5 52 LDA $52 Aktuelle SA >= 2 ? 9898: C9 02 CMP #$02 989A: B0 0C BCS $98A8 ja, (T&S nicht merken) ==> 989C: 20 7C 9D JSR $9D7C T&S holen 989F: A5 4D LDA $4D Track 98A1: 85 4C STA $4C 98A3: A5 4E LDA $4E & Sektor 98A5: 8D 8B 02 STA $028B als letztes benutztes File merken Einsprung von $989A: 98A8: 4C 50 80 JMP $8050 Status bereitstellen File-Modus oder File-Typ aus Kommandozeile holen ($da09) E: x: Nummer des Parameters in Eingabezeile Einsprung von $9719, $9726: 98AB: BC 91 02 LDY $0291,X Position des Parameters holen 98AE: B9 00 02 LDA $0200,Y 1. Zeichen des Parameters holen 98B1: A0 04 LDY #$04 auf Zugriffsart testen Einsprung von $98B9: 98B3: 88 DEY 98B4: 30 08 BMI $98BE nicht gefunden, ==> 98B6: D9 A1 DB CMP $DBA1,Y mit den Zugriffsarten vergleichen 98B9: D0 F8 BNE $98B3 ungleich, ==> 98BB: 8C A7 02 STY $02A7 aktuelle Zugriffsart setzen Einsprung von $98B4: 98BE: A0 06 LDY #$06 auf Filetyp testen Einsprung von $98C6: 98C0: 88 DEY 98C1: 30 08 BMI $98CB nicht gefunden, ==> 98C3: D9 A5 DB CMP $DBA5,Y mit den Filetypen vergleichen 98C6: D0 F8 BNE $98C0 ungleich, ==> 98C8: 8C 2D 02 STY $022D aktuellen Filetyp setzen Einsprung von $98C1: 98CB: 60 RTS APPEND: Fileende suchen und auf Schreiben umschalten ($da2a) Einsprung von $98D4, $87E3, $9847: 98CC: 20 7A 88 JSR $887A Byte aus aktuellem File holen 98CF: A9 80 LDA #$80 98D1: 20 E4 9C JSR $9CE4 Status testen 98D4: F0 F6 BEQ $98CC noch kein Fileende, ==> 98D6: 20 CE 9D JSR $9DCE Blocklaenge holen 98D9: A6 4E LDX $4E 98DB: E8 INX +1 (1. unbenutztes Byte) 98DC: 8A TXA 98DD: D0 05 BNE $98E4 <>0, (Block noch nicht voll) ==> 98DF: 20 18 91 JSR $9118 neuen Folgeblock suchen 98E2: A9 02 LDA #$02 Pufferzeiger auf 2 setzen Einsprung von $98DD: 98E4: 20 22 94 JSR $9422 98E7: A6 50 LDX $50 98E9: A9 01 LDA #$01 auf Schreiben umschalten 98EB: 9D 34 02 STA $0234,X Kanalstatus setzen 98EE: A9 80 LDA #$80 98F0: 05 50 ORA $50 Aktuelle Kanalnummer + Kennzeichen fuer 98F2: A6 52 LDX $52 Schreibkanal 98F4: 95 A8 STA $A8,X in Kanalnummertabelle ablegen 98F6: 60 RTS Oeffnen des Directory als Basicprogramm ($da55) Kommandozeile auswerten Einsprung von $96B8: 98F7: A9 0C LDA #$0C Befehlsnummer fuer 'Directory' setzen 98F9: 8D 2A 02 STA $022A 98FC: A9 00 LDA #$00 Default-Drivenummer = 0 98FE: A6 29 LDX $29 Laenge der Kommandozeile 9900: CA DEX =1 ? 9901: F0 0B BEQ $990E ja (load"$"), ==> 9903: CA DEX =2 ? 9904: D0 21 BNE $9927 nein, (load"$d:xx*=y") ==> 9906: AD 01 02 LDA $0201 Drivenummer aus Kommandozeile holen 9909: 20 95 82 JSR $8295 und pruefen 990C: 30 19 BMI $9927 keine Drivenummer gefunden, ==> Einsprung von $9901: 990E: 85 EF STA $EF Drivenummer merken 9910: EE 2E 02 INC $022E Anzahl Parameter =1 ('*') 9913: EE 2F 02 INC $022F Anzahl Parameter vor '=' =1 ('*') 9916: EE 91 02 INC $0291 Position des 1. Parameters =1 9919: A9 80 LDA #$80 Jokerflag setzen 991B: 85 F4 STA $F4 (alle Files anzeigen) 991D: A9 2A LDA #$2A 991F: 8D 00 02 STA $0200 '*' als Suchmaske setzen 9922: 8D 01 02 STA $0201 9925: D0 18 BNE $993F immer ==> Einsprung von $9904, $990C: 9927: 20 99 80 JSR $8099 Zeile bis ':' auswerten 992A: D0 05 BNE $9931 ':' gefunden ? ja, ==> 992C: 20 AF 81 JSR $81AF Kommandozeilenparameter initialisieren 992F: A0 03 LDY #$03 Drivenummer bei '$0:' Einsprung von $992A: 9931: 88 DEY 9932: 88 DEY (moegliche) Position einer 9933: 8C 91 02 STY $0291 Drivenummer merken 9936: 20 B4 80 JSR $80B4 Kommandozeile auswerten 9939: 20 70 82 JSR $8270 gesuchten Dateityp feststellen 993C: 20 0B 82 JSR $820B Laufwerksnummern pruefen 1. Directory Ausgabepuffer fuellen Einsprung von $9925: 993F: 20 A2 82 JSR $82A2 Laufwerk initialisieren 9942: 20 27 86 JSR $8627 Disknamen in Dir-Zeilenpuffer schreiben 9945: 20 ED 82 JSR $82ED 1. Datei suchen 9948: 20 7C B1 JSR $B17C Ausgabepuffer fuellen 994B: 20 71 90 JSR $9071 Byte aus aktuellem Puffer fuer 994E: A6 50 LDX $50 Ausgabe bereitstellen 9950: 9D 3B 02 STA $023B,X 9953: A9 04 LDA #$04 Dateityp PRG, Drive 0 waehlen 9955: 95 F9 STA $F9,X 9957: A9 00 LDA #$00 Zeiger in Kommandozeile loeschen 9959: 85 CD STA $CD 995B: 60 RTS CLOSE-Routine: aktuelle Sekundaeradresse schliessen ($dac0) E: $50: SA der zu schliessenden Datei [Diese Routine wird aufgerufen, wenn ueber den BUS ein Close-Kommando kommt. Geschlossen werden: - 'normale' Dateien - REL-Dateien - Direktzugriffe - Directory Wenn die SA 15 angegeben wird, werden alle Dateien geschlossen. Veraenderte Puffer werden auf die Diskette geschrieben und die Directory- Eintraege ggf. aktualisiert.] Einsprung von $AC51: 995C: A5 52 LDA $52 Ist die aktuelle SA = 0 ? 995E: D0 0B BNE $996B nein, ==> 9960: A9 00 LDA #$00 Flag: 'Directory wird ausgegeben' loeschen 9962: 8D 6E 02 STA $026E 9965: 20 9E 91 JSR $919E SA schliessen Einsprung von $9976: 9968: 4C 34 94 JMP $9434 interne Kanaele freigeben ==> Einsprung von $995E: 996B: C9 0F CMP #$0F SA=15 (Kommandokanal) ? 996D: F0 17 BEQ $9986 ja, (alle Dateien schliessen) ==> 996F: 20 9F 99 JSR $999F Datei schliessen 9972: A5 52 LDA $52 SA < 2 ? 9974: C9 02 CMP #$02 9976: 90 F0 BCC $9968 ja, ==> 9978: AD AB 02 LDA $02AB Ist ein Fehler aufgetreten ? 997B: D0 06 BNE $9983 ja, ==> 997D: 20 15 B5 JSR $B515 BAM abspeichern 9980: 4C 4C 80 JMP $804C Einsprung von $997B: 9983: 4C 67 80 JMP $8067 Fehlermeldung ausgeben - Alle Dateien schliessen ($daec) Einsprung von $996D: 9986: A9 0E LDA #$0E Mit SA 14 beginnen 9988: 85 52 STA $52 und der Reihe nach alle Dateien schliessen Einsprung von $998F: 998A: 20 9F 99 JSR $999F 998D: C6 52 DEC $52 naechste SA anwaehlen 998F: 10 F9 BPL $998A noch nicht fertig, ==> 9991: AD AB 02 LDA $02AB Ist ein Fehler aufgetreten ? 9994: D0 06 BNE $999C Ja, ==> 9996: 20 15 B5 JSR $B515 BAM ggf. abspeichern 9999: 4C 4C 80 JMP $804C Ende, 00, Ok,00,00 Einsprung von $9994: 999C: 4C 67 80 JMP $8067 Fehlerblinken ==> Datei schliessen ($db02) E: $52: Sekundaeradresse der Datei Einsprung von $883E, $996F, $998A, $B8CC: 999F: A6 52 LDX $52 SA testen 99A1: B5 A8 LDA $A8,X ist ein Kanal zugeordnet ? 99A3: C9 FF CMP #$FF 99A5: D0 01 BNE $99A8 ja, ==> 99A7: 60 RTS Einsprung von $99A5: 99A8: 29 0F AND #$0F Kanalnummer isolieren 99AA: 85 50 STA $50 99AC: 20 5F 90 JSR $905F aktuellen Filetyp holen 99AF: C9 07 CMP #$07 Direktzugriff ? 99B1: F0 0F BEQ $99C2 ja, ==> 99B3: C9 04 CMP #$04 REL-Datei ? 99B5: F0 11 BEQ $99C8 ja, ==> 99B7: 20 42 90 JSR $9042 auf Schreibkanal testen 99BA: B0 09 BCS $99C5 kein Schreibkanal, ==> 99BC: 20 2A 9A JSR $9A2A letzten Block abspeichern 99BF: 20 72 9A JSR $9A72 Eintrag im Directory updaten Einsprung von $99B1: 99C2: 20 15 B5 JSR $B515 BAM abspeichern Einsprung von $99BA: 99C5: 4C 9E 91 JMP $919E SA freigeben REL-Datei schliessen Einsprung von $99B5: 99C8: 20 2E 9D JSR $9D2E ggf. Puffer schreiben 99CB: 20 7D 8D JSR $8D7D Puffer wechseln 99CE: 20 5C A1 JSR $A15C letzten Datenblock suchen 99D1: A6 69 LDX $69 letzte Side-Sektor-Nummer merken 99D3: 86 44 STX $44 99D5: 20 6E A5 JSR $A56E Super-Side-Sektor verwenden ? 99D8: F0 2B BEQ $9A05 ja, ==> Rel-Dateilaenge berechnen (ohne Super-Side-Sektoren) 99DA: E6 44 INC $44 letzte Side-Sektor-Nummer+1 = 99DC: A9 00 LDA #$00 Anzahl der Side-Sektoren 99DE: 85 41 STA $41 Dateilaenge = 0 99E0: 85 42 STA $42 99E2: A5 6A LDA $6A Position der T&S des letzten Datenblocks 99E4: 38 SEC im Side-Sektor 99E5: E9 0E SBC #$0E - 14 = 'Anzahl der Datenbloecke im letzten 99E7: 85 43 STA $43 Side-Sektor' * 2 99E9: 20 82 9E JSR $9E82 Laenge der REL-Datei berechnen 99EC: A6 50 LDX $50 99EE: A5 41 LDA $41 Dateilaenge in Kanaltabelle merken 99F0: 9D 49 02 STA $0249,X 99F3: A5 42 LDA $42 99F5: 9D 50 02 STA $0250,X Einsprung von $9A27: 99F8: A9 40 LDA #$40 b6=1: 'REL-Datei veraendert' ? 99FA: 20 E4 9C JSR $9CE4 Dateistatus testen 99FD: F0 03 BEQ $9A02 nein, ==> 99FF: 20 72 9A JSR $9A72 Directory updaten Einsprung von $99FD: 9A02: 4C 9E 91 JMP $919E SA freigeben Rel-Dateilaenge berechnen (mit Super-Side-Sektoren) Einsprung von $99D8: 9A05: A5 6A LDA $6A Position der T&S des letzten Datenblocks 9A07: 38 SEC im Side-Sektor 9A08: E9 0E SBC #$0E - 14 = 'Anzahl der Datenbloecke im letzten 9A0A: 85 43 STA $43 Side-Sektor' * 2 9A0C: AD 00 01 LDA $0100 letzte Gruppennummer merken 9A0F: 85 58 STA $58 9A11: 20 97 9E JSR $9E97 Laenge der REL-Datei berechnen 9A14: A2 00 LDX #$00 und + 2 nehmen 9A16: A9 02 LDA #$02 [1 Super-SS und der letzte (noch nicht 9A18: 20 CC 9E JSR $9ECC ganz gefuellte) SS] 9A1B: A6 50 LDX $50 Kanalnummer holen 9A1D: A5 5B LDA $5B Dateilaenge in Kanaltabelle merken 9A1F: 9D 49 02 STA $0249,X 9A22: A5 5C LDA $5C 9A24: 9D 50 02 STA $0250,X 9A27: 4C F8 99 JMP $99F8 Datei schliessen letzten Dateiblock abspeichern ($db62) Einsprung von $99BC: 9A2A: A6 50 LDX $50 Kanalnummer holen 9A2C: BD 49 02 LDA $0249,X aktuelle Programmlaenge > 0 ? 9A2F: 1D 50 02 ORA $0250,X 9A32: D0 0C BNE $9A40 ja, ==> 9A34: 20 42 94 JSR $9442 aktuellen Pufferzeiger holen 9A37: C9 02 CMP #$02 = Beginn des Datenbereichs (Block leer) ? 9A39: D0 05 BNE $9A40 nein, ==> [Die Datei ist absolut leer !!! Da die Mindest-Dateilaenge aber 1 Byte ist, wird die Datei um ein CR 'erweitert'.] 9A3B: A9 0D LDA #$0D ja: CR in Puffer schreiben 9A3D: 20 B1 8E JSR $8EB1 [Pufferzeiger = $03 !] Einsprung von $9A32, $9A39: 9A40: 20 42 94 JSR $9442 Pufferzeiger holen 9A43: C9 02 CMP #$02 Ist der Puffer noch leer ? 9A45: D0 12 BNE $9A59 nein, ==> [Der letzte Block wurde genau gefuellt. Deshalb muss der aktuelle Block wieder von der Datei 'abgezogen' werden.] 9A47: 20 7D 8D JSR $8D7D Puffer wechseln 9A4A: A6 50 LDX $50 9A4C: BD 49 02 LDA $0249,X Dateilaenge -1 9A4F: D0 03 BNE $9A54 [Eigentlich, so meint man, muesste der Block 9A51: DE 50 02 DEC $0250,X in der BAM auch freigegeben werden !?] Einsprung von $9A4F: 9A54: DE 49 02 DEC $0249,X 9A57: A9 00 LDA #$00 Pufferzeiger auf 256 setzen Einsprung von $9A45: 9A59: 38 SEC Pufferzeiger -1 (zeigt nun auf das letzte 9A5A: E9 01 SBC #$01 Datenbyte) 9A5C: 48 PHA merken 9A5D: A9 00 LDA #$00 Pufferzeiger auf die Blockverkettung setzen 9A5F: 20 22 94 JSR $9422 9A62: 20 B1 8E JSR $8EB1 $00: letzter Dateiblock in Puffer schreiben 9A65: 68 PLA Blocklaenge 9A66: 20 B1 8E JSR $8EB1 in Puffer schreiben 9A69: 20 02 90 JSR $9002 Block auf Diskette schreiben 9A6C: 20 ED 94 JSR $94ED Jobausfuehrung ueberwachen 9A6F: 4C 7D 8D JMP $8D7D Puffer wechseln Eintrag im Directory nach dem Schreiben updaten ($dba5) Einsprung von $99BF, $99FF: 9A72: A6 50 LDX $50 Kanalnummer der Datei merken 9A74: 8E 8C 02 STX $028C 9A77: A5 52 LDA $52 SA der Datei merken 9A79: 48 PHA entsprechenden Directory-Eintrag holen 9A7A: BD 7D 02 LDA $027D,X Dir-Block des Eintrages holen 9A7D: 85 4E STA $4E 9A7F: BD 84 02 LDA $0284,X Position des Eintrages im Block holen 9A82: 8D 32 02 STA $0232 9A85: AD 2B 02 LDA $022B Tracknummer des Directorys setzen 9A88: 85 4D STA $4D 9A8A: 20 11 9F JSR $9F11 aktuellen Puffer der Datei holen 9A8D: 48 PHA [Der Dir-Block wird in den Puffer der Datei 9A8E: 85 6C STA $6C gelesen, damit die Replace-Funktion den Scratch-Befehl verwenden kann.] 9A90: 20 BD 93 JSR $93BD Directory-Block lesen 9A93: A0 00 LDY #$00 9A95: BD F1 01 LDA $01F1,X Pufferadresse holen 9A98: 85 56 STA $56 und als Pufferzeiger Hi merken 9A9A: AD 32 02 LDA $0232 Position des Eintrages holen und als 9A9D: 85 55 STA $55 Pufferzeiger Lo merken 9A9F: B1 55 LDA ($55),Y Filetyp holen 9AA1: 29 20 AND #$20 b5=1: 'Datei wird ueberschrieben' ? 9AA3: F0 43 BEQ $9AE8 nein, ==> 9AA5: 20 5F 90 JSR $905F Filetyp des Kanals holen 9AA8: C9 04 CMP #$04 = REL-Datei ? 9AAA: F0 44 BEQ $9AF0 ja, ==> REPLACE-Funktion 9AAC: B1 55 LDA ($55),Y b5: Replace-Flag und b6: Scratch-Schutz 9AAE: 29 8F AND #$8F loeschen 9AB0: 91 55 STA ($55),Y 9AB2: C8 INY 9AB3: B1 55 LDA ($55),Y Tracknummer der alten Datei holen 9AB5: 85 4D STA $4D und merken 9AB7: 84 42 STY $42 9AB9: A0 1B LDY #$1B 9ABB: B1 55 LDA ($55),Y T&S der neuen Datei holen und merken 9ABD: 48 PHA (Sektornummer) 9ABE: 88 DEY 9ABF: B1 55 LDA ($55),Y Tracknummer = 0 ? 9AC1: D0 0A BNE $9ACD nein, ==> 9AC3: 85 4D STA $4D [Ja: in diesem Fall existiert gar keine 9AC5: 68 PLA neue Datei, also darf die alte nicht 9AC6: 85 4E STA $4E geloescht werden.] 9AC8: A9 67 LDA #$67 67, Illegal Track or Sector, 00, ss 9ACA: 20 3F FF JSR $FF3F ==> Einsprung von $9AC1: 9ACD: 48 PHA Tracknummer merken 9ACE: A9 00 LDA #$00 9AD0: 91 55 STA ($55),Y Replace-T&S-Zwischenspeicher loeschen 9AD2: C8 INY 9AD3: 91 55 STA ($55),Y 9AD5: 68 PLA 9AD6: A4 42 LDY $42 Tracknummer der neuen Datei als Dateianfang 9AD8: 91 55 STA ($55),Y merken 9ADA: C8 INY 9ADB: B1 55 LDA ($55),Y Sektornummer der alten Datei 9ADD: 85 4E STA $4E merken 9ADF: 68 PLA 9AE0: 91 55 STA ($55),Y und durch neue Sektornummer ersetzen 9AE2: 20 13 87 JSR $8713 alte Datei loeschen 9AE5: 4C F0 9A JMP $9AF0 Datei im Directory abschliessen Einsprung von $9AA3: 9AE8: B1 55 LDA ($55),Y Datei als 'ordnungsgemaess geschlossen' 9AEA: 29 0F AND #$0F kennzeichnen 9AEC: 09 80 ORA #$80 9AEE: 91 55 STA ($55),Y Einsprung von $9AAA, $9AE5: 9AF0: AE 8C 02 LDX $028C Nummer der Datei holen 9AF3: A0 1C LDY #$1C 9AF5: BD 49 02 LDA $0249,X Dateilaenge im Directory eintragen 9AF8: 91 55 STA ($55),Y 9AFA: C8 INY 9AFB: BD 50 02 LDA $0250,X 9AFE: 91 55 STA ($55),Y 9B00: 68 PLA 9B01: AA TAX 9B02: A9 90 LDA #$90 Jobcode fuer 'Sektor schreiben' 9B04: 20 E6 94 JSR $94E6 an DC uebergeben 9B07: 68 PLA 9B08: 85 52 STA $52 SA der Datei zurueckholen 9B0A: 4C 42 90 JMP $9042 SA freigeben Kanal zum Lesen suchen 1.Block und ggf. 1.Side-Sektor lesen ($dc46) E: $52 : benutzte Sekundaeradresse $4d- $4e: 1. Datenblock $0270-$0271: 1. (Super-)Side-Sektor Einsprung von $93D8, $96A3, $96C7, $987D: 9B0D: A9 01 LDA #$01 Lese-Kanal oeffnen 9B0F: 20 5A 91 JSR $915A und einen Puffer belegen 9B12: 20 9B 9B JSR $9B9B Pufferzeiger initialisieren 9B15: AD 2D 02 LDA $022D Filetyp merken 9B18: 48 PHA 9B19: 0A ASL b0=0: Drivenummer; b1-3: Filetyp 9B1A: 95 F9 STA $F9,X in Kanaltabelle eintragen 9B1C: 20 D6 8F JSR $8FD6 1. Block lesen 9B1F: A6 50 LDX $50 9B21: A5 4D LDA $4D existiert ein Folgeblock ? 9B23: D0 05 BNE $9B2A ja, ==> 9B25: A5 4E LDA $4E Blocklaenge merken 9B27: 9D 42 02 STA $0242,X Einsprung von $9B23: 9B2A: 68 PLA Filetyp holen 9B2B: C9 04 CMP #$04 Rel-Datei ? 9B2D: D0 5E BNE $9B8D nein, ==> 9B2F: A4 52 LDY $52 9B31: B9 A8 00 LDA $00A8,Y b6=1: Flag fuer Lesen/Schreiben setzen 9B34: 09 40 ORA #$40 9B36: 99 A8 00 STA $00A8,Y 9B39: AD 6F 02 LDA $026F 9B3C: 9D 5E 02 STA $025E,X Recordlaenge merken 9B3F: 20 04 92 JSR $9204 Puffer suchen 9B42: 10 03 BPL $9B47 gefunden, ==> 9B44: 4C 86 91 JMP $9186 70, No Channel Einsprung von $9B42: 9B47: A6 50 LDX $50 Puffer fuer Side-Sektoren merken 9B49: 9D 65 02 STA $0265,X 9B4C: 48 PHA 9B4D: 20 6E A5 JSR $A56E Super-Side-Sektor Modus gewaehlt ? 9B50: F0 17 BEQ $9B69 ja, ==> 9B52: 68 PLA 9B53: AC 70 02 LDY $0270 T&S des Side-Sektors setzen 9B56: 84 4D STY $4D 9B58: AC 71 02 LDY $0271 9B5B: 84 4E STY $4E 9B5D: 20 88 95 JSR $9588 T&S an DC uebergeben 9B60: 20 AC 9D JSR $9DAC Side-Sektor lesen 9B63: 20 ED 94 JSR $94ED Jobausfuehrung ueberpruefen 9B66: 4C 7B 9B JMP $9B7B Einsprung von $9B50: 9B69: 68 PLA 9B6A: AD 70 02 LDA $0270 T&S des Super-Side-Sektors merken 9B6D: 9D 10 01 STA $0110,X 9B70: AD 71 02 LDA $0271 9B73: 9D 09 01 STA $0109,X 9B76: A9 FF LDA #$FF 'keine Side-Sektor-Gruppe aktiv'-Flag 9B78: 9D 02 01 STA $0102,X setzen Einsprung von $9B66, $9C7F: 9B7B: A6 50 LDX $50 9B7D: A9 02 LDA #$02 'Zeiger auf naechsten Record' 9B7F: 9D 57 02 STA $0257,X auf 1. Record setzen 9B82: A9 00 LDA #$00 9B84: 20 22 94 JSR $9422 Pufferzeiger auf 0 setzen 9B87: 20 E1 A0 JSR $A0E1 1. Record lesen 9B8A: 4C 7C 9D JMP $9D7C T&S des aktiven Kanals holen 1. Byte aus der Datei fuer Ausgabe bereitstellen Einsprung von $9B2D: 9B8D: 20 9B 90 JSR $909B Byte aus aktueller Datei holen 9B90: A6 50 LDX $50 9B92: 9D 3B 02 STA $023B,X und in Ausgabepuffer schreiben 9B95: A9 88 LDA #$88 b3=1: EOI loeschen und 9B97: 9D 34 02 STA $0234,X b7=1: Datei auf Lesen festlegen 9B9A: 60 RTS Pufferzeiger initialisieren ($dcb6) Einsprung von $9B12, $9BCE: 9B9B: A6 50 LDX $50 9B9D: B5 D1 LDA $D1,X 1. Puffer holen 9B9F: 0A ASL ist Puffer belegt ? 9BA0: 30 06 BMI $9BA8 nein, (sollte nie ausgefuehrt werden) ==> 9BA2: A8 TAY 9BA3: A9 02 LDA #$02 Pufferzeiger auf Datenanfang setzen 9BA5: 99 BB 00 STA $00BB,Y Einsprung von $9BA0: 9BA8: B5 D8 LDA $D8,X 2.Puffer inaktiv setzen 9BAA: 09 80 ORA #$80 9BAC: 95 D8 STA $D8,X 9BAE: 0A ASL Puffer belegt ? 9BAF: 30 06 BMI $9BB7 nein, ==> 9BB1: A8 TAY 9BB2: A9 02 LDA #$02 Pufferzeiger auf Datenanfang setzen 9BB4: 99 BB 00 STA $00BB,Y Einsprung von $9BAF: 9BB7: A9 00 LDA #$00 9BB9: 9D 42 02 STA $0242,X Programmlaenge auf 0 setzen 9BBC: 9D 49 02 STA $0249,X 9BBF: 9D 50 02 STA $0250,X Blocklaenge loeschen: 9BC2: 60 RTS 0: noch nicht letzter Block File zum Schreiben oeffnen ($dcda) E: $52 : benutzte Sekundaeradresse A: $4d-$4e: Startblock Einsprung von $93E4, $97AF, $9890: 9BC3: 20 ED B6 JSR $B6ED Freien Block suchen und belegen Einsprung von $B89C: 9BC6: A9 01 LDA #$01 Schreibkanal suchen und 9BC8: 20 57 91 JSR $9157 einen Puffer belegen 9BCB: 20 85 95 JSR $9585 T&S an DC uebergeben 9BCE: 20 9B 9B JSR $9B9B Pufferzeiger initialisieren 9BD1: A6 50 LDX $50 9BD3: AD 2D 02 LDA $022D Aktuellen Dateityp 9BD6: 48 PHA merken 9BD7: 0A ASL b0=0: Drivenummer 9BD8: 95 F9 STA $F9,X b1-3: Dateityp 9BDA: 68 PLA 9BDB: C9 04 CMP #$04 REL-Datei ? 9BDD: F0 06 BEQ $9BE5 ja, ==> 9BDF: A9 01 LDA #$01 b1=1: Datei auf Schreiben festlegen 9BE1: 9D 34 02 STA $0234,X 9BE4: 60 RTS REL-Datei oeffnen Einsprung von $9BDD: 9BE5: A4 52 LDY $52 9BE7: B9 A8 00 LDA $00A8,Y Kanalnummer holen 9BEA: 29 3F AND #$3F b76=01: Lese- und Schreibzugriffe erlauben 9BEC: 09 40 ORA #$40 9BEE: 99 A8 00 STA $00A8,Y Kanalmodus setzen 9BF1: AD 6F 02 LDA $026F Recordlaenge fuer aktuellen Kanal merken 9BF4: 9D 5E 02 STA $025E,X 9BF7: 20 04 92 JSR $9204 Puffer suchen (fuer den Side-Sektor) 9BFA: 10 03 BPL $9BFF Puffer gefunden ? ja, ==> 9BFC: 4C 86 91 JMP $9186 70, No Channel 1. Side-Sektor erzeugen Einsprung von $9BFA: 9BFF: A6 50 LDX $50 9C01: 9D 65 02 STA $0265,X Side-Sektor-Puffer merken 9C04: 20 FA 9D JSR $9DFA Puffer loeschen 9C07: 20 68 B6 JSR $B668 freien Block suchen 9C0A: A5 4D LDA $4D 9C0C: 8D 70 02 STA $0270 und als ersten Side-Sektor merken 9C0F: A5 4E LDA $4E 9C11: 8D 71 02 STA $0271 9C14: A6 50 LDX $50 9C16: BD 65 02 LDA $0265,X Side-Sektor-Puffernummer holen 9C19: 20 88 95 JSR $9588 T&S an DC uebergeben 9C1C: A9 00 LDA #$00 Pufferzeiger des Side-Sektors auf 0 setzen 9C1E: 20 23 9E JSR $9E23 9C21: A9 00 LDA #$00 Byte 0 = 0: Letzter Side-Sektor 9C23: 20 CA 9C JSR $9CCA (Byte in Side-Sektor schreiben) 9C26: A9 11 LDA #$11 Anzahl gueltige Bytes = 17: 9C28: 20 CA 9C JSR $9CCA ein Datenblock vorhanden 9C2B: A9 00 LDA #$00 0 : Nummer des Side-Sektors 9C2D: 20 CA 9C JSR $9CCA Byte in Side-Sektor schreiben 9C30: AD 6F 02 LDA $026F Recordlaenge 9C33: 20 CA 9C JSR $9CCA 9C36: A5 4D LDA $4D T&S des ersten Side-Sektors 9C38: 20 CA 9C JSR $9CCA in Side-Sektor schreiben 9C3B: A5 4E LDA $4E 9C3D: 20 CA 9C JSR $9CCA 9C40: A9 10 LDA #$10 Zeiger auf 1. Datenblock-Verweis setzen 9C42: 20 23 9E JSR $9E23 9C45: 20 7C 9D JSR $9D7C T&S des aktiven Datenpuffers holen 9C48: A5 4D LDA $4D 9C4A: 20 CA 9C JSR $9CCA und in Side-Sektor schreiben 9C4D: A5 4E LDA $4E 9C4F: 20 CA 9C JSR $9CCA 9C52: 20 A6 9D JSR $9DA6 Side-Sektor schreiben 9C55: 20 ED 94 JSR $94ED Jobausfuehrung pruefen 9C58: 20 6E A5 JSR $A56E Super-Side-Sektor verwenden ? 9C5B: D0 03 BNE $9C60 nein, ==> 9C5D: 20 82 9C JSR $9C82 Super-Side-Sektor anlegen Einsprung von $9C5B: 9C60: A9 02 LDA #$02 9C62: 20 22 94 JSR $9422 Pufferzeiger auf Byte 2 setzen 9C65: A6 50 LDX $50 ersten Datenblock erzeugen [Man muss sich vorstellen, vor dem 1. Datensatz existiert ein 'Schein'- Datensatz, dessen Position so gewaehlt werden muss, dass beim Anhaengen eines Datensatzes dieser genau am Datenblock-Anfang erzeugt wird.] 9C67: 38 SEC Position des Schein-Datensatzes berechnen: 9C68: A9 00 LDA #$00 Von 0 (Blockanfang): 9C6A: FD 5E 02 SBC $025E,X Recordlaenge abziehen = Anfangsposition 9C6D: 9D 57 02 STA $0257,X des Schein-Datensatzes 9C70: 20 98 A2 JSR $A298 einen Datenblock voll 'leerer' Records an den Schein-Datensatz haengen. 9C73: 20 56 9D JSR $9D56 Blocklaenge setzen 9C76: 20 9A 9D JSR $9D9A Block schreiben 9C79: 20 ED 94 JSR $94ED Jobausfuehrung ueberpruefen 9C7C: 20 15 B5 JSR $B515 Bam ggf. abspeichern 9C7F: 4C 7B 9B JMP $9B7B Recordzeiger auf 1. Record setzen Super-Side-Sektor anlegen Einsprung von $9C5D: 9C82: A6 50 LDX $50 aktuellen Side-Sektor-Puffer holen 9C84: BD 65 02 LDA $0265,X 9C87: 20 FA 9D JSR $9DFA Puffer mit $00 fuellen 9C8A: 20 23 9E JSR $9E23 Side-Sektor-Pufferzeiger auf 0 9C8D: AD 70 02 LDA $0270 Blockverkettung des Super-Side-Sektors 9C90: 20 CA 9C JSR $9CCA auf 1. Side-Sektor setzen 9C93: AD 71 02 LDA $0271 9C96: 20 CA 9C JSR $9CCA 9C99: A9 FE LDA #$FE $fe: Kennzeichen des Super-Side-Sektors 9C9B: 20 CA 9C JSR $9CCA 9C9E: AD 70 02 LDA $0270 1. Side-Sektor in Gruppentabelle eintragen 9CA1: 20 CA 9C JSR $9CCA 9CA4: AD 71 02 LDA $0271 9CA7: 20 CA 9C JSR $9CCA 9CAA: 20 68 B6 JSR $B668 Folgeblock fuer Datei suchen 9CAD: A6 50 LDX $50 9CAF: A5 4D LDA $4D Als T&S des Super-Side-Sektors 9CB1: 9D 10 01 STA $0110,X des Kanals merken 9CB4: 8D 70 02 STA $0270 und als 1. Side-Sektor merken 9CB7: A5 4E LDA $4E [wird im Directory eingetragen] 9CB9: 9D 09 01 STA $0109,X 9CBC: 8D 71 02 STA $0271 9CBF: A9 FF LDA #$FF Flag: 'kein Side-Sektor geladen' setzen 9CC1: 9D 02 01 STA $0102,X 9CC4: 20 81 A5 JSR $A581 Super-Side-Sektor schreiben 9CC7: 4C 7C 9D JMP $9D7C T&S des Datenblocks holen Byte in aktuellen Side-Sektor schreiben ($dd8d) Einsprung von $9C23, $9C28, $9C2D, $9C33, $9C38, $9C3D, $9C4A, $9C4F, $9C90, $9C96, $9C9B, $9CA1, $9CA7, $A3D8, $A3DC, $A50C, $A510: 9CCA: 48 PHA Datenbyte merken 9CCB: A6 50 LDX $50 9CCD: BD 65 02 LDA $0265,X aktuellen Side-Sektor-Puffer holen 9CD0: 4C BD 8E JMP $8EBD Byte in Puffer schreiben Dateistatus setzen/loeschen ($dd95) 9CD3: 90 06 BCC $9CDB c=1: Status setzen Einsprung von $8891, $9F9B, $A020, $A08F, $A1F7, $A430: 9CD5: A6 50 LDX $50 <-- Status setzen 9CD7: 15 F9 ORA $F9,X alle 1-Bits werden gesetzt 9CD9: D0 06 BNE $9CE1 Einsprung von $9CD3, $8E6D, $9F4E, $9F84, $A075, $A1B5: 9CDB: A6 50 LDX $50 <-- Status loeschen 9CDD: 49 FF EOR #$FF alle 1-Bits werden geloescht 9CDF: 35 F9 AND $F9,X Einsprung von $9CD9: 9CE1: 95 F9 STA $F9,X 9CE3: 60 RTS Status testen Einsprung von $8824, $98D1, $99FA, $9F53, $A035, $A046, $A07D, $A0A8, $A202: 9CE4: A6 50 LDX $50 alle 1-Bits in a werden getestet 9CE6: 35 F9 AND $F9,X 9CE8: 60 RTS Prueft den Jobcode des aktuellen Puffers auf 'Schreiben' ($ddab) Einsprung von $8E02, $9FD2, $9FE0: 9CE9: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen 9CEC: AA TAX 9CED: BD 72 02 LDA $0272,X aktuellen Jobcode holen 9CF0: 29 FE AND #$FE Drivenummer entfernen 9CF2: C9 90 CMP #$90 'Schreiben' ? 9CF4: 60 RTS prueft, ob gesuchtes File durch eine SA angesprochen wird ($ddb7) Einsprung von $869A: 9CF5: A2 00 LDX #$00 mit SA = 0 anfangen Einsprung von $9D04: 9CF7: 86 42 STX $42 9CF9: B5 A8 LDA $A8,X ist ein Kanal zugeordnet ? 9CFB: C9 FF CMP #$FF 9CFD: D0 08 BNE $9D07 ja, ==> Einsprung von $9D1C, $9D23, $9D2A: 9CFF: A6 42 LDX $42 naechste SA probieren 9D01: E8 INX 9D02: E0 10 CPX #$10 wurde letzte SA getestet ? 9D04: 90 F1 BCC $9CF7 nein, ==> 9D06: 60 RTS c=1: File ist nicht geoeffnet Einsprung von $9CFD: 9D07: 86 42 STX $42 9D09: 29 3F AND #$3F Kanalnummer isolieren 9D0B: A8 TAY 9D0C: B9 F9 00 LDA $00F9,Y Drivenummer des Kanals holen 9D0F: 29 01 AND #$01 9D11: 85 41 STA $41 9D13: AE 6D 02 LDX $026D Nummer des gefundenen Files holen 9D16: B5 EF LDA $EF,X mit Drivenummer des Files vergleichen 9D18: 29 01 AND #$01 9D1A: C5 41 CMP $41 9D1C: D0 E1 BNE $9CFF ungleich, (nicht gefunden) ==> 9D1E: B9 7D 02 LDA $027D,Y Directory-Block des Kanals mit 9D21: D5 E5 CMP $E5,X Directory-Block des Files vergleichen 9D23: D0 DA BNE $9CFF ungleich, ==> 9D25: B9 84 02 LDA $0284,Y Position im Dir-Block des Kanals mit 9D28: D5 EA CMP $EA,X Position im Dir-Block des Files vergleichen 9D2A: D0 D3 BNE $9CFF ungleich, ==> 9D2C: 18 CLC 9D2D: 60 RTS c=0: File ist geoeffnet Puffer schreiben, wenn er veraendert wurde ($ddf1) Einsprung von $99C8, $A242, $A45F: 9D2E: 20 1C 9F JSR $9F1C Aktiven Puffer holen 9D31: 50 06 BVC $9D39 Puffer unveraendert ? ==> 9D33: 20 9A 9D JSR $9D9A Block schreiben 9D36: 20 ED 94 JSR $94ED Ausfuehrung ueberpruefen Einsprung von $9D31: 9D39: 60 RTS Folgeblock im aktuellen Block eintragen ($ddfd) Einsprung von $A38A, $A39D: 9D3A: 20 69 9D JSR $9D69 Pufferzeiger holen 9D3D: A5 4D LDA $4D T&S 9D3F: 91 64 STA ($64),Y in Puffer eintragen 9D41: C8 INY 9D42: A5 4E LDA $4E 9D44: 91 64 STA ($64),Y 9D46: 4C 8D A0 JMP $A08D Flag fuer 'Puffer geaendert' setzen T&S des Folgeblocks holen ($de0c) Einsprung von $A245, $A254, $A3B5: 9D49: 20 69 9D JSR $9D69 Zeiger auf Pufferanfang setzen 9D4C: B1 64 LDA ($64),Y T&S aus Blockverkettung als 9D4E: 85 4D STA $4D aktuelle T&S merken 9D50: C8 INY 9D51: B1 64 LDA ($64),Y 9D53: 85 4E STA $4E 9D55: 60 RTS Blocklaenge des letzten Datenblocks setzen ($de19) Einsprung von $9C73, $A3AF: 9D56: 20 69 9D JSR $9D69 Zeiger auf Pufferanfang setzen 9D59: A9 00 LDA #$00 0: letzter Datenblock 9D5B: 91 64 STA ($64),Y in der Blockverkettung eintragen 9D5D: C8 INY 9D5E: A6 50 LDX $50 9D60: BD 57 02 LDA $0257,X Zeiger auf naechsten Datensatz holen 9D63: AA TAX 9D64: CA DEX -1 = letztes benutztes Byte 9D65: 8A TXA 9D66: 91 64 STA ($64),Y merken 9D68: 60 RTS Zeiger auf Anfang des aktiven Puffers setzen ($de2b) Einsprung von $9D3A, $9D49, $9D56, $A143, $A298: 9D69: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen 9D6C: 0A ASL 9D6D: AA TAX 9D6E: B5 BC LDA $BC,X Pufferzeiger Hi holen 9D70: 85 65 STA $65 9D72: A9 00 LDA #$00 Pufferzeiger lo = 0 9D74: 85 64 STA $64 9D76: A0 00 LDY #$00 9D78: 60 RTS T&S der aktuellen Datei holen ($de3b) E: $52: aktuelle SA A: $4d/$4e: aktuelle T&S T&S der aktuellen Sekundaeradresse holen Einsprung von $845F, $84A6, $93E7, $95BB, $97E4, $9834: 9D79: 20 27 90 JSR $9027 Kanal zum Lesen holen T&S des aktuellen Kanals holen Einsprung von $989C, $9B8A, $9C45, $9CC7, $A273, $A3BE, $A9E0, $A9FC, $B668: 9D7C: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen 9D7F: 85 6C STA $6C aktuellen Puffer merken 9D81: 0A ASL (2-Byte Tabelle) 9D82: A8 TAY 9D83: B9 0B 00 LDA $000B,Y T&S aus Jobspeicher holen 9D86: 85 4D STA $4D 9D88: B9 0C 00 LDA $000C,Y 9D8B: 85 4E STA $4E 9D8D: 60 RTS Schreib-Lesejobs aufrufen ($de50) T&S aus $4d/$4e holen, Job ausfuehren, 'Puffer geaendert' loeschen Einsprung von $A4BA: 9D8E: A9 90 LDA #$90 <-- Schreiben 9D90: 85 28 STA $28 9D92: D0 24 BNE $9DB8 Einsprung von $88E0, $8E1B, $9FD7, $9FE5, $9FF5, $A25E: 9D94: A9 80 LDA #$80 <-- Lesen 9D96: 85 28 STA $28 9D98: D0 1E BNE $9DB8 T&S aus Jobpuffer holen, Job ausfuehren, 'Puffer geaendert' loeschen Einsprung von $8740, $88FA, $9C76, $9D33, $9FC7, $A391, $A3B2, $A4F4, $A538: 9D9A: A9 90 LDA #$90 <-- Schreiben 9D9C: 85 28 STA $28 9D9E: D0 24 BNE $9DC4 9DA0: A9 80 LDA #$80 <-- Lesen 9DA2: 85 28 STA $28 9DA4: D0 1E BNE $9DC4 Side Sektoren schreiben/lesen Einsprung von $9C52, $A417: 9DA6: A9 90 LDA #$90 <-- Side-Sektor schreiben 9DA8: 85 28 STA $28 9DAA: D0 02 BNE $9DAE Einsprung von $9B60: 9DAC: A9 80 LDA #$80 <-- Side-Sektor lesen Einsprung von $9DAA: 9DAE: 85 28 STA $28 9DB0: A6 50 LDX $50 9DB2: BD 65 02 LDA $0265,X Puffer des Side-Sektors holen 9DB5: AA TAX 9DB6: 10 13 BPL $9DCB (normalerweise) immer ==> Einsprung von $9D92, $9D98: 9DB8: 20 85 95 JSR $9585 T&S an DC uebergeben 9DBB: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen 9DBE: AA TAX 9DBF: A9 00 LDA #$00 Laufwerksnummer (0) setzen 9DC1: 9D 72 02 STA $0272,X [wird nicht abgefragt] Einsprung von $9D9E, $9DA4: 9DC4: 20 9C A0 JSR $A09C Flag 'Puffer geaendert' loeschen 9DC7: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen 9DCA: AA TAX Einsprung von $9DB6: 9DCB: 4C 71 94 JMP $9471 T&S testen, Job aufrufen T&S des Folgeblocks des aktiven Kanals holen E: $50: Kanalnummer A: $4d-$4e: T&S des Folgeblocks Einsprung von $98D6, $9FBF, $9FEB: 9DCE: A9 00 LDA #$00 9DD0: 20 22 94 JSR $9422 Pufferzeiger auf 0 setzen 9DD3: 20 71 90 JSR $9071 T&S des Folgeblocks holen 9DD6: 85 4D STA $4D 9DD8: 20 71 90 JSR $9071 9DDB: 85 4E STA $4E 9DDD: 60 RTS Pufferinhalte kopieren ($dea5) a: Anzahl der zu kopierenden Bytes (1-128) y: Quellpuffer x: Zielpuffer Einsprung von $A47B: 9DDE: 48 PHA 9DDF: A9 00 LDA #$00 Lo-Bytes der Pufferzeiger = 0 9DE1: 85 40 STA $40 9DE3: 85 42 STA $42 9DE5: B9 F1 01 LDA $01F1,Y Adresse des Quellpuffers holen 9DE8: 85 41 STA $41 9DEA: BD F1 01 LDA $01F1,X Adresse des Zielpuffers holen 9DED: 85 43 STA $43 9DEF: 68 PLA Anzahl zu kopierender Bytes 9DF0: A8 TAY nach y 9DF1: 88 DEY Einsprung von $9DF7: 9DF2: B1 40 LDA ($40),Y Bytes kopieren 9DF4: 91 42 STA ($42),Y 9DF6: 88 DEY 9DF7: 10 F9 BPL $9DF2 9DF9: 60 RTS Puffer mit $00 fuellen ($dec1) E: a: Puffernummer Einsprung von $9C04, $9C87, $A466: 9DFA: A8 TAY 9DFB: B9 F1 01 LDA $01F1,Y Adresse des Puffers (Hi) holen 9DFE: 85 41 STA $41 9E00: A9 00 LDA #$00 (Lo) = 0 9E02: 85 40 STA $40 9E04: A8 TAY Einsprung von $9E08: 9E05: 91 40 STA ($40),Y Puffer mit $00 fuellen 9E07: C8 INY 9E08: D0 FB BNE $9E05 9E0A: 60 RTS Nummer des aktuellen Side-Sektors holen ($ded2) E: $50: Kanalnummer A: a: Nummer des Side-Sektors Einsprung von $9EE4, $A164: 9E0B: A9 00 LDA #$00 Zeiger auf 9E0D: 20 15 9E JSR $9E15 Side-Sektor-Pufferanfang setzen 9E10: A0 02 LDY #$02 2. Byte enthaelt die 9E12: B1 64 LDA ($64),Y Side-Sektor-Nummer 9E14: 60 RTS Side-Sektor-Pufferzeiger auf beliebigen Wert setzen ($dedc) E: a: Position, auf die der Pufferzeiger zeigen soll A: $64-$65: Pufferzeiger Einsprung von $9E0D, $9E24, $A408, $A480, $A5CE: 9E15: 85 64 STA $64 Pufferzeiger Lo setzen 9E17: A6 50 LDX $50 9E19: BD 65 02 LDA $0265,X Side-Sektor-Puffernummer holen 9E1C: AA TAX 9E1D: BD F1 01 LDA $01F1,X Pufferadresse holen 9E20: 85 65 STA $65 Pufferzeiger Hi setzen 9E22: 60 RTS Pufferzeiger des aktuellen Side-Sektors auf beliebigen Wert setzen ($dee9) E: a: Position, auf die der Pufferzeiger zeigen soll Einsprung von $9C1E, $9C42, $9C8A, $9E4F, $A199, $A2FC, $A3D2, $A508: 9E23: 48 PHA Position merken 9E24: 20 15 9E JSR $9E15 Pufferadresse holen 9E27: 48 PHA Pufferadresse merken 9E28: 8A TXA 9E29: 0A ASL 16-Bit Index 9E2A: AA TAX 9E2B: 68 PLA 9E2C: 95 BC STA $BC,X Pufferzeiger setzen 9E2E: 68 PLA 9E2F: 95 BB STA $BB,X 9E31: 60 RTS Gruppe anwaehlen, ggf. Side-Sektor laden ($def8) A: v: 0: gesuchter Record existiert; 1: Record nicht vorhanden Einsprung von $A1F0, $A426: 9E32: 20 D3 9E JSR $9ED3 Gruppe waehlen, Side-Sektor pruefen 9E35: 30 0F BMI $9E46 Record existiert nicht ?, ==> 9E37: 50 14 BVC $9E4D Record O.k. ?, ==> 9E39: A6 50 LDX $50 Side-Sektor-Puffer holen 9E3B: BD 65 02 LDA $0265,X 9E3E: 20 56 9E JSR $9E56 Side-Sektor laden 9E41: 20 D3 9E JSR $9ED3 existiert Record ? 9E44: 10 07 BPL $9E4D ja, ==> Einsprung von $9E35: 9E46: 20 5C A1 JSR $A15C Zeiger auf letzten Datenblock setzen 9E49: 2C BF DB BIT $DBBF v=1: 9E4C: 60 RTS Record existiert nicht Einsprung von $9E37, $9E44: 9E4D: A5 6A LDA $6A Side-Sektor-Pufferzeiger auf 9E4F: 20 23 9E JSR $9E23 Position der T&S im Side-Sektor setzen 9E52: 2C BE DB BIT $DBBE n=0, v=0: O.k. 9E55: 60 RTS Side-Sektor lesen/schreiben ($df1b) E: a : Puffernummer y : Nummer des Side-Sektors *2 $64-$65: Zeiger auf die Side-Sektoren-Tabelle Einsprung von $9E3E, $A186, $A521: 9E56: 85 6C STA $6C <-- Side-Sektor lesen 9E58: A9 80 LDA #$80 9E5A: D0 04 BNE $9E60 9E5C: 85 6C STA $6C <-- Side-Sektor schreiben 9E5E: A9 90 LDA #$90 Einsprung von $9E5A: 9E60: 85 28 STA $28 T&S des Side-Sektors holen 9E62: B1 64 LDA ($64),Y 9E64: 85 4D STA $4D 9E66: C8 INY 9E67: B1 64 LDA ($64),Y 9E69: 85 4E STA $4E 9E6B: A5 6C LDA $6C Puffernummer holen 9E6D: 20 88 95 JSR $9588 T&S an DC uebergeben 9E70: A6 6C LDX $6C Puffernummer holen 9E72: 4C E8 94 JMP $94E8 Side-Sektor lesen/schreiben Pufferzeiger des Side-Sektors nach $64-$65 holen ($df45) Einsprung von $A3C7, $A3F9, $A402: 9E75: A6 50 LDX $50 9E77: BD 65 02 LDA $0265,X Puffer des Side-Sektors holen 9E7A: 4C 45 94 JMP $9445 Pufferzeiger holen Anzahl der benoetigten Blocks einer REL-Datei berechnen ($df4c) (alte Version: Anzahl der Blocks innerhalb einer Gruppe) E: x : Anzahl der gefuellten Side-Sektoren $43: Anzahl Datenbloecke im letzten Side-Sektor *2 $44: Anzahl Side-Sektoren A: $41-$42: Anzahl der belegten Blocks Einsprung von $9E83: 9E7D: A9 78 LDA #$78 120 Datenbloecke pro gefuelltem Side-Sektor 9E7F: 20 8D 9E JSR $9E8D addieren Einsprung von $99E9, $A336: 9E82: CA DEX <-- (Einsprung) 9E83: 10 F8 BPL $9E7D 9E85: A5 43 LDA $43 Anzahl Datenbloecke im letzten Side-Sektor*2 9E87: 4A LSR /2 9E88: 20 8D 9E JSR $9E8D addieren 9E8B: A5 44 LDA $44 Anzahl Side-Sektoren addieren Einsprung von $9E7F, $9E88: 9E8D: 18 CLC Addition 9E8E: 65 41 ADC $41 9E90: 85 41 STA $41 9E92: 90 02 BCC $9E96 9E94: E6 42 INC $42 Einsprung von $9E92: 9E96: 60 RTS Anzahl der benoetigten Blocks einer REL-Datei berechnen (neue Version: beruecksichtigt Super-Side-Sektoren) E: $58: Anzahl der gefuellten Gruppen $44: Anzahl der gefuellten Side-Sektoren der letzten Gruppe $43: Anzahl der Datenblocks im letzten Side-Sektor A: $5b-$5c: Anzahl der belegten Blocks Einsprung von $9A11, $A35B: 9E97: 20 38 8D JSR $8D38 Rechenregister 1 loeschen 9E9A: 20 C3 9E JSR $9EC3 Rechenregister 2 loeschen 9E9D: A4 58 LDY $58 Platzverbrauch der gefuellten Gruppen Einsprung von $9EA9: 9E9F: 88 DEY addieren 9EA0: 30 0A BMI $9EAC $02d6 (726): Anzahl Blocks einer Gruppe: 9EA2: A2 02 LDX #$02 720 Datenbloecke, 6 Side-Sektoren 9EA4: A9 D6 LDA #$D6 9EA6: 20 CC 9E JSR $9ECC addieren 9EA9: 4C 9F 9E JMP $9E9F Einsprung von $9EA0: 9EAC: A4 44 LDY $44 Anzahl gefuellter Side-Sektoren Einsprung von $9EB8: 9EAE: 88 DEY 9EAF: 30 0A BMI $9EBB 9EB1: A2 00 LDX #$00 $0079 (121): 120 Datenbloecke + 9EB3: A9 79 LDA #$79 1 Side-Sektor 9EB5: 20 CC 9E JSR $9ECC addieren 9EB8: 4C AE 9E JMP $9EAE Einsprung von $9EAF: 9EBB: A5 43 LDA $43 Anzahl Datenbloecke im letzten Side-Sektor*2 9EBD: 4A LSR /2 9EBE: A2 00 LDX #$00 9EC0: 4C CC 9E JMP $9ECC addieren Rechenregister 2 loeschen Einsprung von $9E9A: 9EC3: A2 00 LDX #$00 9EC5: 86 60 STX $60 9EC7: 86 61 STX $61 9EC9: 86 62 STX $62 9ECB: 60 RTS Zahl in a/x zum Rechenregister 1 addieren Einsprung von $9EA6, $9EB5, $9EC0, $9A18: 9ECC: 86 61 STX $61 9ECE: 85 60 STA $60 9ED0: 4C 4C 8D JMP $8D4C Wert zu Register 1 addieren Feststellen, ob Record existiert und ggf. richtige Gruppe anwaehlen ($df66) A: n=0, v=0: Record und Side-Sektor sind O.k. n=0, v=1: Ein falscher Side-Sektor ist geladen. Record kann existieren. n=1, v=0: Der richtige Side-Sektor ist geladen. Record existiert nicht. n=1, v=1: Der Side-Sektor (oder sogar die ganze Gruppe) existiert noch nicht. Der gesuchte Record kann also noch nicht existieren. Einsprung von $9E32, $9E41: 9ED3: 20 6E A5 JSR $A56E Ist Super-Side-Sektor aktiv ? 9ED6: D0 0C BNE $9EE4 nein, ==> 9ED8: AD 00 01 LDA $0100 gewuenschte Gruppennummer holen 9EDB: 20 C0 A5 JSR $A5C0 richtige Gruppe anwaehlen 9EDE: F0 04 BEQ $9EE4 gefunden ? ja, ==> 9EE0: 2C C1 DB BIT $DBC1 n- und v-Flag setzen 9EE3: 60 RTS (Gruppe existiert nicht) Einsprung von $9ED6, $9EDE: 9EE4: 20 0B 9E JSR $9E0B Nummer des Side-Sektors holen 9EE7: C5 69 CMP $69 = gesuchter Nummer ? 9EE9: D0 0E BNE $9EF9 nein, ==> 9EEB: A4 6A LDY $6A Zeiger auf T&S des Datenblocks holen 9EED: B1 64 LDA ($64),Y Track = 0 (Block nicht vorhanden) ? 9EEF: F0 04 BEQ $9EF5 ja, ==> 9EF1: 2C BE DB BIT $DBBE n- und v-Flag loeschen (O.k.) 9EF4: 60 RTS (O.k.) Einsprung von $9EEF: 9EF5: 2C C0 DB BIT $DBC0 n-Flag setzen 9EF8: 60 RTS (Record existiert nicht) Einsprung von $9EE9: 9EF9: A5 69 LDA $69 gesuchte Nummer 9EFB: C9 06 CMP #$06 >= 6 9EFD: B0 0A BCS $9F09 ja, ==> 9EFF: 0A ASL 9F00: A8 TAY 9F01: A9 04 LDA #$04 Zeiger auf T&S des gesuchten Side-Sektors 9F03: 85 64 STA $64 setzen 9F05: B1 64 LDA ($64),Y Side-Sektor vorhanden (Track>0) ? 9F07: D0 04 BNE $9F0D ja, ==> Einsprung von $9EFD: 9F09: 2C C1 DB BIT $DBC1 n- und v-Flag setzen 9F0C: 60 RTS (der Side-Sektor existiert nicht) Einsprung von $9F07: 9F0D: 2C BF DB BIT $DBBF v-Flag setzen 9F10: 60 RTS (falscher Side-Sektor geladen) Nummer des aktiven Puffers holen ($df93) E: $50: Kanalnummer [Diese Routine wurde haeufig in den DOS-Routinen direkt eingesetzt (als Macro), um 12-15 Systemtakte zu sparen.] Einsprung von $88EE, $8C29, $8E30, $8EB2, $9006, $9069, $927E, $93AA, $9424, $9442, $9452, $9585, $9624, $9A8A, $9CE9, $9D69, $9D7C, $9DBB, $9DC7, $9FFF, $A462, $A51C, $B191, $B1BA, $B1EB, $B210, $B224: 9F11: A6 50 LDX $50 aktuelle Kanalnummer 9F13: B5 D1 LDA $D1,X 1. Puffer testen 9F15: 10 02 BPL $9F19 aktiv ? ja, ==> 9F17: B5 D8 LDA $D8,X 2. Puffer holen Einsprung von $9F15: 9F19: 29 BF AND #$BF b6: Flag 'Puffer veraendert' 9F1B: 60 RTS ausblenden Aktiven Puffer pruefen und holen ($df9e) A: a: Puffernummer n: 1: kein Puffer aktiv Einsprung von $9D2E, $9FC2, $A092, $A09C, $A4C6: 9F1C: A6 50 LDX $50 aktuelle Kanalnummer = 9F1E: 86 74 STX $74 Zeiger auf aktuelle Puffernummer 9F20: B5 D1 LDA $D1,X 1. Puffer holen 9F22: 10 08 BPL $9F2C ist Puffer aktiv ? ja, ==> 9F24: 8A TXA 9F25: 18 CLC 9F26: 69 07 ADC #$07 Zeiger auf 2. Puffernummer setzen 9F28: 85 74 STA $74 9F2A: B5 D8 LDA $D8,X 2. Puffer holen Einsprung von $9F22: 9F2C: 85 41 STA $41 9F2E: 29 1F AND #$1F Puffernummer merken 9F30: 24 41 BIT $41 Pufferstatus holen 9F32: 60 RTS Pruefen, ob ein Puffer des Kanals nicht belegt ist ($dfb7) A: z: 1: Puffer ist nicht belegt Einsprung von $8E3F: 9F33: A6 50 LDX $50 Kanalnummer 9F35: B5 D1 LDA $D1,X ist 1. Puffer inaktiv 9F37: 30 02 BMI $9F3B ja, ==> 9F39: B5 D8 LDA $D8,X 2. Puffer pruefen Einsprung von $9F37: 9F3B: C9 FF CMP #$FF auf 'nicht belegt' pruefen 9F3D: 60 RTS einem Kanal einen neuen Puffer zuordnen ($dfc2) E: $50: Kanalnummer a : Puffernumer Einsprung von $8E49: 9F3E: A6 50 LDX $50 Kanalnummer 9F40: 09 80 ORA #$80 Puffer inaktiv setzen 9F42: B4 D1 LDY $D1,X ist 1. Puffer belegt ? 9F44: 10 03 BPL $9F49 ja, 2. Puffer belegen ==> 9F46: 95 D1 STA $D1,X 1. Puffer belegen 9F48: 60 RTS Einsprung von $9F44: 9F49: 95 D8 STA $D8,X 2. Puffer belegen 9F4B: 60 RTS DOS 5 naechsten Record holen ($dfd0) Einsprung von $A0E1: 9F4C: A9 20 LDA #$20 b5=0: Flag 'Record voll' loeschen 9F4E: 20 DB 9C JSR $9CDB Dateistatus loeschen 9F51: A9 80 LDA #$80 b7=0: Existiert der gesuchte Record ? 9F53: 20 E4 9C JSR $9CE4 (Dateistatus testen) 9F56: D0 46 BNE $9F9E nein, ==> 9F58: A6 50 LDX $50 aktuelle Recordnummer +1 9F5A: FE 49 02 INC $0249,X Lo 9F5D: D0 03 BNE $9F62 9F5F: FE 50 02 INC $0250,X Hi Einsprung von $9F5D: 9F62: A6 50 LDX $50 9F64: BD 57 02 LDA $0257,X Position des naechsten Records im Block = 0 9F67: F0 30 BEQ $9F99 (Record nicht vorhanden) ?, ==> 9F69: 20 42 94 JSR $9442 Pufferzeiger Lo nach a 9F6C: A6 50 LDX $50 [Wenn der 'Zeiger auf den naechsten Record' 9F6E: DD 57 02 CMP $0257,X < Pufferzeiger ist, dann geht der Record 9F71: 90 03 BCC $9F76 bis in den naechsten Datenblock hinein.] Steht Record in einem Block?, ==> 9F73: 20 BF 9F JSR $9FBF Block ggf. schreiben, Folgeblock lesen Einsprung von $9F71: 9F76: A6 50 LDX $50 9F78: BD 57 02 LDA $0257,X Pufferzeiger auf naechsten Record setzen 9F7B: 20 22 94 JSR $9422 9F7E: A1 BB LDA ($BB,X) Byte aus Record holen 9F80: 85 54 STA $54 und merken 9F82: A9 20 LDA #$20 b5=0: Flag 'Record voll' loeschen 9F84: 20 DB 9C JSR $9CDB Dateistatus loeschen 9F87: 20 BC A2 JSR $A2BC 'Zeiger auf naechsten Record' holen Einsprung von $A22A: 9F8A: 48 PHA (steht in a) 9F8B: 90 29 BCC $9FB6 Steht der Record in einem Block ? ja, ==> 9F8D: A9 00 LDA #$00 Tracknummer des Folgeblocks holen 9F8F: 20 50 94 JSR $9450 existiert ein Folgeblock ? 9F92: D0 22 BNE $9FB6 ja, ==> 9F94: 68 PLA Passt der Record noch genau in den Block ? 9F95: C9 02 CMP #$02 [Dann steht der 'Zeiger auf den naechsten Record' im neuen Block auf dem 2. Byte.] 9F97: F0 12 BEQ $9FAB ja, ==> [Es ist nicht mehr moeglich, einen voll- staendigen Record im letzten Datenblock unterzubringen.] Einsprung von $9F67: 9F99: A9 80 LDA #$80 Flag fuer 'Record nicht vorhanden' setzen 9F9B: 20 D5 9C JSR $9CD5 Status setzen Record existiert nicht; CR und EOI ausgeben Einsprung von $9F56: 9F9E: 20 69 90 JSR $9069 Kanal- und Puffernummer holen 9FA1: B5 BB LDA $BB,X Recordende auf aktuellen Pufferzeiger 9FA3: 99 42 02 STA $0242,Y setzen (provoziert EOI) 9FA6: A9 0D LDA #$0D CR als Ausgabebyte setzen 9FA8: 85 54 STA $54 9FAA: 60 RTS Record passt noch genau in den Datenblock Einsprung von $9F97: 9FAB: 20 B7 9F JSR $9FB7 benutzte Recordlaenge feststellen 9FAE: A6 50 LDX $50 9FB0: A9 00 LDA #$00 Flag 'letzter Record passt genau' setzen 9FB2: 9D 57 02 STA $0257,X 9FB5: 60 RTS benutzte Recordlaenge feststellen Einsprung von $9F8B, $9F92: 9FB6: 68 PLA Einsprung von $9FAB: 9FB7: A6 50 LDX $50 Zeiger auf naechsten Record merken 9FB9: 9D 57 02 STA $0257,X 9FBC: 4C FD A0 JMP $A0FD Letztes Zeichen im Record suchen ggf. alten Puffer speichern, dann Folgeblock(s) einlesen ($e03c) [Wenn der letzte Jobcode 'Lesen' war, dann geht die Routine davon aus, dass der gesuchte Datenblock bereits durch den 2-Puffer-Modus bereitgestellt worden ist. Sie versucht dann, wenn der gerade aktive Puffer nicht noch vorher abgespeichert werden muss, den uebernaechsten Datenblock zu lesen. Ist der letzte Jobcode 'Schreiben', dann konnte der Folgeblock noch nicht gelesen werden. Die Routine versucht dann, sowohl den naechsten, als auch den uebernaechsten Block zu lesen.] Einsprung von $9F73, $A02F, $A0C3: 9FBF: 20 CE 9D JSR $9DCE T&S des Folgeblocks holen 9FC2: 20 1C 9F JSR $9F1C aktiven Puffer holen 9FC5: 50 16 BVC $9FDD Puffer veraendert ? nein, ==> aktuellen Puffer speichern, Folgeblock ggf. lesen 9FC7: 20 9A 9D JSR $9D9A Puffer schreiben 9FCA: 20 7D 8D JSR $8D7D Puffer wechseln 9FCD: A9 02 LDA #$02 9FCF: 20 22 94 JSR $9422 Pufferzeiger auf 2 setzen 9FD2: 20 E9 9C JSR $9CE9 War letzter Jobcode 'Schreiben' ? 9FD5: D0 24 BNE $9FFB nein, (Puffer ist bereits gelesen) ==> 9FD7: 20 94 9D JSR $9D94 Folgeblock lesen 9FDA: 4C ED 94 JMP $94ED Jobausfuehrung pruefen den naechsten und uebernaechsten Puffer bereitstellen Einsprung von $9FC5: 9FDD: 20 7D 8D JSR $8D7D Puffer wechseln 9FE0: 20 E9 9C JSR $9CE9 War letzter Jobcode 'Schreiben' ? 9FE3: D0 06 BNE $9FEB nein, (Block ist bereits gelesen) ==> 9FE5: 20 94 9D JSR $9D94 Folgeblock lesen 9FE8: 20 ED 94 JSR $94ED Jobausfuehrung pruefen Einsprung von $9FE3: 9FEB: 20 CE 9D JSR $9DCE T&S des uebernaechsten Blocks holen 9FEE: A5 4D LDA $4D existiert noch ein Block ? 9FF0: F0 09 BEQ $9FFB nein, ==> 9FF2: 20 7D 8D JSR $8D7D Puffer wechseln 9FF5: 20 94 9D JSR $9D94 uebernaechsten Block lesen [Hier wird die Jobausfuehrung nicht abge- wartet. In frueheren Commodore-Laufwerken konnte so der Puffer 'im Hintergrund' eingelesen werden.] 9FF8: 4C 7D 8D JMP $8D7D Puffer wechseln Einsprung von $9FD5, $9FF0: 9FFB: 60 RTS Ein Byte in Record-Puffer schreiben ($e07c) Byte in Puffer schreiben Einsprung von $A03C, $A086: 9FFC: 20 8D A0 JSR $A08D Flags 'Puffer / REL-Datei geaendert' setzen 9FFF: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen A002: 0A ASL (2-Byte Tabelle) A003: AA TAX A004: A5 54 LDA $54 Datenbyte holen A006: 81 BB STA ($BB,X) und in den Puffer schreiben auf Recordende testen A008: B4 BB LDY $BB,X Pufferzeiger (Lo) holen A00A: C8 INY Pufferende erreicht ? A00B: D0 09 BNE $A016 nein, ==> A00D: A4 50 LDY $50 Ist der 'Zeiger auf naechsten Record' = 0 A00F: B9 57 02 LDA $0257,Y [Dies ist genau dann der Fall, wenn der aktuelle Record genau bis zum Blockende geht und er ausserdem der letzte Record der Datei ist.] A012: F0 0A BEQ $A01E ja, dieser letzte Record ist voll, ==> A014: A0 02 LDY #$02 Ist das Recordende genau am Pufferende ? Einsprung von $A00B: A016: 98 TYA A017: A4 50 LDY $50 aktuellen Pufferzeiger mit A019: D9 57 02 CMP $0257,Y 'Zeiger auf naechsten Record' vergleichen A01C: D0 05 BNE $A023 ungleich, (Record noch nicht voll) ==> Einsprung von $A012: A01E: A9 20 LDA #$20 Flag 'Record voll' setzen A020: 4C D5 9C JMP $9CD5 Zeiger auf naechstes Byte setzen Einsprung von $A01C: A023: F6 BB INC $BB,X Pufferzeiger erhoehen; Pufferende erreicht ? A025: D0 0B BNE $A032 nein, ==> A027: AD 01 01 LDA $0101 Flag '2.Teil des Records geladen' setzen A02A: 09 10 ORA #$10 A02C: 8D 01 01 STA $0101 A02F: 4C BF 9F JMP $9FBF Folgeblock einlesen Einsprung von $A025: A032: 60 RTS Empfangene Daten in Record schreiben ($e0ab) Einsprung von $8E8C: A033: A9 A0 LDA #$A0 Record voll/nicht vorhanden ? A035: 20 E4 9C JSR $9CE4 (b5,7 testen) A038: D0 27 BNE $A061 ja, ==> Einsprung von $A078: A03A: A5 54 LDA $54 Datenbyte holen A03C: 20 FC 9F JSR $9FFC und in Record schreiben A03F: A5 51 LDA $51 EOI empfangen ? A041: F0 0D BEQ $A050 ja, ==> A043: 60 RTS Teil der Error-Routine (Record uebergelaufen & EOI vom Computer empfangen) Einsprung von $A067: A044: A9 20 LDA #$20 b5=1: Ist das Flag: 'Record voll' gesetzt ? A046: 20 E4 9C JSR $9CE4 [Deshalb sind wir ja hier !!!] A049: F0 05 BEQ $A050 nein, (wird nie ausgefuehrt) ==> A04B: A9 51 LDA #$51 51, Overflow in Record A04D: 8D AB 02 STA $02AB Fehlernummer merken Arbeit mit dem aktuellen Record beenden Einsprung von $A041, $A049: A050: 20 7B A0 JSR $A07B Rest des Records mit $00 auffuellen A053: 20 E1 A0 JSR $A0E1 naechsten Record lesen A056: AD AB 02 LDA $02AB Ist ein Fehler aufgetreten ? A059: F0 03 BEQ $A05E nein, ==> A05B: 4C 7C 80 JMP $807C Fehler ausgeben Einsprung von $A059: A05E: 4C 62 A8 JMP $A862 00, Ok,00,00 Laut Dateistatus liegt ein Fehler vor Einsprung von $A038: A061: 29 80 AND #$80 Record nicht vorhanden ? A063: D0 05 BNE $A06A ja, ==> A065: A5 51 LDA $51 (Record ist voll ) EOI empfangen ? A067: F0 DB BEQ $A044 ja, ==> A069: 60 RTS ueberzaelige Daten vergessen Einsprung von $A063: A06A: A5 54 LDA $54 Datenbyte zwischenspeichern A06C: 48 PHA A06D: 20 D6 A2 JSR $A2D6 neuen Block mit Records an die Datei haengen A070: 68 PLA A071: 85 54 STA $54 A073: A9 80 LDA #$80 b7=0: Record existiert A075: 20 DB 9C JSR $9CDB Status loeschen A078: 4C 3A A0 JMP $A03A Byte in den neuen Record schreiben Rest eines Records mit $00 auffuellen ($e0f3) Einsprung von $A089, $A050: A07B: A9 20 LDA #$20 b5=1: Record ist voll ? A07D: 20 E4 9C JSR $9CE4 Dateistatus testen A080: D0 0A BNE $A08C ja, ==> A082: A9 00 LDA #$00 Fuellbyte festlegen A084: 85 54 STA $54 A086: 20 FC 9F JSR $9FFC Byte in Recordpuffer schreiben A089: 4C 7B A0 JMP $A07B bis Record voll ist Einsprung von $A080: A08C: 60 RTS Flag fuer 'Puffer geaendert' setzen ($e105) Einsprung von $9D46, $9FFC: A08D: A9 40 LDA #$40 b6=1: Flag 'REL-Datei geaendert' A08F: 20 D5 9C JSR $9CD5 Dateistatus setzen A092: 20 1C 9F JSR $9F1C aktiven Puffer holen A095: 09 40 ORA #$40 A097: A6 74 LDX $74 b6=1: Flag: 'Puffer veraendert' setzen A099: 95 D1 STA $D1,X A09B: 60 RTS Flag fuer 'Puffer geaendert' loeschen ($e115) Einsprung von $9DC4: A09C: 20 1C 9F JSR $9F1C Aktiven Puffer holen A09F: 29 BF AND #$BF b6=0: 'Puffer geaendert'-Flag loeschen A0A1: A6 74 LDX $74 Zeiger auf Puffernummer A0A3: 95 D1 STA $D1,X A0A5: 60 RTS Byte aus Record-Puffer holen ($e120) Einsprung von $930A: A0A6: A9 80 LDA #$80 Ist b7=1: 'Record existiert nicht' ? A0A8: 20 E4 9C JSR $9CE4 (Dateistatus testen) A0AB: D0 3F BNE $A0EC ja, (50, Record not Present) ==> A0AD: 20 69 90 JSR $9069 Kanal-/Puffernummer holen A0B0: B5 BB LDA $BB,X Recordende erreicht ? A0B2: D9 42 02 CMP $0242,Y A0B5: F0 2A BEQ $A0E1 ja, (naechsten Record lesen) ==> A0B7: F6 BB INC $BB,X Pufferzeiger erhoehen A0B9: D0 0E BNE $A0C9 Pufferende erreicht ? A0BB: AD 01 01 LDA $0101 ja, Flag '2. Teil des Records geladen' A0BE: 09 10 ORA #$10 setzen (s. $a286) A0C0: 8D 01 01 STA $0101 A0C3: 20 BF 9F JSR $9FBF (ueber-)naechsten Datenblock lesen Einsprung von $A22D: A0C6: 20 69 90 JSR $9069 Kanal- und Puffernummer holen Einsprung von $A0B9: A0C9: A1 BB LDA ($BB,X) Byte aus Record holen Einsprung von $A0E9: A0CB: 99 3B 02 STA $023B,Y Byte in Ausgabepuffer schreiben A0CE: A9 89 LDA #$89 b3=1: EOI-Flag loeschen A0D0: 99 34 02 STA $0234,Y A0D3: B5 BB LDA $BB,X Steht der Pufferzeiger auf dem letzten A0D5: D9 42 02 CMP $0242,Y auszugebenden Byte ? A0D8: F0 01 BEQ $A0DB ja, (EOI-Flag setzen)==> A0DA: 60 RTS Einsprung von $A0D8: A0DB: A9 81 LDA #$81 b3=0: EOI-Flag setzen A0DD: 99 34 02 STA $0234,Y A0E0: 60 RTS Naechsten Record lesen ($e153) Einsprung von $9B87, $A053, $A0B5: A0E1: 20 4C 9F JSR $9F4C naechsten Record holen A0E4: 20 69 90 JSR $9069 Kanal- und Puffernummer holen A0E7: A5 54 LDA $54 Byte aus Record A0E9: 4C CB A0 JMP $A0CB fuer Ausgabe bereitstellen Abbruch bei Fehler ($e15e) Einsprung von $A0AB, $A1FA, $A207: A0EC: A6 50 LDX $50 A0EE: A9 0D LDA #$0D CR in Ausgabepuffer schreiben A0F0: 9D 3B 02 STA $023B,X A0F3: A9 81 LDA #$81 b3: 0: EOI-Flag setzen A0F5: 9D 34 02 STA $0234,X A0F8: A9 50 LDA #$50 50, Record not Present A0FA: 20 7C 80 JSR $807C Letztes benutzte Zeichen im Record suchen ($e16e) Einsprung von $9FBC: A0FD: A6 50 LDX $50 A0FF: BD 57 02 LDA $0257,X Zeiger auf naechsten Record holen A102: 85 56 STA $56 A104: C6 56 DEC $56 -1 (letztes Zeichen im Record) A106: C9 02 CMP #$02 Ist letztes Zeichen im alten Datenblock ? A108: D0 04 BNE $A10E nein, ==> A10A: A9 FF LDA #$FF Zeiger auf letztes Zeichen im Datenblock A10C: 85 56 STA $56 setzen Einsprung von $A108: A10E: BD 5E 02 LDA $025E,X Recordlaenge merken (Dies ist der Bereich, A111: 85 57 STA $57 in dem das Zeichen liegen muss) A113: 20 42 94 JSR $9442 Pufferzeiger des aktiven Puffers holen A116: A6 50 LDX $50 Ist Pufferzeiger hinter dem Record-Ende ? A118: C5 56 CMP $56 A11A: 90 19 BCC $A135 nein, ==> A11C: F0 17 BEQ $A135 nein, ==> A11E: 20 7D 8D JSR $8D7D ja, Puffer wechseln (Record hoert im anderen Puffer auf) A121: 20 43 A1 JSR $A143 Recordende suchen A124: 90 08 BCC $A12E nicht gefunden, ==> A126: A6 50 LDX $50 Record geht ueber die Blockgrenze hinaus A128: 9D 42 02 STA $0242,X Recordende merken A12B: 4C 7D 8D JMP $8D7D Puffer wechseln (1. Teil des Records) ==> Einsprung von $A124: A12E: 20 7D 8D JSR $8D7D Puffer wechseln (1. Teil des Records) A131: A9 FF LDA #$FF Zeiger auf Pufferende setzen A133: 85 56 STA $56 Einsprung von $A11A, $A11C: A135: 20 43 A1 JSR $A143 weitersuchen A138: B0 03 BCS $A13D gefunden, ==> [Record ist komplett leer; deshalb wird der A13A: 20 42 94 JSR $9442 Pufferzeiger des aktiven Puffers als Recordende genommen (provoziert EOI).] Einsprung von $A138: A13D: A6 50 LDX $50 A13F: 9D 42 02 STA $0242,X Zeiger auf Recordende merken A142: 60 RTS Recordende im aktiven Puffer suchen A: c: 1: a: Zeiger auf Record-Ende; 0: Recordende nicht gefunden Einsprung von $A121, $A135: A143: 20 69 9D JSR $9D69 Zeiger auf Anfang des aktiven Puffers A146: A4 56 LDY $56 setzen Einsprung von $A153: A148: B1 64 LDA ($64),Y Datenbyte aus Record holen A14A: D0 0D BNE $A159 <> 0, dann Ende gefunden ==> A14C: 88 DEY A14D: C0 02 CPY #$02 Datenbereichs-Anfang erreicht ? A14F: 90 04 BCC $A155 ja, ==> A151: C6 57 DEC $57 Recordlaenge -1 A153: D0 F3 BNE $A148 ==> Einsprung von $A14F: A155: C6 57 DEC $57 Recordlaenge -1 A157: 18 CLC c=0: Anfang noch nicht gefunden A158: 60 RTS Einsprung von $A14A: A159: 98 TYA Zeiger auf Recordende nach a A15A: 38 SEC c=1 Anfang gefunden A15B: 60 RTS Letzten Datenblock einer REL-Datei und dessen Eintrag im Side-Sektor ermitteln ($e1cb) Einsprung von $8895, $99CE, $9E46, $A438: A15C: 20 6E A5 JSR $A56E Super-Side-Sektor aktiv ? A15F: D0 03 BNE $A164 nein, ==> A161: 20 A9 A5 JSR $A5A9 letzte existierende Gruppe holen Einsprung von $A15F: A164: 20 0B 9E JSR $9E0B Nummer des aktuellen Side-Sektors setzen A167: 85 69 STA $69 Letzten Side-Sektor laden A169: A9 04 LDA #$04 Zeiger auf Side-Sektor-Tabelle setzen A16B: 85 64 STA $64 A16D: A0 0A LDY #$0A mit letztem Tabelleneintrag anfangen A16F: D0 04 BNE $A175 immer ==> Einsprung von $A177: A171: 88 DEY vorhergehenden Eintrag testen A172: 88 DEY A173: 30 27 BMI $A19C kein Side-Sektor benutzt ?, ==> Einsprung von $A16F: A175: B1 64 LDA ($64),Y existiert Side-Sektor ? A177: F0 F8 BEQ $A171 nein, ==> A179: 98 TYA so ermittelte Side-Sektor-Nummer A17A: 4A LSR (es war eine 2-Byte-Tabelle) A17B: C5 69 CMP $69 mit aktueller Nummer vergleichen A17D: F0 0A BEQ $A189 gleich, ==> A17F: 85 69 STA $69 neue Side-Sektor-Nummer merken A181: A6 50 LDX $50 A183: BD 65 02 LDA $0265,X Side-Sektor-Puffer holen A186: 20 56 9E JSR $9E56 Side-Sektor laden Einsprung von $A17D: A189: A0 00 LDY #$00 hat letzter Side-Sektor einen Folgeblock ? A18B: 84 64 STY $64 A18D: B1 64 LDA ($64),Y A18F: D0 0B BNE $A19C ja, (Fehler) ==> A191: C8 INY A192: B1 64 LDA ($64),Y Blocklaenge holen A194: A8 TAY Zeiger auf letzten Eintrag setzen A195: 88 DEY (-1: ein Eintrag ist 2 Byte lang) A196: 84 6A STY $6A Zeiger auf T&S des Datenblocks merken A198: 98 TYA Side-Sektor-Pufferzeiger auf letzten A199: 4C 23 9E JMP $9E23 Eintrag setzen Einsprung von $A173, $A18F, $A21F: A19C: A9 67 LDA #$67 67, Illegal Track or Sector A19E: 20 3F FF JSR $FF3F CMDERR Position-Befehl ($e207) A1A1: 20 65 81 JSR $8165 Kommandotabellen initialisieren A1A4: AD 01 02 LDA $0201 SA aus Kommandozeile holen A1A7: 85 52 STA $52 A1A9: 20 27 90 JSR $9027 Entsprechenden Kanal holen A1AC: 90 05 BCC $A1B3 Kanal O.k. ? ja, ==> A1AE: A9 70 LDA #$70 70, No Channel A1B0: 20 7C 80 JSR $807C Einsprung von $A1AC: A1B3: A9 A0 LDA #$A0 Record voll (b5) / nicht vorhanden (b7) A1B5: 20 DB 9C JSR $9CDB Bits im Dateistatus loeschen A1B8: 20 5F 90 JSR $905F Filetyp holen A1BB: F0 05 BEQ $A1C2 REL-Datei ? ja, ==> A1BD: A9 64 LDA #$64 64 File type mismatch A1BF: 20 7C 80 JSR $807C ==> Einsprung von $A1BB: A1C2: AD 02 02 LDA $0202 Recordnummer aus der Befehlszeile holen A1C5: 9D 49 02 STA $0249,X und merken (Lo) A1C8: AD 03 02 LDA $0203 (Hi) A1CB: 9D 50 02 STA $0250,X A1CE: A6 50 LDX $50 A1D0: A9 89 LDA #$89 b3=1: EOI-Flag loeschen A1D2: 9D 34 02 STA $0234,X Kanalstatus setzen A1D5: AD 04 02 LDA $0204 Ist die Startposition im Record angegeben ? A1D8: F0 11 BEQ $A1EB nein, ==> A1DA: 38 SEC A1DB: E9 01 SBC #$01 Startposition = 1 (Anfang) ? A1DD: F0 0C BEQ $A1EB ja, ==> A1DF: DD 5E 02 CMP $025E,X mit Recordlaenge vergleichen A1E2: 90 07 BCC $A1EB Zeigt Zeiger hinter Recordende ? A1E4: A9 51 LDA #$51 ja, 51, Overflow in Record A1E6: 8D AB 02 STA $02AB bereitstellen und einfach A1E9: A9 00 LDA #$00 von Record-Anfang an ausgeben Einsprung von $A1D8, $A1DD, $A1E2: A1EB: 85 68 STA $68 Positionszeiger setzen A1ED: 20 89 8C JSR $8C89 Position des Records berechnen A1F0: 20 32 9E JSR $9E32 Side-Sektor ggf. laden A1F3: 50 08 BVC $A1FD existiert der Side-Sektor ? ja, ==> A1F5: A9 80 LDA #$80 b7=1: 'Record existiert nicht' A1F7: 20 D5 9C JSR $9CD5 Status setzen A1FA: 4C EC A0 JMP $A0EC 50, Record not present Einsprung von $A1F3: A1FD: 20 0D A2 JSR $A20D Datenblock einlesen A200: A9 80 LDA #$80 b7: existiert der Record ? A202: 20 E4 9C JSR $9CE4 (Dateistatus testen) A205: F0 03 BEQ $A20A ja, ==> A207: 4C EC A0 JMP $A0EC 50, Record not present Einsprung von $A205: A20A: 4C 4C 80 JMP $804C 00, Ok,00,00 gesuchten Record zur Ausgabe bereitstellen ($e275) Einsprung von $A1FD, $A42B: A20D: 20 35 A2 JSR $A235 ggf. richtige Datenbloecke lesen A210: A5 6B LDA $6B Pufferzeiger auf gewuenschte Startposition A212: 20 22 94 JSR $9422 setzen A215: A6 50 LDX $50 A217: BD 5E 02 LDA $025E,X Recordlaenge A21A: 38 SEC - A21B: E5 68 SBC $68 Position im Record A21D: B0 03 BCS $A222 >= 0 ? ja, ==> nein: Zeiger steht hinter dem Recordende A21F: 4C 9C A1 JMP $A19C 67, Illegal Track or Sector Zeiger auf naechsten Record berechnen Einsprung von $A21D: A222: 18 CLC a = Anzahl Zeichen bis Recordende A223: 65 6B ADC $6B + Startposition im Datenblock A225: 90 03 BCC $A22A geht Record ueber Blockgrenze ? nein, ==> A227: 69 01 ADC #$01 +2 (SEC) (Blockverkettung ueberspringen) A229: 38 SEC Flag fuer Blockwechsel Einsprung von $A225: A22A: 20 8A 9F JSR $9F8A 'Zeiger auf naechsten Record' setzen und auf Dateiende pruefen A22D: 4C C6 A0 JMP $A0C6 Byte fuer Ausgabe bereitstellen A230: A9 51 LDA #$51 51, Overflow in record A232: 20 7C 80 JSR $807C benoetigte Datenbloecke ggf. einlesen ($e29c) Einsprung von $A20D, $A43B: A235: A5 64 LDA $64 Zeiger auf Side-Sektor-Eintrag merken A237: 85 58 STA $58 A239: A5 65 LDA $65 A23B: 85 59 STA $59 A23D: 20 73 A2 JSR $A273 befindet sich der richtige Block im Puffer? A240: F0 22 BEQ $A264 ja, ==> A242: 20 2E 9D JSR $9D2E Puffer ggf. schreiben A245: 20 49 9D JSR $9D49 T&S des Folgeblocks holen A248: A5 4D LDA $4D existiert Folgeblock ? A24A: F0 19 BEQ $A265 nein, ==> [Der naechste Absatz war bei der 1541 fehlerhaft ($e2b4-$e2bf) und fuehrte zu dem Fehlverhalten des 'P'-Befehls] A24C: 20 7D 8D JSR $8D7D Puffer wechseln A24F: 20 73 A2 JSR $A273 enthaelt er den richtigen Block ? A252: D0 11 BNE $A265 nein, ==> A254: 20 49 9D JSR $9D49 T&S des Folgeblocks holen A257: A5 4D LDA $4D existiert Folgeblock ? A259: F0 09 BEQ $A264 nein, ==> A25B: 20 7D 8D JSR $8D7D Puffer wechseln A25E: 20 94 9D JSR $9D94 Folgeblock einlesen A261: 4C 7D 8D JMP $8D7D Puffer wechseln Einsprung von $A240, $A259: A264: 60 RTS Einsprung von $A24A, $A252: A265: A0 00 LDY #$00 T&S des gesuchten Datenblocks dem A267: B1 58 LDA ($58),Y Side-Sektor entnehmen A269: 85 4D STA $4D A26B: C8 INY A26C: B1 58 LDA ($58),Y A26E: 85 4E STA $4E A270: 4C EA 8F JMP $8FEA Block und ggf. Folgeblock lesen Prueft, ob der richtige Daten-Block im Puffer ist Einsprung von $A23D, $A24F: A273: 20 7C 9D JSR $9D7C T&S des aktiven Puffers holen A276: A0 00 LDY #$00 A278: B1 58 LDA ($58),Y T&S im Side-Sektor mit A27A: C5 4D CMP $4D T&S des Datenblocks vergleichen A27C: F0 01 BEQ $A27F Track gleich, ==> A27E: 60 RTS Einsprung von $A27C: A27F: C8 INY A280: B1 58 LDA ($58),Y A282: C5 4E CMP $4E Sektor gleich ? A284: D0 11 BNE $A297 nein, ==> A286: AD 01 01 LDA $0101 Fehler im 1541-ROM behoben: A289: 29 10 AND #$10 Ist das Flag '2. Teil des Records geladen' A28B: F0 0A BEQ $A297 gesetzt ? nein, ==> [Ja: In diesem Fall stimmen zwar T&S des aktiven Datenpuffers, es befindet sich aber unter Umstaenden nicht der Folgeblock im anderen Puffer, sondern der vorhergegende (Wenn z.B. der Vorgaenger-Block abgespeichert werden muss, kann die 2-Puffer-Automatik den uebernaechsten Block nicht schon im Voraus lesen). Dies merkt die Routine, die das letzte benutzte Zeichen im Record sucht (s. $a0fd), nicht und sucht bei der 1541 im falschen Block. Bei der 1581 werden deshalb vorsichtshalber beide Blocks neu geladen, wenn der letzte Record beim Lesen/Schreiben einen Pufferwechsel noetig gemacht hat.] A28D: AD 01 01 LDA $0101 Flag '2. Teil des Records geladen' A290: 29 EF AND #$EF loeschen A292: 8D 01 01 STA $0101 A295: 49 10 EOR #$10 z-Flag loeschen (= falscher Block im Puffer) Einsprung von $A284, $A28B: A297: 60 RTS Puffer mit leeren Records fuellen ($e2e2) Einsprung von $9C70, $A3A0, $A3AC: A298: 20 69 9D JSR $9D69 Zeiger auf aktiven Puffer setzen A29B: A0 02 LDY #$02 A29D: A9 00 LDA #$00 Datenbereich des Puffers mit $00 auffuellen Einsprung von $A2A2: A29F: 91 64 STA ($64),Y A2A1: C8 INY A2A2: D0 FB BNE $A29F A2A4: 20 BC A2 JSR $A2BC Zeiger auf 1. Record im neuen Datenblock Einsprung von $A2B2: A2A7: 9D 57 02 STA $0257,X setzen A2AA: A8 TAY A2AB: A9 FF LDA #$FF $ff: Kennzeichen fuer Leer-Record A2AD: 91 64 STA ($64),Y A2AF: 20 BC A2 JSR $A2BC Zeiger auf naechsten Record setzen A2B2: 90 F3 BCC $A2A7 Datenblock voll ? nein, ==> A2B4: D0 05 BNE $A2BB Block genau gefuellt ? nein, ==> A2B6: A9 00 LDA #$00 Kennzeichen fuer 'Datenblock genau gefuellt' A2B8: 9D 57 02 STA $0257,X setzen Einsprung von $A2B4: A2BB: 60 RTS Position des naechsten Records berechnen ($e304) A: a: Position des naechsten Records Einsprung von $9F87, $A2A4, $A2AF: A2BC: A6 50 LDX $50 A2BE: BD 57 02 LDA $0257,X 'Zeiger auf naechsten Record' =0 ? A2C1: 38 SEC A2C2: F0 0E BEQ $A2D2 ja, (Zeiger auf 2 setzen) ==> A2C4: 18 CLC A2C5: 7D 5E 02 ADC $025E,X Recordlaenge zum Zeiger addieren A2C8: 90 0B BCC $A2D5 Record passt in den Block, ==> A2CA: D0 06 BNE $A2D2 Record steht in zwei Bloecken, ==> A2CC: A9 02 LDA #$02 Record passt genau in den Block A2CE: 2C BD DB BIT $DBBD z-Flag setzen A2D1: 60 RTS Einsprung von $A2C2, $A2CA: A2D2: 69 01 ADC #$01 Blockverkettung ueberspringen A2D4: 38 SEC c=1: Zeiger steht im neuen Block Einsprung von $A2C8: A2D5: 60 RTS Bloecke zu REL-File hinzufuegen ($e31c) (Super-) Side-Sektoren aktualisieren Einsprung von $A06D: A2D6: 20 38 A4 JSR $A438 Ende der REL-Datei suchen A2D9: 20 89 8C JSR $8C89 Position des neuen Records berechnen Einsprung von $88C2: A2DC: 20 5B B6 JSR $B65B Anzahl 'Blocks free' merken Zeiger auf letztes Zeichen im neuen Record setzen A2DF: A4 50 LDY $50 A2E1: BE 5E 02 LDX $025E,Y aktuelle Recordlaenge holen A2E4: CA DEX -1: A2E5: 8A TXA (das letzte Zeichen im Record wird gesucht) A2E6: 18 CLC Position des Records im Datenblock addieren A2E7: 65 6B ADC $6B A2E9: 90 0C BCC $A2F7 c=0: Record passt in den aktuellen Block A2EB: E6 6A INC $6A Side-Sektor-Zeiger auf T&S des naechsten A2ED: E6 6A INC $6A Datenblocks setzen A2EF: D0 06 BNE $A2F7 Zeiger ist im selben SS, ==> A2F1: E6 69 INC $69 naechsten Side-Sektor nehmen A2F3: A9 10 LDA #$10 Zeiger auf T&S des 1. Datenblocks im neuen A2F5: 85 6A STA $6A Side-Sektor setzen Einsprung von $A2E9, $A2EF: A2F7: A5 56 LDA $56 Zeiger auf T&S des aktuellen Side-Sektors A2F9: 18 CLC +2 nehmen A2FA: 69 02 ADC #$02 (zeigt nun auf naechste T&S) A2FC: 20 23 9E JSR $9E23 Side-Sektor-Pufferzeiger setzen A2FF: A5 69 LDA $69 Nummer des Side-Sektors holen A301: C9 06 CMP #$06 <6, (Gruppe noch nicht voll) ? A303: 90 11 BCC $A316 ja, ==> A305: 20 6E A5 JSR $A56E Super-Side-Sektor verwenden ? A308: D0 07 BNE $A311 nein, ==> A30A: 85 69 STA $69 a=0: Side-Sektor-Nummer =0 A30C: EE 00 01 INC $0100 Gruppennummer erhoehen A30F: D0 05 BNE $A316 immer ==> Einsprung von $A308, $A371, $A378: A311: A9 52 LDA #$52 A313: 20 7C 80 JSR $807C 52, File too large Anzahl benoetigter Blocks berechnen Einsprung von $A303, $A30F: A316: A5 6A LDA $6A Zeiger auf T&S des neuen Datenblocks mit A318: 38 SEC dem alten Wert vergleichen A319: E5 56 SBC $56 A31B: B0 03 BCS $A320 groesser, ==> A31D: E9 0F SBC #$0F $10 (CLC) abziehen (das ist die Startposition der Tabelle im SS) A31F: 18 CLC Flag: 'Side-Sektor nicht voll' setzen Einsprung von $A31B: A320: 48 PHA a: Anzahl anzulegender Datenblocks * 2 modulo 120 (max. 119 Blocks) A321: 20 6E A5 JSR $A56E Super-Side-Sektor verwenden ? A324: F0 1E BEQ $A344 ja, ==> - REL-Dateien ohne Super-Side-Sektor A326: 68 PLA Anzahl der Datenblocks modulo 120 A327: 85 43 STA $43 merken A329: A5 69 LDA $69 neue Side-Sektor Nummer A32B: E5 55 SBC $55 - alte Side-Sektor Nummer (ggf. -1, wenn der SS nicht voll ist) A32D: 85 44 STA $44 = Anzahl gefuellter SS [In $44 soll aber die Anzahl benoetigter Side-Sektoren stehen !!!] A32F: A2 00 LDX #$00 Anzahl benoetigter Blocks = 0 A331: 86 41 STX $41 A333: 86 42 STX $42 A335: AA TAX x= Anzahl gefuellter Side-Sektoren A336: 20 82 9E JSR $9E82 Anzahl benoetigter Blocks berechnen A339: A5 42 LDA $42 benoetigte Blocks (Hi) A33B: D0 2F BNE $A36C >0, (mehrere Blocks anlegen) ==> A33D: A6 41 LDX $41 (Lo) A33F: CA DEX A340: D0 2A BNE $A36C >1, (mehrere Blocks anlegen) ==> A342: F0 26 BEQ $A36A (einen neuen Block anlegen), ==> - mit Super-Side-Sektor Einsprung von $A324: A344: 68 PLA (c=0: Die Blocks mod120 passen in alten SS) A345: 85 43 STA $43 Anzahl der Datenblocks modulo 120 merken A347: A5 69 LDA $69 neue Side-Sektor Nummer A349: E5 55 SBC $55 - alte Side-Sektor-Nummer (ggf. -1) A34B: B0 04 BCS $A351 >0, ==> A34D: E6 58 INC $58 Anzahl anzulegender Gruppen -1 (!) A34F: 69 06 ADC #$06 anzulegende Side-Sektoren +6 [Die Gesamtzahl anzulegender SS mod 6 passt noch in die alte Gruppe.] Einsprung von $A34B: A351: 85 44 STA $44 Anzahl SS mod 6 merken A353: AD 00 01 LDA $0100 Nummer der neuen letzten Gruppe A356: 38 SEC - Nummer der alten letzten Gruppe A357: E5 58 SBC $58 A359: 85 58 STA $58 = Anzahl der anzulegenden Gruppen A35B: 20 97 9E JSR $9E97 Anzahl benoetigter Blocks berechnen A35E: A5 5C LDA $5C Anzahl Blocks (Hi) A360: D0 0A BNE $A36C >0, mehrere Blocks anlegen ==> A362: A6 5B LDX $5B (Lo) A364: D0 01 BNE $A367 >0, ==> A366: 60 RTS kein neuer Block anzulegen ==> Einsprung von $A364: A367: CA DEX >1 A368: D0 02 BNE $A36C ja, mehrere Blocks anlegen Pruefen, ob der benoetigte Platz frei ist [Die Routine enthaelt einen schlimmen Fehler und kann sich deshalb um +/- 255 Blocks irren !!!] Einsprung von $A342: A36A: E6 57 INC $57 Flag 'Nur noch einen Datenblock anlegen' Einsprung von $A33B, $A340, $A360, $A368: A36C: CD 8E 02 CMP $028E sind genug 'Blocks free' ? A36F: 90 09 BCC $A37A ja, ==> A371: D0 9E BNE $A311 nein, 52, File too large ==> A373: AD 8D 02 LDA $028D (Lo) A376: C5 41 CMP $41 [Wenn Super-Side-Sektoren verwendet werden, steht das Lo-Byte doch in $5b !?!] A378: 90 97 BCC $A311 nein, 52, File too large ==> neue Datenbloecke und ggf. Side-Sektoren anhaengen Einsprung von $A36F: A37A: A9 01 LDA #$01 Position des letzten gebrauchten Bytes A37C: 20 50 94 JSR $9450 aus aktuellem Puffer holen A37F: 18 CLC A380: 69 01 ADC #$01 +1 A382: A6 50 LDX $50 A384: 9D 57 02 STA $0257,X = Position des neuen Records A387: 20 68 B6 JSR $B668 Folgeblock suchen A38A: 20 3A 9D JSR $9D3A und in der Blockverkettung eintragen A38D: A5 57 LDA $57 soll nur ein neuer Block angelegt werden ? A38F: D0 15 BNE $A3A6 ja, ==> A391: 20 9A 9D JSR $9D9A Block schreiben - Blocks anhaengen Einsprung von $A3F1, $A3F7, $A3FE: A394: 20 7D 8D JSR $8D7D Puffer wechseln A397: 20 85 95 JSR $9585 T&S des neuen Blocks an DC uebergeben A39A: 20 68 B6 JSR $B668 Folgeblock suchen A39D: 20 3A 9D JSR $9D3A und in der Blockverkettung eintragen A3A0: 20 98 A2 JSR $A298 Block mit Datensaetzen anlegen A3A3: 4C B2 A3 JMP $A3B2 ==> - letzten Block anhaengen Einsprung von $A38F, $A400: A3A6: 20 7D 8D JSR $8D7D Puffer wechseln A3A9: 20 85 95 JSR $9585 T&S des neuen Blocks an DC uebergeben A3AC: 20 98 A2 JSR $A298 Block mit Datensaetzen anlegen A3AF: 20 56 9D JSR $9D56 Blocklaenge setzen - ggf. neuen Side-Sektor anlegen Einsprung von $A3A3: A3B2: 20 9A 9D JSR $9D9A Block schreiben A3B5: 20 49 9D JSR $9D49 T&S des Folgeblocks holen A3B8: A5 4D LDA $4D und merken A3BA: 48 PHA A3BB: A5 4E LDA $4E A3BD: 48 PHA A3BE: 20 7C 9D JSR $9D7C T&S des aktuellen Blocks holen A3C1: A5 4E LDA $4E und merken A3C3: 48 PHA A3C4: A5 4D LDA $4D A3C6: 48 PHA A3C7: 20 75 9E JSR $9E75 Side-Sektor-Pufferzeiger holen A3CA: AA TAX Zeiger (Lo) > 0 ? A3CB: D0 0A BNE $A3D7 Ja, (T&S passen noch in den alten SS) ==> A3CD: 20 59 A4 JSR $A459 neuen Side-Sektor anlegen A3D0: A9 10 LDA #$10 Side-Sektor-Zeiger auf 1. Feld der A3D2: 20 23 9E JSR $9E23 Datenblock-Tabelle setzen A3D5: E6 55 INC $55 Side-Sektor Nummer +1 Einsprung von $A3CB: A3D7: 68 PLA T&S des aktuellen Datenblocks A3D8: 20 CA 9C JSR $9CCA in Side-Sektor schreiben A3DB: 68 PLA A3DC: 20 CA 9C JSR $9CCA A3DF: 68 PLA A3E0: 85 4E STA $4E T&S des Folgeblocks zurueckholen A3E2: 68 PLA A3E3: 85 4D STA $4D kein Folgeblock vorhanden ? A3E5: F0 1B BEQ $A402 ja, ==> - Pruefen, ob der letzte anzulegende Datenblock erreicht ist A3E7: 20 6E A5 JSR $A56E Super-Side-Sektor verwenden ? A3EA: D0 07 BNE $A3F3 nein, ==> A3EC: A5 5A LDA $5A Aktuelle Gruppennummer A3EE: CD 00 01 CMP $0100 < angewaehlte Gruppennummer ? A3F1: 90 A1 BCC $A394 ja, ==> Einsprung von $A3EA: A3F3: A5 55 LDA $55 Aktuelle Side-Sektor-Nummer A3F5: C5 69 CMP $69 = angewaehlte Side-Sektor-Nummer ? A3F7: D0 9B BNE $A394 nein, ==> A3F9: 20 75 9E JSR $9E75 Side-Sektor-Pufferzeiger holen A3FC: C5 6A CMP $6A Angewaehlter Datenblock erreicht ? A3FE: 90 94 BCC $A394 nein, ==> A400: F0 A4 BEQ $A3A6 ja, letzten Block anlegen ==> - Ende-Kennzeichen setzen und Side-Sektoren speichern Einsprung von $A3E5: A402: 20 75 9E JSR $9E75 Side-Sektor-Pufferzeiger (Lo) holen A405: 48 PHA und merken A406: A9 00 LDA #$00 Side-Sektor-Pufferzeiger $64-$65 auf A408: 20 15 9E JSR $9E15 Pufferanfang setzen A40B: A9 00 LDA #$00 A40D: A8 TAY Blockverkettung setzen: A40E: 91 64 STA ($64),Y Flag 'letzter Side-Sektor' setzen A410: C8 INY A411: 68 PLA letztes benutztes Byte im A412: 38 SEC Side-Sektor merken A413: E9 01 SBC #$01 (-1, da der Zeiger auf dem 1. unbenutzten A415: 91 64 STA ($64),Y Byte stand) A417: 20 A6 9D JSR $9DA6 Side-Sektor schreiben A41A: 20 ED 94 JSR $94ED Jobausfuehrung pruefen A41D: 20 15 B5 JSR $B515 BAM abspeichern auf erfolgreiche Arbeit testen; Record anwaehlen A420: 20 89 8C JSR $8C89 Position des Records berechnen A423: 20 7D 8D JSR $8D7D Puffer wechseln A426: 20 32 9E JSR $9E32 Gruppe anwaehlen und Side-Sektor laden A429: 70 03 BVS $A42E Record nicht vorhanden ?, ==> A42B: 4C 0D A2 JMP $A20D Record zur Ausgabe bereitstellen Einsprung von $A429: A42E: A9 80 LDA #$80 b7=1: Flag: 'Record existiert nicht' A430: 20 D5 9C JSR $9CD5 im Dateistatus setzen A433: A9 50 LDA #$50 A435: 20 7C 80 JSR $807C 50, Record not present Parameter des letzten Records der Datei merken Einsprung von $88AE, $A2D6: A438: 20 5C A1 JSR $A15C Ende der REL-Datei suchen A43B: 20 35 A2 JSR $A235 benoetigte Blocks einlesen A43E: 20 6E A5 JSR $A56E Super-Side-Sektoren verwenden ? A441: D0 07 BNE $A44A nein, ==> A443: AD 00 01 LDA $0100 aktuelle Gruppennummer A446: 85 5A STA $5A = bearbeitete Gruppennummer A448: 85 58 STA $58 Anzahl vorhendener Gruppen merken Einsprung von $A441: A44A: A5 6A LDA $6A Zeiger auf aktuelle T&S des Side-Sektors A44C: 85 56 STA $56 merken A44E: A5 69 LDA $69 Side-Sektor-Nummer merken A450: 85 55 STA $55 (als aktuell bearbeitete) A452: A9 00 LDA #$00 Flags loeschen: A454: 85 57 STA $57 nur einen Datenblock anlegen A456: 85 68 STA $68 Zeiger in Record loeschen A458: 60 RTS Neuen Side-Sektor zur relativen Datei hinzufuegen ($e31c) Einsprung von $A3CD: A459: 20 68 B6 JSR $B668 Folgeblock fuer Datei suchen A45C: 20 7D 8D JSR $8D7D Puffer wechseln [Fuer das Erzeugen und Updaten der Side-Sektoren wird der gerade inaktive Datenpuffer verwendet.] A45F: 20 2E 9D JSR $9D2E Puffer ggf. schreiben A462: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen A465: 48 PHA und merken A466: 20 FA 9D JSR $9DFA Puffer mit $00 fuellen A469: A6 50 LDX $50 A46B: BD 65 02 LDA $0265,X Side-Sektor-Puffer holen A46E: A8 TAY als Quellpuffer merken A46F: 68 PLA Datenpuffer als Zielpuffer merken A470: AA TAX A471: 20 6E A5 JSR $A56E Wird Super-Side-Sektor verwendet? A474: D0 03 BNE $A479 nein, ==> A476: 4C 47 A5 JMP $A547 ggf. neue Gruppe anlegen ==> Neuen Side-Sektor anlegen Einsprung von $A474, $A54D, $A56B: A479: A9 10 LDA #$10 Side-Sektor-Header uebernehmen A47B: 20 DE 9D JSR $9DDE y: Quellpuffer; x: Zielpuffer; a: Anzahl A47E: A9 00 LDA #$00 Side-Sektor-Nummer erhoehen A480: 20 15 9E JSR $9E15 Side-Sektor-Pufferzeiger holen A483: A0 02 LDY #$02 [Die Nummer wird aus dem alten Side-Sektor A485: B1 64 LDA ($64),Y geholt, um 1 erhoeht und in den neuen A487: 48 PHA Side-Sektor geschrieben.] A488: A9 00 LDA #$00 A48A: 20 22 94 JSR $9422 Auf neuen Side-Sektor schalten A48D: 68 PLA A48E: 18 CLC Side-Sektor-Nummer +1 A48F: 69 01 ADC #$01 A491: 91 64 STA ($64),Y Nummer merken T&S des Side-Sektors alten Side-Sektor eintragen A493: 0A ASL (2-Byte Tabelle) A494: 69 04 ADC #$04 Tabelle beginnt beim 4. Byte im Side-Sektor A496: 85 58 STA $58 Zeiger auf die T&S A498: A8 TAY des aktuellen Side-Sektors merken A499: 38 SEC -2 (vorhergehender Side-Sektor) A49A: E9 02 SBC #$02 Zeiger auf die T&S der zu updatenden A49C: 85 59 STA $59 Side-Sektoren merken Einsprung von $A568: A49E: A5 4D LDA $4D T&S in Side-Sektor eintragen A4A0: 85 56 STA $56 und merken A4A2: 91 64 STA ($64),Y A4A4: C8 INY A4A5: A5 4E LDA $4E A4A7: 85 57 STA $57 A4A9: 91 64 STA ($64),Y A4AB: A0 00 LDY #$00 Blockverkettung setzen A4AD: 98 TYA [1. Byte ist 0: Kennzeichen fuer den letzten A4AE: 91 64 STA ($64),Y Side-Sektor. A4B0: C8 INY Das 2. Byte gibt die Position des letzten A4B1: A9 11 LDA #$11 gebrauchten Bytes im Side-Sektor an. A4B3: 91 64 STA ($64),Y Es wird hier auf 17 gesetzt: Der erste gueltige Zeiger auf einen Datenblock steht in den Bytes 16-17; die restlichen Zeiger sind noch nicht belegt.] A4B5: A9 10 LDA #$10 Pufferzeiger auf ersten Datenblock-Zeiger A4B7: 20 22 94 JSR $9422 setzen A4BA: 20 8E 9D JSR $9D8E neuen Side-Sektor schreiben A4BD: 20 ED 94 JSR $94ED Jobausfuehrung pruefen A4C0: A6 50 LDX $50 A4C2: BD 65 02 LDA $0265,X Alten Side-Sektor merken A4C5: 48 PHA A4C6: 20 1C 9F JSR $9F1C aktiven Puffer holen A4C9: A6 50 LDX $50 A4CB: 9D 65 02 STA $0265,X und als neuen Side-Sektor merken A4CE: 68 PLA A4CF: A6 74 LDX $74 Alten Side-Sektor als aktiven Datenpuffer A4D1: 95 D1 STA $D1,X merken A4D3: A9 00 LDA #$00 Pufferzeiger auf Datenblock setzen A4D5: 20 22 94 JSR $9422 A4D8: A0 00 LDY #$00 Blockverkettung des alten Side-Sektors A4DA: A5 4D LDA $4D auf den neuen setzen A4DC: 91 64 STA ($64),Y A4DE: C8 INY A4DF: A5 4E LDA $4E A4E1: 91 64 STA ($64),Y Super-Side-Sektor updaten A4E3: 20 6E A5 JSR $A56E wird Super-Side-Sektor verwendet? A4E6: D0 41 BNE $A529 nein, ==> A4E8: A5 55 LDA $55 alte Side-Sektor-Nummer holen A4EA: C9 FF CMP #$FF wurde eine neue Gruppe angelegt ? A4EC: D0 3B BNE $A529 nein ==> A4EE: A5 4E LDA $4E T&S des neuen Side-Sektors merken A4F0: 48 PHA A4F1: A5 4D LDA $4D A4F3: 48 PHA A4F4: 20 9A 9D JSR $9D9A alten Side-Sektor schreiben A4F7: 20 ED 94 JSR $94ED Jobausfuehrung pruefen A4FA: 20 7D 8D JSR $8D7D Puffer wechseln A4FD: 20 7E A5 JSR $A57E Super-Side-Sektor laden A500: E6 5A INC $5A Aktuelle Gruppennummer +1 A502: A5 5A LDA $5A A504: 0A ASL 2-Byte Tabelle A505: 18 CLC A506: 69 03 ADC #$03 Die Tabelle faengt bei Byte 3 an A508: 20 23 9E JSR $9E23 Pufferzeiger setzen A50B: 68 PLA A50C: 20 CA 9C JSR $9CCA T&S der neuen Gruppe in die Gruppentabelle A50F: 68 PLA eintragen A510: 20 CA 9C JSR $9CCA A513: 20 81 A5 JSR $A581 Super-Side-Sektor schreiben A516: A5 5A LDA $5A Aktuelle Gruppennummer holen A518: 48 PHA A519: 4C CC A5 JMP $A5CC Gruppe anwaehlen, Ende ==> Tabellen der anderen Side-Sektoren anpassen Einsprung von $A542: A51C: 20 11 9F JSR $9F11 Nummer des aktiven Puffers holen A51F: A6 50 LDX $50 A521: 20 56 9E JSR $9E56 Side-Sektor lesen (y: Nummer*2; a: Puffer) A524: A9 00 LDA #$00 A526: 20 22 94 JSR $9422 Pufferzeiger auf 0 setzen Einsprung von $A4E6, $A4EC: A529: C6 59 DEC $59 <-- Einsprung A52B: C6 59 DEC $59 Zeiger auf vorherigen SS setzen A52D: A4 58 LDY $58 Zeiger auf T&S des neuen SS A52F: A5 56 LDA $56 A531: 91 64 STA ($64),Y T&S in Side-Sektoren-Tabelle eintragen A533: C8 INY A534: A5 57 LDA $57 A536: 91 64 STA ($64),Y A538: 20 9A 9D JSR $9D9A Aktuellen Puffer schreiben A53B: 20 ED 94 JSR $94ED Jobausfuehrung ueberpruefen A53E: A4 59 LDY $59 Zeiger auf T&S des naechsten Side-Sektors A540: C0 03 CPY #$03 holen A542: B0 D8 BCS $A51C noch nicht fertig, ==> A544: 4C 7D 8D JMP $8D7D Puffer wechseln Wenn Gruppe voll, dann neue Gruppe anlegen Einsprung von $A476: A547: A5 55 LDA $55 Alte Side-Sektor-Nummer A549: C9 05 CMP #$05 >= 5 ? A54B: B0 03 BCS $A550 Ja (Gruppe voll), ==> A54D: 4C 79 A4 JMP $A479 zurueck in alte Routine (wie ohne Super-Side-Sektor) Neue Gruppe anlegen Einsprung von $A54B: A550: A9 FF LDA #$FF Der neue Side-Sektor ist die Nummer 0 A552: 85 55 STA $55 (also ist der alte die -1) A554: A9 00 LDA #$00 Pufferzeiger auf Pufferanfang A556: 20 22 94 JSR $9422 setzen A559: A0 02 LDY #$02 A55B: 91 64 STA ($64),Y a=0: Mit Side-Sektor 0 beginnen A55D: A6 50 LDX $50 A55F: BD 5E 02 LDA $025E,X Recordlaenge festlegen A562: C8 INY A563: 91 64 STA ($64),Y A565: C8 INY y=4 !? A566: F0 03 BEQ $A56B ??? A568: 4C 9E A4 JMP $A49E weiter bei Blockverkettung setzen Einsprung von $A566: A56B: 4C 79 A4 JMP $A479 Prueft, ob Super-Side-Sektoren verwendet werden, oder nicht Einsprung von $8898, $88B9, $8C9A, $99D5, $9B4D, $9C58, $9ED3, $A15C, $A305, $A321, $A3E7, $A43E, $A471, $A4E3: A56E: AD 01 01 LDA $0101 REL-Datei-Modus A571: 29 20 AND #$20 b5: 1: Super-Side-Sektor aus A573: 60 RTS Super-Side-Sektor laden Einsprung von $A5C9: A574: A6 50 LDX $50 A576: A9 FE LDA #$FE Super-Side-Sektor im Puffer ? A578: DD 02 01 CMP $0102,X A57B: D0 01 BNE $A57E nein, ==> A57D: 60 RTS ja ==> Einsprung von $A57B, $A4FD: A57E: A9 80 LDA #$80 <-- Super-Side-Sektor lesen A580: 2C B $2C Einsprung von $9CC4, $A513: A581: A9 90 LDA #$90 <-- Super-Side-Sektor schreiben A583: 48 PHA A584: A6 50 LDX $50 A586: BD 10 01 LDA $0110,X T&S holen A589: 85 4D STA $4D A58B: BD 09 01 LDA $0109,X A58E: 85 4E STA $4E (fuer den Fehlerfall vorsichts- A590: A9 FF LDA #$FF halber) Flag: 'kein Side-Sektor A592: 9D 02 01 STA $0102,X geladen' setzen A595: BD 65 02 LDA $0265,X A598: 85 6C STA $6C A59A: 20 88 95 JSR $9588 T&S an DC uebergeben A59D: 68 PLA A59E: 20 E4 94 JSR $94E4 Job aufrufen A5A1: A6 50 LDX $50 A5A3: A9 FE LDA #$FE $fe: Flag fuer A5A5: 9D 02 01 STA $0102,X 'Super-Side-Sektor geladen' A5A8: 60 RTS letzte existierende Gruppe ermitteln Einsprung von $A161: A5A9: A9 5A LDA #$5A 90 (groesste moegliche Gruppennummer bei den verwendeten 24-Bit Rechnungen) A5AB: 8D 00 01 STA $0100 als gesuchte Gruppe merken A5AE: 20 C0 A5 JSR $A5C0 Gruppe anwaehlen A5B1: D0 01 BNE $A5B4 Gruppe existiert nicht, ==> A5B3: 60 RTS Einsprung von $A5B1, $A5BD: A5B4: CE 00 01 DEC $0100 Gruppennummer -1 A5B7: AD 00 01 LDA $0100 A5BA: 20 D2 A5 JSR $A5D2 Gruppe anwaehlen A5BD: D0 F5 BNE $A5B4 nicht vorhanden, ==> A5BF: 60 RTS Gruppe anwaehlen E: a: gewuenschte Gruppennummer Einsprung von $9EDB, $A5AE: A5C0: A6 50 LDX $50 A5C2: DD 02 01 CMP $0102,X Ist richtige Gruppe bereits gewaehlt ? A5C5: D0 01 BNE $A5C8 nein, ==> A5C7: 60 RTS Einsprung von $A5C5: A5C8: 48 PHA Gruppennummer merken A5C9: 20 74 A5 JSR $A574 Super-Side-Sektor laden Einsprung von $A519: A5CC: A9 03 LDA #$03 Zeiger auf Tabelle mit T&S der A5CE: 20 15 9E JSR $9E15 Gruppenanfaenge setzen A5D1: 68 PLA Einsprung von $A5BA: A5D2: AA TAX Gruppennummer nach x A5D3: 0A ASL (2-Byte Tabelle) A5D4: A8 TAY A5D5: B1 64 LDA ($64),Y Eintrag vorhanden (Track>0) ? A5D7: D0 03 BNE $A5DC ja, ==> A5D9: 09 FF ORA #$FF Fehler-Ende A5DB: 60 RTS Einsprung von $A5D7: A5DC: 85 4D STA $4D T&S des 1. Side-Sektors als aktuelle T&S A5DE: C8 INY merken A5DF: B1 64 LDA ($64),Y A5E1: 85 4E STA $4E A5E3: 8A TXA Gruppennummer merken A5E4: 48 PHA A5E5: A9 FF LDA #$FF A5E7: A6 50 LDX $50 Flag: 'Kein Side-Sektor geladen' setzen A5E9: 9D 02 01 STA $0102,X A5EC: BD 65 02 LDA $0265,X Puffer fuer Side-Sektor holen A5EF: 85 6C STA $6C A5F1: 20 88 95 JSR $9588 T&S an DC uebergeben A5F4: A9 80 LDA #$80 A5F6: 20 E4 94 JSR $94E4 1. Side-Sektor der Gruppe lesen A5F9: A6 50 LDX $50 A5FB: 68 PLA A5FC: 9D 02 01 STA $0102,X aktuelle Gruppennummer merken A5FF: A9 00 LDA #$00 O.k. Ende A601: 60 RTS Fehlermeldungen ($e4fc) [Komplett grossgeschriebene Woerter werden durch nur ein Byte dargestellt. Bei dem ersten und dem letzten Zeichen einer Meldung ist das b7 gesetzt.] A602: 00 00, A603: A0 4F CB oK A606: 02 02, A607: A0 53 45 4C 45 43 54 45 44 20 selected A60F: 50 41 52 54 49 54 49 4F CE partitioN A61A: 20 21 22 23 24 27 20/21/22/23/24/27, A620: D2 45 41 44 89 Read ERROR A625: 52 52, A626: 83 20 54 4F 4F 20 FILE too A62C: 4C 41 52 47 C5 largE A631: 50 50, A632: 8B 06 20 50 52 45 53 45 4E D4 RECORD NOT presenT A63C: 51 51, A63D: CF 56 45 52 46 4C 4F 57 20 Overflow A646: 49 4E 8B in RECORD A649: 25 28 25/28, A64B: 8A 89 WRITE ERROR A64D: 26 26, A64E: 8A 20 50 52 4F 54 45 43 54 20 WRITE protect A652: 4F CE oN A65A: 29 29, A65B: 88 20 49 44 85 DISK id MISMATCH A660: 30 31 32 33 34 30/31/32/33/34, A665: D3 59 4E 54 41 58 89 Syntax ERROR A66C: 60 60, A66D: 8A 03 84 WRITE FILE OPEN A670: 63 63, A671: 83 20 45 58 49 53 54 D3 FILE existS A679: 64 64, A67A: 83 20 54 59 50 45 85 FILE type MISMATCH A681: 65 65, A682: CE 4F 20 42 4C 4F 43 CB No blocK A68A: 66 67 66/67, A68C: C9 4C 4C 45 47 41 4C 20 Illegal A694: 54 52 41 43 4B 20 4F 52 20 track or A69D: 53 45 43 54 4F D2 sectoR A6A3: 61 61, A6A4: 83 06 84 FILE NOT OPEN A6A7: 39 62 39/62, A6A9: 83 06 87 FILE NOT FOUND A6AC: 01 01, A6AD: 83 53 20 FILEs A6B0: 53 43 52 41 54 43 48 45 CE scratcheD A6B9: 70 70, A6BA: CE 4F 20 43 48 41 4E 4E 45 CC No channeL A6C4: 71 71, A6C5: C4 49 52 89 Dir ERROR A6C9: 72 72, A6CA: 88 20 46 55 4C CC DISK fulL A6D0: 73 73, A6D1: C3 4F 50 59 52 49 47 48 54 20 Copyright A6DB: 43 42 4D 20 44 4F 53 20 cbm dos A6E3: 56 31 30 20 31 35 38 B1 v10 1581 A6EB: 74 74, A6EC: C4 52 49 56 45 06 20 Drive NOT A6F3: 52 45 41 44 D9 readY A6F8: 75 75, A6F9: C6 4F 52 4D 41 54 20 Format A700: 45 52 52 4F D2 erroR A705: 76 76, A706: C3 4F 4E 54 52 4F 4C 4C 45 52 Controller A710: 20 45 52 52 4F D2 erroR A716: 77 77, A717: D3 45 4C 45 43 54 45 44 20 Selected A720: 50 41 52 54 49 54 49 4F 4E 20 partition A72A: 49 4C 4C 45 47 41 CC illegaL A731: 79 79, A732: D3 4F 46 54 57 41 52 45 20 Software A73B: 44 41 56 49 44 20 david A741: 53 49 52 41 43 55 53 41 2E 20 siracusa. A74B: 48 41 52 44 57 41 52 45 20 hardware A754: 47 52 45 47 20 greg A759: 42 45 52 4C 49 CE berliN A75F: 7A 7:, A760: C4 45 44 49 43 41 54 45 44 20 dedicated A76A: 54 4F 20 4D 59 20 57 49 46 45 to my wife A774: 20 4C 49 53 C1 lisa A779: 09 09 A77A: C5 52 52 4F D2 ErroR A77F: 0A 0a A780: D7 52 49 52 C5 WritE A785: 03 03 A786: C6 49 4C C5 FilE A78A: 04 04 A78B: CF 50 45 CE OpeN A78F: 05 05 A790: CD 49 53 4D 41 54 43 C8 MismatcH A798: 06 06 A799: CE 4F D4 NoT A79C: 07 07 A79D: C6 4F 55 4E C4 FounD A7A2: 08 08 A7A3: C4 49 53 CB DisK A7A7: 0B 0b A7A8: D2 45 43 4F 52 C4 RecorD Error-Routine des Controllers ($e60a) A7AE: 48 PHA Fehlernummer merken A7AF: 86 6C STX $6C Puffernummer bzw Jobspeichernummer merken A7B1: 8A TXA A7B2: 0A ASL (Index fuer 2-Byte Tabelle) A7B3: AA TAX A7B4: B5 0B LDA $0B,X T&S des Fehlers holen A7B6: 85 4D STA $4D A7B8: B5 0C LDA $0C,X A7BA: 85 4E STA $4E A7BC: 68 PLA Fehlernummer zurueckholen Job-Errorcodes in DOS-Errorcodes umwandeln A7BD: 29 0F AND #$0F Fehlercode = $10 ? A7BF: F0 10 BEQ $A7D1 ja, (24, Read Error) ==> A7C1: C9 03 CMP #$03 NOADAM_DV_ER: keine Sync-Markierungen A7C3: F0 08 BEQ $A7CD ja, (74, Drive not Ready) ==> A7C5: C9 0E CMP #$0E SYNTAX_DV_ER: ungueltiger Jobcode A7C7: F0 04 BEQ $A7CD ja, (74, Drive not Ready) ==> A7C9: C9 0F CMP #$0F NODSKPRS_DV_ER: A7CB: D0 06 BNE $A7D3 nein, Fehlrecode errechnen Einsprung von $A7C3, $A7C7: A7CD: A9 74 LDA #$74 Meldung: '74, Drive not Ready' ausgeben A7CF: D0 08 BNE $A7D9 ==> Einsprung von $A7BF: A7D1: A9 06 LDA #$06 24, Read Error ausgeben Einsprung von $A7CB: A7D3: 09 20 ORA #$20 Fehlernummer + 20 (BCD) -2 A7D5: AA TAX (Aus den Fehlern: 02,04,05,07,08 und 09 A7D6: CA DEX die entsprechenden DOS-Meldungen errechnen. A7D7: CA DEX Bsp.: aus 5 wird 23; aus 9 wird 27) A7D8: 8A TXA Einsprung von $A7CF: A7D9: 48 PHA Fehlernummer merken A7DA: AD 2A 02 LDA $022A aktuelle DOS-Befehlsnummer holen A7DD: C9 00 CMP #$00 = 0 (Validate) ? A7DF: D0 0F BNE $A7F0 nein, ==> A7E1: A9 FF LDA #$FF Befehlsnummer loeschen A7E3: 8D 2A 02 STA $022A A7E6: 68 PLA Fehlernummer zurueckholen A7E7: 20 6D A8 JSR $A86D Fehlertext generieren A7EA: 20 03 8F JSR $8F03 Partition initialisieren A7ED: 4C F4 A7 JMP $A7F4 Einsprung von $A7DF: A7F0: 68 PLA CmdError: Error-Routine des DOS ($e645) A7F1: 20 6D A8 JSR $A86D Fehlertext generieren Einsprung von $A7ED: A7F4: 20 71 80 JSR $8071 INPUT-Puffer loeschen A7F7: A9 00 LDA #$00 BAM nicht schreiben A7F9: 85 35 STA $35 A7FB: 20 F1 81 JSR $81F1 LED-Blinken aktivieren A7FE: 20 34 94 JSR $9434 interne Schreib-/Lesekanaele freigeben A801: A9 00 LDA #$00 A803: 85 CD STA $CD Zeiger in INPUT-Puffer loeschen A805: A6 4F LDX $4F Stackpointer initialisieren A807: 9A TXS A808: A5 53 LDA $53 Sekundaeradresse vom Bus A80A: 29 0F AND #$0F A80C: 85 52 STA $52 als aktuelle Sekundaeradresse setzen A80E: C9 0F CMP #$0F = Fehlerkanal A810: F0 29 BEQ $A83B ja, Ende A812: 78 SEI A813: 24 76 BIT $76 Uebertragungsmodus holen A815: 70 17 BVS $A82E LISTEN ? ==> A817: 30 0F BMI $A828 TALK ? ==> A819: A6 52 LDX $52 A81B: B5 A8 LDA $A8,X A81D: C9 FF CMP #$FF War SA geschlossen ? A81F: F0 1A BEQ $A83B ja, Ende A821: 29 0F AND #$0F entsprechende Kanalnummer holen A823: 85 50 STA $50 A825: 4C 31 A8 JMP $A831 Fehlerbehandlung bei Talk Einsprung von $A817: A828: 20 27 90 JSR $9027 Kanal zum Lesen holen A82B: 4C 31 A8 JMP $A831 Fehlerbehandlung bei Listen Einsprung von $A815: A82E: 20 42 90 JSR $9042 Kanal zum Schreiben holen Einsprung von $A825, $A82B: A831: 20 5F 90 JSR $905F Filetyp holen A834: C9 04 CMP #$04 REL-Datei oder Direktzugriff ? A836: B0 03 BCS $A83B ja, (Kanal nicht freigeben) ==> A838: 20 9E 91 JSR $919E Kanal freigeben Einsprung von $A810, $A81F, $A836: A83B: 4C 00 FF JMP $FF00 Zur Haupt-Warteschleife DOS 6 Byte in Ziffernstring umwandeln ($e69b) E: a: Bytewert (von 0-99) y: Position, an der die Zahl in den Puffer geschrieben werden soll Byte in BCD umwandeln Einsprung von $A890, $A89A: A83E: 08 PHP i-Flag merken A83F: 78 SEI Interrupt sperren (damit die Dezimal- A840: AA TAX arithmetik aktiviert werden kann) A841: A9 00 LDA #$00 A843: F8 SED Einsprung von $A84C: A844: E0 00 CPX #$00 Schleife x-mal durchlaufen A846: F0 07 BEQ $A84F A848: 18 CLC X(binaer)-mal a erhoehen (BCD) A849: 69 01 ADC #$01 adc arbeitet im BCD-Modus A84B: CA DEX dex arbeitet im Binaer-Modus A84C: 4C 44 A8 JMP $A844 Einsprung von $A846: A84F: D8 CLD A850: 28 PLP BCD-Zahl in Ziffernstring umwandeln Einsprung von $A877: A851: AA TAX BCD-Zahl merken A852: 4A LSR Erst hoeherwertige Ziffer in Ausgabepuffer A853: 4A LSR schreiben A854: 4A LSR A855: 4A LSR A856: 20 5A A8 JSR $A85A A859: 8A TXA dann die niederwertige Ziffer BCD-Ziffer in Zeichen umwandeln Einsprung von $A856: A85A: 29 0F AND #$0F A85C: 09 30 ORA #$30 BCD-Ziffer + '0' ergibt '(Ziffer)' A85E: 91 CF STA ($CF),Y in Puffer schreiben A860: C8 INY A861: 60 RTS Fehlermeldung bereitstellen ($e6bc) '00, OK,00,00' in Errorpuffer schreiben Einsprung von $8008, $A05E: A862: 20 E5 81 JSR $81E5 Fehlerflag loeschen, LED aus A865: A9 00 LDA #$00 00, OK Errortext mit T&S=0 generieren E: a: Fehlernummer im BCD-Code Einsprung von $8C81, $8C86, $9386, $AFE0, $B0B0: A867: A0 00 LDY #$00 ,00,00 A869: 84 4D STY $4D A86B: 84 4E STY $4E Error ausgeben E: a : Fehlernummer im BCD-Code $4d-$4e: T&S im Binaercode Einsprung von $8061, $A7E7, $A7F1, $B5AE: A86D: A0 00 LDY #$00 Anfang des Errorpuffers A86F: A2 D0 LDX #$D0 A871: 86 CF STX $CF $02d0 A873: A2 02 LDX #$02 A875: 86 D0 STX $D0 A877: 20 51 A8 JSR $A851 Fehlernummer in A ausgeben + tax A87A: A9 2C LDA #$2C A87C: 91 CF STA ($CF),Y ',' in Puffer schreiben A87E: C8 INY A87F: AD D0 02 LDA $02D0 erstes Zeichen zur Ausgabe bereitstellen A882: 8D 41 02 STA $0241 (s.u.) A885: 8A TXA A886: 20 AD A8 JSR $A8AD Fehlertext in Puffer schreiben A889: A9 2C LDA #$2C A88B: 91 CF STA ($CF),Y ',' in Puffer schreiben A88D: C8 INY A88E: A5 4D LDA $4D A890: 20 3E A8 JSR $A83E Tracknummer in Puffer schreiben A893: A9 2C LDA #$2C A895: 91 CF STA ($CF),Y ',' in Puffer schreiben A897: C8 INY A898: A5 4E LDA $4E A89A: 20 3E A8 JSR $A83E Sektornummer in Puffer schreiben A89D: 88 DEY A89E: 98 TYA Ende der Fehlermeldung merken A89F: 18 CLC A8A0: 69 D0 ADC #$D0 + Anfang des Error-Puffers A8A2: 8D 48 02 STA $0248 = Puffergroesse A8A5: E6 CF INC $CF 1. Zeichen steht bereits zur Ausgabe bereit A8A7: A9 88 LDA #$88 Zeiger auf 2. Zeichen setzen A8A9: 8D 3A 02 STA $023A b7=1: Lesekanal; b4=1: kein EOI A8AC: 60 RTS Fehlertext in Puffer schreiben ($e706) E: a: Fehlernummer im BCD-Code y: Position im Fehlerpuffer [Diese Routine ruft sich selbst rekursiv auf: Zuerst wird in der Fehlermeldungstabelle die richtige Fehlernummer gesucht. Dabei muessen die Fehlertexte, die in Bytes mit gesetztem Bit7 eingeschlossen sind, uebersprungen werden. Ist die richtige Fehlernummer gefunden, muss das naechste Byte mit gesetztem Bit7 gesucht werden. Ab diesem Byte werden nun die Zeichen (Bytes>=32) mit geloeschtem Bit7 in den Fehlerpuffer geschrieben. Bytes < 32 stellen eigenstaendige Fehlertexte dar, die durch einen erneuten Aufruf dieser Routine in den Puffer geschrieben werden. Eine Rekursion wird beendet, wenn das naechste Byte mit gestztem Bit7 ausgegeben worden ist.] Einsprung von $A906, $A886: A8AD: AA TAX A8AE: A5 55 LDA $55 Zeiger in Fehlertabelle retten A8B0: 48 PHA (fuer rekursiven Aufruf) A8B1: A5 56 LDA $56 A8B3: 48 PHA A8B4: A9 02 LDA #$02 Zeiger auf Tabelle mit Fehlermeldungen A8B6: 85 55 STA $55 setzen ($a602) A8B8: A9 A6 LDA #$A6 A8BA: 85 56 STA $56 A8BC: 8A TXA A8BD: A2 00 LDX #$00 Einsprung von $A8DD: A8BF: C1 55 CMP ($55,X) Fehlernummer mit Nummer in der Tabelle A8C1: F0 21 BEQ $A8E4 vergleichen; gleich, ==> A8C3: 48 PHA Fehlernummer merken A8C4: 20 1C A9 JSR $A91C ist im Byte b7=1 (dann ist c=1): Wechsel A8C7: 90 05 BCC $A8CE zwischen Nummern und Meldung ? nein, ==> A8C9: 20 1C A9 JSR $A91C ja: Naechsten Wechsel suchen und damit die A8CC: 90 FB BCC $A8C9 Fehlermeldung ueberlesen; bis b7=1 ==> Einsprung von $A8C7: A8CE: A5 56 LDA $56 Tabellenende erreicht ($a7ae) ? A8D0: C9 A7 CMP #$A7 A8D2: 90 08 BCC $A8DC nein, ==> A8D4: D0 0A BNE $A8E0 ja, ==> A8D6: A9 AE LDA #$AE A8D8: C5 55 CMP $55 A8DA: 90 04 BCC $A8E0 ja, ==> Einsprung von $A8D2: A8DC: 68 PLA nein: Fehlernummer zurueckholen A8DD: 4C BF A8 JMP $A8BF Einsprung von $A8D4, $A8DA: A8E0: 68 PLA Fehlernummer vom Stack entfernen A8E1: 4C F4 A8 JMP $A8F4 Ende ==> Einsprung von $A8C1, $A8E7: A8E4: 20 0E A9 JSR $A90E naechstes Byte holen A8E7: 90 FB BCC $A8E4 b7=1: Wechsel zwischen Nummern und Text ? Einsprung von $A8EF: A8E9: 20 FB A8 JSR $A8FB ja, ein Zeichen / eine Meldung ausgeben A8EC: 20 0E A9 JSR $A90E naechstes Byte holen A8EF: 90 F8 BCC $A8E9 Text noch nicht zu Ende, ==> A8F1: 20 FB A8 JSR $A8FB letztes Zeichen ausgeben Einsprung von $A8E1: A8F4: 68 PLA A8F5: 85 56 STA $56 letzten 'Zeiger in Fehlertabelle' A8F7: 68 PLA zurueckholen A8F8: 85 55 STA $55 A8FA: 60 RTS Einsprung von $A8E9, $A8F1: A8FB: C9 20 CMP #$20 Zeichen oder Meldung ausgeben ? A8FD: B0 0B BCS $A90A Zeichen, ==> A8FF: AA TAX A900: A9 20 LDA #$20 Space in Fehler-Puffer schreiben A902: 91 CF STA ($CF),Y A904: C8 INY A905: 8A TXA A906: 20 AD A8 JSR $A8AD Meldung ausgeben A909: 60 RTS Einsprung von $A8FD: A90A: 91 CF STA ($CF),Y Zeichen ausgeben A90C: C8 INY A90D: 60 RTS Byte aus Fehlertabelle holen Einsprung von $A8E4, $A8EC: A90E: E6 55 INC $55 <-- erst Zeiger erhoehen, dann Byte holen A910: D0 02 BNE $A914 A912: E6 56 INC $56 Einsprung von $A910, $A91C: A914: A1 55 LDA ($55,X) b7 des Zeichens ins Carry schieben A916: 0A ASL A917: A1 55 LDA ($55,X) Zeichen holen A919: 29 7F AND #$7F A91B: 60 RTS Einsprung von $A8C4, $A8C9: A91C: 20 14 A9 JSR $A914 <-- erst Byte holen, dann Zeiger erhoehen A91F: E6 55 INC $55 A921: D0 02 BNE $A925 A923: E6 56 INC $56 Einsprung von $A921: A925: 60 RTS Autoboot-Routine A926: 26 43 4F 50 59 52 49 47 ©rig A92E: 48 54 20 43 42 4D 20 38 ht cbm 8 A936: 36 0D 6 JCBMBOOT: Autoboot-Programm aufrufen Einsprung von $8ED6, $AFDB, $FF57: A938: 20 0F AA JSR $AA0F ERROR-Vektoren merken und auf JCBMBOOTRTN setzen A93B: 08 PHP keine Wirkung A93C: 58 CLI A93D: A0 11 LDY #$11 Komandozeilenlaenge auf 17 Bytes setzen A93F: 84 29 STY $29 Einsprung von $A948: A941: B9 26 A9 LDA $A926,Y Filename in Komandozeile schreiben A944: 99 00 02 STA $0200,Y A947: 88 DEY A948: 10 F7 BPL $A941 A94A: 30 0A BMI $A956 Utility-Loader aufrufen JCBMBOOTRTN: Ruecksprung aus Autoboot-Programm Einsprung von $FF5A: A94C: A6 4F LDX $4F Stackpointer-Reset A94E: 9A TXS A94F: 20 95 BA JSR $BA95 Sprungvektoren zurueckholen A952: 78 SEI A953: 4C DE AF JMP $AFDE Meldung ausgeben, Ende ==> Utility-Loader (&) ($e7a3) Einsprung von $A94A: A956: 20 AE 84 JSR $84AE auf Diskettenwechsel testen A959: A5 91 LDA $91 Ist die Sektorgroesse = 512 Bytes ? A95B: C9 02 CMP #$02 A95D: D0 1D BNE $A97C nein, (Fehler) ==> A95F: A9 01 LDA #$01 Position der Drivenummer setzen A961: 8D 91 02 STA $0291 A964: 20 FD 81 JSR $81FD Laufwerksnummer holen A967: AD 2F 02 LDA $022F Anzahl Dateinamen (= 1 !) A96A: 48 PHA merken A96B: A9 01 LDA #$01 Anzahl Dateinamen =1 setzen [is' schon] A96D: 8D 2F 02 STA $022F A970: A9 FF LDA #$FF Flag: 'Aufrufadresse gefunden' loeschen A972: 85 55 STA $55 A974: 20 B9 82 JSR $82B9 Datei suchen A977: AD 97 02 LDA $0297 Starttrack > 0 (Datei gefunden) ? A97A: D0 05 BNE $A981 ja, ==> Einsprung von $A95D: A97C: A9 39 LDA #$39 39, Syntax Error A97E: 20 7C 80 JSR $807C ==> Einsprung von $A97A: A981: 68 PLA a=1 A982: 8D 2F 02 STA $022F Anzahl Dateinamen =1 A985: AD 97 02 LDA $0297 T&S des 1. Dateiblocks setzen A988: 85 4D STA $4D A98A: AD 9C 02 LDA $029C A98D: 85 4E STA $4E A98F: A9 03 LDA #$03 A991: 20 D1 93 JSR $93D1 Dateityp USR setzen und Datei oeffnen Einsprung von $A9EA: A994: A9 00 LDA #$00 A996: 85 56 STA $56 Checksumme initialisieren A998: 20 F5 A9 JSR $A9F5 Startadresse (Lo) aus der Datei holen A99B: 85 57 STA $57 und merken A99D: 20 07 AA JSR $AA07 zur Checksumme addieren A9A0: 20 F5 A9 JSR $A9F5 Startadresse (Hi) aus der Datei holen A9A3: 85 58 STA $58 merken A9A5: 20 07 AA JSR $AA07 und zur Checksumme addieren A9A8: A5 55 LDA $55 Wurde die Aufrufadresse schon festgelegt ? A9AA: F0 0A BEQ $A9B6 ja, ==> A9AC: A5 57 LDA $57 Startadresse merken A9AE: 48 PHA A9AF: A5 58 LDA $58 A9B1: 48 PHA A9B2: A9 00 LDA #$00 Flag: 'Aufrufadresse gefunden' setzen A9B4: 85 55 STA $55 Einsprung von $A9AA: A9B6: 20 F5 A9 JSR $A9F5 Programm-Blockgroesse merken A9B9: 85 59 STA $59 A9BB: 20 07 AA JSR $AA07 und zur Checksumme addieren Einsprung von $A9D5: A9BE: 20 F5 A9 JSR $A9F5 Programmbyte holen A9C1: A0 00 LDY #$00 A9C3: 91 57 STA ($57),Y und an die geforderte Adresse schreiben A9C5: 20 07 AA JSR $AA07 Byte zur Checksumme addieren A9C8: A5 57 LDA $57 Zeiger erhoehen A9CA: 18 CLC A9CB: 69 01 ADC #$01 A9CD: 85 57 STA $57 A9CF: 90 02 BCC $A9D3 A9D1: E6 58 INC $58 Einsprung von $A9CF: A9D3: C6 59 DEC $59 Anzahl zu ladender Bytes -1 A9D5: D0 E7 BNE $A9BE sind noch Bytes des Blocks zu laden, ==> A9D7: 20 76 88 JSR $8876 Byte aus der Datei holen A9DA: A5 54 LDA $54 Byte mit Checksumme vergleichen A9DC: C5 56 CMP $56 A9DE: F0 08 BEQ $A9E8 gleich, ==> A9E0: 20 7C 9D JSR $9D7C T&S fuer die Fehlermeldung holen A9E3: A9 50 LDA #$50 50, Record not Present A9E5: 20 3F FF JSR $FF3F ==> Einsprung von $A9DE: A9E8: A5 51 LDA $51 EOI-Flag: Dateiende erreicht ? A9EA: D0 A8 BNE $A994 nein, ==> A9EC: 68 PLA A9ED: 85 58 STA $58 Aufrufadresse zurueckholen A9EF: 68 PLA A9F0: 85 57 STA $57 A9F2: 6C 57 00 JMP ($0057) und Programm starten Byte aus der Datei holen und auf Dateiende pruefen Einsprung von $A998, $A9A0, $A9B6, $A9BE: A9F5: 20 76 88 JSR $8876 Byte aus der Datei holen A9F8: A5 51 LDA $51 EOI gesetzt A9FA: D0 08 BNE $AA04 nein, ==> A9FC: 20 7C 9D JSR $9D7C T&S fuer die Fehlermeldung holen A9FF: A9 51 LDA #$51 51, Overflow in Record AA01: 20 3F FF JSR $FF3F ==> Einsprung von $A9FA: AA04: A5 54 LDA $54 Programmbyte holen AA06: 60 RTS Byte zur Checksumme addieren Einsprung von $A99D, $A9A5, $A9BB, $A9C5: AA07: 18 CLC AA08: 65 56 ADC $56 Byte addieren AA0A: 69 00 ADC #$00 bei Uebertrag +1 AA0C: 85 56 STA $56 AA0E: 60 RTS Sprungadressen der Error-Routinen merken und auf JCBMBOOTRTN umlenken Einsprung von $A938: AA0F: 20 7C BA JSR $BA7C Sprungvektoren retten AA12: A9 4C LDA #$4C $a94c: JCBMBOOTRTN AA14: 8D BA 01 STA $01BA Error-Routine des DOS 'verbiegen' AA17: A9 A9 LDA #$A9 AA19: 8D BB 01 STA $01BB AA1C: A9 4C LDA #$4C $a94c: JCBMBOOTRTN AA1E: 8D AE 01 STA $01AE Job-Error-Routine 'verbiegen' AA21: A9 A9 LDA #$A9 AA23: 8D AF 01 STA $01AF AA26: 60 RTS Sektorversatz einstellen Einsprung von $AA53: AA27: AD 04 02 LDA $0204 bei der 1581 ist nur der Wert 1 sinnvoll AA2A: 85 2E STA $2E AA2C: 60 RTS Anzahl Leseversuche einstellen Einsprung von $AA57: AA2D: AD 04 02 LDA $0204 Wert aus Kommandozeile holen AA30: 85 30 STA $30 AA32: 60 RTS Cache-Verzoegerung einstellen Einsprung von $AA48: AA33: AD 04 02 LDA $0204 Wert in 1/100 sec AA36: 85 9D STA $9D AA38: 60 RTS ROM-Test Einsprung von $AA5B: AA39: 4C 1D AB JMP $AB1D Burst-Befehl $1e: CHGUTL (bei der 1571: $8fe5) AA3C: 78 SEI AA3D: A6 29 LDX $29 AA3F: E0 04 CPX #$04 AA41: 90 40 BCC $AA83 31, SYNTAX ERROR AA43: AD 03 02 LDA $0203 AA46: C9 49 CMP #$49 Cache-Verzoegerung einstellen AA48: F0 E9 BEQ $AA33 AA4A: AD 03 02 LDA $0203 AA4D: C9 42 CMP #$42 Busmodus waehlen AA4F: F0 37 BEQ $AA88 AA51: C9 53 CMP #$53 Sektorversatz einstellen AA53: F0 D2 BEQ $AA27 AA55: C9 52 CMP #$52 Leseversuche setzen AA57: F0 D4 BEQ $AA2D AA59: C9 54 CMP #$54 ROM-Test aufrufen AA5B: F0 DC BEQ $AA39 AA5D: C9 4D CMP #$4D Memory-Read/Write AA5F: F0 47 BEQ $AAA8 AA61: C9 56 CMP #$56 Disk-Verify ein/aus AA63: F0 35 BEQ $AA9A AA65: A8 TAY AA66: C0 04 CPY #$04 Geraeteadresse einstellen AA68: 90 19 BCC $AA83 31, Syntax Error AA6A: C0 1F CPY #$1F AA6C: B0 15 BCS $AA83 31, Syntax Error Geraeteadresse einstellen AA6E: A9 40 LDA #$40 TALK AA70: 85 78 STA $78 und AA72: A9 20 LDA #$20 LISTEN AA74: 85 77 STA $77 Geraeteadressen loeschen AA76: 98 TYA AA77: 18 CLC und mit neuer Geraeteadresse AA78: 65 78 ADC $78 addieren AA7A: 85 78 STA $78 (Talk) AA7C: 98 TYA AA7D: 18 CLC AA7E: 65 77 ADC $77 (Listen) AA80: 85 77 STA $77 AA82: 60 RTS Einsprung von $AA41, $AA68, $AA6C, $AB00, $AB14: AA83: A9 31 LDA #$31 31, Syntax Error AA85: 4C 7C 80 JMP $807C Busmode waehlen Einsprung von $AA4F: AA88: A5 76 LDA $76 b3=0: auf langsamen Bus schalten AA8A: 29 F7 AND #$F7 AA8C: 85 76 STA $76 AA8E: 20 09 AB JSR $AB09 Parameter holen AA91: 4A LSR AA92: 4A LSR AA93: 4A LSR AA94: 4A LSR AA95: 05 76 ORA $76 Bit gesetzt, dann b3=1: FSM AA97: 85 76 STA $76 AA99: 60 RTS Verify ein/ausschalten Einsprung von $AA63: AA9A: A5 8D LDA $8D b7=0: Verify aus AA9C: 29 7F AND #$7F AA9E: 85 8D STA $8D AAA0: 20 09 AB JSR $AB09 Parameter holen (in Bit 7) AAA3: 05 8D ORA $8D Bit gesetzt, dann b7=1: Verify ein AAA5: 85 8D STA $8D AAA7: 60 RTS Burst-Memory-Read/Write Einsprung von $AA5F: AAA8: 78 SEI AAA9: A5 76 LDA $76 b2=0: Burst-Clock initialisieren AAAB: 29 FB AND #$FB AAAD: 85 76 STA $76 AAAF: A0 00 LDY #$00 Memory-Adresse setzen AAB1: 84 46 STY $46 AAB3: AD 05 02 LDA $0205 ($xx00) AAB6: 85 47 STA $47 AAB8: AD 04 02 LDA $0204 Befehl AABB: C9 57 CMP #$57 AABD: F0 18 BEQ $AAD7 U0>MW, ==> AABF: C9 52 CMP #$52 U0>MR ? AAC1: D0 3D BNE $AB00 nicht R/W ==> 31, Syntax Error Memory-Read AAC3: 20 D4 AC JSR $ACD4 FSM-vorbereiten (auf Ausgabe schalten) Einsprung von $AACC, $AAD3: AAC6: B1 46 LDA ($46),Y Byte aus Memory holen AAC8: 20 86 BF JSR $BF86 und auf FSM-Bus ausgeben AACB: C8 INY naechste Adresse AACC: D0 F8 BNE $AAC6 ganze Speicherseite ausgeben, ==> AACE: E6 47 INC $47 naechste Seite auswaehlen AAD0: CE 06 02 DEC $0206 noch eine Seite ausgeben ? AAD3: D0 F1 BNE $AAC6 ja, ==> AAD5: F0 26 BEQ $AAFD nein ==> Memory-Write Einsprung von $AABD, $AAF4, $AAFB: AAD7: AD 01 40 LDA $4001 'Naechstes Byte bitte' AADA: 49 08 EOR #$08 (Clock-Ausgang kippen) AADC: 2C 0D 40 BIT $400D Schieberegister vorbereiten AADF: 8D 01 40 STA $4001 AAE2: A9 08 LDA #$08 Einsprung von $AAEC, $AB06: AAE4: 2C 01 40 BIT $4001 ATN aufgetreten? AAE7: 30 1A BMI $AB03 Ja, ==> AAE9: 2C 0D 40 BIT $400D b3=1: ist das Byte uebertragen ? AAEC: F0 F6 BEQ $AAE4 nein, ==> AAEE: AD 0C 40 LDA $400C ja, Byte holen AAF1: 91 46 STA ($46),Y und abspeichern AAF3: C8 INY AAF4: D0 E1 BNE $AAD7 ganze Seite einlesen AAF6: E6 47 INC $47 AAF8: CE 06 02 DEC $0206 ($0206) Seiten uebertragen AAFB: D0 DA BNE $AAD7 noch nicht fertig, ==> Einsprung von $AAD5: AAFD: 4C 4C 80 JMP $804C Ende ==> Einsprung von $AAC1: AB00: 4C 83 AA JMP $AA83 31, Syntax Error Einsprung von $AAE7: AB03: 20 15 AD JSR $AD15 ATN testen und bearbeiten ==> AB06: 4C E4 AA JMP $AAE4 Parameter '0' und '1' auswerten (CHGUTL-Parameter) A: b7: Wert entsprechend der Angabe Einsprung von $AA8E, $AAA0: AB09: AD 04 02 LDA $0204 Test auf '0' oder '1' AB0C: C9 31 CMP #$31 AB0E: F0 07 BEQ $AB17 AB10: C9 30 CMP #$30 AB12: F0 03 BEQ $AB17 AB14: 4C 83 AA JMP $AA83 31, SYNTAX ERROR Einsprung von $AB0E, $AB12: AB17: 29 01 AND #$01 '0' : b7=0; AB19: 18 CLC '1' : b7=1; AB1A: 6A ROR AB1B: 6A ROR AB1C: 60 RTS ROM-Signatur pruefen (CRC-Test) (bei der 1571: $924e) Einsprung von $AA39, $FF5D: AB1D: 08 PHP vlg. Blockheader-CRC-Test ($da63) AB1E: 78 SEI AB1F: A5 02 LDA $02 Register retten AB21: 48 PHA AB22: A5 03 LDA $03 AB24: 48 PHA AB25: A5 04 LDA $04 AB27: 48 PHA AB28: A5 05 LDA $05 AB2A: 48 PHA AB2B: A5 06 LDA $06 AB2D: 48 PHA AB2E: A5 07 LDA $07 AB30: 48 PHA AB31: A5 08 LDA $08 AB33: 48 PHA AB34: A5 09 LDA $09 AB36: 48 PHA AB37: A5 0A LDA $0A AB39: 48 PHA AB3A: A9 FF LDA #$FF #$ffff: Startwert fuer Pruefsumme AB3C: 85 07 STA $07 AB3E: 85 08 STA $08 AB40: A9 00 LDA #$00 Startadresse auf $8000 AB42: 85 09 STA $09 AB44: A9 80 LDA #$80 AB46: 85 0A STA $0A AB48: A0 02 LDY #$02 bei $8002 anfangen Einsprung von $AB97, $AB9B: AB4A: B1 09 LDA ($09),Y Der Test arbeitet mit 16-Bit-Werten AB4C: 85 03 STA $03 Wert aus ROM nach $03/$02 AB4E: AA TAX AB4F: C8 INY AB50: B1 09 LDA ($09),Y AB52: 85 02 STA $02 AB54: 8A TXA AB55: A2 10 LDX #$10 16 Verschiebungen [---- -- -- LDA 03 (Nur zum besseren Verstaendnis !!!)] Einsprung von $AB94: AB57: 85 04 STA $04 (aktuelles b15 merken) AB59: 18 CLC Nun werden alle 16 Bits aus $02/$03 der AB5A: 26 02 ROL $02 Reihe nach (von Hi nach Lo) getestet. AB5C: 26 03 ROL $03 AB5E: A9 00 LDA #$00 Ist das Bit nicht gesetzt, wird der AB60: 85 05 STA $05 Wert $0000, nach $05/$06 geschrieben. AB62: 85 06 STA $06 AB64: 24 04 BIT $04 AB66: 10 08 BPL $AB70 AB68: A9 21 LDA #$21 Ist es gesetzt, dann wird der Wert $1021 AB6A: 85 05 STA $05 nach $05/$06 geschrieben AB6C: A9 10 LDA #$10 AB6E: 85 06 STA $06 Einsprung von $AB66: AB70: 24 08 BIT $08 Ist das MSB von $07/$08 gesetzt, dann AB72: 10 0C BPL $AB80 wird die Abfrage genau umgedreht AB74: A5 05 LDA $05 ($1021, wenn Bit=0) AB76: 49 21 EOR #$21 AB78: 85 05 STA $05 AB7A: A5 06 LDA $06 AB7C: 49 10 EOR #$10 AB7E: 85 06 STA $06 Einsprung von $AB72: AB80: 18 CLC $07/$08 * 2 AB81: 26 07 ROL $07 (Das MSB wird geloescht) AB83: 26 08 ROL $08 AB85: A5 07 LDA $07 $07/$08 = $07/$08 eor $05/06 AB87: 45 05 EOR $05 AB89: 85 07 STA $07 AB8B: A5 08 LDA $08 AB8D: 45 06 EOR $06 AB8F: 85 08 STA $08 AB91: A5 03 LDA $03 naechstes Bit testen AB93: CA DEX AB94: D0 C1 BNE $AB57 AB96: C8 INY AB97: D0 B1 BNE $AB4A Naechsten 16-Bit Wert holen, ==> AB99: E6 0A INC $0A naechste Seite bearbeiten AB9B: D0 AD BNE $AB4A bis ROM-Ende weitermachen, ==> AB9D: A4 07 LDY $07 Pruefsumme in y/x merken AB9F: A6 08 LDX $08 ABA1: 68 PLA Register zurueckholen ABA2: 85 0A STA $0A ABA4: 68 PLA ABA5: 85 09 STA $09 ABA7: 68 PLA ABA8: 85 08 STA $08 ABAA: 68 PLA ABAB: 85 07 STA $07 ABAD: 68 PLA ABAE: 85 06 STA $06 ABB0: 68 PLA ABB1: 85 05 STA $05 ABB3: 68 PLA ABB4: 85 04 STA $04 ABB6: 68 PLA ABB7: 85 03 STA $03 ABB9: 68 PLA ABBA: 85 02 STA $02 (alles klar ?) ABBC: CC 00 80 CPY $8000 Ist die Pruefsumme Ok. ? ABBF: D0 07 BNE $ABC8 nein, ==> ABC1: EC 01 80 CPX $8001 ABC4: D0 02 BNE $ABC8 nein, ==> ABC6: 28 PLP ABC7: 60 RTS ROM Ok. Einsprung von $ABBF, $ABC4: ABC8: A2 03 LDX #$03 4x LED Blinken ABCA: 86 40 STX $40 ABCC: 4C F5 AE JMP $AEF5 Laufwerk verriegeln ==> ATN-bearbeiten ($e85b; bei der 1571: $80ce) Vorbereitung ABCF: 78 SEI ABD0: A5 9D LDA $9D Cache-Verzoegerungszaehler initialisieren ABD2: 85 9C STA $9C ABD4: A5 76 LDA $76 LISTEN & TALK loeschen ABD6: 29 3E AND #$3E b0: Flag 'ATN aufgetreten' loeschen ABD8: 85 76 STA $76 ABDA: A6 4F LDX $4F Stack initialisieren ABDC: 9A TXS ABDD: 20 BB AC JSR $ACBB FSM-Bus auf Eingabe stellen ABE0: A9 80 LDA #$80 EOI-Flag loeschen ABE2: 85 51 STA $51 Bus im ATN-Modus bedienen ABE4: A5 76 LDA $76 b1=1: ATN-Modus aktivieren ABE6: 09 02 ORA #$02 ABE8: 85 76 STA $76 ABEA: 20 03 AD JSR $AD03 CLOCK OUT auf Lo ABED: 20 F1 AC JSR $ACF1 DATA OUT auf Hi ABF0: AD 01 40 LDA $4001 automatische ATN-Beantwortung ausschalten, ABF3: 29 EF AND #$EF damit die Software den Bus im ATN-Modus ABF5: 8D 01 40 STA $4001 bedienen kann - Kommando-Byte vom Computer einlesen Einsprung von $ABFF: ABF8: AD 01 40 LDA $4001 liegt kein ATN mehr an ? ABFB: 10 5D BPL $AC5A ja, ==> ABFD: 29 04 AND #$04 Warten bis CLOCK IN = Lo wird ABFF: D0 F7 BNE $ABF8 (zeigt an, dass Daten kommen) Einsprung von $AC58: AC01: 20 42 AE JSR $AE42 Byte vom seriellen Bus holen - UNLISTEN AC04: C9 3F CMP #$3F UNLISTEN AC06: D0 09 BNE $AC11 nein, ==> AC08: A5 76 LDA $76 Busbetrieb auf AC0A: 29 9F AND #$9F b5: seriell, langsam AC0C: 85 76 STA $76 b6: kein LISTEN AC0E: 4C 1B AC JMP $AC1B ATN Ende abwarten - UNTALK Einsprung von $AC06: AC11: C9 5F CMP #$5F UNTALK ? AC13: D0 09 BNE $AC1E nein, ==> AC15: A5 76 LDA $76 Busbetrieb auf AC17: 29 5F AND #$5F b5: seriell,langsam AC19: 85 76 STA $76 b7: kein TALK Einsprung von $AC0E: AC1B: 4C 96 AC JMP $AC96 ATN Ende abwarten - TALK Einsprung von $AC13: AC1E: C5 78 CMP $78 TALK ? AC20: D0 0A BNE $AC2C nein, ==> AC22: A5 76 LDA $76 ja, AC24: 09 80 ORA #$80 b7: Flag fuer TALK setzen AC26: 29 BF AND #$BF b6: Flag fuer LISTEN loeschen AC28: 85 76 STA $76 AC2A: D0 29 BNE $AC55 ==> - LISTEN Einsprung von $AC20: AC2C: C5 77 CMP $77 LISTEN ? AC2E: D0 0A BNE $AC3A nein, ==> AC30: A5 76 LDA $76 ja, AC32: 09 40 ORA #$40 b6: Flag fuer LISTEN setzen AC34: 29 7F AND #$7F b7: Flag fuer TALK loeschen AC36: 85 76 STA $76 AC38: D0 1B BNE $AC55 - Sekundaeradresse einlesen Einsprung von $AC2E: AC3A: AA TAX AC3B: 29 60 AND #$60 Sekundaeradresse (b65=11) ? AC3D: C9 60 CMP #$60 AC3F: D0 50 BNE $AC91 nein, (anderes Geraet war gemeint) ==> AC41: 8A TXA Sekundaeradresse vom Computer AC42: 85 53 STA $53 mit Kommandobits merken AC44: 29 0F AND #$0F AC46: 85 52 STA $52 SA pur merken - CLOSE AC48: A5 53 LDA $53 Kommando vom Computer AC4A: 29 F0 AND #$F0 AC4C: C9 E0 CMP #$E0 = 'schliessen' ? AC4E: D0 46 BNE $AC96 nein, (Datenmodus aktivieren) ==> AC50: 58 CLI AC51: 20 5C 99 JSR $995C aktuellen Kanal schliessen AC54: 78 SEI Einsprung von $AC2A, $AC38: AC55: 2C 01 40 BIT $4001 ATN testen AC58: 30 A7 BMI $AC01 gesetzt, ==> Bus im Datenmodus bedienen Einsprung von $ABFB, $AC99, $AD2C: AC5A: A5 76 LDA $76 b1=0: ATN-Modus loeschen AC5C: 29 FD AND #$FD Datenmodus aktivieren AC5E: 85 76 STA $76 AC60: AD 01 40 LDA $4001 Automatische ATN-Beantwortung einschalten AC63: 09 10 ORA #$10 AC65: 8D 01 40 STA $4001 - LISTEN bearbeiten AC68: 24 76 BIT $76 LISTEN ? AC6A: 50 0F BVC $AC7B nein ==> AC6C: A9 20 LDA #$20 FSM-Betrieb ? AC6E: 24 76 BIT $76 AC70: F0 03 BEQ $AC75 nein, ==> AC72: 20 9D AC JSR $AC9D ja, schnellen Bus-Modus anfordern Einsprung von $AC70: AC75: 20 36 FF JSR $FF36 LISTEN behandeln AC78: 4C E4 AE JMP $AEE4 FSM abschliessen, Ende - TALK bearbeiten Einsprung von $AC6A: AC7B: 24 76 BIT $76 TALK ? AC7D: 10 0F BPL $AC8E nein, ==> AC7F: 20 E8 AC JSR $ACE8 DATA OUT auf Lo AC82: 20 FA AC JSR $ACFA CLOCK OUT auf Hi AC85: 20 2F AD JSR $AD2F kurze Zeit warten AC88: 20 33 FF JSR $FF33 TALK behandeln AC8B: 20 2F AD JSR $AD2F kurze Zeit warten Einsprung von $AC7D: AC8E: 4C DF AE JMP $AEDF FSM auf Eingabe schalten, Ende - ATN-Modus abwarten, wenn z.B. ein anderes Geraet angesprochen wird Einsprung von $AC3F: AC91: A9 00 LDA #$00 Alle Ausgaenge Lo (Laufwerk passiv halten) AC93: 8D 01 40 STA $4001 Einsprung von $AC1B, $AC4E, $AC9B: AC96: 2C 01 40 BIT $4001 Ist ATN noch gesetzt ? AC99: 10 BF BPL $AC5A nein, ==> AC9B: 30 F9 BMI $AC96 Warten bis ATN geloescht ist FSM: DRF (Device Request Fast) Signal senden (bei der 1571: $8199) Einsprung von $ACA5, $AC72: AC9D: 20 15 AD JSR $AD15 ATN-Modus testen ACA0: 20 0C AD JSR $AD0C Bus auslesen ACA3: 29 04 AND #$04 Auf CLOCK Lo warten ACA5: D0 F6 BNE $AC9D ACA7: 20 D4 AC JSR $ACD4 FSM auf Ausgabe schalten ACAA: A9 00 LDA #$00 $00 in serielles Schieberegister laden ACAC: 8D 0C 40 STA $400C ACAF: A9 08 LDA #$08 b3: 1: SDR ist leer Einsprung von $ACB4: ACB1: 2C 0D 40 BIT $400D Uebertragung abwarten ACB4: F0 FB BEQ $ACB1 FSM auf Eingang schalten ACB6: EA NOP [s. 1571-DOS: ACB7: EA NOP 81C4 A9 84 LDA #$84 eigentlich #88 ACB8: EA NOP 81C6 8D 0D 40 STA $400D ACB9: EA NOP Interrupt bei Alarmzeit (Fehler des DOS) ACBA: EA NOP haette genau die richtige Laenge.] Einsprung von $ABDD, $AEE4, $AEEC, $B102, $BEC5, $BF63: ACBB: 08 PHP <-- I-Flag retten ACBC: 78 SEI ACBD: AD 0E 40 LDA $400E SDR auf Eingang schalten ACC0: 29 BF AND #$BF ACC2: 20 C7 DB JSR $DBC7 Schiebezaehler initialisieren ACC5: AD 01 40 LDA $4001 Bustreiber auf Eingang schalten ACC8: 29 DF AND #$DF ACCA: 8D 01 40 STA $4001 ACCD: 28 PLP ACCE: 60 RTS FSM auf Ausgabe schalten ACCF: EA NOP [s. 1571-DOS: ACD0: EA NOP 81E0 A9 08 LDA #$08 ACD1: EA NOP 81E2 8D 0D 40 STA $400D ACD2: EA NOP Interrupt bei FSM-Ein-/Ausgabe verhindern ACD3: EA NOP haette genau die richtige Laenge.] Einsprung von $AAC3, $ACA7, $AEEF, $B8DB, $BB15, $BE7C, $BEBF, $BF5A: ACD4: 08 PHP <-- I-Flag retten ACD5: 78 SEI ACD6: AD 01 40 LDA $4001 Bustreiber auf Ausgang schalten ACD9: 09 20 ORA #$20 ACDB: 8D 01 40 STA $4001 ACDE: AD 0E 40 LDA $400E SDR auf Ausgabe schalten ACE1: 09 40 ORA #$40 ACE3: 20 E0 DB JSR $DBE0 Schiebezaehler initialisieren ACE6: 28 PLP ACE7: 60 RTS DATA OUT auf Lo (die Busleitung wird dadurch Hi) Einsprung von $AC7F, $AE02, $AE23, $AE53, $AE76: ACE8: AD 01 40 LDA $4001 b1=0 ACEB: 29 FD AND #$FD ACED: 8D 01 40 STA $4001 ACF0: 60 RTS DATA OUT auf Hi (die Busleitung wird dadurch Lo) Einsprung von $ABED, $ADFD, $AE6E, $AEB2: ACF1: AD 01 40 LDA $4001 b1=1 ACF4: 09 02 ORA #$02 ACF6: 8D 01 40 STA $4001 ACF9: 60 RTS CLOCK OUT auf Hi (die Busleitung wird dadurch Lo) Einsprung von $AC82, $ADA0, $AE20: ACFA: AD 01 40 LDA $4001 b3=1 ACFD: 09 08 ORA #$08 ACFF: 8D 01 40 STA $4001 AD02: 60 RTS CLOCK OUT auf Lo (die Busleitung wird dadurch Hi) Einsprung von $ABEA, $AD73, $AE11, $BBBA, $BC71: AD03: AD 01 40 LDA $4001 b3=0 AD06: 29 F7 AND #$F7 AD08: 8D 01 40 STA $4001 AD0B: 60 RTS Bus auslesen und entprellen Einsprung von $AD12, $ACA0, $AD6D, $AD7C, $AD8F, $AD99, $ADA6, $ADEB, $AE2D, $AE4C, $AE65, $AE7C, $AEA7: AD0C: AD 01 40 LDA $4001 Bus-Register auslesen AD0F: CD 01 40 CMP $4001 Ist der Wert stabil ? AD12: D0 F8 BNE $AD0C nein, ==> AD14: 60 RTS ATN-Modus testen ($ea59; bei der 1571: $ea59) Einsprung von $AB03, $AC9D, $AD6A, $AD79, $AD8C, $AD96, $ADA3, $AE2A, $AE39, $AE49, $AE5F, $AE79, $AEA4, $AFE3, $BBAE, $BC65, $BF83, $C026: AD15: A9 02 LDA #$02 AD17: 24 76 BIT $76 ist ATN-Modus gesetzt ? AD19: F0 06 BEQ $AD21 nein, ==> AD1B: AD 01 40 LDA $4001 ATN-Modus: ist ATN auch aktiv ? AD1E: 10 0C BPL $AD2C nein, (ATN-Modus beenden) ==> Einsprung von $AD24: AD20: 60 RTS ja, also weitermachen Einsprung von $AD19: AD21: AD 01 40 LDA $4001 Daten-Modus: ist ATN aktiv ? AD24: 10 FA BPL $AD20 nein, also weitermachen ==> AD26: 2C 0D 40 BIT $400D ATN-IRQ-Flag loeschen AD29: 4C 30 FF JMP $FF30 ATN behandeln (ATN-Modus setzen) ==> Einsprung von $AD1E: AD2C: 4C 5A AC JMP $AC5A ATN-Modus beenden ==> Kurze Zeit warten (bei der 1571: $a47e) Einsprung von $AC85, $AC8B, $AE0E, $AE1D, $C36F, $CFD7, $CFDA, $CFDD: AD2F: 8A TXA 2 <-- (40 us warten) AD30: A2 0C LDX #$0C 2 AD32: D0 03 BNE $AD37 3 => 7 Einsprung von $AE05, $AE14, $C352, $CBFF: AD34: 8A TXA 2 <-- (16 us warten) AD35: A2 03 LDX #$03 2 => 4 Einsprung von $AD32, $AD38: AD37: CA DEX 2 AD38: D0 FD BNE $AD37 3 => 5 * x AD3A: AA TAX 2 AD3B: 60 RTS 12 (incl. JSR) NMI-Routine ($ff01) [schaltet immer in den C64 Modus !!!] AD3C: AD 02 02 LDA $0202 'U9x' AD3F: C9 2D CMP #$2D %0010.1101: b1=0 AD41: F0 05 BEQ $AD48 AD43: 38 SEC AD44: E9 2B SBC #$2B bei '-': $00: b1=0 [CMP #2b waere besser] AD46: D0 11 BNE $AD59 weder '+' noch '-', (Warmstart) ==> Einsprung von $AD41: AD48: 29 02 AND #$02 b1 ist immer 0 !!! AD4A: 0A ASL AD4B: 0A ASL AD4C: 0A ASL AD4D: 85 38 STA $38 bei '+' $00 AD4F: 78 SEI bei '-' $00 (sollte $10 sein) AD50: A5 76 LDA $76 Busmodus setzen AD52: 29 EF AND #$EF AD54: 05 38 ORA $38 AD56: 85 76 STA $76 AD58: 60 RTS Einsprung von $AD46: AD59: 4C 06 FF JMP $FF06 Warmstart-Vektor Daten auf seriellen Bus ausgeben ($e909; bei der 1571: $823d) Pruefen, ob die SA auch tatsaechlich Daten zum Computer senden darf AD5C: 78 SEI AD5D: 20 27 90 JSR $9027 Kanal zum Lesen suchen AD60: B0 07 BCS $AD69 Schreibkanal gefunden, ==> Einsprung von $AE3C: AD62: A6 50 LDX $50 AD64: BD 34 02 LDA $0234,X Kanalstatus holen AD67: 30 01 BMI $AD6A Lesekanal, ==> Einsprung von $AD60: AD69: 60 RTS kein Lesekanal / Dateiende ueberschritten Einsprung von $AD67: AD6A: 20 15 AD JSR $AD15 ATN-Modus testen AD6D: 20 0C AD JSR $AD0C Bus auslesen AD70: 29 01 AND #$01 DATA IN isolieren AD72: 08 PHP AD73: 20 03 AD JSR $AD03 CLOCK OUT = Lo setzen AD76: 28 PLP war DATA IN = Lo ? AD77: F0 13 BEQ $AD8C ja, (EOI senden) ==> warten, bis der Computer bereit ist Einsprung von $AD81: AD79: 20 15 AD JSR $AD15 ATN-Modus testen AD7C: 20 0C AD JSR $AD0C Bus auslesen AD7F: 29 01 AND #$01 DATA IN isolieren AD81: D0 F6 BNE $AD79 Auf Freigabe warten (DATA IN = Lo) AD83: A6 50 LDX $50 AD85: BD 34 02 LDA $0234,X Kanalstatus testen AD88: 29 08 AND #$08 b3=1: kein EOI ? AD8A: D0 14 BNE $ADA0 ja, ==> EOI senden [Da wird eigentlich gar nichts gesendet, sondern nur gewartet, bis der Computer die DATA-Leitung von Lo nach Hi gekippt hat.] Einsprung von $AD77, $AD94: AD8C: 20 15 AD JSR $AD15 ATN-Modus testen AD8F: 20 0C AD JSR $AD0C Bus auslesen AD92: 29 01 AND #$01 Warten, bis DATA IN = Lo wird AD94: D0 F6 BNE $AD8C Einsprung von $AD9E: AD96: 20 15 AD JSR $AD15 ATN-Modus testen AD99: 20 0C AD JSR $AD0C Bus auslesen AD9C: 29 01 AND #$01 AD9E: F0 F6 BEQ $AD96 Warten, bis DATA IN = Hi wird Einsprung von $AD8A, $ADAB: ADA0: 20 FA AC JSR $ACFA CLOCK OUT = Hi setzen ADA3: 20 15 AD JSR $AD15 ATN-Modus testen ADA6: 20 0C AD JSR $AD0C Bus auslesen ADA9: 29 01 AND #$01 ADAB: D0 F3 BNE $ADA0 Warten, bis DATA IN = Lo wird ADAD: A9 20 LDA #$20 Bus-Modus ADAF: 24 76 BIT $76 b5=1: FSM-Modus ? ADB1: F0 34 BEQ $ADE7 nein, ==> FSM-Betrieb [Die eigentliche Datenuebertragung dauert: 33 us Programm + 56 us Uebertragung = 89 us (bei 202 Blocks 4,5 s).] ADB3: AD 01 40 LDA $4001 4 Bustreiber auf Ausgabe schalten ADB6: 09 20 ORA #$20 2 ADB8: 8D 01 40 STA $4001 4 ADBB: AD 0E 40 LDA $400E 4 SDR auf Ausgabe schalten ADBE: 09 40 ORA #$40 2 ADC0: 8D 0E 40 STA $400E 4 ADC3: 2C 0D 40 BIT $400D 4 Flag: 'oebertragung beendet' loeschen ADC6: A6 50 LDX $50 3 ADC8: BD 3B 02 LDA $023B,X 4 Datenbyte in das SDR schreiben ADCB: 8D 0C 40 STA $400C 4 ADCE: A9 08 LDA #$08 - und die Uebertragung abwarten Einsprung von $ADD3: ADD0: 2C 0D 40 BIT $400D 4 [Warten dauert: ADD3: F0 FB BEQ $ADD0 2 Uebertragungszeit + Ende erkennen] ADD5: AD 0E 40 LDA $400E 4 SDR auf Eingabe schalten ADD8: 29 BF AND #$BF 2 ADDA: 8D 0E 40 STA $400E 4 ADDD: AD 01 40 LDA $4001 4 Bustreiber auf Eingabe schalten ADE0: 29 DF AND #$DF 2 ADE2: 8D 01 40 STA $4001 4 ADE5: D0 43 BNE $AE2A 3 ==> 65 Takte = 33 us seriell, langsam [Die eigentliche Datenuebertragung dauert: - im C64-Modus : 8*188 us. Dies entspricht bei 202 Blocks 1 min 17 sec. - im VC20-Modus: 8*109 us (= 44 sec).] Einsprung von $ADB1: ADE7: A9 08 LDA #$08 ADE9: 85 66 STA $66 Zaehler fuer 8 Datenbits initialisieren Einsprung von $AE28: ADEB: 20 0C AD JSR $AD0C 22 Bus auslesen ADEE: 29 01 AND #$01 2 ist DATA IN = Hi ? ADF0: D0 4D BNE $AE3F 2 ja, (Ausgabefehler) ==> ADF2: A6 50 LDX $50 3 ADF4: BD 3B 02 LDA $023B,X 4 naechstes Datenbit ins Carry schieben ADF7: 6A ROR 2 ADF8: 9D 3B 02 STA $023B,X 4 ADFB: B0 05 BCS $AE02 2 ist das Bit = 1 ? ja, ==> ADFD: 20 F1 AC JSR $ACF1 11:Bit=0: DATA OUT auf Hi setzen AE00: D0 03 BNE $AE05 1:[Takte/2, da Programm verzweigt] ==> Einsprung von $ADFB: AE02: 20 E8 AC JSR $ACE8 11:Bit=1: DATA OUT auf Lo setzen Einsprung von $AE00: AE05: 20 34 AD JSR $AD34 32 16 us warten AE08: A9 10 LDA #$10 2 C64 Modus ? AE0A: 24 76 BIT $76 3 AE0C: D0 03 BNE $AE11 2 nein, (VC20) ==> AE0E: 20 2F AD JSR $AD2F 80 40 us warten Einsprung von $AE0C: AE11: 20 03 AD JSR $AD03 22 CLOCK OUT auf Lo setzen AE14: 20 34 AD JSR $AD34 32 16 us warten AE17: A9 10 LDA #$10 2 b4=0: C64 Modus ? AE19: 24 76 BIT $76 3 AE1B: D0 03 BNE $AE20 2 nein, (VC20)==> AE1D: 20 2F AD JSR $AD2F 80 ja, 40 us warten Einsprung von $AE1B: AE20: 20 FA AC JSR $ACFA 22 CLOCK OUT auf Hi setzen AE23: 20 E8 AC JSR $ACE8 22 DATA OUT auf Lo setzen AE26: C6 66 DEC $66 5 sind noch Bits zu uebertragen ? AE28: D0 C1 BNE $ADEB 3 ja, ==> (C64-Modus: 376 Takte = 188 us) Warten, bis der Computer den Bus sperrt Einsprung von $ADE5, $AE32: AE2A: 20 15 AD JSR $AD15 ATN-Modus testen AE2D: 20 0C AD JSR $AD0C Bus auslesen AE30: 29 01 AND #$01 AE32: F0 F6 BEQ $AE2A warten, bis DATA IN = Hi AE34: 58 CLI AE35: 20 03 93 JSR $9303 Byte aus dem aktuellen Kanal holen AE38: 78 SEI AE39: 20 15 AD JSR $AD15 ATN-Modus testen AE3C: 4C 62 AD JMP $AD62 Byte ausgeben Einsprung von $ADF0: AE3F: 4C D9 AE JMP $AED9 Byte vom seriellen Bus holen ($e9c9; bei der 1571: $82c7) Warten, bis Computer bereit ist Einsprung von $AC01, $AECF: AE42: 2C 0D 40 BIT $400D Flag 'Daten ueber FSM-Bus empfangen' loeschen AE45: A9 08 LDA #$08 Zaehler auf 8 Datenbits setzen AE47: 85 66 STA $66 Einsprung von $AE51: AE49: 20 15 AD JSR $AD15 ATN-Modus testen AE4C: 20 0C AD JSR $AD0C Bus auslesen AE4F: 29 04 AND #$04 AE51: D0 F6 BNE $AE49 auf CLOCK IN = Lo warten AE53: 20 E8 AC JSR $ACE8 DATA OUT auf Lo AE56: A9 01 LDA #$01 b0: DATA IN Einsprung von $AE5B: AE58: 2C 01 40 BIT $4001 AE5B: D0 FB BNE $AE58 auf DATA IN = Lo warten auf EOI testen AE5D: A2 0A LDX #$0A EOI-Zaehler initialisieren (ca. 520 Takte) Einsprung von $AE6A: AE5F: 20 15 AD JSR $AD15 ATN-Modus testen AE62: CA DEX ca. 260 us gewartet ? AE63: F0 09 BEQ $AE6E ja, (EOI) ==> AE65: 20 0C AD JSR $AD0C Bus auslesen AE68: 29 04 AND #$04 Ist CLOCK IN = Lo ? AE6A: F0 F3 BEQ $AE5F ja, (weiter warten) ==> AE6C: D0 19 BNE $AE87 (Byte empfangen) ==> - Computer mitteilen, dass EOI-empfangen wurde Einsprung von $AE63: AE6E: 20 F1 AC JSR $ACF1 DATA OUT auf Hi AE71: A2 18 LDX #$18 50 us warten Einsprung von $AE74: AE73: CA DEX [Die Routine im Computer, die das DATA Hi AE74: D0 FD BNE $AE73 prueft, braucht ca. 38 us.] AE76: 20 E8 AC JSR $ACE8 DATA OUT auf Lo Einsprung von $AE81: AE79: 20 15 AD JSR $AD15 ATN-Modus testen AE7C: 20 0C AD JSR $AD0C Bus auslesen AE7F: 29 04 AND #$04 AE81: F0 F6 BEQ $AE79 auf CLOCK IN = Hi warten AE83: A9 00 LDA #$00 EOI-Flag setzen AE85: 85 51 STA $51 Byte empfangen Einsprung von $AE6C, $AEA0, $AEB0: AE87: AD 01 40 LDA $4001 AE8A: 49 01 EOR #$01 Datenbit kippen (Daten werden AE8C: AA TAX Lo-aktiv uebertragen) AE8D: AD 0D 40 LDA $400D Sind Daten ueber FSM-Bus gekommen ? AE90: 29 08 AND #$08 AE92: F0 08 BEQ $AE9C nein, ==> AE94: AD 0C 40 LDA $400C Datenbyte aus SDR holen AE97: 85 54 STA $54 und merken AE99: 4C B2 AE JMP $AEB2 Einsprung von $AE92: AE9C: 8A TXA AE9D: 4A LSR Datenbit ins Carry schieben AE9E: 29 02 AND #$02 b1: CLOCK IN = 1 ? AEA0: D0 E5 BNE $AE87 Ja, ==> AEA2: 66 54 ROR $54 empfangenes Bit ins Datenbyte schieben Einsprung von $AEAC: AEA4: 20 15 AD JSR $AD15 ATN-Modus testen AEA7: 20 0C AD JSR $AD0C Bus auslesen AEAA: 29 04 AND #$04 AEAC: F0 F6 BEQ $AEA4 auf CLOCK IN = Hi warten AEAE: C6 66 DEC $66 Sind noch Bits zu empfangen ? AEB0: D0 D5 BNE $AE87 ja, ==> Einsprung von $AE99: AEB2: 20 F1 AC JSR $ACF1 DATA OUT auf Hi setzen AEB5: A5 54 LDA $54 Datenbyte holen AEB7: 60 RTS Daten vom seriellem Bus holen ($ea2e; bei der 1571: $8342) Einsprung von $AED6: AEB8: 78 SEI AEB9: 20 42 90 JSR $9042 Schreibkanal holen AEBC: B0 06 BCS $AEC4 Kanal ist kein kein Schreibkanal, ==> AEBE: BD 34 02 LDA $0234,X Kanalstatus holen AEC1: 6A ROR AEC2: B0 0B BCS $AECF Schreibkanal, (O.k.)==> Einsprung von $AEBC: AEC4: A5 53 LDA $53 SA vom Computer holen AEC6: 29 F0 AND #$F0 Kommando-Bits isolieren AEC8: C9 F0 CMP #$F0 = OPEN ? AECA: F0 03 BEQ $AECF ja, ==> AECC: 4C DF AE JMP $AEDF Fehler: Busbetrieb beenden ==> Einsprung von $AEC2, $AECA: AECF: 20 42 AE JSR $AE42 Daten vom seriellen Bus holen AED2: 58 CLI AED3: 20 78 8E JSR $8E78 und in den aktuellen Puffer schreiben AED6: 4C B8 AE JMP $AEB8 Ende bei Uebertragungsfehler Einsprung von $AE3F: AED9: A5 76 LDA $76 AEDB: 29 DF AND #$DF b5=0: Busbetrieb auf: seriell, langsam AEDD: 85 76 STA $76 Busbetrieb beenden Einsprung von $AC8E, $AECC: AEDF: A9 10 LDA #$10 b0-3=0: seriellen Bus freigeben AEE1: 8D 01 40 STA $4001 b4 =1: automatische ATN-Beantwortung ein Einsprung von $AC78: AEE4: 20 BB AC JSR $ACBB FSM auf Eingang schalten AEE7: 4C 00 FF JMP $FF00 JIDLE (Hauptschleife) ==> JSPINOUT: FSM-Datenrichtung festlegen c=0: Eingabe vom Computer c=1: Ausgabe an Computer Einsprung von $FF63: AEEA: B0 03 BCS $AEEF AEEC: 4C BB AC JMP $ACBB FSM auf Eingabe stellen Einsprung von $AEEA: AEEF: 4C D4 AC JMP $ACD4 FSM auf Ausgabe stellen Fehlerblinken nach Selbsttest ($ea6e) Einsprung von $AF5B, $AF64, $AF6A: AEF2: A2 00 LDX #$00 <-- einmal blinken AEF4: 2C B $2C Einsprung von $ABCC, $AFC7: AEF5: A6 40 LDX $40 <-- ($40)+1 mal blinken AEF7: 9A TXS Einsprung von $AF22: AEF8: BA TSX Einsprung von $AF1C: AEF9: A9 60 LDA #$60 beide LEDs ein AEFB: 0D 00 40 ORA $4000 AEFE: 8D 00 40 STA $4000 AF01: 98 TYA y=0 Einsprung von $AF08: AF02: 18 CLC Warten Einsprung von $AF05: AF03: 69 01 ADC #$01 AF05: D0 FC BNE $AF03 AF07: 88 DEY AF08: D0 F8 BNE $AF02 AF0A: AD 00 40 LDA $4000 LEDs ausschalten AF0D: 29 9F AND #$9F AF0F: 8D 00 40 STA $4000 Einsprung von $AF20: AF12: 98 TYA y=0 Einsprung von $AF19: AF13: 18 CLC Warten Einsprung von $AF16: AF14: 69 01 ADC #$01 AF16: D0 FC BNE $AF14 AF18: 88 DEY AF19: D0 F8 BNE $AF13 AF1B: CA DEX Noch mal Blinken ? AF1C: 10 DB BPL $AEF9 ja, ==> AF1E: E0 F9 CPX #$F9 Verzoegerung nach dem Blinken AF20: D0 F0 BNE $AF12 AF22: F0 D4 BEQ $AEF8 neu beginnen Reset-Routine ($eaa0) I/O initialisieren AF24: 78 SEI AF25: D8 CLD AF26: A9 FE LDA #$FE Port A (PA) und AF28: 8D 00 40 STA $4000 AF2B: A9 65 LDA #$65 Datenrichtung A (DDRA) AF2D: 8D 02 40 STA $4002 AF30: A9 D5 LDA #$D5 AF32: 8D 01 40 STA $4001 PB setzen AF35: A9 3A LDA #$3A AF37: 8D 03 40 STA $4003 DDRB AF3A: A9 00 LDA #$00 Timer A fuer FSM auf $0006 stellen AF3C: 8D 05 40 STA $4005 [3,5 us Takt, 2 Takte pro Bit, 8 Bits AF3F: A9 06 LDA #$06 = 56 us Uebertragungsdauer fuer 1 Byte AF41: 8D 04 40 STA $4004 = 2,9 s fuer 202 Blocks] AF44: A9 01 LDA #$01 Timer A starten AF46: 8D 0E 40 STA $400E AF49: A9 9A LDA #$9A IRQ bei: b1: Unterlauf von Timer B; AF4B: 8D 0D 40 STA $400D b3: SDR-voll/leer; b4: ATN-Signal Zero-Page testen AF4E: A0 00 LDY #$00 AF50: A2 00 LDX #$00 Einsprung von $AF56: AF52: 8A TXA AF53: 95 00 STA $00,X :0000 00 01 02 03 .. .. AF55: E8 INX in entsprechende Z-Adressen schreiben AF56: D0 FA BNE $AF52 Einsprung von $AF6D: AF58: 8A TXA AF59: D5 00 CMP $00,X und pruefen AF5B: D0 95 BNE $AEF2 ungleich, (RAM-Fehler) ==> Einsprung von $AF60: AF5D: F6 00 INC $00,X 256 mal incrementieren AF5F: C8 INY AF60: D0 FB BNE $AF5D AF62: D5 00 CMP $00,X muss alten Wert ergeben AF64: D0 8C BNE $AEF2 ansonsten RAM-Fehler ==> AF66: 94 00 STY $00,X y=0 abspeichern AF68: B5 00 LDA $00,X ist Speicherzelle wirklich 0 ? AF6A: D0 86 BNE $AEF2 nein, (RAM-Fehler) ==> AF6C: E8 INX ganze Z-Page testen AF6D: D0 E9 BNE $AF58 ROM testen AF6F: E6 40 INC $40 = 1 AF71: A2 7F LDX #$7F Anfangen bei $8002 AF73: 86 47 STX $47 AF75: E8 INX x=$80 (ROM-Laenge) AF76: A9 00 LDA #$00 AF78: 85 46 STA $46 AF7A: A0 02 LDY #$02 AF7C: 18 CLC Einsprung von $AF85: AF7D: E6 47 INC $47 Einsprung von $AF82: AF7F: 71 46 ADC ($46),Y Alle Bytes des ROMs addieren AF81: C8 INY (bei Uebertrag +1) AF82: D0 FB BNE $AF7F AF84: CA DEX AF85: D0 F6 BNE $AF7D AF87: 69 FF ADC #$FF +$ff AF89: 85 47 STA $47 sollte 0 ergeben AF8B: D0 00 BNE $AF8D Fehler ignorieren * Old ROM: AF8B: D0 3A BNE $AFC7 zur Fehlerroutine RAM mit Testwerten fuellen Page 1 mit $01,$02,$03, ... Page 2 mit $02,$03,$04, ... ... AF8D: A9 01 LDA #$01 Bei $0100 anfangen AF8F: 85 47 STA $47 AF91: E6 40 INC $40 = 2 AF93: A2 1F LDX #$1F RAM-Groesse Einsprung von $AF9C, $AFA1: AF95: 98 TYA Index AF96: 18 CLC AF97: 65 47 ADC $47 + PageNr AF99: 91 46 STA ($46),Y abspeichern AF9B: C8 INY AF9C: D0 F7 BNE $AF95 AF9E: E6 47 INC $47 AFA0: CA DEX AFA1: D0 F2 BNE $AF95 RAM testen und loeschen AFA3: A2 1F LDX #$1F RAM-Groesse Einsprung von $AFBE: AFA5: C6 47 DEC $47 RAM rueckwaerts testen Einsprung von $AFBB: AFA7: 88 DEY Anfangen mit $ff AFA8: 98 TYA Index AFA9: 18 CLC AFAA: 65 47 ADC $47 + PageNr AFAC: D1 46 CMP ($46),Y sollte abgespeichert sein AFAE: D0 17 BNE $AFC7 wenn nicht, (RAM-Fehler) ==> AFB0: 49 FF EOR #$FF Bits negieren AFB2: 91 46 STA ($46),Y und abspeichern AFB4: 51 46 EOR ($46),Y Dies sollte 0 ergeben AFB6: 91 46 STA ($46),Y RAM loeschen AFB8: D0 0D BNE $AFC7 <>0, (RAM-Fehler) ==> AFBA: 98 TYA AFBB: D0 EA BNE $AFA7 naechstes Byte der Page testen, ==> AFBD: CA DEX AFBE: D0 E5 BNE $AFA5 naechste Page testen, ==> AFC0: A9 80 LDA #$80 Autoboot einschalten AFC2: 8D FB 01 STA $01FB AFC5: D0 03 BNE $AFCA Einsprung von $AF8B, $AFAE, $AFB8: AFC7: 4C F5 AE JMP $AEF5 RAM/ROM-Fehler ==> Warmstart ($eb22) Einsprung von $AFC5: AFCA: 78 SEI AFCB: A2 8F LDX #$8F Stackpointer initialisieren AFCD: 86 4F STX $4F AFCF: 9A TXS AFD0: 20 AD FF JSR $FFAD DOS-Vektoren initialisieren AFD3: 20 E9 AF JSR $AFE9 DOS-Tabellen initialisieren AFD6: 2C FB 01 BIT $01FB Autoboot ? AFD9: 10 03 BPL $AFDE nein, ==> AFDB: 4C 38 A9 JMP $A938 ja ==> Einsprung von $AFD9, $A953: AFDE: A9 73 LDA #$73 73, COPYR... AFE0: 20 67 A8 JSR $A867 Meldung bereitstellen AFE3: 20 15 AD JSR $AD15 Bus bedienen AFE6: 4C 00 FF JMP $FF00 zur Warteschleife DOS 7 Dos-Tabellen initialisieren ($eb3a) Einsprung von $AFD3: AFE9: AD 00 40 LDA $4000 Geraetenummer auslesen AFEC: 29 18 AND #$18 AFEE: 4A LSR AFEF: 4A LSR AFF0: 4A LSR Schalter-Bits + 8 AFF1: 09 48 ORA #$48 TALK (+ $40) AFF3: 85 78 STA $78 AFF5: 49 60 EOR #$60 LISTEN (+ $20) AFF7: 85 77 STA $77 AFF9: A2 08 LDX #$08 Hi-Bytes der Pufferadressen AFFB: A9 0B LDA #$0B berechnen Einsprung von $B004: AFFD: 9D F1 01 STA $01F1,X $01F1: 03 04 .. 0b B000: 38 SEC B001: E9 01 SBC #$01 B003: CA DEX B004: 10 F7 BPL $AFFD B006: A2 00 LDX #$00 Pufferzeiger initialisieren B008: A0 00 LDY #$00 Einsprung von $B018: B00A: A9 00 LDA #$00 B00C: 95 BB STA $BB,X Lo-Byte = 0 B00E: E8 INX B00F: B9 F1 01 LDA $01F1,Y Hi-Byte = 03 04 .. 0b B012: 95 BB STA $BB,X B014: E8 INX B015: C8 INY B016: C0 09 CPY #$09 B018: D0 F0 BNE $B00A B01A: A9 00 LDA #$00 INPUT-Puffer nach $0200 B01C: 95 BB STA $BB,X B01E: A9 02 LDA #$02 B020: 95 BC STA $BC,X B022: A9 D0 LDA #$D0 ERROR-Puffer nach $02d0 B024: 95 BD STA $BD,X B026: A9 02 LDA #$02 B028: 95 BE STA $BE,X B02A: A9 FF LDA #$FF Kanalzuordnung loeschen B02C: A2 12 LDX #$12 (SA sind keinem Kanal zugeordnet) Einsprung von $B031: B02E: 95 A8 STA $A8,X B030: CA DEX B031: 10 FB BPL $B02E B033: A2 06 LDX #$06 Einsprung von $B03D: B035: 95 D1 STA $D1,X 1. Pufferzuordnung freigeben B037: 95 D8 STA $D8,X 2. Pufferzuordnung freigeben B039: 9D 65 02 STA $0265,X Side-Sektor Tabelle loeschen B03C: CA DEX Puffer 7+8 werden nicht B03D: 10 F6 BPL $B035 Kanaelen zugeordnet (BAM) B03F: A9 09 LDA #$09 Puffer 9 (INPUT) auf Kanal 5 B041: 85 D6 STA $D6 B043: A9 0A LDA #$0A Puffer 10 (ERROR) auf Kanal 6 B045: 85 D7 STA $D7 B047: A9 06 LDA #$06 SA 16 belegt Kanal 6 (lesen) B049: 85 B8 STA $B8 B04B: A9 85 LDA #$85 SA 15 belegt Kanal 5 (schreiben) B04D: 85 B7 STA $B7 B04F: A9 1F LDA #$1F Kanal 0-4 freigeben B051: 85 70 STA $70 B053: A9 01 LDA #$01 Kanal 5 auf Schreiben stellen B055: 8D 39 02 STA $0239 B058: A9 88 LDA #$88 Kanal 6 auf Lesen / kein EOI B05A: 8D 3A 02 STA $023A B05D: A9 80 LDA #$80 Pufferbelegung: Puffer 7 belegen B05F: 85 6D STA $6D [Puffer 8 hat kein Bit; ist immer belegt] B061: A9 01 LDA #$01 Diskette wurde gewechselt B063: 85 25 STA $25 B065: 20 C3 89 JSR $89C3 Standard Uservektoren-Tabelle setzen B068: 20 59 8D JSR $8D59 Reihenfolge der Pufferbelegung festlegen B06B: A9 01 LDA #$01 Sektorversatz auf 1 B06D: 85 2E STA $2E B06F: A9 02 LDA #$02 Anzahl der Leseversuche B071: 85 30 STA $30 B073: A9 00 LDA #$00 Burst-OR-Maske B075: 85 8A STA $8A B077: A9 FF LDA #$FF Burst-AND-Maske B079: 85 89 STA $89 B07B: A9 00 LDA #$00 Zeiger auf Cachepuffer B07D: 85 8B STA $8B B07F: A9 0C LDA #$0C nach $0c00 B081: 85 8C STA $8C B083: A9 08 LDA #$08 FSM-Bus aktiv / C64-Modus B085: 85 76 STA $76 B087: A9 33 LDA #$33 Dos-Version B089: 8D EC 01 STA $01EC B08C: A9 44 LDA #$44 1581-Formatkennzeichen B08E: 8D EB 01 STA $01EB B091: A9 C0 LDA #$C0 E/A-Byte: b6=1: CRC-Test ein; b7:Verify ein B093: 85 8D STA $8D b5=0: Super-Side-Sektoren verwenden B095: A9 50 LDA #$50 Anlaufzeit des Motors setzen (0,8 sec) B097: 8D D9 01 STA $01D9 B09A: A9 20 LDA #$20 Cache-Verzoegerung auf 32 (= 320 ms) setzen B09C: 85 9D STA $9D B09E: A2 00 LDX #$00 Job 0 benutzen B0A0: A9 82 LDA #$82 RESET_DV: Controller initialisieren B0A2: 20 9D 95 JSR $959D Job ausfuehren B0A5: C9 02 CMP #$02 Fehler ? B0A7: B0 05 BCS $B0AE ja, (Controller Error) ==> B0A9: A9 C0 LDA #$C0 RESTORE_DV: ('Bump') B0AB: 4C 9D 95 JMP $959D Job ausfuehren Einsprung von $B0A7: B0AE: A9 76 LDA #$76 76, Controller Error B0B0: 4C 67 A8 JMP $A867 Ganze Diskette als Partition setzen Einsprung von $84BB, $8ECB, $946D, $B7F7, $C2FC: B0B3: A9 00 LDA #$00 0: erste physikalische Spur B0B5: 85 8E STA $8E B0B7: A9 01 LDA #$01 1: logischer Starttrack der Partition B0B9: 85 90 STA $90 B0BB: A9 03 LDA #$03 3: 1. Sektor des Verzeichnisses B0BD: 8D E5 01 STA $01E5 B0C0: A9 51 LDA #$51 81: letzter Track der Partition +1 B0C2: 8D 2C 02 STA $022C B0C5: A9 4F LDA #$4F 79: letzte physikalische Spur B0C7: 85 8F STA $8F B0C9: A9 28 LDA #$28 40: Track des Directory setzen B0CB: 8D 2B 02 STA $022B B0CE: 60 RTS Physikalisches 1581-Diskettenformat festlegen Einsprung von $84B8, $8751, $8EC8, $946A, $C2F9: B0CF: A9 28 LDA #$28 40 Sektoren pro Track B0D1: 85 75 STA $75 B0D3: A0 02 LDY #$02 Sektorgroesse 2: 512 Bytes B0D5: 84 91 STY $91 B0D7: B9 06 BD LDA $BD06,Y Anzahl der Sektoren / Spur holen B0DA: 85 92 STA $92 = Anzahl der Sektoren / Spur B0DC: 85 93 STA $93 = letzte Sektornummer B0DE: 8D F0 01 STA $01F0 = groesste physikalische Sektornummer B0E1: 88 DEY y=1 B0E2: 84 94 STY $94 1. Sektornummer auf Zylinder = 1 B0E4: 8C EF 01 STY $01EF kleinster physikalischer Sektor B0E7: A9 F5 LDA #$F5 $f5: Verify vergleicht mit Cacheinhalt B0E9: 85 9B STA $9B (<>$f5: Vergleich mit $9b) B0EB: A9 23 LDA #$23 Anzahl der $4e-Bytes fuer Luecke zwischen B0ED: 85 9A STA $9A zwei Sektoren B0EF: 60 RTS JIDLE - Hauptleerschleife ($ebe7) B0F0: 78 SEI B0F1: A9 10 LDA #$10 automatische ATN-Beantwortung einschalten B0F3: 8D 01 40 STA $4001 Bus-Leitungen freigeben B0F6: 58 CLI B0F7: A5 7B LDA $7B Ist das Befehlsmodus-Flag gesetzt ? B0F9: F0 0A BEQ $B105 nein, ==> B0FB: A9 00 LDA #$00 Flag loeschen B0FD: 85 7B STA $7B B0FF: 20 04 80 JSR $8004 und Befehl auswerten B102: 20 BB AC JSR $ACBB FSM abschliessen Einsprung von $B0F9, $B158: B105: 58 CLI B106: A9 01 LDA #$01 Bus-Modus-Flag testen B108: 24 76 BIT $76 b0=1: Ist ein ATN aufgetreten ? B10A: F0 03 BEQ $B10F nein, ==> B10C: 4C 30 FF JMP $FF30 JATNSRV: ATN bedienen Drive-LED ein-/ausschalten Einsprung von $B10A: B10F: A5 87 LDA $87 Ist der Cachepuffer veraendert ? B111: D0 1E BNE $B131 ja, (LED an) ==> B113: A0 09 LDY #$09 8 Jobpuffer pruefen B115: A2 0E LDX #$0E 14 Kanaele pruefen Einsprung von $B126: B117: B5 A8 LDA $A8,X ist der Kanal aktiv ? B119: C9 FF CMP #$FF <> $ff B11B: D0 14 BNE $B131 ja, ==> B11D: 88 DEY B11E: 30 05 BMI $B125 sind alle Jobpuffer getestet ? ja, ==> B120: B9 02 00 LDA $0002,Y b7=1: ist Job noch aktiv ? B123: 30 0C BMI $B131 ja, ==> Einsprung von $B11E: B125: CA DEX B126: 10 EF BPL $B117 sind noch Kanaele zu pruefen ? ja, ==> B128: A5 79 LDA $79 b6=0: Drive-LED ausschalten B12A: 29 BF AND #$BF B12C: 85 79 STA $79 B12E: 4C 37 B1 JMP $B137 ==> Einsprung von $B111, $B11B, $B123: B131: A5 79 LDA $79 b6=1: Drive-LED einschalten B133: 09 40 ORA #$40 B135: 85 79 STA $79 Fehlerblinken ein-/ausschalten Einsprung von $B12E: B137: A5 25 LDA $25 wurde die Diskette gewechselt ? B139: F0 03 BEQ $B13E nein, ==> B13B: 20 6E 92 JSR $926E alle SA freigeben Einsprung von $B139: B13E: AE AB 02 LDX $02AB Fehlerflag pruefen B141: F0 08 BEQ $B14B =0: kein Fehler aufgetreten, ==> B143: A5 79 LDA $79 b5=1: Fehlerblinken einschalten B145: 09 20 ORA #$20 B147: 85 79 STA $79 B149: D0 06 BNE $B151 Einsprung von $B141: B14B: A5 79 LDA $79 b5=0: Fehlerblinken ausschalten B14D: 29 DF AND #$DF B14F: 85 79 STA $79 Einsprung von $B149: B151: A5 9C LDA $9C Verzoegerungszeit fuer 'Cache schreiben' B153: D0 03 BNE $B158 vorbei ? nein, ==> B155: 20 5B B1 JSR $B15B ja: Cache schreiben Einsprung von $B153: B158: 4C 05 B1 JMP $B105 weiter warten ==> Cache am Ende der Verzoegerungszeit auf Diskette schreiben Einsprung von $B155: B15B: A5 87 LDA $87 ist Cache veraendert worden ? B15D: F0 1C BEQ $B17B nein, ==> B15F: A9 40 LDA #$40 Flag: 'T&S nicht pruefen' setzen B161: 8D A8 02 STA $02A8 B164: A5 6C LDA $6C aktuelle Puffernummer B166: 48 PHA B167: A5 4D LDA $4D und T&S B169: 48 PHA B16A: A5 4E LDA $4E retten B16C: 48 PHA B16D: A2 07 LDX #$07 B16F: 20 6C FF JSR $FF6C Cache auf Diskette schreiben B172: 68 PLA T&S zurueckholen B173: 85 4E STA $4E B175: 68 PLA B176: 85 4D STA $4D B178: 68 PLA aktuelle Puffernummer zurueckholen B179: 85 6C STA $6C Einsprung von $B15D: B17B: 60 RTS Directory formatieren und in Ausgabepuffer schreiben ($ec9e) [Der Directory-Zeilen-Puffer wird in den Ausgabepuffer kopiert, dann wird eine neue Zeile formatiert. Dieser Vorgang wiederholt sich, bis der Ausgabepuffer voll ist. Beim ersten Aufruf muss sich der Diskname in dem Dir-Zeilen-Puffer befinden (s. $8627) und der erste Filename mit JSR $82ed gefunden worden sein. 8-Basiczeilen muessen den Ausgabepuffer genau fuellen, deshalb ist jede Zeile 32-Bytes lang, bis auf den Disknamen: Er ist nur 30 Bytes lang, damit noch 2 Bytes Basic-Startadresse in den Puffer passen. Ist der ganze Puffer ausgegeben worden, kann die Formatierung mit JSR $b1c8 fortgesetzt werden.] Einsprung von $9948: B17C: A9 00 LDA #$00 B17E: 85 52 STA $52 Aktuelle SA=0 B180: A9 01 LDA #$01 B182: 20 5A 91 JSR $915A Lesekanal suchen 1 Puffer belegen B185: A9 00 LDA #$00 Pufferzeiger auf 0 setzen B187: 20 22 94 JSR $9422 B18A: A6 50 LDX $50 Kanalnummer holen B18C: A9 00 LDA #$00 B18E: 9D 42 02 STA $0242,X EOI-Flag loeschen B191: 20 11 9F JSR $9F11 Pufferzeiger auf 0 setzen B194: AA TAX [alle 256 Bytes werden genutzt] B195: A9 00 LDA #$00 letzten Jobcode loeschen B197: 9D 72 02 STA $0272,X (Drivenummer 0 ) B19A: A9 01 LDA #$01 Startadersse = $0401 B19C: 20 B1 8E JSR $8EB1 Byte in Puffer schreiben B19F: A9 04 LDA #$04 [diese Adresse stammt noch aus der Zeit der B1A1: 20 B1 8E JSR $8EB1 alten CBM-Rechner / VC-20.] B1A4: A9 01 LDA #$01 Platzhalter fuer den Basic-Verkettungszeiger B1A6: 20 B1 8E JSR $8EB1 in den Puffer schreiben B1A9: 20 B1 8E JSR $8EB1 B1AC: AD 8D 02 LDA $028D Drivenummer als Basiczeilennummer B1AF: 20 B1 8E JSR $8EB1 in Puffer schreiben (Lo) B1B2: A9 00 LDA #$00 B1B4: 20 B1 8E JSR $8EB1 (Hi) B1B7: 20 37 B2 JSR $B237 Disk-Namen in den Puffer kopieren B1BA: 20 11 9F JSR $9F11 aktiven Puffer holen B1BD: 0A ASL B1BE: AA TAX B1BF: D6 BB DEC $BB,X Pufferzeiger -2 (=32) B1C1: D6 BB DEC $BB,X B1C3: A9 00 LDA #$00 Basic-Zeilenende-Kennzeichen in Puffer B1C5: 20 B1 8E JSR $8EB1 schreiben Puffer mit Directoryzeilen fuellen Einsprung von $B1E9, $B25D: B1C8: A9 01 LDA #$01 <-- (Einsprung) B1CA: 20 B1 8E JSR $8EB1 Platzhalter fuer den Basic-Verkettungszeiger B1CD: 20 B1 8E JSR $8EB1 B1D0: 20 4D 85 JSR $854D Directory-Zeile erzeugen B1D3: 90 2C BCC $B201 kein File mehr auszugeben ?, ==> B1D5: AD 8D 02 LDA $028D Programmlaenge als Basic-Zeilennummer B1D8: 20 B1 8E JSR $8EB1 verwenden (LO) B1DB: AD 8E 02 LDA $028E (Hi) B1DE: 20 B1 8E JSR $8EB1 B1E1: 20 37 B2 JSR $B237 Directoryzeile in Puffer kopieren B1E4: A9 00 LDA #$00 Basic-Zeilenende-Kennzeichen B1E6: 20 B1 8E JSR $8EB1 in Puffer schreiben B1E9: D0 DD BNE $B1C8 Puffer noch nicht voll, ==> Einsprung von $B234: B1EB: 20 11 9F JSR $9F11 aktiven Puffer holen B1EE: 0A ASL B1EF: AA TAX B1F0: A9 00 LDA #$00 Pufferzeiger auf 0 setzen B1F2: 95 BB STA $BB,X B1F4: A9 88 LDA #$88 B1F6: A4 50 LDY $50 Flag: B1F8: 8D 6E 02 STA $026E 'Directory wird auf SA 0 ausgegeben' setzen B1FB: 99 34 02 STA $0234,Y b7=1: 'Daten ausgeben'; b3=1: kein EOI B1FE: A5 54 LDA $54 aktuelles Datenbyte zurueckholen B200: 60 RTS 'Blocks free'-Meldung in den Puffer schreiben Einsprung von $B1D3: B201: AD 8D 02 LDA $028D 'Blocks free' als Basic-Zeilennummer merken B204: 20 B1 8E JSR $8EB1 (Lo) B207: AD 8E 02 LDA $028E B20A: 20 B1 8E JSR $8EB1 (Hi) B20D: 20 37 B2 JSR $B237 Directoryzeile in Puffer kopieren B210: 20 11 9F JSR $9F11 B213: 0A ASL Pufferzeiger -2 B214: AA TAX [Die Zeile darf incl. Basic-Ende-Zeichen B215: D6 BB DEC $BB,X nicht laenger als 32 Bytes sein.] B217: D6 BB DEC $BB,X B219: A9 00 LDA #$00 Zeichen fuer Basic-Ende in Puffer schreiben B21B: 20 B1 8E JSR $8EB1 (3 x $00) B21E: 20 B1 8E JSR $8EB1 B221: 20 B1 8E JSR $8EB1 B224: 20 11 9F JSR $9F11 aktuellen Pufferzeiger holen B227: 0A ASL B228: A8 TAY B229: B9 BB 00 LDA $00BB,Y B22C: A6 50 LDX $50 B22E: 9D 42 02 STA $0242,X und als Puffer-Ende merken B231: DE 42 02 DEC $0242,X -1 (letztes benutztes Zeichen merken) B234: 4C EB B1 JMP $B1EB Directoryzeile in Ausgabepuffer kopieren ($ed59) Einsprung von $B1B7, $B1E1, $B20D: B237: A0 00 LDY #$00 Einsprung von $B242: B239: B9 AC 02 LDA $02AC,Y Byte aus Dir-Zeilen-Puffer holen B23C: 20 B1 8E JSR $8EB1 und in Puffer schreiben B23F: C8 INY B240: C0 1B CPY #$1B 27 Zeichen kopieren B242: D0 F5 BNE $B239 B244: 60 RTS Byte aus Directory holen und zur Ausgabe bereitstellen ($ed67) Einsprung von $936A: B245: 20 71 90 JSR $9071 Byte aus aktuellen Puffer holen B248: F0 01 BEQ $B24B Puffer-Ende, ==> B24A: 60 RTS Einsprung von $B248: B24B: 85 54 STA $54 Byte merken B24D: A4 50 LDY $50 B24F: B9 42 02 LDA $0242,Y Puffergroesse holen B252: F0 08 BEQ $B25C =0 (noch nicht letzter Block), ==> B254: A9 80 LDA #$80 b3=0: EOI-Flag im Kanalstatus setzen B256: 99 34 02 STA $0234,Y B259: A5 54 LDA $54 Byte zurueckholen B25B: 60 RTS Einsprung von $B252: B25C: 48 PHA Byte aus dem Directory merken B25D: 20 C8 B1 JSR $B1C8 Ausgabepuffer neu fuellen B260: 68 PLA Byte zurueckholen B261: 60 RTS Validate-Befehl ($ed84) B262: 20 85 80 JSR $8085 Drivenummer holen B265: 20 03 8F JSR $8F03 Partition initialisieren B268: 20 4A B4 JSR $B44A neue BAM erzeugen, BAM-Blocks belegen B26B: A9 00 LDA #$00 Flag fuer Suche nach benutzten Directory- B26D: 85 73 STA $73 Eintraegen setzen B26F: 20 24 84 JSR $8424 1. Directory-Eintrag suchen B272: D0 38 BNE $B2AC gefunden, ==> Directory-Blocks belegen Einsprung von $B2AA: B274: A9 00 LDA #$00 1. Directory-Sektor holen B276: 85 4E STA $4E B278: AD 2B 02 LDA $022B B27B: 85 4D STA $4D B27D: 20 C7 B2 JSR $B2C7 Blocks belegen B280: 20 15 B5 JSR $B515 BAM abspeichern B283: 4C 4C 80 JMP $804C Ende Datei-Blocks (incl. Side-Sektoren) belegen Einsprung von $B2B6: B286: C8 INY y=1 B287: B1 64 LDA ($64),Y Track- & B289: 48 PHA B28A: C8 INY B28B: B1 64 LDA ($64),Y Sektornummer B28D: 48 PHA merken B28E: A0 13 LDY #$13 B290: B1 64 LDA ($64),Y sind Side-Sektoren vorhanden ? B292: F0 0A BEQ $B29E nein, ==> B294: 85 4D STA $4D T&S des ersten Side-Sektors B296: C8 INY setzen B297: B1 64 LDA ($64),Y B299: 85 4E STA $4E B29B: 20 C7 B2 JSR $B2C7 Blocks belegen Einsprung von $B292: B29E: 68 PLA B29F: 85 4E STA $4E T&S des Datenbereichs zurueckholen B2A1: 68 PLA B2A2: 85 4D STA $4D B2A4: 20 C7 B2 JSR $B2C7 und Blocks belegen naechstes File holen Einsprung von $B2BE, $B2C4: B2A7: 20 77 84 JSR $8477 Naechstes File suchen B2AA: F0 C8 BEQ $B274 Directory-Ende, ==> Einsprung von $B272: B2AC: A0 00 LDY #$00 B2AE: B1 64 LDA ($64),Y Filetyp holen B2B0: 10 0F BPL $B2C1 File nicht geschlossen, ==> B2B2: 29 07 AND #$07 Filetyp = CBM ? B2B4: C9 05 CMP #$05 B2B6: D0 CE BNE $B286 nein, ==> Partitions in BAM belegen B2B8: 20 23 B3 JSR $B323 Partition-Parameter holen B2BB: 20 3C B3 JSR $B33C Partition in BAM belegen B2BE: 4C A7 B2 JMP $B2A7 offene Files loeschen Einsprung von $B2B0: B2C1: 20 3B 87 JSR $873B Filetyp = 0 (DEL) setzen B2C4: 4C A7 B2 JMP $B2A7 naechstes File suchen Blocks eines Files in BAM belegen ($ede5) [Es ist etwas unguenstig, dass das File auf der selben SA geoeffnet wird, wie das Directory. So muss nach jedem File das Directory neu geladen werden.] Einsprung von $B27D, $B29B, $B2A4: B2C7: 20 B5 94 JSR $94B5 auf gueltige T&S pruefen B2CA: 20 72 B5 JSR $B572 Block in Bam belegen B2CD: 20 CF 93 JSR $93CF File auf SA 17 zum Lesen oeffnen Einsprung von $B2EC: B2D0: A9 00 LDA #$00 Pufferzeiger auf 0 setzen B2D2: 20 22 94 JSR $9422 B2D5: 20 71 90 JSR $9071 T&S des Folgeblocks holen B2D8: 85 4D STA $4D B2DA: 20 71 90 JSR $9071 B2DD: 85 4E STA $4E B2DF: A5 4D LDA $4D existiert Folgeblock ? B2E1: D0 03 BNE $B2E6 ja, ==> B2E3: 4C 9E 91 JMP $919E aktuelle SA schliessen Einsprung von $B2E1: B2E6: 20 72 B5 JSR $B572 naechsten Block in BAM belegen B2E9: 20 AA 93 JSR $93AA naechsten Block lesen B2EC: 4C D0 B2 JMP $B2D0 naechsten Block einer Partition holen A: c: 1: Track wurde gewechselt; z: 1: Ende der Partition erreicht Einsprung von $86D3, $B342, $B7CD, $B830, $B8AD: B2EF: AD EE 01 LDA $01EE Anzahl der uebrigen Blocks -1 B2F2: D0 08 BNE $B2FC Lo-Byte >0, ==> B2F4: AD ED 01 LDA $01ED Hi-Byte =0 (fertig), ==> B2F7: F0 1D BEQ $B316 B2F9: CE ED 01 DEC $01ED Hi-Byte -1 Einsprung von $B2F2: B2FC: CE EE 01 DEC $01EE Lo-Byte -1 B2FF: E6 4E INC $4E Sektornummer erhoehen B301: A5 75 LDA $75 'letzter Sektor +1' erreicht ? B303: C5 4E CMP $4E B305: D0 0F BNE $B316 nein, ==> B307: A9 00 LDA #$00 Sektornummer =0 B309: 85 4E STA $4E B30B: A5 4D LDA $4D Aktueller Track = B30D: CD 2B 02 CMP $022B Direktory-Track ? B310: F0 0C BEQ $B31E ja, ==> B312: E6 4D INC $4D Tracknummer +1 [Es ist ein Fehler, dass die Tracknummer erst nach der Gueltigkeitsabfrage erhoeht wird; so merkt die Routine es erst am Ende des Tracks, wenn die Partition Directory-Blocks umfassen soll. Trotzdem ist das Directory davor geschuetzt, ueberschrieben zu werden, da der erste Block im Directory (Verzeichnis-Header) immer als belegt gekennzeichnet ist und dadurch der Partition-Befehl abbricht. Ausserdem verhindert eine zusaetzliche Abfrage ($b822), dass eine Partition im Track 40 beginnt. Innerhalb von Partitions ist es moeglich, im Verzeichnis-Track eine Partition zu definieren, die den letzten Block des Tracks nicht beinhalten darf.] B314: 38 SEC c=1: Track wurde gewechselt B315: 24 B $24 Einsprung von $B2F7, $B305: B316: 18 CLC c=0: gleicher Track B317: AD ED 01 LDA $01ED Ist die Anzahl der uebrigen Blocks =0 ? B31A: 0D EE 01 ORA $01EE ja, dann z=1 B31D: 60 RTS Einsprung von $B310: B31E: A9 67 LDA #$67 67, Illegal Track or Sector B320: 4C 3F FF JMP $FF3F Partition-Parameter aus Verzeichniseintrag holen Einsprung von $B2B8, $B7C7: B323: A0 01 LDY #$01 B325: B1 64 LDA ($64),Y Starttrack B327: 85 4D STA $4D B329: C8 INY B32A: B1 64 LDA ($64),Y Startsektor B32C: 85 4E STA $4E B32E: A0 1C LDY #$1C B330: B1 64 LDA ($64),Y Partition-Laenge B332: 8D EE 01 STA $01EE Lo B335: C8 INY B336: B1 64 LDA ($64),Y B338: 8D ED 01 STA $01ED Hi B33B: 60 RTS Partition in Bam belegen Einsprung von $B345, $B2BB: B33C: 20 B5 94 JSR $94B5 auf gueltigen Block testen B33F: 20 72 B5 JSR $B572 und in Bam belegen B342: 20 EF B2 JSR $B2EF naechsten Block holen B345: D0 F5 BNE $B33C noch einer uebrig ? ja, ==> B347: 60 RTS NEW-Befehl ($ee0d) B348: 20 FD 81 JSR $81FD Laufwerksnummer holen B34B: A5 EF LDA $EF Laufwerksnummer OK. ? B34D: 10 05 BPL $B354 ja, ==> B34F: A9 33 LDA #$33 33, Syntax Error B351: 4C 7C 80 JMP $807C Einsprung von $B34D: B354: A9 00 LDA #$00 B356: 85 6E STA $6E Drivestatus loeschen B358: 8D FA 01 STA $01FA Schreibschutz-Status loeschen B35B: 20 F6 81 JSR $81F6 Drive-LED einschalten B35E: A2 00 LDX #$00 B360: AC 92 02 LDY $0292 2. Parameter B363: C4 29 CPY $29 = Zeilenende ? B365: F0 19 BEQ $B380 ja, nur Verzeichnis anlegen ==> B367: B9 00 02 LDA $0200,Y Neue ID setzen B36A: 95 1D STA $1D,X (x=0) B36C: B9 01 02 LDA $0201,Y B36F: 95 1E STA $1E,X B371: 20 62 92 JSR $9262 Kanaele der SA 1-14 freigeben B374: 20 69 FF JSR $FF69 Prueft auf Diskettenwechsel B377: 20 46 87 JSR $8746 Partition formatieren B37A: 20 3D B4 JSR $B43D BAM-Puffer loeschen B37D: 4C 90 B3 JMP $B390 Verzeichnis anlegen ??? Einsprung von $B365: B380: 20 69 FF JSR $FF69 Prueft auf Diskettenwechsel B383: 20 03 8F JSR $8F03 Partition initialisieren B386: A5 6F LDA $6F Formatkennzeichen mit B388: CD EB 01 CMP $01EB 1581-Kennzeichen vergleichen B38B: F0 03 BEQ $B390 gleich, ==> B38D: 4C CB 94 JMP $94CB 73, Copyright CBM ... Verzeichnis-Header und BAM anlegen ($ee56) Verzeichnis-Header anlegen Einsprung von $B37D, $B38B: B390: A5 6C LDA $6C letzte Jobnummer B392: A8 TAY B393: 0A ASL *2 B394: AA TAX B395: AD 77 DB LDA $DB77 Position des Verzeichnisnamens B398: 95 BB STA $BB,X Pufferzeiger setzen B39A: AE 91 02 LDX $0291 B39D: A9 1B LDA #$1B B39F: 20 EE 84 JSR $84EE Diskettennamen kopieren B3A2: A0 00 LDY #$00 B3A4: 84 64 STY $64 Pufferzeiger auf 0 setzen B3A6: AD 2B 02 LDA $022B Verzeichnis-Track B3A9: 91 64 STA ($64),Y als Zeiger auf naechsten Block B3AB: C8 INY B3AC: A9 03 LDA #$03 1. Verzeichnis-Sektor B3AE: 8D E5 01 STA $01E5 B3B1: 91 64 STA ($64),Y als Zeiger auf naechsten Block B3B3: C8 INY B3B4: AD EB 01 LDA $01EB Formatkennzeichen B3B7: 85 6F STA $6F = aktuelles Formatkennzeichen B3B9: 91 64 STA ($64),Y im Block merken B3BB: C8 INY B3BC: A9 00 LDA #$00 $00 B3BE: 91 64 STA ($64),Y B3C0: A0 16 LDY #$16 Weiter bei Position 22 B3C2: A5 1D LDA $1D ID1 B3C4: 91 64 STA ($64),Y B3C6: C8 INY B3C7: A5 1E LDA $1E ID2 B3C9: 91 64 STA ($64),Y B3CB: C8 INY B3CC: A9 A0 LDA #$A0 $a0 B3CE: 91 64 STA ($64),Y B3D0: C8 INY B3D1: AD EC 01 LDA $01EC DOS-Versionsnummer B3D4: 91 64 STA ($64),Y B3D6: C8 INY B3D7: A5 6F LDA $6F Diskettenversionsnummer B3D9: 91 64 STA ($64),Y B3DB: C8 INY B3DC: A9 A0 LDA #$A0 $a0 B3DE: 91 64 STA ($64),Y B3E0: C8 INY B3E1: 91 64 STA ($64),Y $a0 B3E3: C8 INY B3E4: A9 00 LDA #$00 Rest vom Block mit $00 fuellen Einsprung von $B3E9: B3E6: 91 64 STA ($64),Y B3E8: C8 INY B3E9: D0 FB BNE $B3E6 B3EB: A9 00 LDA #$00 Sektornummer = 0 B3ED: 20 35 B4 JSR $B435 T&S des 1. Directory-Sektors setzen B3F0: 20 C1 93 JSR $93C1 Puffer schreiben 1. Directory-Sektor anlegen B3F3: A9 00 LDA #$00 B3F5: 85 64 STA $64 Pufferzeiger auf 0 B3F7: A8 TAY Einsprung von $B3FB: B3F8: 91 64 STA ($64),Y Puffer mit $00 fuellen B3FA: C8 INY B3FB: D0 FB BNE $B3F8 B3FD: C8 INY y=1 B3FE: A9 FF LDA #$FF $00, $ff an Blockanfang schreiben B400: 91 64 STA ($64),Y (Zeichen fuer letzten Dir-Block) B402: AD E5 01 LDA $01E5 Nummer des 1. Dir-Sektors holen B405: 20 35 B4 JSR $B435 und als aktuelle T&S setzen B408: 20 C1 93 JSR $93C1 Puffer schreiben BAM anlegen B40B: 20 4A B4 JSR $B44A neue BAM anlegen B40E: AD 2B 02 LDA $022B B411: 85 4D STA $4D Verzeichnis-Header in BAM belegen B413: A9 00 LDA #$00 B415: 85 4E STA $4E B417: 20 72 B5 JSR $B572 Block belegen B41A: E6 4E INC $4E B41C: 20 72 B5 JSR $B572 1. BAM-Block belegen B41F: E6 4E INC $4E B421: 20 72 B5 JSR $B572 2. BAM-Block belegen B424: AD E5 01 LDA $01E5 B427: 85 4E STA $4E 1. Verzeichnis-Block belegen B429: 20 72 B5 JSR $B572 B42C: 20 12 B6 JSR $B612 BAM auf Diskette schreiben B42F: 20 03 8F JSR $8F03 Partition initialisieren B432: 4C 4C 80 JMP $804C Ok. Ende T&S eines Blocks des Verzeichnisses setzen Einsprung von $B3ED, $B405: B435: 85 4E STA $4E Sektornummer in a B437: AD 2B 02 LDA $022B Directory-Track B43A: 85 4D STA $4D B43C: 60 RTS BAM-Puffer loeschen ($f005) Einsprung von $B37A: B43D: A9 00 LDA #$00 B43F: A8 TAY Einsprung von $B447: B440: 99 00 0A STA $0A00,Y 1. Puffer & B443: 99 00 0B STA $0B00,Y 2. Puffer B446: C8 INY loeschen B447: D0 F7 BNE $B440 B449: 60 RTS neue BAM erzeugen ($eeb7) Einsprung von $B268, $B40B: B44A: A9 00 LDA #$00 beim Erzeugen der Bam mit der B44C: 85 4D STA $4D ersten Spur beginnen B44E: AD 2B 02 LDA $022B Link-Zeiger der BAM-Bloecke setzen B451: 8D 00 0A STA $0A00 im 1. BAM-Puffer: tt, $02 B454: A9 00 LDA #$00 B456: 8D 00 0B STA $0B00 im 2. BAM-Puffer: $00, $ff B459: A9 02 LDA #$02 B45B: 8D 01 0A STA $0A01 B45E: A9 FF LDA #$FF B460: 8D 01 0B STA $0B01 B463: AD EB 01 LDA $01EB 1581-Formatkennzeichen abspeichern B466: 8D 02 0A STA $0A02 B469: 8D 02 0B STA $0B02 B46C: 49 FF EOR #$FF negiert B46E: 8D 03 0A STA $0A03 ergibt das ergaenzende Formatkennzeichen B471: 8D 03 0B STA $0B03 B474: A5 1D LDA $1D ID1 und B476: 8D 04 0A STA $0A04 B479: 8D 04 0B STA $0B04 B47C: A5 1E LDA $1E ID2 abspeichern B47E: 8D 05 0A STA $0A05 B481: 8D 05 0B STA $0B05 B484: A5 8D LDA $8D E/A-Byte B486: 8D 06 0A STA $0A06 B489: 8D 06 0B STA $0B06 B48C: A9 00 LDA #$00 Auto-Boot ausschalten B48E: 8D 07 0A STA $0A07 B491: 8D 07 0B STA $0B07 Bloecke, die zur Partition gehoeren, freigeben alle anderen als belegt kennzeichnen B494: 20 52 B6 JSR $B652 Zeiger auf 1. BAM-Eintrag setzen ($4d = 0) Einsprung von $B4E9: B497: A0 10 LDY #$10 $10: Start der BAM im BAM-Block Einsprung von $B4DF: B499: E6 4D INC $4D naechsten Track waehlen B49B: A5 4D LDA $4D aktuelle Tracknummer B49D: C5 90 CMP $90 mit Start der Partition vergleichen B49F: F0 0B BEQ $B4AC = : Blocks freigeben ==> B4A1: 90 07 BCC $B4AA < : Blocks belegen ==> B4A3: CD 2C 02 CMP $022C >= Ende der Partition ? B4A6: F0 02 BEQ $B4AA B4A8: 90 02 BCC $B4AC nein, (Blocks freigeben) ==> Einsprung von $B4A1, $B4A6: B4AA: 18 CLC ja: Blocks belegen B4AB: 24 B $24 Einsprung von $B49F, $B4A8: B4AC: 38 SEC Blocks freigeben B4AD: 08 PHP B4AE: A9 00 LDA #$00 Bam-Muster: 'Alle Blocks belegt' B4B0: 85 40 STA $40 B4B2: 85 41 STA $41 B4B4: 85 42 STA $42 B4B6: 85 43 STA $43 B4B8: 85 44 STA $44 B4BA: A6 75 LDX $75 Anzahl Sektoren pro Track holen B4BC: 8A TXA B4BD: B0 02 BCS $B4C1 c=1, ==> B4BF: A9 00 LDA #$00 c=0: 0 Blocks frei Einsprung von $B4BD: B4C1: 91 31 STA ($31),Y Anzahl der freien Blocks B4C3: C8 INY Einsprung von $B4D1: B4C4: 28 PLP [Diese Routine ist fuer Disketten gedacht, B4C5: 08 PHP die eine flexible Zahl Blocks/Track haben B4C6: 26 40 ROL $40 haben und bei denen die Blockzahl kein B4C8: 26 41 ROL $41 Vielfaches von 8 ist (1541: 17-21 Blocks). B4CA: 26 42 ROL $42 Bei der 1581 (40 Blocks / Track) werden: B4CC: 26 43 ROL $43 bei c=1 alle Bytes = $ff, B4CE: 26 44 ROL $44 bei c=0 alle Bytes = $00] B4D0: CA DEX Anzahl zu belegender Sektoren -1 B4D1: D0 F1 BNE $B4C4 naechsten Sektor belegen, ==> B4D3: 28 PLP Einsprung von $B4DC: B4D4: B5 40 LDA $40,X Bitmuster in BAM kopieren B4D6: 91 31 STA ($31),Y B4D8: C8 INY B4D9: E8 INX B4DA: E0 05 CPX #$05 (5 Bytes) B4DC: 90 F6 BCC $B4D4 B4DE: 98 TYA Ende des BAM-Puffers erreicht ? B4DF: D0 B8 BNE $B499 nein, ==> B4E1: A5 32 LDA $32 War es bereits der 2. Puffer ? B4E3: C9 0B CMP #$0B B4E5: F0 04 BEQ $B4EB ja, ==> B4E7: E6 32 INC $32 naechsten BAM-Puffer waehlen B4E9: D0 AC BNE $B497 immer ==> Directory-Bloecke in BAM belegen und 'Blocks free' berechnen Einsprung von $B4E5: B4EB: A9 01 LDA #$01 Flag 'BAM abspeichern' setzen B4ED: 85 35 STA $35 B4EF: A9 00 LDA #$00 'Blocks Free' Lo =0 (wozu ?) B4F1: 8D A9 02 STA $02A9 B4F4: AD 2B 02 LDA $022B Directory-Track holen B4F7: 85 4D STA $4D B4F9: A9 00 LDA #$00 Verzeichnis-Header B4FB: 85 4E STA $4E B4FD: 20 72 B5 JSR $B572 belegen B500: E6 4E INC $4E 1. BAM-Block B502: 20 72 B5 JSR $B572 belegen B505: E6 4E INC $4E 2. BAM-Block B507: 20 72 B5 JSR $B572 belegen B50A: AD E5 01 LDA $01E5 1. Verzeichnis-Block B50D: 85 4E STA $4E B50F: 20 72 B5 JSR $B572 belegen B512: 4C 85 8F JMP $8F85 Anzahl 'Blocks free' berechnen Wenn die BAM geaendert wurde, dann BAM auf Fehler pruefen und wenn Ok., abspeichern ($eef4) Einsprung von $872C, $997D, $9996, $99C2, $9C7C, $A41D, $B280, $B633, $DBEE: B515: A5 35 LDA $35 wurde BAM geaendert ? B517: F0 28 BEQ $B541 nein, ==> B519: AD 2C 02 LDA $022C letzter Track der Partition B51C: 85 66 STA $66 B51E: 20 52 B6 JSR $B652 Zeiger auf 1. BAM-Puffer setzen Einsprung von $B53B: B521: A9 10 LDA #$10 Bei 1. Track des BAM-Puffers anfangen Einsprung von $B531: B523: 85 31 STA $31 B525: 20 5E B7 JSR $B75E BAM-Eintrag pruefen B528: C6 66 DEC $66 noch ein Track zu pruefen ? B52A: F0 12 BEQ $B53E nein, ==> B52C: 18 CLC B52D: A5 31 LDA $31 Naechsten Track auswaehlen B52F: 69 06 ADC #$06 B531: 90 F0 BCC $B523 Ende des Bampuffer ? nein, ==> B533: A5 32 LDA $32 aktuelle Puffer-Nummer testen B535: C9 0B CMP #$0B war schon der 2. Bampuffer dran ? B537: F0 05 BEQ $B53E ja, ==> B539: E6 32 INC $32 auf 2. Puffer schalten B53B: 4C 21 B5 JMP $B521 und pruefen Einsprung von $B52A, $B537: B53E: 20 12 B6 JSR $B612 BAM auf Diskette schreiben Einsprung von $B517: B541: A9 00 LDA #$00 Flag fuer 'BAM geaendert' loeschen B543: 85 35 STA $35 B545: 60 RTS Block in Bam freigeben ($ef5f) E: $4c, $4e: T&S Einsprung von $86D0, $8713, $8732, $8B29, $B82D: B546: 20 B4 B5 JSR $B5B4 BAM-Zeiger auf aktuellen Track setzen B549: 20 D8 B5 JSR $B5D8 ist Block ueberhaupt belegt ? B54C: D0 23 BNE $B571 nein, ==> B54E: B1 31 LDA ($31),Y Block freigeben B550: 1D EA B5 ORA $B5EA,X durch setzen des entsprechenden Bits B553: 91 31 STA ($31),Y B555: A9 01 LDA #$01 Flag fuer 'BAM geaendert' setzen B557: 85 35 STA $35 B559: A0 00 LDY #$00 B55B: 18 CLC B55C: B1 31 LDA ($31),Y Anzahl der freien Blocks +1 B55E: 69 01 ADC #$01 B560: 91 31 STA ($31),Y B562: A5 4D LDA $4D Aktueller Track B564: CD 2B 02 CMP $022B = Direktory-Track B567: F0 34 BEQ $B59D ja, ==> [Dieser Sprung sollte nach $b571 oder $b5a0 gehen, aber doch sicherlich nicht nach $b59d ! Dieser Fehler ist auch schon in der 1541 vorhanden.] B569: EE A9 02 INC $02A9 Anzahl der 'Blocks free' +1 B56C: D0 03 BNE $B571 B56E: EE AA 02 INC $02AA Einsprung von $B54C, $B56C: B571: 60 RTS Block in BAM belegen ($ef93) E: $4d, $4e: T&S Einsprung von $8B42, $B2CA, $B2E6, $B33F, $B417, $B41C, $B421, $B429, $B4FD, $B502, $B507, $B50F, $B6DE, $B73E, $B828, $B8AA: B572: 20 B4 B5 JSR $B5B4 BAM-Zeiger auf aktuellen Track setzen B575: 20 D8 B5 JSR $B5D8 ist Block schon belegt ? B578: F0 39 BEQ $B5B3 ja, ==> B57A: B1 31 LDA ($31),Y Block belegen B57C: 5D EA B5 EOR $B5EA,X B57F: 91 31 STA ($31),Y B581: A9 01 LDA #$01 Flag fuer 'BAM geaendert' setzen B583: 85 35 STA $35 B585: A0 00 LDY #$00 B587: B1 31 LDA ($31),Y Anzahl der freien Blocks -1 B589: 38 SEC B58A: E9 01 SBC #$01 B58C: 91 31 STA ($31),Y B58E: A5 4D LDA $4D Aktueller Track B590: CD 2B 02 CMP $022B = Direktory-Track B593: F0 0B BEQ $B5A0 ja, ==> B595: AD A9 02 LDA $02A9 Anzahl 'Blocks free' -1 B598: D0 03 BNE $B59D B59A: CE AA 02 DEC $02AA Einsprung von $B598, $B567: B59D: CE A9 02 DEC $02A9 Einsprung von $B593: B5A0: AD AA 02 LDA $02AA Sind weniger als 3 Blocks frei ? B5A3: D0 0E BNE $B5B3 B5A5: AD A9 02 LDA $02A9 B5A8: C9 03 CMP #$03 B5AA: B0 05 BCS $B5B1 B5AC: A9 72 LDA #$72 72, Disk full ausgeben, aber nicht als B5AE: 4C 6D A8 JMP $A86D Fehler behandeln, sondern als Hinweis Einsprung von $B5AA: B5B1: A9 01 LDA #$01 z=0: Block ist belegt worden Einsprung von $B578, $B5A3: B5B3: 60 RTS (z=1: Block war schon belegt) BAM-Zeiger auf Eintrag fuer aktuellen Track setzen ($f011) Einsprung von $B546, $B572, $B675, $B710, $B72B, $B746: B5B4: A5 6E LDA $6E Drivestatus Ok. ? B5B6: F0 05 BEQ $B5BD ja, ==> B5B8: A9 74 LDA #$74 74, Drive not ready B5BA: 20 3F FF JSR $FF3F Einsprung von $B5B6, $8FA0: B5BD: 20 52 B6 JSR $B652 Zeiger auf 1. BAM-Puffer setzen B5C0: A5 4D LDA $4D (Tracks 1-40) B5C2: C9 29 CMP #$29 Tracknummer < 41 B5C4: 90 04 BCC $B5CA ja, ==> B5C6: E9 28 SBC #$28 Auf 2. BAM-Puffer schalten B5C8: E6 32 INC $32 (Tracks 41-80) Einsprung von $B5C4: B5CA: 0A ASL Tracknummer * 6 [5 Bytes fuer das Bitmuster B5CB: 85 31 STA $31 (5 * 8 Bit = 40 Bit fuer 40 Blocks) B5CD: 0A ASL +1 Byte (Anzahl freier Blocks) = 6 Bytes] B5CE: 18 CLC B5CF: 65 31 ADC $31 B5D1: 69 0A ADC #$0A + 10 (Anfang der Tabelle) B5D3: 85 31 STA $31 Zeigt auf BAM-Bitmuster des aktuellen B5D5: A0 00 LDY #$00 Tracks B5D7: 60 RTS Pruefen, ob Block $4e im aktuellen Track frei ist ($efd2) Einsprung von $B549, $B575, $B752: B5D8: A5 4E LDA $4E Blocknummer / 8 + 1 B5DA: 4A LSR = Position des Bytes mit gesuchtem Bit B5DB: 4A LSR B5DC: 4A LSR B5DD: A8 TAY B5DE: C8 INY Anzahl freie Blocks ueberspringen B5DF: A5 4E LDA $4E Blocknummer and #$07 B5E1: 29 07 AND #$07 = Position des gesuchten Bits im Byte B5E3: AA TAX B5E4: B1 31 LDA ($31),Y Zustand des Bits ermitteln B5E6: 3D EA B5 AND $B5EA,X Bit=0 (z=1): Block belegt B5E9: 60 RTS B5EA: 01 02 04 08 10 20 40 80 Bit-Tabelle (fuer BAM-Zugriffe) Wenn BAM-Puffer leer, dann BAM einlesen ($f0df) Einsprung von $B640, $B64F: B5F2: A5 6C LDA $6C aktuellen Puffer merken B5F4: 85 3F STA $3F B5F6: AD 00 0A LDA $0A00 ist eine Bam im Speicher B5F9: D0 2F BNE $B62A ja, ==> B5FB: A9 07 LDA #$07 in Puffer 7 den Block tt,01 laden B5FD: A2 01 LDX #$01 (tt = Dir-Track) B5FF: 20 43 B6 JSR $B643 T&S und Puffernummer an DC B602: 20 DE 94 JSR $94DE Job ausfuehren und ueberwachen B605: A9 08 LDA #$08 in Puffer 8 den Block tt,02 laden B607: A2 02 LDX #$02 B609: 20 43 B6 JSR $B643 T&S und Puffernummer an DC B60C: 20 DE 94 JSR $94DE Job ausfuehren und ueberwachen B60F: 4C 2A B6 JMP $B62A aktuelle Puffernummer zurueckholen BAM auf Diskette schreiben Einsprung von $B42C, $B53E: B612: A5 6C LDA $6C aktuellen Puffer merken B614: 85 3F STA $3F B616: A9 07 LDA #$07 Puffer 7 B618: A2 01 LDX #$01 in den Directory-Sektor 1 schreiben B61A: 20 43 B6 JSR $B643 T&S und Puffernummer uebergeben B61D: 20 E2 94 JSR $94E2 Dir-Sektor schreiben B620: A9 08 LDA #$08 Puffer 8 B622: A2 02 LDX #$02 in den Directory-Sektor 2 schreiben B624: 20 43 B6 JSR $B643 T&S und Puffernummer uebergeben B627: 20 E2 94 JSR $94E2 Dir-Sektor schreiben Einsprung von $B5F9, $B60F: B62A: A5 3F LDA $3F Puffernummer wieder herstellen B62C: 85 6C STA $6C B62E: A9 00 LDA #$00 Flag fuer 'Bam nicht veraendert' B630: 85 35 STA $35 B632: 60 RTS Verzeichnis-Header in aktuellen Puffer lesen, ggf. BAM lesen Einsprung von $862A: B633: 20 15 B5 JSR $B515 Bam ggf. abspeichern B636: A2 00 LDX #$00 Verzeichnis-Header (x: Sektornummer) B638: A5 6C LDA $6C in aktuellen Puffer lesen B63A: 20 43 B6 JSR $B643 T&S an DC uebergeben B63D: 20 DE 94 JSR $94DE Job ausfuehren und ueberwachen B640: 4C F2 B5 JMP $B5F2 Wenn Bam-Puffer leer, Bam lesen T&S und Puffernummer eines Dir-Sektors an DC uebergeben Einsprung von $B5FF, $B609, $B61A, $B624, $B63A: B643: 85 6C STA $6C Puffernummer B645: 86 4E STX $4E Sekornummer B647: AE 2B 02 LDX $022B Directory-Track setzen B64A: 86 4D STX $4D B64C: 4C 88 95 JMP $9588 T&S an DC uebergeben BAM-Zeiger auf 1. BAM-Puffer setzen ($ef3a) Einsprung von $8F41: B64F: 20 F2 B5 JSR $B5F2 BAM wenn noetig einlesen Einsprung von $B494, $B51E, $B5BD: B652: A9 0A LDA #$0A Zeiger auf 1. BAM-Puffer setzen ($0a00) B654: 85 32 STA $32 B656: A9 00 LDA #$00 B658: 85 31 STA $31 B65A: 60 RTS Anzahl freier Blocks zur Ausgabe bereitstellen ($ef4d) Einsprung von $8679, $A2DC: B65B: AD A9 02 LDA $02A9 Anzahl freier Blocks B65E: 8D 8D 02 STA $028D Als Basic-Zeilennummer speichern B661: AD AA 02 LDA $02AA B664: 8D 8E 02 STA $028E B667: 60 RTS Folgeblock fuer Datei suchen ($f11e) [Die Suche nach einem freien Block wird in 3 Phasen unterteilt: 1. Ausgehend vom aktuellen Track wird ein Track gesucht, in dem mindestens ein freier Block ist. Dabei wird vom Directory weg gesucht (nach Track 39 kommt 38; nach Track 41 kommt 42). Wenn bis zum Rand der Diskette (Partition) kein Track gefunden wurde kommt Phase 2. 2. Es wird auf der anderen Seite des Directorys nach einem Track mit freien Blocks gesucht. 3. Die Routine versucht es noch einmal auf der ersten Seite, um evtl. freie Blocks zu finden, die sich zwischen Directory und dem aktuellen Block befinden. Ist die aktuelle Tracknummer = Directory-Track, dann wird die Suche auf den Directory-Track beschraenkt. Achtung: Leider ist diese Routine nicht fuer den Cachepuffer optimiert worden: Wenn alle Blocks auf einem Track belegt worden sind, wird fuer den naechsten Sektor die Tracknummer erhoeht und der Sektorversatz zur aktuellen Sektornummer addiert. War der letzte Sektor nicht die Nummer 40, wird mitten in der Spur angefangen, die Blocks zu belegen. Die Folge ist, dass diese Spur spaeter 2 mal geladen werden muss. z.B.: Der 1. belegte Sektor ist die Nummer 4, dann wird der Cache mit der Seite 0 gefuellt. Nun koennen die Blocks 4-19 gelesen werden. Fuer die Blocks 20-39 muss die Seite 1 geladen werden, und schliesslich fuer die Blocks 0-3 wieder die Seite 0. Diese Situation tritt zum Glueck nur selten auf (besonders bei REL-Files).] Einsprung von $9118, $9C07, $9CAA, $A387, $A39A, $A459: B668: 20 7C 9D JSR $9D7C T&S der aktuellen Datei holen B66B: A9 03 LDA #$03 B66D: 85 40 STA $40 Zaehler fuer Phasen der Blocksuche setzen B66F: A9 01 LDA #$01 Flag 'BAM veraendert' setzen B671: 05 35 ORA $35 [Dieses ORA stammt von der 1541 und ist B673: 85 35 STA $35 bei der 1581 ueberfluessig.] Einsprung von $B68C, $B69E, $B6AD, $B6BB, $93F5: B675: 20 B4 B5 JSR $B5B4 BAM-Zeiger auf aktuellen Track setzen B678: B1 31 LDA ($31),Y Anzahl freier Blocks holen B67A: D0 43 BNE $B6BF >0, (freie Blocks) ==> B67C: A5 4D LDA $4D 'aktueller Track' mit 'Dir-Track' B67E: CD 2B 02 CMP $022B vergleichen B681: F0 1D BEQ $B6A0 = , Suche beenden ==> B683: 90 20 BCC $B6A5 < , (in Richtung Track1 suchen) ==> in Richtung Track80 suchen B685: E6 4D INC $4D Tracknummer erhoehen B687: A5 4D LDA $4D B689: CD 2C 02 CMP $022C Ist der Track innerhalb der Partition B68C: D0 E7 BNE $B675 ja, ==> B68E: AE 2B 02 LDX $022B auf die andere Seite wechseln B691: CA DEX Suche bei 'Directory-Track -1' fortsetzen B692: 86 4D STX $4D B694: E4 90 CPX $90 existiert die andere Seite ? B696: 90 17 BCC $B6AF (bei Partitions nicht), ==> [eigentlich muesste bei Partitions die 2. Phase uebersprungen werden: 2 x DEC 40. Dies geschieht aber nicht. Dadurch sucht das DOS bei den beiden letzten Phasen im gleichen Bereich.] B698: A9 00 LDA #$00 Sektor = 0 setzen [Spaeter wird der Sektor- B69A: 85 4E STA $4E versatz addiert! Dann wird nicht mehr am Spuranfang begonnen, Blocks zu belegen, sondern bei Sektor 1.] B69C: C6 40 DEC $40 naechste Phase B69E: D0 D5 BNE $B675 noch eine Suchphase, ==> Einsprung von $B681, $B6BD: B6A0: A9 72 LDA #$72 72, Disk full B6A2: 20 7C 80 JSR $807C in Richtung Track1 suchen Einsprung von $B683: B6A5: A5 4D LDA $4D Ist Start der Partition erreicht? B6A7: C5 90 CMP $90 [Die Abfrage kommt doch einen Track zu spaet !? (Sie wird aber zum Glueck nie gebraucht, da immer vom Directory weg gesucht wird)] B6A9: 90 04 BCC $B6AF befand sich der letzte gepruefte Track vor dem Partition-Anfang ? ja, ==> B6AB: C6 4D DEC $4D Tracknummer -1 B6AD: D0 C6 BNE $B675 Disketten-Anfang? nein, (hier klappt's) ==> Einsprung von $B696, $B6A9: B6AF: AE 2B 02 LDX $022B Seite wechseln B6B2: E8 INX B6B3: 86 4D STX $4D B6B5: A9 00 LDA #$00 Sektor = 0 setzen B6B7: 85 4E STA $4E [Spaeter wird der Sektorversatz addiert !] B6B9: C6 40 DEC $40 naechste Phase B6BB: D0 B8 BNE $B675 noch eine Suchphase, ==> B6BD: F0 E1 BEQ $B6A0 72, Disk full freien Sektor auf dem aktuellen Track suchen Einsprung von $B67A: B6BF: A5 4E LDA $4E Sektornummer um Sektorversatz erhoehen B6C1: 18 CLC B6C2: 65 2E ADC $2E B6C4: 85 4E STA $4E B6C6: A5 75 LDA $75 Anzahl Sektoren pro Track holen (40) B6C8: 85 28 STA $28 Jobcode ??? [Stammt noch von der 1541.] B6CA: C5 4E CMP $4E ist das Spurende ueberschritten ? B6CC: B0 0B BCS $B6D9 nein, [Sektor 40 ist aber auch zu gross] ==> B6CE: 38 SEC Tracknummer >= 41: B6CF: A5 4E LDA $4E Sektornummer - Anzahl der Sektoren / Track B6D1: E5 75 SBC $75 B6D3: 85 4E STA $4E B6D5: F0 02 BEQ $B6D9 =0, ==> B6D7: C6 4E DEC $4E -1 Einsprung von $B6CC, $B6D5: B6D9: 20 46 B7 JSR $B746 naechsten freien Block auf dem Track suchen B6DC: F0 03 BEQ $B6E1 nicht gefunden, ==> Einsprung von $B6E8: B6DE: 4C 72 B5 JMP $B572 Block in BAM belegen Einsprung von $B6DC: B6E1: A9 00 LDA #$00 Sektornummer =0 setzen B6E3: 85 4E STA $4E B6E5: 20 46 B7 JSR $B746 und noch einmal einen freien Block suchen B6E8: D0 F4 BNE $B6DE erfolgreich, ==> B6EA: 4C 41 B7 JMP $B741 71, Dir Error Startblock einer neuen Datei suchen ($f1a9) Einsprung von $9BC3: B6ED: A9 01 LDA #$01 Flag 'Bam geaendert' setzen B6EF: 05 35 ORA $35 B6F1: 85 35 STA $35 B6F3: A5 55 LDA $55 Wert (von Side-Sektoren) merken B6F5: 48 PHA B6F6: A9 01 LDA #$01 Distanz zum Directory-Track = 1 B6F8: 85 55 STA $55 Tracks < Directory-Track untersuchen Einsprung von $B730: B6FA: AD 2B 02 LDA $022B Directory-Track B6FD: 38 SEC B6FE: E5 55 SBC $55 - Distanz B700: 85 4D STA $4D = zu testende Spur B702: 08 PHP B703: C5 90 CMP $90 >= Starttrack der Partition ? B705: B0 04 BCS $B70B ja, ==> B707: 28 PLP B708: 4C 17 B7 JMP $B717 Tracks > Directory-Track ueberpruefen ==> Einsprung von $B705: B70B: 28 PLP B70C: 90 09 BCC $B717 Tracknummer <= 0 ? ja, ==> B70E: F0 07 BEQ $B717 ja, ==> B710: 20 B4 B5 JSR $B5B4 BAM-Zeiger auf aktuellen Track setzen B713: B1 31 LDA ($31),Y Anzahl freier Blocks holen B715: D0 1B BNE $B732 >0, (Starttrack gefunden) ==> Tracks > Directory-Track untersuchen Einsprung von $B708, $B70C, $B70E: B717: AD 2B 02 LDA $022B Directory-Track B71A: 18 CLC B71B: 65 55 ADC $55 + Distanz B71D: 85 4D STA $4D = zu testende Spur B71F: E6 55 INC $55 Distanz erhoehen B721: CD 2C 02 CMP $022C Spur >= 'Letzter Track der Partition + 1' ? B724: 90 05 BCC $B72B nein, ==> B726: A9 67 LDA #$67 ja: 67, Illegal Track or Sector B728: 20 3F FF JSR $FF3F Einsprung von $B724: B72B: 20 B4 B5 JSR $B5B4 BAM-Zeiger auf aktuellen Track setzen B72E: B1 31 LDA ($31),Y Anzahl freier Blocks holen B730: F0 C8 BEQ $B6FA =0, (weitersuchen) ==> freien Block im Track suchen Einsprung von $B715: B732: 68 PLA B733: 85 55 STA $55 geretteten Wert zurueckholen B735: A9 00 LDA #$00 mit 1. Sektor der Spur anfangen B737: 85 4E STA $4E B739: 20 46 B7 JSR $B746 freien Block im Track suchen B73C: F0 03 BEQ $B741 keinen gefunden, ==> B73E: 4C 72 B5 JMP $B572 Block in BAM belegen Einsprung von $B73C, $B6EA: B741: A9 71 LDA #$71 71, Dir Error B743: 20 3F FF JSR $FF3F naechsten freien Block im aktuellen Track suchen ($f1fa) Einsprung von $8B38, $8B56, $B6D9, $B6E5, $B739: B746: 20 B4 B5 JSR $B5B4 aktuellen BAM-Eintrag holen B749: 20 5E B7 JSR $B75E und auf Fehler pruefen Einsprung von $B759: B74C: A5 4E LDA $4E existiert angegebener Sektor ? B74E: C5 75 CMP $75 (groesste Sektornummer +1) B750: B0 09 BCS $B75B nein, ==> B752: 20 D8 B5 JSR $B5D8 ist der Block frei ? B755: D0 06 BNE $B75D ja, ==> B757: E6 4E INC $4E naechsten Block probieren B759: D0 F1 BNE $B74C immer ==> Einsprung von $B750: B75B: A9 00 LDA #$00 z=1: alle Sektoren belegt Einsprung von $B755: B75D: 60 RTS Prueft, ob im aktuellen Track die Anzahl freier Blocks stimmt. ($f220) [Der Wert, der die Anzahl der freien Blocks angibt, wird mit der Anzahl der Bits, die einen freien Block kennzeichnen, verglichen. Bei Abweichungen voneinander wird 'DIR Error' ausgegeben.] Einsprung von $B525, $B749: B75E: A9 00 LDA #$00 B760: 85 2F STA $2F Anzahl freier Blocks loeschen B762: AC 76 DB LDY $DB76 Anzahl der BAM-Bytes pro Spur B765: 88 DEY -1 (Index beginnt bei 0) Einsprung von $B773: B766: A2 08 LDX #$08 8 Bits pro Byte B768: B1 31 LDA ($31),Y Byte mit Bitmuster holen Einsprung von $B770: B76A: 0A ASL Alle Bits nacheinander ins Carry schieben B76B: 90 02 BCC $B76F gesetzte Bits zaehlen; nicht gesetzt, ==> B76D: E6 2F INC $2F (gesetztes Bit heisst: Block frei) Einsprung von $B76B: B76F: CA DEX B770: D0 F8 BNE $B76A naechstes Bit, ==> B772: 88 DEY [Die BAM-Bytes 1-5 zusammen muessen B773: D0 F1 BNE $B766 genausoviele 1-Bits haben B775: B1 31 LDA ($31),Y wie im Byte 0 angegeben ist] B777: C5 2F CMP $2F B779: D0 01 BNE $B77C wenn nicht, ==> B77B: 60 RTS Einsprung von $B779: B77C: A9 71 LDA #$71 71, DIR ERROR B77E: 20 3F FF JSR $FF3F Partition-Befehl B781: 20 AE 84 JSR $84AE testet auf Diskettenwechsel B784: A5 29 LDA $29 Laenge der Befehlszeile B786: C9 02 CMP #$02 < 2 ('/') ? B788: 90 6D BCC $B7F7 ja, ==> B78A: A9 01 LDA #$01 Position der moeglichen Drivenummer setzen B78C: 8D 91 02 STA $0291 B78F: 20 FD 81 JSR $81FD Drivenummer holen B792: 20 B9 82 JSR $82B9 Datei im Directory suchen B795: AD 97 02 LDA $0297 gefunden ? B798: F0 13 BEQ $B7AD nein ==> B79A: 20 51 B8 JSR $B851 Partition-Namen holen B79D: 90 20 BCC $B7BF Partition erstellen ? nein, ==> B79F: A9 63 LDA #$63 63, File exists B7A1: 2C B $2C Einsprung von $B7B0, $B7C5: B7A2: A9 62 LDA #$62 62, File not found B7A4: 2C B $2C Einsprung von $B7BA: B7A5: A9 30 LDA #$30 30, Syntax error B7A7: 2C B $2C Einsprung von $B7D2, $B7D8, $B7E2, $B7E4: B7A8: A9 77 LDA #$77 77, Selected Partition illegal B7AA: 20 7C 80 JSR $807C Fehlermeldung (T&S=0) ausgeben Testen, ob die nicht vorhandene Partition erstellt werden soll Einsprung von $B798: B7AD: 20 51 B8 JSR $B851 Partition-Namen holen B7B0: 90 F0 BCC $B7A2 Partition erstellen ? nein, ==> B7B2: AE 90 02 LDX $0290 Ende des Partition-Namens ('/xxx,abcdC') B7B5: BD 06 02 LDA $0206,X +6: ist Befehl zum Erstellen der Partition B7B8: C9 43 CMP #$43 (Create) vorhanden ? B7BA: D0 E9 BNE $B7A5 nein, ==> B7BC: 4C 8D B8 JMP $B88D Parameter holen, Partition erstellen Partition anwaehlen Einsprung von $B79D: B7BF: A5 F4 LDA $F4 Dateityp feststellen B7C1: 29 07 AND #$07 B7C3: C9 05 CMP #$05 CBM-Datei ? B7C5: D0 DB BNE $B7A2 nein, ==> B7C7: 20 23 B3 JSR $B323 Partition-Parameter holen Einsprung von $B7D0: B7CA: 20 B5 94 JSR $94B5 Auf gueltigen Block testen B7CD: 20 EF B2 JSR $B2EF Naechten Block der Partition holen B7D0: D0 F8 BNE $B7CA gehoert Block noch zur Partition, ==> B7D2: 90 D4 BCC $B7A8 Trackwechsel erfolgt ? nein, ==> B7D4: A0 02 LDY #$02 Startsektor holen B7D6: B1 64 LDA ($64),Y B7D8: D0 CE BNE $B7A8 <>0, (P. muss am Trackanfang beginnen) ==> B7DA: 88 DEY B7DB: A5 4D LDA $4D aktuelle Tracknummer (1. Track nach der P.) B7DD: AA TAX B7DE: F1 64 SBC ($64),Y - Starttrack (= Anzahl Tracks der P.)) B7E0: C9 02 CMP #$02 muss > 2 sein (entspricht >=120 Blocks) B7E2: F0 C4 BEQ $B7A8 Partition zu klein, ==> B7E4: 90 C2 BCC $B7A8 ja, ==> B7E6: B1 64 LDA ($64),Y Starttrack B7E8: 8D 2B 02 STA $022B = Track des Directorys B7EB: 85 90 STA $90 = Start der Partition B7ED: 8E 2C 02 STX $022C Ende der Partition +1 merken B7F0: CA DEX -1 = Ende der Partition B7F1: CA DEX -1 = physikalische Spurnummer B7F2: 86 8F STX $8F letzte physikalische Spurnummer merken B7F4: 4C FA B7 JMP $B7FA P. initialisieren, Meldung ausgeben Wurzelverzeichnis anwaehlen Einsprung von $B788: B7F7: 20 B3 B0 JSR $B0B3 ganze Diskette als Partition Einsprung von $B7F4: B7FA: 20 62 92 JSR $9262 Kanaele der SA 1-14 freigeben B7FD: 20 03 8F JSR $8F03 Partition initialisieren B800: A5 90 LDA $90 Partitionanfang B802: 85 4D STA $4D = Track (fuer Meldung) B804: AC 2C 02 LDY $022C Partitionende+1 B807: 88 DEY - 1 B808: 84 4E STY $4E = 'Sektor' B80A: A9 02 LDA #$02 02, Selected Partition, $4d, $4e B80C: A0 00 LDY #$00 Zeiger in INPUT-Puffer = 0 B80E: 4C 5F 80 JMP $805F Meldung ausgeben Pruefen, ob alle Blocks der Partition vor dem Anlegen noch frei sind Einsprung von $B88D: B811: A5 35 LDA $35 'BAM veraendert'-Flag merken B813: 48 PHA B814: AD A9 02 LDA $02A9 Anzahl 'Blocks free' merken B817: 48 PHA B818: AD AA 02 LDA $02AA B81B: 48 PHA B81C: 20 5F B8 JSR $B85F Partition-Parameter aus Kommandozeile holen Einsprung von $B833: B81F: 20 B5 94 JSR $94B5 auf gueltigen Block testen B822: A5 4D LDA $4D aktueller Track B824: C9 28 CMP #$28 = Haupt-Directory-Track ? B826: F0 19 BEQ $B841 ja, ==> B828: 20 72 B5 JSR $B572 Block in BAM belegen B82B: F0 14 BEQ $B841 Block war schon belegt, ==> B82D: 20 46 B5 JSR $B546 Block wieder freigeben B830: 20 EF B2 JSR $B2EF naechsten Block der Part. holen B833: D0 EA BNE $B81F noch nicht fertig, ==> B835: 68 PLA B836: 8D AA 02 STA $02AA Anzahl 'Blocks free' zurueckholen B839: 68 PLA B83A: 8D A9 02 STA $02A9 B83D: 68 PLA B83E: 85 35 STA $35 'BAM veraendert'-Flag zurueckholen B840: 60 RTS Einsprung von $B826, $B82B: B841: 68 PLA B842: 8D AA 02 STA $02AA Anzahl 'Blocks free' zurueckholen B845: 68 PLA B846: 8D A9 02 STA $02A9 B849: 68 PLA B84A: 85 35 STA $35 'BAM veraendert'-Flag zurueckholen B84C: A9 67 LDA #$67 67, Illegal Track or Sector B84E: 4C 3F FF JMP $FF3F Partition-Namen holen Einsprung von $B79A, $B7AD: B851: A2 01 LDX #$01 Name faengt nach dem 1. Zeichen ('/') an B853: 20 26 85 JSR $8526 Laenge des Namens feststellen B856: A5 29 LDA $29 Kommandozeilenlaenge B858: 38 SEC - Ende des Namens B859: ED 90 02 SBC $0290 = Laenge der uebrigen Parameter B85C: C9 04 CMP #$04 >= 4 (Partition Erstellen) ? B85E: 60 RTS Parameter fuer die Partitionerstellung holen Einsprung von $B81C, $B899, $B8A2, $B8B2: B85F: AC 90 02 LDY $0290 Ende des Partitionnamens B862: C8 INY +1 = Position des 1. Parameters B863: B9 00 02 LDA $0200,Y Starttrack B866: 85 4D STA $4D merken B868: C8 INY B869: B9 00 02 LDA $0200,Y Startsektor B86C: 85 4E STA $4E merken B86E: C8 INY B86F: B9 00 02 LDA $0200,Y Laenge des Bereiches B872: 8D EE 01 STA $01EE Lo B875: C8 INY B876: B9 00 02 LDA $0200,Y B879: 8D ED 01 STA $01ED Hi B87C: 18 CLC B87D: AD EE 01 LDA $01EE Laenge = 0 ? B880: 6D ED 01 ADC $01ED B883: F0 03 BEQ $B888 Ja, ==> B885: 4C B5 94 JMP $94B5 T&S auf gueltigen Bereich testen Einsprung von $B883: B888: A9 77 LDA #$77 77, Selected Partition illegal B88A: 20 7C 80 JSR $807C Neuen Bereich anlegen Einsprung von $B7BC: B88D: 20 11 B8 JSR $B811 Sind Blocks fuer die Partition noch frei ? B890: A9 05 LDA #$05 ja: B892: 8D 2D 02 STA $022D B895: A9 12 LDA #$12 internen Schreibkanal anwaehlen B897: 85 52 STA $52 B899: 20 5F B8 JSR $B85F Parameter aus der Kommandozeile holen B89C: 20 C6 9B JSR $9BC6 File zum Schreiben oeffnen B89F: 20 AB 95 JSR $95AB Neue Partition im Directory eintragen B8A2: 20 5F B8 JSR $B85F Parameter aus der Kommandozeile holen Einsprung von $B8B0: B8A5: 20 B5 94 JSR $94B5 T&S auf gueltigen Bereich testen B8A8: A5 4D LDA $4D [wird nicht gebraucht] B8AA: 20 72 B5 JSR $B572 Block in BAM belegen B8AD: 20 EF B2 JSR $B2EF naechsten Block der Partition holen B8B0: D0 F3 BNE $B8A5 noch nicht Partition-Ende, ==> B8B2: 20 5F B8 JSR $B85F Parameter aus der Kommandozeile holen B8B5: A6 50 LDX $50 B8B7: AD EE 01 LDA $01EE Dateilaenge setzen B8BA: 9D 49 02 STA $0249,X B8BD: AD ED 01 LDA $01ED B8C0: 9D 50 02 STA $0250,X B8C3: A9 00 LDA #$00 ein Byte in Puffer schreiben [sonst wuerde B8C5: 20 B1 8E JSR $8EB1 der Block von der Datei wieder abgezogen. B8C8: A9 12 LDA #$12 (s. $9a47)] B8CA: 85 52 STA $52 internen Schreibkanal anwaehlen B8CC: 20 9F 99 JSR $999F Datei schliessen B8CF: 4C 4C 80 JMP $804C DOS 8 Burst-Befehl $1f: Fastload (bei der 1571: $9080) Einsprung von $B8D9: B8D2: 4C 4C 80 JMP $804C Burst-Load mit langsamen Bus (Ende) ==> Datei suchen B8D5: A9 08 LDA #$08 <-- (Einsprung) B8D7: 24 76 BIT $76 langsamen Bus benutzen ? B8D9: F0 F7 BEQ $B8D2 ja, (Ende) ==> B8DB: 20 D4 AC JSR $ACD4 FSM-Bus vorbereiten, auf Ausgabe schalten B8DE: 20 06 BA JSR $BA06 Filenamen holen B8E1: B0 59 BCS $B93C Drive 1, dann Fehler B8E3: 20 AE 84 JSR $84AE Drive ggf. initialisieren B8E6: A5 6E LDA $6E Drivestatus holen B8E8: D0 52 BNE $B93C Fehler, (Ende) ==> B8EA: A9 80 LDA #$80 Flag: 'Datei hat nur einen Block' setzen B8EC: 85 3C STA $3C B8EE: 20 64 BA JSR $BA64 Fehlerbehandlung auf eigene Routinen biegen B8F1: AD 00 02 LDA $0200 '*' als Filename ? B8F4: C9 2A CMP #$2A B8F6: D0 0F BNE $B907 nein, ==> B8F8: A5 4C LDA $4C ja, letztes File laden B8FA: F0 0B BEQ $B907 kein letztes File, ==> B8FC: 48 PHA Track des letzten Files merken B8FD: AD 8B 02 LDA $028B Sektornummer B900: 8D 9C 02 STA $029C merken B903: 68 PLA [Die Fehlervektoren werden vergessen !!!] B904: 4C 41 B9 JMP $B941 Datei laden ==> Einsprung von $B8F6, $B8FA: B907: A9 00 LDA #$00 B909: A8 TAY [unnoetig] B90A: AA TAX B90B: 8D 91 02 STA $0291 moegl. Position der Laufwerksnummer setzen B90E: 20 FD 81 JSR $81FD Laufwerksnummer holen B911: AD 2F 02 LDA $022F Anzahl Dateinamen (=1) merken B914: 48 PHA B915: A9 01 LDA #$01 Anzahl Dateinamen =1 setzen B917: 8D 2F 02 STA $022F B91A: A9 FF LDA #$FF ['Aufrufadresse gefunden' (hier unnoetig) B91C: 85 55 STA $55 vgl. &-Befehl $a961-$a974 mit $b90b-$b91e] B91E: 20 B9 82 JSR $82B9 Datei suchen B921: 68 PLA Anzahl Dateinamen (1) zurueckholen B922: 8D 2F 02 STA $022F B925: 20 95 BA JSR $BA95 Vektoren der Fehlerbehandlung zurueckholen B928: 24 7C BIT $7C Burst Kommandobyte holen B92A: 30 08 BMI $B934 b7=1: Dateityp nicht testen ? ja, ==> B92C: A5 F4 LDA $F4 Dateityp holen B92E: 29 07 AND #$07 [Fehler aus 1571-DOS beseitigt: nur Datei- B930: C9 02 CMP #02 TYP ($B0-2) testen.] B932: D0 05 BNE $B939 Typ = PRG ? nein, ==> Einsprung von $B92A: B934: AD 97 02 LDA $0297 Starttrack holen B937: D0 08 BNE $B941 >0 (Datei gefunden), ==> Einsprung von $B932: B939: A2 02 LDX #$02 Datei nicht gefunden B93B: 2C B $2C Einsprung von $B8E1, $B8E8: B93C: A2 0F LDX #$0F kein Laufwerk verfuegbar B93E: 4C EC B9 JMP $B9EC Datei laden Einsprung von $B904, $B937: B941: 85 4C STA $4C Starttrack merken (letzte benutzte Datei) B943: A2 00 LDX #$00 B945: 95 0B STA $0B,X Tracknummer in Jobspeicher schreiben B947: AD 9C 02 LDA $029C Startsektor B94A: 8D 8B 02 STA $028B fuer 'letzte benutzte Datei' merken B94D: 95 0C STA $0C,X Sektornummer in Jobspeicher schreiben - Track ggf. einlesen; Zeiger auf Position im Cache setzen Einsprung von $B98D: B94F: 58 CLI B950: A2 00 LDX #$00 Jobspeicher 0 verwenden B952: A9 AA LDA #$AA TREAD_DV: Track einlesen; Zeiger $9f setzen B954: 20 B7 BF JSR $BFB7 Job aufrufen B957: AA TAX B958: E0 02 CPX #$02 ist ein Lesefehler aufgetreten ? B95A: 90 03 BCC $B95F B95C: 4C D7 B9 JMP $B9D7 ja, ==> - auf Dateiende pruefen Einsprung von $B95A: B95F: 78 SEI B960: A0 00 LDY #$00 Pufferzeiger (Lo) auf 0 setzen B962: 84 7E STY $7E B964: B9 9F 00 LDA $009F,Y Zeiger auf den Block im Cache holen B967: 29 7F AND #$7F b7 (Flag: 'T&S ins phy. Format gewandelt') B969: 18 CLC ausblenden B96A: 65 8C ADC $8C + Cacheanfang B96C: 85 7F STA $7F als Pufferzeiger (Hi) merken B96E: B1 7E LDA ($7E),Y Folgetrack holen B970: F0 1E BEQ $B990 =0 (Dateiende) ? ja, ==> B972: 06 3C ASL $3C Flag: 'Datei hat nur einen Block' loeschen B974: 20 FC 01 JSR $01FC Jobrueckmeldung in x als Status ausgeben - Block uebertragen B977: A0 02 LDY #$02 Zeiger auf 1. Datenbyte setzen Einsprung von $B980: B979: B1 7E LDA ($7E),Y Datenbyte holen B97B: AA TAX B97C: 20 FC 01 JSR $01FC und an Computer senden B97F: C8 INY B980: D0 F7 BNE $B979 ganzen Block ausgeben, ==> B982: A2 00 LDX #$00 B984: B1 7E LDA ($7E),Y T&S des Folgeblocks in Jobspeicher B986: 95 0B STA $0B,X uebernehmen B988: C8 INY B989: B1 7E LDA ($7E),Y B98B: 95 0C STA $0C,X B98D: 4C 4F B9 JMP $B94F - letzten Block der Datei ausgeben Einsprung von $B970: B990: A2 1F LDX #$1F Meldung: 'letzter Dateiblock' ausgeben B992: 20 FC 01 JSR $01FC B995: 24 3C BIT $3C Flag: 'Datei hat nur einen Block' testen B997: 10 1F BPL $B9B8 Flag geloescht, ==> - einzigen Block der Datei ausgeben B999: A0 01 LDY #$01 B99B: B1 7E LDA ($7E),Y Zeiger auf letztes Byte im Block holen B99D: 38 SEC [+1 waere Anzahl Bytes im Block] B99E: E9 03 SBC #$03 -3 [2 Bytes Verkettungszeiger und B9A0: 85 38 STA $38 2 Bytes Startadresse B9A2: AA TAX 1 Byte ist schon abgezogen ==> -3.] B9A3: 20 FC 01 JSR $01FC Anzahl Bytes ausgeben B9A6: C8 INY B9A7: B1 7E LDA ($7E),Y Startadresse (Lo) ausgeben B9A9: AA TAX [Der Computer zaehlt bei der Startadresse B9AA: 20 FC 01 JSR $01FC die Anzahl uebertragener Bytes nicht B9AD: C8 INY weiter.] B9AE: B1 7E LDA ($7E),Y Startadresse (Hi) ausgeben B9B0: AA TAX B9B1: 20 FC 01 JSR $01FC B9B4: A0 04 LDY #$04 Zeiger auf Byte 4 setzen B9B6: D0 0D BNE $B9C5 ==> - Datei enthaelt mehrere Bloecke Einsprung von $B997: B9B8: A0 01 LDY #$01 B9BA: B1 7E LDA ($7E),Y Zeiger auf letztes Byte im Block holen B9BC: AA TAX [+1 waere Anzahl Bytes im Block] B9BD: CA DEX -1 [2 Bytes Verkettungszeiger B9BE: 86 38 STX $38 1 Byte ist schon abgezogen == -1.] B9C0: 20 FC 01 JSR $01FC Anzahl Bytes ausgeben B9C3: A0 02 LDY #$02 - Datenbytes des letzten Blocks ausgeben Einsprung von $B9B6, $B9CE: B9C5: B1 7E LDA ($7E),Y Datenbyte holen B9C7: AA TAX B9C8: 20 FC 01 JSR $01FC und ausgeben B9CB: C8 INY B9CC: C6 38 DEC $38 Anzahl auszugebender Bytes vermindern B9CE: D0 F5 BNE $B9C5 alle Bytes ausgeben, ==> B9D0: 4C 4C 80 JMP $804C 00, Ok ERROR: Controller-Error-Routine des Burst-Fastloads B9D3: AA TAX Fehlernummer merken B9D4: 20 95 BA JSR $BA95 Vektoren der Error-Routinen zuruecksetzen [Wieso wird bei einem Lesefehler 'File not found' ausgegeben ?] Einsprung von $B95C: B9D7: 20 FB B9 JSR $B9FB $02: 'File not found' ausgeben [besser waere JSR $01FC.] B9DA: A2 00 LDX #$00 B9DC: 4C 2D FF JMP $FF2D ERROR-Routine des Controllers CMDERR: Fehler-Routine des Burst-Fastloads [Der Vektor, der auf diese Routine zeigen soll, wird falsch berechnet (s. $ba71) und zeigt nach $dfdf !!! Der Bereich $dfdf-$ff00 ist mit $ff gefuellt. Dies ist ein illegaler Opcode mit 3-Byte Laenge. Funktion: (INC, SBC) abs,x Von $dfdf bis $ff01 stehen genau 2657 dieser Befehle. Bei $ff02 steht noch ein ORA ($6c,x). Das naechste Byte ($92) beendet die Programmausfuehrung dann endgueltig. Mir ist keine Bedingung bekannt, die zum Aufruf dieser Routine haette fuehren sollen, wenn man aber als Filenamen '*' angibt und das letzte benutzte File laedt, wird vergessen, den Vektor zurueckzusetzen. Das naechste fehlerhafte Diskettenkommando fuehrt dann zum Absturz.] B9DF: 48 PHA Fehlernummer retten B9E0: 08 PHP B9E1: 78 SEI B9E2: A2 02 LDX #$02 $02: 'File not found' ausgeben B9E4: 20 FC 01 JSR $01FC B9E7: 28 PLP B9E8: 20 95 BA JSR $BA95 Vektoren der Error-Routinen zuruecksetzen B9EB: 68 PLA Fehlernummer zurueckholen [sollte nach x !] Fehlermeldung ausgeben (bei der 1571: $91ad) E: x: Fehlernummer Einsprung von $B93E: B9EC: 20 FB B9 JSR $B9FB $02: 'File not found' ausgeben Fehlernummer aus x nach a B9EF: C9 02 CMP #$02 x = 2 ! B9F1: F0 03 BEQ $B9F6 ==> B9F3: A9 74 LDA #$74 74, Drive not ready B9F5: 2C B $2C Einsprung von $B9F1: B9F6: A9 62 LDA #$62 62, File not found B9F8: 4C 7C 80 JMP $807C T&S=0, CMDERR $02 auf FSM-Bus ausgeben (File not found), TXA Einsprung von $B9D7, $B9EC: B9FB: 78 SEI B9FC: 86 38 STX $38 B9FE: A2 02 LDX #$02 Byte $02 BA00: 20 FC 01 JSR $01FC auf FSM-Bus ausgeben BA03: A5 38 LDA $38 BA05: 60 RTS Filenamen nach Drivenummer durchsuchen und Burstbefehl entfernen (bei der 1571: $91ea) A: c: 1: Drivenummer ist '1' Einsprung von $B8DE: BA06: A0 03 LDY #$03 Laenge des Burst-Befehls BA08: A5 29 LDA $29 Befehlszeilenlaenge BA0A: 38 SEC BA0B: E9 03 SBC #$03 - 3 ('u0.') BA0D: 85 29 STA $29 BA0F: AD 04 02 LDA $0204 Drivenummer suchen BA12: C9 3A CMP #$3A (erkennbar an dem ':') BA14: D0 0E BNE $BA24 keine Drivenummer angegeben, ==> BA16: AD 03 02 LDA $0203 Drivenummer holen BA19: AA TAX BA1A: 29 30 AND #$30 ist das Zeichen wirklich eine Drivenummer ? BA1C: C9 30 CMP #$30 (b54 = 11) BA1E: D0 04 BNE $BA24 nein, ==> BA20: E0 31 CPX #$31 Wenn Drivenummer = '1', dann BA22: F0 1A BEQ $BA3E Fehler ==> Einsprung von $BA14, $BA1E: BA24: AD 03 02 LDA $0203 Sind Burst-Befehl und Filename durch ':' BA27: C9 3A CMP #$3A getrennt (ohne Drivenummer) ? BA29: D0 03 BNE $BA2E nein, ==> BA2B: C6 29 DEC $29 ja, auch ':' entfernen BA2D: C8 INY Laenge des Burst-Befehls =4 setzen Einsprung von $BA29: BA2E: A2 00 LDX #$00 Burst-Befehl entfernen Einsprung von $BA3A: BA30: B9 00 02 LDA $0200,Y durch Verschieben der restlichen Eingaben BA33: 9D 00 02 STA $0200,X BA36: C8 INY BA37: E8 INX BA38: E4 29 CPX $29 BA3A: D0 F4 BNE $BA30 noch Zeichen zu verschieben ? ja, ==> BA3C: 18 CLC Drivenummer Ok. BA3D: 24 B $24 Einsprung von $BA22: BA3E: 38 SEC falsche Drivenummer BA3F: 60 RTS Byte auf FSM-Bus ausgeben (bei der 1571: $9228) E: x: auszugebendes Byte Einsprung von $BA46, $BA50: BA40: AD 01 40 LDA $4001 Seriellen Bus auslesen BA43: CD 01 40 CMP $4001 und entprellen BA46: D0 F8 BNE $BA40 BA48: 29 FF AND #$FF ATN-Modus BA4A: 30 15 BMI $BA61 ja, ==> BA4C: 45 76 EOR $76 Warten, bis Burst-Clock kippt BA4E: 29 04 AND #$04 BA50: F0 EE BEQ $BA40 BA52: 8E 0C 40 STX $400C Byte ausgeben BA55: 45 76 EOR $76 BA57: 85 76 STA $76 Burst-Clock-Zustand merken BA59: A9 08 LDA #$08 Uebertragung abwarten Einsprung von $BA5E: BA5B: 2C 0D 40 BIT $400D BA5E: F0 FB BEQ $BA5B b3=0 (SDR schiebt noch), ==> BA60: 60 RTS Einsprung von $BA4A: BA61: 4C 30 FF JMP $FF30 JATNSRV Fehlerbehandlung fuer Burst-Fastload setzen Einsprung von $B8EE: BA64: 20 7C BA JSR $BA7C Sprungvektoren retten BA67: A9 D3 LDA #$D3 ERROR: Error-Routine des Controllers auf BA69: 8D AE 01 STA $01AE $b9d3 setzen BA6C: A9 B9 LDA #$B9 BA6E: 8D AF 01 STA $01AF BA71: A9 DF LDA #$DF CMDERR: Error-Routine des DOS auf $dfdf BA73: 8D BA 01 STA $01BA setzen BA76: A9 DF LDA #$DF [Da ist kein Programm !? BA78: 8D BB 01 STA $01BB Vermutlich ist $b9df gemeint.] BA7B: 60 RTS Sprungvektoren der Fehlerbehandlung retten Einsprung von $AA0F, $BA64: BA7C: AD AE 01 LDA $01AE Vektor der Job-Error-Routine merken BA7F: 8D E6 01 STA $01E6 BA82: AD AF 01 LDA $01AF BA85: 8D E7 01 STA $01E7 BA88: AD BA 01 LDA $01BA Vektor der Error-Routine des DOS merken BA8B: 8D E8 01 STA $01E8 BA8E: AD BB 01 LDA $01BB BA91: 8D E9 01 STA $01E9 BA94: 60 RTS Sprungvektoren der Fehlerbehandlung zurueckschreiben Einsprung von $A94F, $B925, $B9D4, $B9E8: BA95: AD E6 01 LDA $01E6 Vektor der Job-Error-Routine zurueckholen BA98: 8D AE 01 STA $01AE BA9B: AD E7 01 LDA $01E7 BA9E: 8D AF 01 STA $01AF BAA1: AD E8 01 LDA $01E8 Vektor der Error-Routine des DOS BAA4: 8D BA 01 STA $01BA zurueckholen BAA7: AD E9 01 LDA $01E9 BAAA: 8D BB 01 STA $01BB BAAD: 60 RTS Burst-Befehl: Read mit logischen Blockangaben (bei der 1571: $83a4) Einsprung von $BAB5: BAAE: A9 8D LDA #$8D b0-3: kein logisches Diskettenformat BAB0: 4C FC BA JMP $BAFC b7: Fremdformat; Burststatus ausgeben Einsprung von $BAF1, $BB1A: BAB3: A5 8A LDA $8A <-- Burst-Status OR-Maske holen BAB5: 30 F7 BMI $BAAE b7=1: Fremdformat ? ja, ==> BAB7: A2 00 LDX #$00 BAB9: AD 03 02 LDA $0203 Tracknummer in Jobspeicher schreiben BABC: 95 0B STA $0B,X BABE: AD 04 02 LDA $0204 Sektornummer in Jobspeicher schreiben BAC1: 95 0C STA $0C,X BAC3: A9 80 LDA #$80 Job $80: READ_DV: Block einlesen BAC5: 20 B0 BF JSR $BFB0 Job ausfuehren BAC8: 20 66 BF JSR $BF66 Burst-Status setzen BACB: 24 7C BIT $7C E-Flag (b6)=1: Lesefehler ignorieren ? BACD: 70 07 BVS $BAD6 ja, ==> BACF: C9 02 CMP #$02 ist ein Fehler aufgetreten ? BAD1: 90 03 BCC $BAD6 nein, ==> BAD3: 4C FC BA JMP $BAFC Burst-Status setzen und ausgeben ==> Einsprung von $BACD, $BAD1: BAD6: 20 AB BF JSR $BFAB Burst-Status ausgeben BAD9: A0 00 LDY #$00 Pufferzeiger auf $0300 setzen BADB: 84 7E STY $7E BADD: A9 03 LDA #$03 BADF: 85 7F STA $7F Einsprung von $BAE7: BAE1: B1 7E LDA ($7E),Y Datenbyte holen BAE3: 20 86 BF JSR $BF86 und an Computer senden BAE6: C8 INY BAE7: D0 F8 BNE $BAE1 ganzen Datenblock senden, ==> BAE9: CE 05 02 DEC $0205 Anzahl zu sendender Bloecke -1 BAEC: F0 06 BEQ $BAF4 =0 ? ja, ==> BAEE: 20 7A C0 JSR $C07A naechsten logischen Sektor holen BAF1: 4C B3 BA JMP $BAB3 Block laden und ausgeben ==> Einsprung von $BAEC: BAF4: 4C 44 BF JMP $BF44 ggf. die angegebene Spur anfahren Burst-Status uebermitteln (bei der 1571: $837c) Einsprung von $BB13: BAF7: A9 0B LDA #$0B Diskettenwechsel BAF9: 2C B $2C Burst-Befehle $01,$05,$0b,$0d,$11,$15,$1b: Laufwerk n.v. BAFA: A9 4F LDA #$4F Laufwerk 1 (n.v.) Status in a setzen und uebermitteln (bei der 1571: $8381) Einsprung von $BAB0, $BAD3, $BB3D, $BBB7, $BC6E, $BCE9, $BE76, $BF41: BAFC: 20 66 BF JSR $BF66 Status setzen BAFF: 20 BF BE JSR $BEBF Status ueber FSM ausgeben Einsprung von $BD0F, $BDF5: BB02: AD EA 01 LDA $01EA Status BB05: C9 02 CMP #$02 < 2 ? BB07: B0 01 BCS $BB0A nein, ==> BB09: 60 RTS ja Einsprung von $BB07, $BBE5, $BC88: BB0A: 29 0F AND #$0F Fehlercode isolieren BB0C: A2 00 LDX #$00 T&S fuer Fehlertext aus Jobpuffer0 BB0E: 4C 2D FF JMP $FF2D ERROR: Controller-Error-Routine Burst-Befehle $00,$10: Read (bei der 1571: $8371) BB11: A5 25 LDA $25 wurde die Diskette gewechselt ? BB13: D0 E2 BNE $BAF7 ja, ==> Einsprung von $BB6E: BB15: 20 D4 AC JSR $ACD4 FSM auf Ausgabe schalten BB18: A5 7C LDA $7C Burst-Kommandobyte holen BB1A: 30 97 BMI $BAB3 L-Flag (b7)=1: logische T&S angegeben, ==> (bei der 1571: $8d67) BB1C: A2 00 LDX #$00 Job 0 benutzen BB1E: AD 03 02 LDA $0203 Tracknummer holen BB21: 95 0B STA $0B,X und in Jobpuffer eintragen BB23: AD 04 02 LDA $0204 Sektornummer holen BB26: 95 0C STA $0C,X und in Jobpuffer eintragen BB28: A5 7C LDA $7C Burst-Kommandobyte holen BB2A: 29 10 AND #$10 b4: Seitennummer isolieren BB2C: 9D CE 01 STA $01CE,X und in Job-Puffer (SIDS) eintragen BB2F: A9 B2 LDA #$B2 TPREAD_DV: physikalische Spur einlesen BB31: 20 B0 BF JSR $BFB0 Job aufrufen BB34: 20 66 BF JSR $BF66 Burst-Status setzen BB37: 24 7C BIT $7C Burst-Kommandobyte holen; BB39: 70 04 BVS $BB3F E-Flag (b6)=1: Fehler ignorieren ? ja, ==> BB3B: C9 02 CMP #$02 Jobrueckmeldung < 2 (Ok.) ? BB3D: B0 BD BCS $BAFC nein, (Status ausgeben, Ende) ==> Einsprung von $BB39: BB3F: 20 AB BF JSR $BFAB Burst-Status an Computer uebertragen BB42: A0 00 LDY #$00 BB44: 84 7E STY $7E Pufferzeiger Lo =0 setzen BB46: B9 9F 00 LDA $009F,Y Zeiger auf den Block im Cache holen BB49: 29 7F AND #$7F Umwandlungs-Flag ausblenden BB4B: 18 CLC BB4C: 65 8C ADC $8C + Cache-Start BB4E: 85 7F STA $7F als Pufferzeiger Hi merken BB50: A6 91 LDX $91 Sektorgroesse holen BB52: E0 03 CPX #$03 Anzahl auszugebender Speicherseiten merken BB54: D0 01 BNE $BB57 1 oder 2 Seiten, ==> BB56: E8 INX 4 Seiten ausgeben Einsprung von $BB54, $BB5D, $BB64: BB57: B1 7E LDA ($7E),Y Byte aus Cachepuffer holen BB59: 20 86 BF JSR $BF86 und an Computer senden BB5C: C8 INY BB5D: D0 F8 BNE $BB57 ganze Speicherseite ausgeben, ==> BB5F: CA DEX naechste Seite holen BB60: F0 04 BEQ $BB66 keine Seite mehr auszugeben, ==> BB62: E6 7F INC $7F Pufferzeiger Hi erhoehen BB64: D0 F1 BNE $BB57 ==> Einsprung von $BB60: BB66: CE 05 02 DEC $0205 Anzahl auszugebender Sektoren -1 BB69: F0 06 BEQ $BB71 fertig, ==> BB6B: 20 40 C0 JSR $C040 naechste Blocknummer holen BB6E: 4C 15 BB JMP $BB15 Block lesen und ausgeben Einsprung von $BB69: BB71: 4C 47 BF JMP $BF47 ggf. Kopf auf die angegebene Spur setzen Burst-Befehl: Write mit logischen Blockangaben Einsprung von $BB83: BB74: A9 8D LDA #$8D b0-3: kein logisches Diskettenformat BB76: 8D EA 01 STA $01EA b7: Fremdformat; Burststatus ausgeben BB79: A5 7C LDA $7C Burst-Kommandobyte holen BB7B: 09 08 ORA #$08 Flag: 'Nachdem die Daten empfangen worden BB7D: 85 7C STA $7C sind, Fehlermeldung ausgeben' setzen BB7F: D0 04 BNE $BB85 ==> (bei der 1571: $840e) Einsprung von $BBF0, $BC09: BB81: A5 8A LDA $8A <-- Burst-Status-OR-Maske holen BB83: 30 EF BMI $BB74 b7=1: Fremdformat ? Einsprung von $BB7F: BB85: A0 00 LDY #$00 BB87: 84 7E STY $7E Pufferzeiger auf $0300 setzen BB89: A9 03 LDA #$03 BB8B: 85 7F STA $7F Einsprung von $BBAA: BB8D: AD 01 40 LDA $4001 Burst-Clock kippen (und damit ein neues BB90: 49 08 EOR #$08 Byte anfordern) BB92: 2C 0D 40 BIT $400D Flag: 'Byte empfangen' des SDR loeschen BB95: 8D 01 40 STA $4001 Burst-Clock setzen BB98: A9 08 LDA #$08 Einsprung von $BBA2, $BBB1: BB9A: 2C 01 40 BIT $4001 ist b7=1: ATN empfangen ? BB9D: 30 0F BMI $BBAE ja, ==> BB9F: 2C 0D 40 BIT $400D BBA2: F0 F6 BEQ $BB9A warten, bis b3=1: Byte empfangen, ==> BBA4: AD 0C 40 LDA $400C Byte aus dem Schieberegister holen BBA7: 91 7E STA ($7E),Y und in Puffer schreiben BBA9: C8 INY BBAA: D0 E1 BNE $BB8D ganzen Block einlesen, ==> BBAC: F0 0C BEQ $BBBA ==> Einsprung von $BB9D: BBAE: 20 15 AD JSR $AD15 ATN-Modus testen BBB1: 4C 9A BB JMP $BB9A weiter auf Byte warten ==> Einsprung von $BBC1: BBB4: AD EA 01 LDA $01EA Burst-Status aus Zwischenspeicher holen BBB7: 4C FC BA JMP $BAFC und an Computer senden Einsprung von $BBAC: BBBA: 20 03 AD JSR $AD03 CLOCK OUT auf Lo setzen BBBD: A5 7C LDA $7C Burst-Kommandobyte holen BBBF: 29 08 AND #$08 b3=1: kein logisches Format ? BBC1: D0 F1 BNE $BBB4 ja, (Fehler ausgeben) ==> BBC3: A2 00 LDX #$00 BBC5: AD 03 02 LDA $0203 Zielblock setzen BBC8: 95 0B STA $0B,X Tracknummer BBCA: AD 04 02 LDA $0204 BBCD: 95 0C STA $0C,X Sektornummer BBCF: A9 90 LDA #$90 Job $90: WRITE_DV BBD1: 20 B0 BF JSR $BFB0 Job aufrufen BBD4: 20 66 BF JSR $BF66 Burst-Status setzen BBD7: 20 5A BF JSR $BF5A und an Computer senden BBDA: 24 7C BIT $7C Burst-Kommandobyte holen BBDC: 70 0A BVS $BBE8 E-Flag (b6)=1: Fehler ignorieren ? ja, ==> BBDE: AD EA 01 LDA $01EA Fehlercode holen BBE1: C9 02 CMP #$02 < 2 ? BBE3: 90 03 BCC $BBE8 ja, ==> BBE5: 4C 0A BB JMP $BB0A Fehler im Klartext ausgeben Einsprung von $BBDC, $BBE3: BBE8: CE 05 02 DEC $0205 Anzahl zu schreibender Bloecke -1 BBEB: F0 06 BEQ $BBF3 alle Bloecke geschrieben, ==> BBED: 20 7A C0 JSR $C07A naechsten logischen Sektor holen BBF0: 4C 81 BB JMP $BB81 Daten vom Compi holen und abspeichern ==> Einsprung von $BBEB: BBF3: 4C 44 BF JMP $BF44 Kopf ggf. auf die angegebene Spur setzen Burststatus bei Schreibfehlern ausgeben Einsprung von $BC03: BBF6: A9 0B LDA #$0B Diskettenwechsel BBF8: 2C B $2C Burst-Befehle $03,13: Laufwerk n.v. BBF9: A9 4F LDA #$4F Laufwerk1 (n.v.) BBFB: 8D EA 01 STA $01EA BBFE: 4C 2F BC JMP $BC2F Uebertragung abwarten, Fehler ausgeben ==> Burst-Befehle $02,$12: Write (bei der 1571: $83ec) Einsprung von $BC93: BC01: A5 25 LDA $25 wurde die Diskette gewechselt ? BC03: D0 F1 BNE $BBF6 ja, ==> BC05: A5 7C LDA $7C Burst-Kommandobyte holen; L-Flag (b7)=1: BC07: 10 03 BPL $BC0C logisches Format angegeben ? nein, ==> BC09: 4C 81 BB JMP $BB81 ja: Write mit logischen Sektorangaben ==> Write mit physikalischen Sektorangaben (bei der 1571: $8df6) Cache mit Spurdaten fuellen; ggf. alte Daten speichern Einsprung von $BC07: BC0C: A2 00 LDX #$00 Jobspeicher 0 waehlen BC0E: A5 7C LDA $7C Burst-Kommandobyte holen BC10: 29 10 AND #$10 S-Flag in den Job-Seitenspeicher (SIDS) BC12: 9D CE 01 STA $01CE,X uebertragen BC15: AD 03 02 LDA $0203 Track- und Sektornummer in Jobspeicher BC18: 95 0B STA $0B,X schreiben BC1A: AD 04 02 LDA $0204 BC1D: 95 0C STA $0C,X BC1F: A9 B4 LDA #$B4 TPWRT_DV: ggf. Cache auf Diskette schreiben BC21: 20 B0 BF JSR $BFB0 und neue Spur einlesen; Job ausfuehren BC24: 20 66 BF JSR $BF66 Burst-Status setzen BC27: C9 02 CMP #$02 ist ein Fehler aufgetreten ? BC29: 90 0A BCC $BC35 nein, ==> BC2B: A9 00 LDA #$00 Flag: 'Cachepuffer veraendert' loeschen BC2D: 85 87 STA $87 Einsprung von $BBFE: BC2F: A5 7C LDA $7C Fehler-Flag im Burst-Kommandobyte setzen BC31: 09 08 ORA #$08 BC33: 85 7C STA $7C Daten vom Computer in den Cachepuffer uebertragen Einsprung von $BC29: BC35: 20 99 BC JSR $BC99 Zeiger in Cachepuffer ($7e) berechnen BC38: A6 91 LDX $91 Sektorgroesse holen BC3A: E0 03 CPX #$03 Sektorgroesse in Speicherseiten berechnen BC3C: D0 01 BNE $BC3F [Veraenderung ist nur bei 1024-Byte-Bloecken BC3E: E8 INX notwedig.] Einsprung von $BC3C, $BC5C, $BC61: BC3F: AD 01 40 LDA $4001 Bus-Register auslesen; CLOCK-OUT kippen und BC42: 49 08 EOR #$08 damit ein neues Byte anfordern BC44: 2C 0D 40 BIT $400D Flag: 'Byte empfangen' des SDR loeschen BC47: 8D 01 40 STA $4001 Burst-Clock setzen BC4A: A9 08 LDA #$08 Einsprung von $BC54, $BC68: BC4C: 2C 01 40 BIT $4001 ATN testen BC4F: 30 14 BMI $BC65 ist ein ATN empfangen worden ? ja, ==> BC51: 2C 0D 40 BIT $400D b3=1: auf Uebertragungsende testen BC54: F0 F6 BEQ $BC4C Uebertragung abwarten, ==> BC56: AD 0C 40 LDA $400C Byte aus SDR auslesen BC59: 91 7E STA ($7E),Y und in Cache schreiben BC5B: C8 INY BC5C: D0 E1 BNE $BC3F ganze Speicherseite uebertragen, ==> BC5E: E6 7F INC $7F Cachezeiger Hi erhoehen BC60: CA DEX Anzahl zu uebertragender Seiten -1 BC61: D0 DC BNE $BC3F noch eine Seite zu uebertragen, ==> BC63: F0 0C BEQ $BC71 fertig mit dem Block ==> Einsprung von $BC4F: BC65: 20 15 AD JSR $AD15 ATN-Modus testen BC68: 4C 4C BC JMP $BC4C und weiter warten Einsprung von $BC78: BC6B: AD EA 01 LDA $01EA Burst-Status aus Zwischenspeicher holen BC6E: 4C FC BA JMP $BAFC und an den Computer senden Einsprung von $BC63: BC71: 20 03 AD JSR $AD03 CLOCK OUT auf Lo setzen BC74: A5 7C LDA $7C Burst-Kommando holen BC76: 29 08 AND #$08 ist das Fehler-Flag gesetzt ? BC78: D0 F1 BNE $BC6B ja, ==> BC7A: 20 5A BF JSR $BF5A Status an den Computer senden BC7D: 24 7C BIT $7C Burst-Kommando holen; ist das E-Flag (b6)=1 BC7F: 70 0A BVS $BC8B (Schreibfehler ignorieren) ? ja, ==> BC81: AD EA 01 LDA $01EA Jobrueckmeldung holen BC84: C9 02 CMP #$02 kein Fehler aufgetreten ? BC86: 90 03 BCC $BC8B ja, ==> BC88: 4C 0A BB JMP $BB0A Fehlermeldung im Klartext ausgeben Einsprung von $BC7F, $BC86: BC8B: CE 05 02 DEC $0205 Anzahl abzuspeichernder Blocks -1 BC8E: F0 06 BEQ $BC96 =0 (Ende), ==> BC90: 20 40 C0 JSR $C040 naechsten physikalischen Sektor holen BC93: 4C 01 BC JMP $BC01 naechsten Block vom Compi holen ==> Einsprung von $BC8E: BC96: 4C 47 BF JMP $BF47 Kopf ggf. auf die angegebene Spur setzen Zeiger in Cachepuffer berechnen Einsprung von $BC35: BC99: A0 00 LDY #$00 Zeiger Lo = 0 BC9B: 84 7E STY $7E BC9D: AD 04 02 LDA $0204 aktuelle Sektornummer holen BCA0: 38 SEC BCA1: E5 94 SBC $94 - 1. Sektornummer auf der Spur BCA3: A6 91 LDX $91 Einsprung von $BCA9: BCA5: CA DEX * Sektorlaenge BCA6: F0 04 BEQ $BCAC BCA8: 0A ASL BCA9: 4C A5 BC JMP $BCA5 Einsprung von $BCA6: BCAC: 18 CLC BCAD: 65 8C ADC $8C + Cache-Start BCAF: 85 7F STA $7F = Zeiger Hi BCB1: 60 RTS Burst-Befehle $04,$14: Inquire Disk (bei der 1571: $848b) Einsprung von $BE06: BCB2: AD 02 02 LDA $0202 Burst-Befehl holen BCB5: 29 01 AND #$01 N-Flag (b0) testen (Laufwerksnummer) BCB7: D0 2E BNE $BCE7 Laufwerk 1 angesprochen ? ja, ==> BCB9: A2 00 LDX #$00 Burst-Status loeschen BCBB: 86 80 STX $80 (bei der 1571: $8a09) BCBD: A9 C0 LDA #$C0 RESTORE_DV: Kopf auf Spur 0 setzen BCBF: 20 B0 BF JSR $BFB0 BCC2: 08 PHP i-Flag merken BCC3: 58 CLI i-Flag loeschen BCC4: A9 80 LDA #$80 DOS-Fehlermeldungen unterdruecken BCC6: 85 81 STA $81 BCC8: 20 F1 BE JSR $BEF1 Standard-1581-Format setzen BCCB: 20 03 8F JSR $8F03 Diskette initialisieren BCCE: 06 81 ASL $81 DOS-Fehlermeldungen wieder zulassen BCD0: 28 PLP i-Flag zurueckholen BCD1: A5 7C LDA $7C Burst-Kommandobyte holen BCD3: 29 10 AND #$10 S-Flag (b4) holen (Seitenauswahl) BCD5: 4A LSR BCD6: 4A LSR BCD7: 4A LSR BCD8: 4A LSR BCD9: 9D CE 01 STA $01CE,X und in Job-Seitenspeicher (SIDS) schreiben BCDC: A9 9C LDA #$9C SIDE_DV: Diskettenseite auswaehlen BCDE: 20 9D 95 JSR $959D Job aufrufen BCE1: A9 B0 LDA #$B0 SEEKHD_DV: beliebigen Blockheader suchen BCE3: 20 B0 BF JSR $BFB0 Job aufrufen BCE6: 2C B $2C Einsprung von $BCB7: BCE7: A9 4F LDA #$4F b6=1: Laufwerk 1; b0-3=$0f: Laufwerk n.v. Einsprung von $BD04: BCE9: 20 FC BA JSR $BAFC Status ausgeben BCEC: A9 01 LDA #$01 BCEE: 8D EF 01 STA $01EF kleinste Sektornummer setzen BCF1: 85 94 STA $94 1. Sektornummer auf der Spur BCF3: A6 22 LDX $22 Sektorgroesse aus Blockheader holen BCF5: BD 06 BD LDA $BD06,X Anzahl Sektoren pro Spur holen BCF8: F0 08 BEQ $BD02 = 0 (128-Byte-Sektoren) ? ja, => BCFA: 85 92 STA $92 Anzahl Sektoren der Spur setzen BCFC: 85 93 STA $93 letzter Sektor auf der Spur BCFE: 8D F0 01 STA $01F0 groesste Sektornummer der Spur BD01: 60 RTS Einsprung von $BCF8: BD02: A9 0E LDA #$0E Syntax-Fehler (gemeint ist: Format wird BD04: D0 E3 BNE $BCE9 nicht unterstuetzt) ==> Anzahl der Sektoren pro Spur bei verschiedenen Sektorgroessen. 128-Byte-Sektoren werden nicht unterstuetzt BD06: 00 10 0A 05 ??? Einsprung von $BD17: BD0A: A9 4F LDA #$4F b6 : Drivenummer 1 b0-3: Drive nicht vorhanden BD0C: 20 66 BF JSR $BF66 Burststatus setzen BD0F: 4C 02 BB JMP $BB02 und ausgeben Burst-Befehle $06,$07,$16,$17: Format (bei der 1571: $84b7) BD12: AD 02 02 LDA $0202 N-Flag (b0): Laufwerksnummer BD15: 29 01 AND #$01 BD17: D0 F1 BNE $BD0A N=1: Laufwerk n. v., ==> BD19: AD 02 02 LDA $0202 M-Flag (b7): Modus-Flag BD1C: 10 40 BPL $BD5E M=0: 1581-Format mit Verzeichnis, ==> (bei der 1571: $8c67) BD1E: A5 29 LDA $29 BD20: 38 SEC BD21: E9 03 SBC #$03 Laenge der Kommandozeile = 3 ? BD23: A8 TAY ('U0.') BD24: F0 56 BEQ $BD7C Ja, Defaultwerte benutzen BD26: AD 03 02 LDA $0203 Sektorgroesse setzen BD29: 85 91 STA $91 BD2B: 88 DEY Anzahl der angegebenen Parameter: BD2C: F0 52 BEQ $BD80 1, ==> BD2E: 88 DEY Nummer der letzten Spur BD2F: F0 54 BEQ $BD85 2, ==> BD31: 88 DEY Anzahl der Sektoren BD32: F0 59 BEQ $BD8D 3, ==> BD34: 88 DEY Startspur BD35: F0 5B BEQ $BD92 4, ==> BD37: 88 DEY Fuellbyte BD38: F0 5D BEQ $BD97 5, ==> BD3A: AD 08 02 LDA $0208 1. Sektornummer BD3D: 85 94 STA $94 BD3F: 88 DEY BD40: F0 59 BEQ $BD9B 6, ==> BD42: AD 09 02 LDA $0209 Groesse der Luecke zwischen zwei Sektoren BD45: 85 9A STA $9A BD47: 4C A2 BD JMP $BDA2 >= 7, ==> Diskette im 1581-Format formatieren BD4A: 4E 30 3A 43 4F 50 59 52 n0:copyr BD52: 49 47 48 54 20 43 42 4D ight cbm BD5A: 2C 38 36 0D ,86 Einsprung von $BD1C: BD5E: A0 13 LDY #$13 Kommandostring in Kommandozeile kopieren Einsprung von $BD67: BD60: B9 4A BD LDA $BD4A,Y BD63: 99 00 02 STA $0200,Y Name: 'copyright cbm', ID:'86' BD66: 88 DEY BD67: 10 F7 BPL $BD60 BD69: A9 14 LDA #$14 Laenge der Befehlszeile BD6B: 85 29 STA $29 BD6D: A9 11 LDA #$11 Position des Kommas BD6F: 8D 92 02 STA $0292 BD72: A9 01 LDA #$01 Position der Drivenummer BD74: 8D 91 02 STA $0291 BD77: A2 00 LDX #$00 (nutzlos) BD79: 4C 2A FF JMP $FF2A JNEW: Diskette formatieren Spezialformat anfertigen (bei der 1571: $8c90) Einsprung von $BD24: BD7C: A9 02 LDA #$02 Sektorgroesse auf 512 Bytes setzen BD7E: 85 91 STA $91 Einsprung von $BD2C: BD80: A9 4F LDA #$4F letzte Spur = 79 BD82: 8D 04 02 STA $0204 Einsprung von $BD2F: BD85: A6 91 LDX $91 Sektorgroesse holen BD87: BD 06 BD LDA $BD06,X Anzahl der Sektoren pro Spur BD8A: 8D 05 02 STA $0205 Einsprung von $BD32: BD8D: A9 00 LDA #$00 Startspur = 0 BD8F: 8D 06 02 STA $0206 Einsprung von $BD35: BD92: A9 E5 LDA #$E5 Fuellbyte = 229 BD94: 8D 07 02 STA $0207 Einsprung von $BD38: BD97: A9 01 LDA #$01 1. Sektornummer = 1 BD99: 85 94 STA $94 Einsprung von $BD40: BD9B: A6 91 LDX $91 Sektorgroesse holen BD9D: BD F8 BD LDA $BDF8,X Groesse der Luecke zwischen zwei Sektoren BDA0: 85 9A STA $9A Einsprung von $BD47: BDA2: A5 90 LDA $90 Starttrack der aktuellen Partition merken BDA4: 48 PHA BDA5: A5 9B LDA $9B Fuellbyte fuer Datenbloecke merken BDA7: 48 PHA BDA8: A5 8F LDA $8F Nummer der letzten physikalischen Spur BDAA: 48 PHA BDAB: AD 04 02 LDA $0204 letzte physikalische Spur festlegen BDAE: 85 8F STA $8F BDB0: AD 05 02 LDA $0205 Anzahl der Sektoren festlegen BDB3: 85 92 STA $92 BDB5: 18 CLC BDB6: 65 94 ADC $94 + '1. Sektornummer' BDB8: 38 SEC BDB9: E9 01 SBC #$01 - 1 BDBB: 85 93 STA $93 = letzte Sektornummer BDBD: 8D F0 01 STA $01F0 = groesste Sektornummer der Spur BDC0: AC 06 02 LDY $0206 Starttrack fuer Formatieren festlegen BDC3: C8 INY +1 (logisches Format) BDC4: 84 90 STY $90 Start der Partition merken BDC6: AD 07 02 LDA $0207 Fuellbyte fuer Datenbloecke festlegen BDC9: 85 9B STA $9B BDCB: A5 90 LDA $90 Starttrack als aktuellen Track setzen BDCD: 85 4D STA $4D BDCF: A9 00 LDA #$00 Job0 benutzen BDD1: 85 4E STA $4E Sektornummer = 0 BDD3: 20 88 95 JSR $9588 T&S in Jobspeicher schreiben BDD6: A9 C0 LDA #$C0 Job-Befehl $c0: RESTORE_DV BDD8: 20 9D 95 JSR $959D Controller aufrufen BDDB: A9 F0 LDA #$F0 Job-Befehl $f0: FORMATDK_DV BDDD: 20 9D 95 JSR $959D Controller aufrufen BDE0: C9 02 CMP #$02 Fehler ? BDE2: B0 03 BCS $BDE7 Ja, ==> BDE4: A9 00 LDA #$00 Ok. Meldung merken BDE6: 2C B $2C Einsprung von $BDE2: BDE7: A9 06 LDA #$06 Format-Error merken BDE9: 20 66 BF JSR $BF66 Burst-Status setzen BDEC: 68 PLA BDED: 85 8F STA $8F letzte physikalische Spur zurueckholen BDEF: 68 PLA BDF0: 85 9B STA $9B Fuellbyte zurueckholen BDF2: 68 PLA BDF3: 85 90 STA $90 Starttrack der Partition zurueckholen BDF5: 4C 02 BB JMP $BB02 Fehler im Klartext ausgeben BDF8: 0E 16 26 44 Anzahl Bytes zwischen zwei Sektoren Burst-Befehle $08,$09: (n.v.) (bei der 1571: $85a5) BDFC: A9 0E LDA #$0E Syntax Error in BDFE: 20 66 BF JSR $BF66 Burst-Status eintragen BE01: A9 31 LDA #$31 31, SYNTAX ERROR BE03: 4C 7C 80 JMP $807C Burst-Befehle $0a,$1a: Query Disk Format (bei der 1571: $8517) BE06: 20 B2 BC JSR $BCB2 Burst-Befehl: INQUIRE-DISK (bei der 1571: $8f5f) BE09: A2 00 LDX #$00 Anzahl gefundener Sektoren = 0 setzen BE0B: 86 3D STX $3D BE0D: A9 C0 LDA #$C0 RESTORE_DV ('BUMP') BE0F: 20 F4 DB JSR $DBF4 Nummer der ersten Spur ermitteln BE12: C9 02 CMP #$02 Fehler ? BE14: B0 59 BCS $BE6F ja, ==> BE16: A5 1F LDA $1F gefundene Spurnummer aus Blockheader als BE18: 85 8E STA $8E '1. physikalische Spurnummer' uebernehmen BE1A: 24 7C BIT $7C Burst-Kommandobyte holen BE1C: 10 0F BPL $BE2D F-Flag (b7): bestimmte Spur abfragen ? BE1E: AD 03 02 LDA $0203 ja: BE21: 8D BC 01 STA $01BC Tracknummer in HDRS2 des Jobs0 schreiben BE24: A9 8C LDA #$8C SEEK_DV: sucht physikalischn Zylinder BE26: 20 9D 95 JSR $959D Job aufrufen BE29: C9 02 CMP #$02 Fehler ? BE2B: B0 42 BCS $BE6F ja, ==> Einsprung von $BE1C: BE2D: A5 7C LDA $7C Burst-Kommandobyte holen BE2F: 29 10 AND #$10 S-Flag holen (Seitenauswahl) BE31: 4A LSR und nach b0 verschieben BE32: 4A LSR BE33: 4A LSR BE34: 4A LSR x=0 BE35: 9D CE 01 STA $01CE,X in den Job-Seitenspeicher (SIDS) schreiben BE38: A9 9C LDA #$9C SIDE_DV: Seite auswaehlen BE3A: 20 9D 95 JSR $959D Job aufrufen BE3D: A9 B0 LDA #$B0 SEEKHD_DV: erstbesten Sektor suchen BE3F: 20 9D 95 JSR $959D Job aufrufen BE42: C9 02 CMP #$02 ist ein Fehler aufgetreten ? BE44: B0 29 BCS $BE6F ja, ==> BE46: A5 21 LDA $21 gefundene Sektornummer BE48: 85 3E STA $3E merken [Jetzt werden so lange Blockheader gesucht und die Sektornummer gemerkt, bis die zuerst gefundene Nummer wieder auftaucht.] Einsprung von $BE64: BE4A: A2 00 LDX #$00 Job0 benutzen BE4C: A9 B0 LDA #$B0 SEEKHD_DV: naechsten Sektor suchen BE4E: 20 9D 95 JSR $959D Job aufrufen BE51: C9 02 CMP #$02 Fehler ? BE53: B0 1A BCS $BE6F ja, ==> BE55: A5 21 LDA $21 Sektornummer aus dem Blockheader holen BE57: A4 3D LDY $3D Anzahl gefundener Sektoren holen BE59: 99 0B 02 STA $020B,Y Sektor in die Sektorentabelle eintragen BE5C: E6 3D INC $3D Sektorenzahl erhoehen BE5E: C0 1F CPY #$1F Ende des 'Kommandopuffers' erreicht ? BE60: B0 0B BCS $BE6D ja, ==> BE62: C5 3E CMP $3E erste Sektornummer wieder erreicht ? BE64: D0 E4 BNE $BE4A nein, ==> Daten auswerten BE66: A5 3D LDA $3D BE68: 85 92 STA $92 Anzahl Sektoren merken BE6A: A9 00 LDA #$00 Ok. BE6C: 2C B $2C Einsprung von $BE60: BE6D: A9 02 LDA #$02 Header nicht gefunden (meint, Tabelle voll) Einsprung von $BE14, $BE2B, $BE44, $BE53: BE6F: 20 66 BF JSR $BF66 Burst-Status setzen (bei der 1571: $8523) BE72: C9 02 CMP #$02 Fehler ? BE74: 90 03 BCC $BE79 nein, ==> BE76: 4C FC BA JMP $BAFC Status ausgeben ==> Einsprung von $BE74: BE79: 20 97 C0 JSR $C097 groesste/kleinste Sektornummer suchen BE7C: 20 D4 AC JSR $ACD4 FSM auf Ausgabe schalten BE7F: AD EF 01 LDA $01EF kleinste gefundene Sektornummer BE82: 85 94 STA $94 als 1. Sektornummer der Spur merken BE84: AD F0 01 LDA $01F0 groesste gefundene Sektornummer BE87: 85 93 STA $93 als letzten Sektor der Spur merken Spurinformation an Computer senden BE89: 20 AB BF JSR $BFAB Burst-Status ausgeben BE8C: A5 92 LDA $92 Anzahl der Sektoren BE8E: 20 86 BF JSR $BF86 ausgeben BE91: A5 1F LDA $1F Tracknummer BE93: 20 86 BF JSR $BF86 ausgeben BE96: AD EF 01 LDA $01EF kleinste Sektornummer BE99: 20 86 BF JSR $BF86 ausgeben BE9C: AD F0 01 LDA $01F0 groesste Sektornummer BE9F: 20 86 BF JSR $BF86 ausgeben BEA2: A9 01 LDA #$01 1 (soll Sektorversatz sein) BEA4: 20 86 BF JSR $BF86 ausgeben BEA7: A9 20 LDA #$20 Sektorentabelle senden (T-Flag (b5)=1) ? BEA9: 24 7C BIT $7C BEAB: F0 0D BEQ $BEBA nein, ==> BEAD: A0 00 LDY #$00 Tabelle ausgeben Einsprung von $BEB8: BEAF: B9 0B 02 LDA $020B,Y BEB2: 20 86 BF JSR $BF86 Byte an Computer senden BEB5: C8 INY BEB6: C4 92 CPY $92 Anzahl Sektoren auf der Spur BEB8: D0 F5 BNE $BEAF Einsprung von $BEAB: BEBA: 60 RTS Burst-Befehl $0c: Inquire Status (bei der 1571: $856b) BEBB: 24 7C BIT $7C b7: W-Bit abfragen (0=Status schreiben) BEBD: 10 09 BPL $BEC8 W=0, dann ==> Einsprung von $BAFF: BEBF: 20 D4 AC JSR $ACD4 FSM zur Ausgabe vorbereiten BEC2: 20 AB BF JSR $BFAB Burst-Statusbyte ausgeben BEC5: 4C BB AC JMP $ACBB FSM auf Eingabe Einsprung von $BEBD: BEC8: AD 03 02 LDA $0203 Neuen Status BECB: 85 80 STA $80 in Burst-Status BECD: A9 20 LDA #$20 b5: M-Bit abfragen (1=Maske aendern) BECF: 24 7C BIT $7C Burst-Status-Maske aendern ? BED1: F0 0A BEQ $BEDD nein ==> BED3: AD 04 02 LDA $0204 neue OR-Maske BED6: 85 8A STA $8A BED8: AD 05 02 LDA $0205 neue AND-Maske BEDB: 85 89 STA $89 Einsprung von $BED1: BEDD: 24 7C BIT $7C b6: C-Bit abfragen (1=Diskette anmelden) BEDF: 50 10 BVC $BEF1 nicht gesetzt ==> BEE1: 08 PHP BEE2: 58 CLI Diskette anmelden BEE3: A9 80 LDA #$80 DOS-Fehler unterdruecken BEE5: 85 81 STA $81 BEE7: 20 69 FF JSR $FF69 Prueft auf Diskettenwechsel BEEA: 20 03 8F JSR $8F03 Diskette initialisieren BEED: 06 81 ASL $81 Fehler freigeben BEEF: 28 PLP BEF0: 60 RTS Standard-1581-Format setzen Einsprung von $BEDF, $BCC8: BEF1: A9 01 LDA #$01 Flag fuer Diskettenwechsel setzen BEF3: 85 25 STA $25 BEF5: 4C 69 FF JMP $FF69 1581-Format vorwaehlen Burst-Befehle $0e,$0f: (n.v.) BEF8: A2 0E LDX #$0E Syntax Error in Burst-Status eintragen BEFA: 20 66 BF JSR $BF66 BEFD: A9 31 LDA #$31 31, SYNTAX ERROR BEFF: 4C 7C 80 JMP $807C Burst-Befehle $1c,$1d: Dump Cache BF02: AD 02 02 LDA $0202 BF05: A8 TAY Laufwerksnummer BF06: 29 01 AND #$01 = 1 BF08: D0 32 BNE $BF3C ja, Fehler ==> BF0A: A2 00 LDX #$00 Jobnummer 0 verwenden BF0C: 98 TYA immer Schreiben ? BF0D: 10 15 BPL $BF24 nein ==> BF0F: 29 40 AND #$40 ja BF11: 4A LSR Seite holen BF12: 4A LSR BF13: 4A LSR BF14: 4A LSR BF15: 4A LSR BF16: 4A LSR BF17: 29 01 AND #$01 [doppelt maskiert haelt besser !?] BF19: 85 97 STA $97 aktuelle Seite setzen BF1B: AD 03 02 LDA $0203 Phys. Spur holen BF1E: 85 95 STA $95 BF20: A9 80 LDA #$80 Flag fuer Spur schreiben BF22: 85 87 STA $87 setzen Einsprung von $BF0D: BF24: A5 87 LDA $87 Cache auf Disk schreiben ? BF26: 10 17 BPL $BF3F nein ==> BF28: A9 B6 LDA #$B6 DET_WP: Schreibschutz testen BF2A: 20 9D 95 JSR $959D Job aufrufen BF2D: 8D FA 01 STA $01FA Ergebnis merken BF30: D0 0F BNE $BF41 Diskette schreibgeschuetzt ==> BF32: A9 80 LDA #$80 BF34: 85 81 STA $81 DOS-Fehlermeldung unterdruecken BF36: 20 6C FF JSR $FF6C Cache schreiben BF39: 06 81 ASL $81 Fehlermeldungen zulassen BF3B: 2C B $2C Einsprung von $BF08: BF3C: A9 4F LDA #$4F kein Laufwerk verfuegbar BF3E: 2C B $2C Einsprung von $BF26: BF3F: A9 00 LDA #$00 O.K. Einsprung von $BF30: BF41: 4C FC BA JMP $BAFC Kopf ggf. auf die angegebene Spur setzen (bei der 1571: $891b) Einsprung von $BAF4, $BBF3: BF44: CE 06 02 DEC $0206 Tracknummer in phy. Format umwandeln Einsprung von $BB71, $BC96: BF47: A5 29 LDA $29 Laenge der Befehlszeile holen BF49: C9 07 CMP #$07 ist eine Folgespur angegeben ? BF4B: 90 0C BCC $BF59 nein, ==> BF4D: A2 00 LDX #$00 Jobnummer 0 setzen BF4F: AD 06 02 LDA $0206 neue Tracknummer holen BF52: 95 0B STA $0B,X und in Jobspeicher schreiben BF54: A9 A8 LDA #$A8 PSEEK_DV: Sucht den angegebenen phy. Sektor BF56: 4C 9D 95 JMP $959D Job aufrufen Einsprung von $BF4B: BF59: 60 RTS Burst-Status senden, wenn gerade Daten vom Computer empfangen werden Einsprung von $BBD7, $BC7A: BF5A: 20 D4 AC JSR $ACD4 FSM auf Ausgabe schalten BF5D: 20 AB BF JSR $BFAB Burst-Status-Byte ausgeben BF60: 20 29 C0 JSR $C029 Auf Signal vom Computer warten BF63: 4C BB AC JMP $ACBB FSM auf Eingabe schalten Burst-Status setzen Einsprung von $BAC8, $BAFC, $BB34, $BBD4, $BC24, $BD0C, $BDE9, $BDFE, $BE6F, $BEFA: BF66: 8D EA 01 STA $01EA Fehlercode BF69: A6 91 LDX $91 Sektorengroesse BF6B: A5 80 LDA $80 b7: Fremdformat BF6D: 29 80 AND #$80 BF6F: 0D EA 01 ORA $01EA + Fehlercode BF72: 1D 7F BF ORA $BF7F,X + Sektorengroesse BF75: 25 89 AND $89 Burst-AND-Maske BF77: 05 8A ORA $8A Burst-OR-Maske BF79: 85 80 STA $80 = Neuer Burst-Status BF7B: AD EA 01 LDA $01EA Fehlercode zurueckholen BF7E: 60 RTS BF7F: 00 10 20 30 Sektorengroesse-Codes FSM: Byte ausgeben (bei der 1571: $9228) Einsprung von $BF91: BF83: 4C 15 AD JMP $AD15 ATN-Modus testen Einsprung von $AAC8, $BAE3, $BB59, $BE8E, $BE93, $BE99, $BE9F, $BEA4, $BEB2, $BFAD: BF86: 48 PHA <-- Einsprung Einsprung von $BF8D, $BF97: BF87: AD 01 40 LDA $4001 Normalen Bus auslesen BF8A: CD 01 40 CMP $4001 BF8D: D0 F8 BNE $BF87 und entprellen BF8F: 29 FF AND #$FF nz-Flags neu setzen BF91: 30 F0 BMI $BF83 ATN, (dann Abbruch) ==> BF93: 45 76 EOR $76 letzter FSM-Clock-Zustand BF95: 29 04 AND #$04 (b2: CLOCK IN) BF97: F0 EE BEQ $BF87 Clock-gekippt ? nein, ==> BF99: 68 PLA Ja: Byte ausgeben BF9A: 8D 0C 40 STA $400C Byte in FSM-Schieberegister schreiben BF9D: A5 76 LDA $76 neuen Clock-Zustand merken BF9F: 49 04 EOR #$04 BFA1: 85 76 STA $76 BFA3: A9 08 LDA #$08 Schiebevorgang abwarten Einsprung von $BFA8: BFA5: 2C 0D 40 BIT $400D b3=1: Vorgang beendet ? BFA8: F0 FB BEQ $BFA5 nein, ==> BFAA: 60 RTS Statusbyte ausgeben Einsprung von $BAD6, $BB3F, $BE89, $BEC2, $BF5D: BFAB: A5 80 LDA $80 Burst-Statusbyte BFAD: 4C 86 BF JMP $BF86 ausgeben Job ausfuehren und ggf. bei Fehlern mehrmals versuchen (bei der 1571: $864b) Einsprung von $BAC5, $BB31, $BBD1, $BC21, $BCBF, $BCE3: BFB0: 48 PHA BFB1: A9 40 LDA #$40 T&S-Check ausschalten BFB3: 8D A8 02 STA $02A8 BFB6: 68 PLA Einsprung von $B954: BFB7: 08 PHP i-Flag merken BFB8: 58 CLI i-Flag loeschen BFB9: 85 28 STA $28 Jobcode merken BFBB: 20 9D 95 JSR $959D Job aufrufen BFBE: C9 02 CMP #$02 kein Fehler ? BFC0: 90 03 BCC $BFC5 ja, ==> BFC2: 20 CE BF JSR $BFCE Fehler behandeln Einsprung von $BFC0: BFC5: A9 00 LDA #$00 Fehlerpruefung wieder einschalten BFC7: 8D A8 02 STA $02A8 BFCA: B5 02 LDA $02,X Jobrueckmeldung holen BFCC: 28 PLP i-Flag zurueckholen BFCD: 60 RTS Einsprung von $BFC2: BFCE: AD A8 02 LDA $02A8 DOS-Fehlerunterdrueckung einschalten BFD1: 09 80 ORA #$80 BFD3: 8D A8 02 STA $02A8 BFD6: 86 6C STX $6C BFD8: A5 28 LDA $28 BFDA: 9D 72 02 STA $0272,X BFDD: 20 9D 95 JSR $959D BFE0: 4C ED 94 JMP $94ED mehrere Leseversuche durchfuehren Cachepuffer auf Diskette schreiben E: x: zu verwendender Jobspeicher Einsprung von $FF6C: BFE3: A9 A2 LDA #$A2 TRKWRT_DV (Cache schreiben) BFE5: 9D 72 02 STA $0272,X BFE8: A5 95 LDA $95 Track im Cache BFEA: 85 4D STA $4D = aktueller Track BFEC: A5 94 LDA $94 1. Sektornummer auf Track BFEE: 85 4E STA $4E = aktuelle Sektornummer BFF0: 86 6C STX $6C Jobnummer merken BFF2: 8A TXA BFF3: 20 88 95 JSR $9588 T&S an DC uebergeben BFF6: A6 6C LDX $6C Jobnummer BFF8: A5 30 LDA $30 Anzahl Schreibversuche BFFA: 29 3F AND #$3F BFFC: 85 28 STA $28 in Zaehler BFFE: 20 1D C0 JSR $C01D Schreibjob ausfuehren C001: 90 15 BCC $C018 kein Fehler, ==> Einsprung von $C00A: C003: 20 19 C0 JSR $C019 Schreibflag setzen, neuer Versuch C006: 90 10 BCC $C018 kein Fehler, ==> C008: C6 28 DEC $28 Naechster Versuch C00A: D0 F7 BNE $C003 C00C: 24 81 BIT $81 Fehlermeldung unterdruecken (Burst) ? C00E: 30 08 BMI $C018 ja, ==> C010: 2C A8 02 BIT $02A8 Fehlermeldung unterdruecken (DOS-Flag) ? C013: 30 03 BMI $C018 ja, ==> C015: 4C 2F 95 JMP $952F Fehlermeldung ausgeben Einsprung von $C001, $C006, $C00E, $C013: C018: 60 RTS Einsprung von $C003: C019: A9 80 LDA #$80 Flag: 'Cache veraendert' setzen C01B: 85 87 STA $87 Einsprung von $BFFE: C01D: A5 4D LDA $4D aktuellen Track C01F: 85 95 STA $95 als Track im Cachepuffer setzen C021: A0 01 LDY #$01 1 Schreibversuch C023: 4C 69 95 JMP $9569 Cache schreiben FSM: Wartet, bis naechstes Byte gesendet werden soll (bei der 1571: $86a0) Einsprung von $C033: C026: 20 15 AD JSR $AD15 ATN-Modus testen Einsprung von $C02F, $C039, $BF60: C029: AD 01 40 LDA $4001 Seriellen Port auslesen C02C: CD 01 40 CMP $4001 und entprellen C02F: D0 F8 BNE $C029 C031: 29 FF AND #$FF Flags herstellen C033: 30 F1 BMI $C026 b7=1 (ATN) ? ja, ==> C035: 45 76 EOR $76 FSM-Clock C037: 29 04 AND #$04 = letzter FSM-Clock Zustand C039: F0 EE BEQ $C029 ja, Warten ==> C03B: 45 76 EOR $76 FSM-Clock Zustand merken C03D: 85 76 STA $76 C03F: 60 RTS physikalischen Folgesektor holen (bei der 1571: $886c) Einsprung von $BB6B, $BC90: C040: 38 SEC C041: AD EF 01 LDA $01EF kleinste gefundene Sektornummer C044: F0 03 BEQ $C049 =0, ==> C046: E9 02 SBC #$02 C048: 2C B $2C Einsprung von $C044: C049: E9 01 SBC #$01 a=$ff C04B: 85 3D STA $3D C04D: AD 04 02 LDA $0204 aktuelle Sektornummer mit der C050: CD F0 01 CMP $01F0 groessten gefundenen Sektornummer vergleichen C053: F0 06 BEQ $C05B gleich, ==> C055: 18 CLC Sektornummer erhoehen C056: 69 01 ADC #$01 C058: 4C 6E C0 JMP $C06E [Hier ist doch das Carry geloescht, oder ?] Einsprung von $C053: C05B: A5 7C LDA $7C Seite wechseln (0/1) C05D: A8 TAY C05E: 49 10 EOR #$10 C060: 85 7C STA $7C C062: 98 TYA C063: 29 10 AND #$10 war Seite 1 angewaehlt ? C065: F0 03 BEQ $C06A nein, ==> C067: EE 03 02 INC $0203 Spurnummer erhoehen Einsprung von $C065: C06A: A5 94 LDA $94 1. Sektornumer holen C06C: B0 08 BCS $C076 , ==> Einsprung von $C058: C06E: 90 06 BCC $C076 ==> C070: ED F0 01 SBC $01F0 [Wird nie aufgerufen ?] C073: 18 CLC " C074: 65 3D ADC $3D " Einsprung von $C06C, $C06E: C076: 8D 04 02 STA $0204 neue Sektornummer merken C079: 60 RTS logischen Folgesektor holen (bei der 1571: $886c) Einsprung von $BAEE, $BBED: C07A: A5 75 LDA $75 Anzahl Sektoren pro Spur C07C: 38 SEC C07D: E9 01 SBC #$01 -1 C07F: 85 3D STA $3D = letzte Sektornummer C081: AD 04 02 LDA $0204 aktuellen Sektor holen C084: C5 3D CMP $3D ist der letzte Sektor des Tracks erreicht ? C086: F0 06 BEQ $C08E ja, ==> C088: 18 CLC Sektornummer erhoehen C089: 69 01 ADC #$01 C08B: 4C 93 C0 JMP $C093 Einsprung von $C086: C08E: EE 03 02 INC $0203 Tracknummer erhoehen C091: A9 00 LDA #$00 Sektornummer auf 0 setzen Einsprung von $C08B: C093: 8D 04 02 STA $0204 C096: 60 RTS Groesste/kleinste Sektornummer suchen (bei der 1571: $8961) kleinste Sektornummer suchen Einsprung von $BE79: C097: A4 92 LDY $92 C099: 88 DEY C09A: A9 FF LDA #$FF groesstmoegliche Sektornummer Einsprung von $C0A5: C09C: D9 0B 02 CMP $020B,Y ist Sektornummer in der Tabelle kleiner ? C09F: 90 03 BCC $C0A4 nein, ==> C0A1: B9 0B 02 LDA $020B,Y ja, Nummer merken Einsprung von $C09F: C0A4: 88 DEY C0A5: 10 F5 BPL $C09C alle Sektornummern vergleichen, ==> C0A7: 8D EF 01 STA $01EF kleinste Nummer merken groesste Sektornummer suchen C0AA: A4 92 LDY $92 Anzahl der Sektoren C0AC: 88 DEY C0AD: A9 00 LDA #$00 kleinstmoegliche Sektornummer Einsprung von $C0B8: C0AF: D9 0B 02 CMP $020B,Y Sektornummer groesser ? C0B2: B0 03 BCS $C0B7 nein, ==> C0B4: B9 0B 02 LDA $020B,Y ja, Nummer merken Einsprung von $C0B2: C0B7: 88 DEY C0B8: 10 F5 BPL $C0AF alle Sektornummern vergleichen C0BA: 8D F0 01 STA $01F0 groesste Nummer merken C0BD: 60 RTS Controller-Programm 1 JLCC: Controller-Routine [Zuerst werden alle Jobspeicher getestet (Job8 zuerst), ob Jobauftraege vorliegen. Bei den entsprechenden Jobs werden ggf. die T&S in das phy. Format umgewandelt. Jobs, die sich mit den aktuellen Cachedaten bearbeiten lassen, werden sofort bearbeitet. Anschliessend wird der Job mit der niedrigsten Nummer bearbeitet: ggf. werden der Motor eingeschaltet, der Kopf positioniert, u.s.w. Wenn eine neue Spur in den Cache geladen worden ist, beginnt anschliessend die Jobauswertung wieder von Vorne (mit den neuen Cache-Daten). Schliesslich wird die eigentliche Job-Routine aufgerufen. Wenn kein aktiver Job mehr anliegt, oder der Schreib-/Lesekopf bewegt werden muss, wird in die Hauptsteuer-Routine verzweigt, die fuer die Motor- und LED-Steuerung zustaendig ist. Im Gegensatz zu frueheren Commodore-Laufwerken uebergibt das Controller- programm die Regie nicht an das DOS, solange der Schreib-/Lesekopf positioniert wird. Damit koennen Bloecke (bei der 1581 Spuren) nicht mehr 'im Hintergrund' eingelesen werden. Achtung: Wenn die Jobroutine mehrere Jobs 'gleichzeitig' bekommt, kann sie sich in der Seitenauswahl irren, da fuer alle Jobs zusammen nur ein Seitenregister ($96) existiert und dieses bei mehreren Jobs gnadenlos ueberschrieben wird !!!] C0BE: BA TSX Stackpointer retten fuer Funktionsabbruch C0BF: 86 2C STX $2C und fuer Break-Flag pruefen Jobspeicher pruefen C0C1: A9 80 LDA #$80 Flag fuer 'kein Job aktiv' setzen C0C3: 85 83 STA $83 C0C5: A0 08 LDY #$08 mit Jobpuffer 8 beginnen Einsprung von $C0D5, $CDFD: C0C7: B9 02 00 LDA $0002,Y <-- Jobspeicher pruefen C0CA: 30 12 BMI $C0DE liegt Job an, dann ==> C0CC: B9 9F 00 LDA $009F,Y Zeiger in Cachepuffer (Hi) C0CF: 29 7F AND #$7F b7=0: Flag: 'T&S wurden noch nicht ins C0D1: 99 9F 00 STA $009F,Y phy. Format umgewandelt' setzen Einsprung von $C101: C0D4: 88 DEY naechsten Jobspeicher pruefen C0D5: 10 F0 BPL $C0C7 C0D7: A4 83 LDY $83 b7=0: aktiven Job gefunden ? C0D9: 10 29 BPL $C104 ja, ==> C0DB: 4C 00 CE JMP $CE00 Zur Hauptsteuer-Routine ==> Jobcode analysieren und ggf. Job mit Cachedaten durchfuehren Einsprung von $C0CA: C0DE: 84 83 STY $83 Aktuelle Jobnummer merken C0E0: AA TAX Jobcode merken C0E1: 98 TYA Index fuer 2-Byte Puffer berechnen C0E2: 0A ASL C0E3: 85 99 STA $99 C0E5: BD E7 C1 LDA $C1E7,X Nummer der Jobroutine nach $84 C0E8: 85 84 STA $84 C0EA: AA TAX C0EB: BD 63 C1 LDA $C163,X Job-Kommandobits holen C0EE: 85 85 STA $85 C0F0: BD 84 C1 LDA $C184,X C0F3: 85 86 STA $86 C0F5: 20 3C FF JSR $FF3C logisches in physikalisches Format wandeln C0F8: 06 85 ASL $85 b6=1: Cachedaten verwenden ? C0FA: 90 03 BCC $C0FF nein, ==> C0FC: 20 51 CF JSR $CF51 Wenn moeglich, Cache verwenden Einsprung von $C0FA: C0FF: A4 83 LDY $83 aktuelle Jobnummer zurueckholen C101: 4C D4 C0 JMP $C0D4 naechsten Jobspeicher testen Der Job kann nicht mit Cachedaten durchgefuehrt werden Einsprung von $C0D9: C104: 06 85 ASL $85 b5=1: Motor einschalten ? C106: 90 03 BCC $C10B nein, ==> C108: 20 63 CD JSR $CD63 Motor einschalten Einsprung von $C106: C10B: 06 85 ASL $85 b4=1: Anlaufzeit abwarten ? C10D: 90 03 BCC $C112 nein, ==> C10F: 20 7B CD JSR $CD7B Motor-Anlaufzeit abwarten Einsprung von $C10D: C112: 06 85 ASL $85 b3=1: Diskettenformat abfragen ? C114: 90 03 BCC $C119 nein, ==> C116: 20 A6 CF JSR $CFA6 Diskettenformat abfragen Einsprung von $C114: C119: 06 85 ASL $85 b2=1: Cache ggf. schreiben ? C11B: 90 14 BCC $C131 nein, ==> C11D: A5 87 LDA $87 b7=1: wurde Cache veraendert ? C11F: 10 10 BPL $C131 nein, ==> C121: A5 95 LDA $95 aktueller Track im Cache C123: 85 88 STA $88 = Solltrack bei Kopfbewegung C125: C5 27 CMP $27 steht Kopf schon auf der richtigen Spur ? C127: D0 17 BNE $C140 nein, (Spur anfahren) ==> C129: A5 97 LDA $97 Seitennummer der aktuellen Cachedaten holen C12B: 20 C0 CF JSR $CFC0 Seite anwaehlen C12E: 4C 00 C6 JMP $C600 Cache auf Diskette schreiben Einsprung von $C11B, $C11F: C131: 06 85 ASL $85 b1=1: Kopf ggf. positionieren ? C133: 90 14 BCC $C149 nein, ==> C135: A4 99 LDY $99 Jobnummer*2 holen C137: B9 BC 01 LDA $01BC,Y physikalische Spurnummer holen (HDRS2) C13A: 85 88 STA $88 und als Sollspur merken C13C: C5 27 CMP $27 = aktuelle Spurnummer ? C13E: F0 09 BEQ $C149 ja, ==> Einsprung von $C127: C140: A5 26 LDA $26 b6=1: 'Schrittmotor ist aktiv' C142: 09 40 ORA #$40 im Drivestatus setzen C144: 85 26 STA $26 C146: 4C 00 CE JMP $CE00 Zur Hauptsteuer-Routine ==> Einsprung von $C133, $C13E: C149: 06 85 ASL $85 b0=1: Seite anwaehlen ? C14B: 90 05 BCC $C152 nein, ==> C14D: A5 96 LDA $96 aktuelle Diskettenseite holen C14F: 20 C0 CF JSR $CFC0 und anwaehlen Einsprung von $C14B: C152: A5 84 LDA $84 Befehlsnummer C154: 0A ASL als Index auf eine 2-Byte-Tabelle C155: AA TAX C156: BD A5 C1 LDA $C1A5,X Adresse der Jobroutine holen C159: 85 48 STA $48 C15B: BD A6 C1 LDA $C1A6,X C15E: 85 49 STA $49 C160: 4C AF C5 JMP $C5AF Zum Patch springen * Old ROM: C160: 6C 48 00 JMP ($0048) Job aufrufen Tabellen des Controller-Programms C163: FF 00 30 00 20 00 32 30 Steuerbits fuer die allgemeinen C16B: FF 30 00 00 00 00 00 00 Routinen der Jobbehandlung. C173: BB 3C 3B 3B 3F 30 BB 30 C17B: 00 3A B2 FF FF 7F 7F 30 C183: 00 C184: 00 80 80 80 80 80 80 00 C18C: 20 80 80 80 80 80 80 80 C194: 00 00 40 60 00 00 00 00 C19C: 00 00 00 40 60 40 60 80 C1A4: 80 |------------ Befehl erwartet T&S im logischen Format ||----------- zum Lesem/Schreiben Cachepuffer benutzen |||---------- Motor einschalten ||||--------- Motor-Anlaufzeit abwarten |||| |------- Diskettenformat abfragen |||| ||------ Cache schreiben, wenn noetig |||| |||----- Schreib-/Lesekopf ggf. positionieren |||| ||||---- Diskettenseite anwaehlen |||| |||| |||| |||| |---- 0: T&S sind im HDRS ( $0b- $1c) |||| |||| | 1: T&S sind im HDRS2 ($01bc-$01cd) |||| |||| | bzw. keine T&S benoetigt |||| |||| ||--- keine Daten kopieren |||| |||| |||-- In den Cache schreiben |||| |||| ||| VVVV VVVV VVV C163: %1111.1111 ,C184 %0000.0000 READ_DV C164: %0000.0000 ,C185 %1000.0000 RESET_DV C165: %0011.0000 ,C186 %1000.0000 MOTON_DV C166: %0000.0000 ,C187 %1000.0000 MOTOFF_DV C167: %0010.0000 ,C188 %1000.0000 MOTONI_DV C168: %0000.0000 ,C189 %1000.0000 MOTOFFI_DV C169: %0011.0010 ,C18A %1000.0000 SEEK_DV C16A: %0011.0000 ,C18B %0000.0000 FORMAT_DV C16B: %1111.1111 ,C18C %0010.0000 WRITE_DV C16C: %0011.0000 ,C18D %1000.0000 DISKIN_DV C16D: %0000.0000 ,C18E %1000.0000 LEDACTON_DV C16E: %0000.0000 ,C18F %1000.0000 LEDACTOFF_DV C16F: %0000.0000 ,C190 %1000.0000 ERRLEDON_DV C170: %0000.0000 ,C191 %1000.0000 ERRLEDOFF_DV C171: %0000.0000 ,C192 %1000.0000 SIDE_DV C172: %0000.0000 ,C193 %1000.0000 BUFMOV_DV C173: %1011.1011 ,C194 %0000.0000 WRTVER_DV C174: %0011.1100 ,C195 %0000.0000 TRKWRT_DV C175: %0011.1011 ,C196 %0100.0000 SP_READ C176: %0011.1011 ,C197 %0110.0000 SP_WRITE C177: %0011.1111 ,C198 %0000.0000 PSEEK_DV C178: %0011.0000 ,C199 %0000.0000 SEEKHD_DV C179: %1011.1011 ,C19A %0000.0000 SEEKPHD_DV C17A: %0011.0000 ,C19B %0000.0000 RESTORE_DV C17B: %0000.0000 ,C19C %0000.0000 JUMPC_DV C17C: %0011.1010 ,C19D %0000.0000 EXBUF_DV C17D: %1011.0010 ,C19E %0000.0000 FORMATDK_DV C17E: %1111.1111 ,C19F %0100.0000 TREAD_DV C17F: %1111.1111 ,C1A0 %0110.0000 TWRT_DV C180: %0111.1111 ,C1A1 %0100.0000 TPREAD_DV C181: %0111.1111 ,C1A2 %0110.0000 TPWRT_DV C182: %0011.0000 ,C1A3 %1000.0000 DETWP_DV C183: %0000.0000 ,C1A4 %1000.0000 ungueltiger Jobcode Adressen der Jobroutinen, Funktionsnummer, Jobcodes C1A5: 00 C9 W $C900 00 $80: READ_DV C1A7: E7 C2 W $C2E7 01 $82: RESET_DV C1A9: 90 C3 W $C390 02 $84: MOTON_DV C1AB: 93 C3 W $C393 03 $86: MOTOFF_DV C1AD: 96 C3 W $C396 04 $88: MOTONI_DV C1AF: A9 C3 W $C3A9 05 $8a: MOTOFFI_DV C1B1: AF C3 W $C3AF 06 $8c: SEEK_DV C1B3: BB C3 W $C3BB 07 $8e: FORMAT_DV C1B5: 00 C9 W $C900 08 $90: WRITE_DV C1B7: D7 C6 W $C6D7 09 $92: DISKIN_DV C1B9: 46 C5 W $C546 0a $94: LEDACTON_DV C1BB: 4F C5 W $C54F 0b $96: LEDACTOFF_DV C1BD: 58 C5 W $C558 0c $98: ERRLEDON_DV C1BF: 61 C5 W $C561 0d $9a: ERRLEDOFF_DV C1C1: 6A C5 W $C56A 0e $9c: SIDE_DV C1C3: 89 C5 W $C589 0f $9e: BUFMOV_DV C1C5: E1 C9 W $C9E1 10 $a0: WRTVER_DV C1C7: AC C5 W $C5AC 11 $a2: TRKWRT_DV C1C9: 00 C8 W $C800 12 $a4: SP_READ C1CB: 00 C7 W $C700 13 $a6: SP_WRITE C1CD: D7 C6 W $C6D7 14 $a8: PSEEK_DV C1CF: 09 CB W $CB09 15 $b0: SEEKHD_DV C1D1: E4 CA W $CAE4 16 $b8: SEEKPHD_DV C1D3: 0F CB W $CB0F 17 $c0: RESTORE_DV C1D5: 26 CB W $CB26 18 $d0: JUMPC_DV C1D7: 26 CB W $CB26 19 $e0: EXBUF_DV C1D9: 35 CB W $CB35 1a $f0: FORMATDK_DV C1DB: 00 C9 W $C900 1b $aa: TREAD_DV C1DD: 00 C9 W $C900 1c $ac: TWRT_DV C1DF: 00 C9 W $C900 1d $b2: TPREAD_DV C1E1: 00 C9 W $C900 1e $b4: TPWRT_DV C1E3: 76 CB W $CB76 1f $b6: DETWP_DV C1E5: 85 CB W $CB85 20 ungueltiger Jobcode Jobcodes C1E7: 20 20 20 20 20 20 20 20 $00-$7f unbenutzt C1EF: 20 20 20 20 20 20 20 20 Der Jobcode wird als Index in C1F7: 20 20 20 20 20 20 20 20 diese Tabelle benutzt. C1FF: 20 20 20 20 20 20 20 20 Der Wert in der entsprechenden C207: 20 20 20 20 20 20 20 20 Zelle ergibt die Funktionsnummer. C20F: 20 20 20 20 20 20 20 20 Diese wird als Index( * 2) in die C217: 20 20 20 20 20 20 20 20 vorhergehende Tabelle benutzt, C21F: 20 20 20 20 20 20 20 20 in der die Adresse der C227: 20 20 20 20 20 20 20 20 aufzurufenden Routine steht. C22F: 20 20 20 20 20 20 20 20 C237: 20 20 20 20 20 20 20 20 C23F: 20 20 20 20 20 20 20 20 C247: 20 20 20 20 20 20 20 20 C24F: 20 20 20 20 20 20 20 20 C257: 20 20 20 20 20 20 20 20 C25F: 20 20 20 20 20 20 20 20 C267: 00 20 01 20 02 20 03 20 Funktionen der vorhergehenden C26F: 04 20 05 20 06 20 07 20 Tabelle entnehmen C277: 08 20 09 20 0A 20 0B 20 C27F: 0C 20 0D 20 0E 20 0F 20 C287: 10 20 11 20 12 20 13 20 C28F: 14 20 1B 20 1C 20 20 20 C297: 15 20 1D 20 1E 20 1F 20 C29F: 16 20 20 20 20 20 20 20 C2A7: 17 20 20 20 20 20 20 20 C2AF: 20 20 20 20 20 20 20 20 C2B7: 18 20 20 20 20 20 20 20 C2BF: 20 20 20 20 20 20 20 20 C2C7: 19 20 20 20 20 20 20 20 C2CF: 20 20 20 20 20 20 20 20 C2D7: 1A 20 20 20 20 20 20 20 C2DF: 20 20 20 20 20 20 20 20 ----------------------------- JOB $82: RESET_DV ----------------------------- C2E7: A0 FF LDY #$FF Warten, Warten, Warten C2E9: 20 D5 CB JSR $CBD5 (1/2 s insgesamt) C2EC: A0 FF LDY #$FF C2EE: 20 D5 CB JSR $CBD5 C2F1: A9 80 LDA #$80 Track im Cache = $80 (kein Track) C2F3: 85 95 STA $95 C2F5: A9 00 LDA #$00 Cachepuffer nicht veraendert C2F7: 85 87 STA $87 C2F9: 20 CF B0 JSR $B0CF physikalisches 1581-Format festlegen C2FC: 20 B3 B0 JSR $B0B3 ganze Diskette als Partition setzen C2FF: A9 4E LDA #$4E Wert $4e20 fuer Timer B C301: 8D D7 01 STA $01D7 20000 Taktzyklen bei 2 Mhz C304: A9 20 LDA #$20 ergibt 100 Durchlaeufe / sec C306: 8D D8 01 STA $01D8 C309: 20 9F CB JSR $CB9F Timer B setzen Controllerbefehle C30C: A9 08 LDA #$08 Restore C30E: 8D DA 01 STA $01DA Schrittmotor auf 6 ms / Schritt einstellen C311: A9 18 LDA #$18 Seek: Spur suchen C313: 8D DB 01 STA $01DB C316: A9 28 LDA #$28 Step C318: 8D DC 01 STA $01DC C31B: A9 48 LDA #$48 Step-in C31D: 8D DD 01 STA $01DD C320: A9 68 LDA #$68 Step-out C322: 8D DE 01 STA $01DE C325: A9 88 LDA #$88 Read Sector C327: 8D DF 01 STA $01DF C32A: A9 AA LDA #$AA Write Sector C32C: 8D E0 01 STA $01E0 C32F: A9 C8 LDA #$C8 Read Adress C331: 8D E1 01 STA $01E1 C334: A9 E8 LDA #$E8 Read Track C336: 8D E2 01 STA $01E2 C339: A9 FA LDA #$FA Write Track C33B: 8D E3 01 STA $01E3 C33E: A9 D0 LDA #$D0 Force Interrupt (Controller Init) C340: 8D E4 01 STA $01E4 C343: A9 12 LDA #$12 Zeit fuer Beruhigung des Schrittmotors C345: 85 98 STA $98 ca. 18 ms Controller testen C347: A0 FF LDY #$FF Controller testen Einsprung von $C365: C349: 8C 01 60 STY $6001 Spur-, Sektor- und Datenregister mit allen C34C: 8C 02 60 STY $6002 Werten von $ff-$00 beschreiben, C34F: 8C 03 60 STY $6003 C352: 20 34 AD JSR $AD34 15 us warten, C355: CC 01 60 CPY $6001 alle Register testen. C358: D0 2E BNE $C388 weichen die Werte ab, dann ist der C35A: CC 02 60 CPY $6002 Controller defekt C35D: D0 29 BNE $C388 (defekt, ==>) C35F: CC 03 60 CPY $6003 C362: D0 24 BNE $C388 (defekt, ==>) C364: 88 DEY alle Kombinationen testen C365: D0 E2 BNE $C349 noch nicht fertig, ==> C367: 20 D1 CF JSR $CFD1 Controller initialisieren C36A: A9 00 LDA #$00 C36C: 8D 08 40 STA $4008 ??? C36F: 20 2F AD JSR $AD2F 35 us warten C372: AD 08 40 LDA $4008 C375: D0 0F BNE $C386 C377: EE DA 01 INC $01DA Kopftransport-Geschwindigkeit C37A: EE DB 01 INC $01DB auf 12 ms pro Schritt einstellen C37D: EE DC 01 INC $01DC [passiert bei mir immer] C380: EE DD 01 INC $01DD C383: EE DE 01 INC $01DE Einsprung von $C375: C386: D0 03 BNE $C38B Einsprung von $C358, $C35D, $C362: C388: A9 0D LDA #$0D CONTROLLER_ER C38A: 2C B $2C Einsprung von $C386, $C393, $C3B8, $C5A3, $C5A9, $C5AC, $C6DA, $CB0C, $CB23: C38B: A9 00 LDA #$00 Ok. C38D: 4C CC CD JMP $CDCC Rueckmeldung des Jobs JOB $84: MOTON_DV C390: 4C 99 C3 JMP $C399 Ende ==> JOB $86: MOTOFF_DV C393: 4C 8B C3 JMP $C38B Ende ==> JOB $88: MOTONI_DV C396: 20 B1 CB JSR $CBB1 Motor einschalten Einsprung von $C390, $C3AC, $C54C, $C555, $C55E, $C567, $C586, $CF87: C399: A9 00 LDA #$00 Einsprung von $CFA3: C39B: A4 83 LDY $83 Jobauftrag loeschen C39D: 99 02 00 STA $0002,Y C3A0: A9 80 LDA #$80 Jobbehandlung neu starten C3A2: 85 83 STA $83 Jobnummer: Flag: 'kein Job aktiv' setzen C3A4: A0 08 LDY #$08 alle Jobspeicher pruefen C3A6: 4C FA CD JMP $CDFA ==> JOB $8a: MOTOFFI_DV C3A9: 20 BA CB JSR $CBBA Motor ausschalten C3AC: 4C 99 C3 JMP $C399 JOB $8c: SEEK_DV C3AF: A5 88 LDA $88 Solltrack C3B1: C5 27 CMP $27 = Isttrack ? C3B3: F0 03 BEQ $C3B8 ja, (Ende) ==> C3B5: 4C 00 CE JMP $CE00 Zur Steuerroutine Einsprung von $C3B3: C3B8: 4C 8B C3 JMP $C38B OK, ENDE JOB $8e: FORMAT_DV C3BB: 20 B7 CF JSR $CFB7 Copyzeiger auf Cachepuffer-Anfang setzen C3BE: 20 D6 C3 JSR $C3D6 Spur formatieren C3C1: B0 0E BCS $C3D1 Fehler ? ja, ==> C3C3: 20 3F CD JSR $CD3F Controller-Status pruefen C3C6: D0 0B BNE $C3D3 Fehler ? ja, ==> C3C8: 20 B7 CF JSR $CFB7 Copyzeiger auf Cachepuffer-Anfang setzen C3CB: 20 00 CA JSR $CA00 Verify (Bei Fehler kein RTS) C3CE: A9 01 LDA #$01 01: Ok. C3D0: 2C B $2C Einsprung von $C3C1: C3D1: A9 06 LDA #$06 Format-Error Einsprung von $C3C6: C3D3: 4C CC CD JMP $CDCC alle Jobs nochmal pruefen Spur formatieren Einsprung von $C3BE, $CB41: C3D6: A5 88 LDA $88 Solltrack: Spur mit angegebener Tracknummer C3D8: 8D 01 60 STA $6001 formatieren (auch wenn Kopf wo anders ist) C3DB: 20 E3 CF JSR $CFE3 Precompensation ein-/ausschalten C3DE: A5 94 LDA $94 1. Sektornummer auf der Spur C3E0: 85 39 STA $39 merken C3E2: A5 92 LDA $92 Anzahl der Sektoren C3E4: 85 3A STA $3A merken C3E6: AD E3 01 LDA $01E3 Controller Befehl 'Write Track' C3E9: 20 F4 CB JSR $CBF4 Befehl an Controller geben C3EC: A2 20 LDX #$20 32 mal $4e schreiben Einsprung von $C3F6, $C3FE: C3EE: AD 00 60 LDA $6000 (Zeit, um auf Schreibmodus umschalten zu C3F1: 29 03 AND #$03 koennen) C3F3: 4A LSR Controller-Ready ? C3F4: 90 26 BCC $C41C ja, (Sprung nach $c544) ==> C3F6: F0 F6 BEQ $C3EE Byte-Ready ? nein, ==> C3F8: A9 4E LDA #$4E C3FA: 8D 03 60 STA $6003 $4e ins Datenregister schreiben C3FD: CA DEX C3FE: D0 EE BNE $C3EE 32 mal, ==> Einsprung von $C529: C400: A2 0C LDX #$0C 12 mal $00 schreiben (Sync-Markierung) Einsprung von $C40A, $C412: C402: AD 00 60 LDA $6000 C405: 29 03 AND #$03 C407: 4A LSR C408: 90 12 BCC $C41C [lauter bcc bis $c544] C40A: F0 F6 BEQ $C402 C40C: A9 00 LDA #$00 C40E: 8D 03 60 STA $6003 C411: CA DEX C412: D0 EE BNE $C402 C414: A2 03 LDX #$03 3 mal $f5 schreiben Einsprung von $C41E, $C426: C416: AD 00 60 LDA $6000 C419: 29 03 AND #$03 [$f5 ist das Zeichen fuer den Controller, C41B: 4A LSR fuer alle folgenden Bytes eine Einsprung von $C3F4, $C408: C41C: 90 51 BCC $C46F CRC-Pruefsumme zu berechnen. C41E: F0 F6 BEQ $C416 $f7 veranlasst den Controller spaeter, C420: A9 F5 LDA #$F5 die Pruefsumme auf Diskette zu schreiben. C422: 8D 03 60 STA $6003 Auch beim spaeteren Lesen werden diese C425: CA DEX Zeichen erkannt und ausgefuehrt.] C426: D0 EE BNE $C416 C428: EA NOP Einsprung von $C431: C429: AD 00 60 LDA $6000 1 mal $fe schreiben C42C: 29 03 AND #$03 (bedeutet zusammen mit den $f5, C42E: 4A LSR dass der Blockheader folgt) C42F: 90 3E BCC $C46F C431: F0 F6 BEQ $C429 C433: A9 FE LDA #$FE C435: 8D 03 60 STA $6003 C438: EA NOP Einsprung von $C441: C439: AD 00 60 LDA $6000 Spurnummer schreiben C43C: 29 03 AND #$03 C43E: 4A LSR C43F: 90 2E BCC $C46F C441: F0 F6 BEQ $C439 C443: AD 01 60 LDA $6001 C446: 8D 03 60 STA $6003 Einsprung von $C451: C449: AD 00 60 LDA $6000 Aktuelle Seite schreiben C44C: 29 03 AND #$03 C44E: 4A LSR C44F: 90 1E BCC $C46F C451: F0 F6 BEQ $C449 C453: A5 96 LDA $96 C455: 8D 03 60 STA $6003 C458: EA NOP Einsprung von $C461: C459: AD 00 60 LDA $6000 Aktuelle Sektornummer schreiben C45C: 29 03 AND #$03 C45E: 4A LSR C45F: 90 0E BCC $C46F C461: F0 F6 BEQ $C459 C463: A5 39 LDA $39 C465: 8D 03 60 STA $6003 C468: EA NOP Einsprung von $C471: C469: AD 00 60 LDA $6000 Sektorgroesse schreiben C46C: 29 03 AND #$03 C46E: 4A LSR Einsprung von $C41C, $C42F, $C43F, $C44F, $C45F: C46F: 90 33 BCC $C4A4 C471: F0 F6 BEQ $C469 C473: A5 91 LDA $91 C475: 8D 03 60 STA $6003 C478: EA NOP Einsprung von $C481: C479: AD 00 60 LDA $6000 $f7: CRC-Pruefsumme schreiben C47C: 29 03 AND #$03 (s. $c419) C47E: 4A LSR C47F: 90 23 BCC $C4A4 C481: F0 F6 BEQ $C479 C483: A9 F7 LDA #$F7 C485: 8D 03 60 STA $6003 C488: A2 16 LDX #$16 22 mal $4e schreiben Einsprung von $C492, $C49A: C48A: AD 00 60 LDA $6000 (einfache Luecke) C48D: 29 03 AND #$03 C48F: 4A LSR C490: 90 12 BCC $C4A4 C492: F0 F6 BEQ $C48A C494: A9 4E LDA #$4E C496: 8D 03 60 STA $6003 C499: CA DEX C49A: D0 EE BNE $C48A C49C: A2 0C LDX #$0C 12 mal $00 schreiben Einsprung von $C4A6, $C4AE: C49E: AD 00 60 LDA $6000 (Sync-Markierung) C4A1: 29 03 AND #$03 C4A3: 4A LSR Einsprung von $C46F, $C47F, $C490: C4A4: 90 3B BCC $C4E1 C4A6: F0 F6 BEQ $C49E C4A8: A9 00 LDA #$00 C4AA: 8D 03 60 STA $6003 C4AD: CA DEX C4AE: D0 EE BNE $C49E C4B0: A2 03 LDX #$03 3 mal $f5 schreiben Einsprung von $C4BA, $C4C2: C4B2: AD 00 60 LDA $6000 (CRC-Check anfangen) C4B5: 29 03 AND #$03 C4B7: 4A LSR C4B8: 90 27 BCC $C4E1 C4BA: F0 F6 BEQ $C4B2 C4BC: A9 F5 LDA #$F5 C4BE: 8D 03 60 STA $6003 C4C1: CA DEX C4C2: D0 EE BNE $C4B2 C4C4: EA NOP Einsprung von $C4CD: C4C5: AD 00 60 LDA $6000 1 mal $fb schreiben C4C8: 29 03 AND #$03 (bedeutet zusammen mit den $f5, C4CA: 4A LSR dass der Datenblock folgt) C4CB: 90 14 BCC $C4E1 C4CD: F0 F6 BEQ $C4C5 C4CF: A9 FB LDA #$FB C4D1: 8D 03 60 STA $6003 C4D4: A4 91 LDY $91 Sektorgroesse in 256 Bytes C4D6: C0 03 CPY #$03 feststellen C4D8: D0 01 BNE $C4DB C4DA: C8 INY Einsprung von $C4D8, $C4E3, $C4F8, $C4FD: C4DB: AD 00 60 LDA $6000 Daten schreiben C4DE: 29 03 AND #$03 C4E0: 4A LSR Einsprung von $C4A4, $C4B8, $C4CB: C4E1: 90 61 BCC $C544 C4E3: F0 F6 BEQ $C4DB C4E5: A5 9B LDA $9B Fuellbyte = $f5 ? C4E7: C9 F5 CMP #$F5 C4E9: D0 08 BNE $C4F3 nein, (Block mit Fuellbyte fuellen) ==> C4EB: 84 82 STY $82 ja, Daten aus Cache benutzen C4ED: A0 00 LDY #$00 C4EF: B1 4A LDA ($4A),Y C4F1: A4 82 LDY $82 Einsprung von $C4E9: C4F3: 8D 03 60 STA $6003 C4F6: E6 4A INC $4A Zeiger in Cachepuffer erhoehen C4F8: D0 E1 BNE $C4DB C4FA: E6 4B INC $4B C4FC: 88 DEY noch einen 256-Byte Block schreiben C4FD: D0 DC BNE $C4DB Einsprung von $C507: C4FF: AD 00 60 LDA $6000 $f7: CRC-Pruefsumme schreiben C502: 29 03 AND #$03 C504: 4A LSR C505: 90 3D BCC $C544 C507: F0 F6 BEQ $C4FF C509: A9 F7 LDA #$F7 C50B: 8D 03 60 STA $6003 C50E: A6 9A LDX $9A Anzahl der $4e-Bytes fuer die Luecke zwischen C510: EA NOP zwischen zwei Sektoren holen Einsprung von $C519, $C521: C511: AD 00 60 LDA $6000 x mal $4e schreiben C514: 29 03 AND #$03 C516: 4A LSR C517: 90 2B BCC $C544 C519: F0 F6 BEQ $C511 C51B: A9 4E LDA #$4E C51D: 8D 03 60 STA $6003 C520: CA DEX C521: D0 EE BNE $C511 C523: C6 3A DEC $3A Anzahl der noch zu schreibenden C525: F0 06 BEQ $C52D Sektoren =0 ? ja, ==> C527: E6 39 INC $39 Sektornummer + 1 C529: 4C 00 C4 JMP $C400 naechsten Block ==> C52C: EA NOP Einsprung von $C525, $C535, $C53D: C52D: AD 00 60 LDA $6000 so lange $4e schreiben, bis C530: 29 03 AND #$03 'Controller ready' C532: 4A LSR C533: 90 0A BCC $C53F C535: F0 F6 BEQ $C52D C537: 18 CLC C538: A9 4E LDA #$4E C53A: 8D 03 60 STA $6003 C53D: D0 EE BNE $C52D Einsprung von $C533: C53F: 20 EC CB JSR $CBEC auf 'Controller ready' warten C542: 18 CLC Ok. C543: 24 B $24 Einsprung von $C4E1, $C505, $C517: C544: 38 SEC Error-Ende C545: 60 RTS LED-Routinen des Controller-Programms JOB $94: LEDACTON_DV C546: A5 79 LDA $79 b6=1: Drive-LED an C548: 09 40 ORA #$40 C54A: 85 79 STA $79 C54C: 4C 99 C3 JMP $C399 JOB $96: LEDACTOFF_DV C54F: A5 79 LDA $79 b6=0: Drive-LED aus C551: 29 BF AND #$BF C553: 85 79 STA $79 C555: 4C 99 C3 JMP $C399 JOB $98: ERRLEDON_DV C558: A5 79 LDA $79 b5=1: Fehler-LED-Blinken C55A: 09 20 ORA #$20 C55C: 85 79 STA $79 C55E: 4C 99 C3 JMP $C399 JOB $9a: ERRLEDOFF_DV C561: A5 79 LDA $79 b5=0: kein Fehler-LED-Blinken C563: 29 DF AND #$DF C565: 85 79 STA $79 C567: 4C 99 C3 JMP $C399 JOB $9c: SIDE_DV C56A: A4 83 LDY $83 Jobpuffernummer C56C: B9 CE 01 LDA $01CE,Y Seite holen C56F: 29 01 AND #$01 C571: 85 97 STA $97 als aktuelle Seite C573: D0 03 BNE $C578 C575: A9 00 LDA #$00 wenn a=0, dann a=0 C577: 2C B $2C Einsprung von $C573: C578: A9 01 LDA #$01 wenn a=1, dann a=1 C57A: 85 36 STA $36 C57C: AD 00 40 LDA $4000 Schreib-/Leseelektronik C57F: 29 FE AND #$FE umschalten C581: 05 36 ORA $36 b0=0: Seite 0 C583: 8D 00 40 STA $4000 b0=1: Seite 1 C586: 4C 99 C3 JMP $C399 Jobbehandlung neustarten JOB $9e: BUFMOVE_DV C589: A4 99 LDY $99 2-Byte Index C58B: B9 0C 00 LDA $000C,Y Sektorparameter wird als Kommandobyte C58E: 85 39 STA $39 zweckentfremdet C590: 24 39 BIT $39 Transfer Richtung C592: 10 12 BPL $C5A6 b7: 0: Aus Cache in Puffer ==> Daten in Cache kopieren C594: B9 BC 01 LDA $01BC,Y Nummer des 'aktuellen Tracks im Cache' C597: 85 95 STA $95 neu setzen C599: A4 83 LDY $83 C59B: B9 CE 01 LDA $01CE,Y aktuelle Seite imsetzen C59E: 85 97 STA $97 C5A0: 20 A4 CE JSR $CEA4 Kopieren C5A3: 4C 8B C3 JMP $C38B Ok, Ende Daten aus dem Cache kopieren Einsprung von $C592: C5A6: 20 AF CE JSR $CEAF Kopieren C5A9: 4C 8B C3 JMP $C38B Ok, Ende JOB $a2: TRKWRT_DV C5AC: 4C 8B C3 JMP $C38B Ok. Ende anspringen Patches Einsprung von $C160: C5AF: 78 SEI Interrupts sperren C5B0: 6C 48 00 JMP ($0048) Job aufrufen * Old ROM: C5AF: FF FF FF FF C5B2: FF .... C5FF: .... FF Cachepuffer auf Diskette schreiben Pruefen, ob der Kopf auf der richtigen Spur steht Einsprung von $C12E: C600: 20 A6 CF JSR $CFA6 Blockheader lesen C603: A5 95 LDA $95 steht der Kopf auf der richtigen Spur ? C605: C5 1F CMP $1F (Spur im Cache mit gefundener Nummer vgl.) C607: F0 03 BEQ $C60C ja, ==> C609: 4C 88 CB JMP $CB88 nein: MISHD_DV_ER ==> Berechnen, welcher Sektor als naechstes geschrieben werden kann und seine Position im Cachepuffer bestimmen Einsprung von $C607: C60C: 8D 01 60 STA $6001 Spurnummer setzen C60F: 20 E3 CF JSR $CFE3 Precompensation ein-/ausschalten C612: 20 B7 CF JSR $CFB7 Zeiger auf Cachepuffer-Anfang setzen C615: A5 92 LDA $92 Anzahl der Sektoren holen C617: 85 3A STA $3A C619: A5 21 LDA $21 aktuelle Sektornummer holen C61B: AA TAX und merken C61C: C5 93 CMP $93 letzten Sektor der Spur erreicht ? C61E: 08 PHP (Ergebnis merken) - Position des Folgesektors im Cachepuffer bestimmen C61F: D0 06 BNE $C627 nicht letzter Sektor der Spur, ==> C621: A5 94 LDA $94 1. Sektornummer auf der Spur holen C623: AA TAX und merken C624: 38 SEC -1 [ergibt einen gedachten Sektor vor dem C625: E9 01 SBC #$01 1. Sektor - entspricht letztem Sektor.] Einsprung von $C61F: C627: 38 SEC aktuelle Sektornummer C628: E5 94 SBC $94 - '1. Sektornummer auf der Spur' C62A: 18 CLC C62B: 69 01 ADC #$01 +1 (Folgesektor wird gesucht) C62D: A4 91 LDY $91 Blockgroesse holen Einsprung von $C633: C62F: 88 DEY [Um dir Position im Cache zu bekommen, C630: F0 03 BEQ $C635 muss die Sektornummer mit der Blockgroesse C632: 0A ASL multipliziert werden C633: 90 FA BCC $C62F (*256, *512, oder *1024)] Einsprung von $C630: C635: 20 8D CB JSR $CB8D Zeiger in Cache setzen - physikalische Sektornummer des Folgesektors bestimmen C638: 8A TXA aktuelle Sektornummer holen C639: 28 PLP = letzter Sektor der Spur ? C63A: F0 05 BEQ $C641 ja, ==> C63C: 18 CLC Sektornummer +1 C63D: 69 01 ADC #$01 C63F: D0 02 BNE $C643 immer ==> Einsprung von $C63A: C641: A5 94 LDA $94 1. Sektornummer der Spur Einsprung von $C63F: C643: 8D 02 60 STA $6002 Sektor anwaehlen C646: EA .... NOP [20 NOPS] C659: .... EA NOP Einsprung von $C6AA, $C6C9: C65A: AD E0 01 LDA $01E0 Controller-Befehl: 'Write sector' C65D: 20 F4 CB JSR $CBF4 in Controller schreiben Anzahl der zu schreibenden Seiten pro Sektor berechnen C660: A4 91 LDY $91 Blockgroesse holen C662: C0 03 CPY #$03 [y=1: 256 Bytes, 1 Seite; C664: D0 01 BNE $C667 y=2: 512 Bytes, 2 Seiten; C666: C8 INY y=3: 1024 Bytes, 4 Seiten.] Sektor schreiben Einsprung von $C664, $C66F, $C67E, $C683: C667: AD 00 60 LDA $6000 Controller-Status einlesen C66A: 29 03 AND #$03 C66C: 4A LSR C66D: 90 5D BCC $C6CC b0=0: 'Controller ready', ==> C66F: F0 F6 BEQ $C667 b1=0: noch kein 'Byte ready', ==> C671: 84 82 STY $82 C673: A0 00 LDY #$00 C675: B1 4A LDA ($4A),Y Byte aus Cachepuffer holen C677: 8D 03 60 STA $6003 und auf Diskette schreiben C67A: A4 82 LDY $82 C67C: E6 4A INC $4A Pufferzeiger erhoehen C67E: D0 E7 BNE $C667 C680: E6 4B INC $4B C682: 88 DEY noch eine Speicherseite abspeichern ? C683: D0 E2 BNE $C667 ja, ==> C685: 20 3F CD JSR $CD3F Controller-Status pruefen C688: D0 42 BNE $C6CC Fehler, ==> C68A: C6 3A DEC $3A noch einen Sektor schreiben ? C68C: F0 3E BEQ $C6CC nein, ==> C68E: AD 02 60 LDA $6002 aktuellen Sektor merken C691: EE 02 60 INC $6002 naechsten Sektor anwaehlen C694: EA .... NOP [20 NOPS] C6A7: .... EA NOP auf Spurende pruefen C6A8: C5 93 CMP $93 wurde gerade der letzte Sektor der Spur C6AA: D0 AE BNE $C65A geschrieben ? nein, ==> C6AC: A5 8C LDA $8C Cachezeiger auf Cachepufferanfang setzen C6AE: 85 4B STA $4B C6B0: A5 94 LDA $94 1. physikalischen Sektor anwaehlen C6B2: 8D 02 60 STA $6002 C6B5: EA .... NOP [20 NOPS] C6C8: .... EA NOP C6C9: 4C 5A C6 JMP $C65A auf korrekte Durchfuehrung des Schreibvorgangs pruefen Einsprung von $C66D, $C688, $C68C: C6CC: 20 3F CD JSR $CD3F Controller-Status pruefen C6CF: F0 03 BEQ $C6D4 kein Fehler, ==> C6D1: 4C CC CD JMP $CDCC Jobauftrag beenden Einsprung von $C6CF: C6D4: 4C E1 C9 JMP $C9E1 Verify durchfuehren JOBs $92, $a8: DISKIN_DV, PSEEK_DV C6D7: 20 A6 CF JSR $CFA6 Header lesen / Spur, Seite merken C6DA: 4C 8B C3 JMP $C38B Ok-Rueckmeldung C6DD: FF .... C6FF: .... FF JOB $a6: SP_WRITE C700: 20 A6 CF JSR $CFA6 Blockheader lesen C703: A5 88 LDA $88 Solltrack C705: C5 1F CMP $1F = aktueller Track ? C707: F0 03 BEQ $C70C ja, ==> C709: 4C 88 CB JMP $CB88 Error $02 (Header nicht gefunden) Einsprung von $C707: C70C: A6 83 LDX $83 Jobnummer holen und als Index in eine C70E: B5 0B LDA $0B,X 2 (!) Byte Tabelle verwenden C710: 8D 01 60 STA $6001 physikalische T&S des Sektors holen C713: B5 0C LDA $0C,X [Das funktioniert nur bei Job 0 ! C715: 8D 02 60 STA $6002 Da aber der verwendete Puffer immer $0300 C718: A9 00 LDA #$00 ist, besteht kein Grund, einen anderen C71A: 85 4A STA $4A Jobpuffer zu verwenden.] C71C: A9 03 LDA #$03 Zeiger auf Pufferanfang ($0300) setzen C71E: 85 4B STA $4B C720: EA .... NOP [19 NOPS] C732: .... EA NOP C733: AD E0 01 LDA $01E0 Controller-Befehl 'Write Sector' C736: 20 F4 CB JSR $CBF4 an Controller uebergeben C739: A4 91 LDY $91 Blockgroesse holen C73B: C0 03 CPY #$03 Anzahl der zu schreibenden Seiten berechnen C73D: D0 02 BNE $C741 C73F: C8 INY 128-Byte-Sektoren werden nicht C740: EA NOP unterstuetzt) Einsprung von $C73D, $C749, $C758, $C75D: C741: AD 00 60 LDA $6000 Controller-Status holen C744: 29 03 AND #$03 C746: 4A LSR C747: 90 16 BCC $C75F 'Controller ready', ==> C749: F0 F6 BEQ $C741 noch nicht 'Byte ready', ==> C74B: 84 82 STY $82 C74D: A0 00 LDY #$00 C74F: B1 4A LDA ($4A),Y Byte auf Diskette schreiben C751: 8D 03 60 STA $6003 C754: A4 82 LDY $82 C756: E6 4A INC $4A Pufferzeiger erhoehen C758: D0 E7 BNE $C741 C75A: E6 4B INC $4B C75C: 88 DEY noch eine Speicherseite zu schreiben ? C75D: D0 E2 BNE $C741 ja, ==> Einsprung von $C747: C75F: 20 3F CD JSR $CD3F Controller-Status pruefen C762: 4C CC CD JMP $CDCC Jobauftrag beenden C765: FF .... C7FF: .... FF Controller-Programm 2 JOB $a4: SP_READ C800: 20 A6 CF JSR $CFA6 Blockheader lesen C803: A5 88 LDA $88 befindet sich der Kopf auf der C805: C5 1F CMP $1F richtigen Spur ? C807: F0 03 BEQ $C80C ja, ==> C809: 4C 88 CB JMP $CB88 02, MISHD_DV_ER Einsprung von $C807: C80C: A6 83 LDX $83 Jobnummer holen [Dies ist der Index fuer 1-Byte Tabellen !!! C80E: B5 0B LDA $0B,X Das Holen der T&S funktioniert daher nur C810: 8D 01 60 STA $6001 bei Job 0. Da die Pufferadresse aber C813: B5 0C LDA $0C,X sowieso immer $0300 ist, laesst sich dieser C815: 8D 02 60 STA $6002 Fehler verschmerzen.] C818: A9 00 LDA #$00 $0300: Pufferadresse C81A: 85 4A STA $4A Pufferzeiger setzen C81C: A9 03 LDA #$03 C81E: 85 4B STA $4B C820: EA .... NOP [19 NOPS] C832: .... EA NOP C833: AD DF 01 LDA $01DF Controller-Befehl: 'Read Sector' C836: 20 F4 CB JSR $CBF4 Kommando an Controller uebergeben C839: A4 91 LDY $91 Blockgroesse holen C83B: C0 03 CPY #$03 Anzahl der einzulesenden Speicherseiten C83D: D0 02 BNE $C841 ermitteln C83F: C8 INY C840: EA NOP Einsprung von $C83D, $C849, $C858, $C85D: C841: AD 00 60 LDA $6000 Controllestatus abfragen C844: 29 03 AND #$03 C846: 4A LSR C847: 90 16 BCC $C85F 'Controller ready', (Fehler) ==> C849: F0 F6 BEQ $C841 noch nicht 'Byte ready', (warten) ==> C84B: 84 82 STY $82 C84D: A0 00 LDY #$00 C84F: AD 03 60 LDA $6003 Byte von Diskette C852: 91 4A STA ($4A),Y in Puffer schreiben C854: A4 82 LDY $82 C856: E6 4A INC $4A Pufferzeiger erhoehen C858: D0 E7 BNE $C841 C85A: E6 4B INC $4B C85C: 88 DEY noch eine Seite einlesen ? C85D: D0 E2 BNE $C841 ja, ==> Einsprung von $C847: C85F: 20 3F CD JSR $CD3F Controller-Status pruefen C862: 4C CC CD JMP $CDCC Jobauftrag beenden C865: FF .... C8FF: .... FF JOBs $80, $90: READ_DV, WRITE_DV $aa, $ac: TREAD_DV, TWRT_DV $b2, $b4: TPREAD_DV, TPWRT_DV C900: 20 A6 CF JSR $CFA6 Blockheader lesen C903: A5 88 LDA $88 Steht Kopf auf richtiger Spur ? C905: C5 1F CMP $1F (Solltrack=Track in Blockheader) C907: F0 03 BEQ $C90C ja, ==> C909: 4C 88 CB JMP $CB88 nein: Blockheader nicht gefunden ==> Einsprung von $C907: C90C: 8D 01 60 STA $6001 zu lesende Spur in Controller schreiben C90F: 20 B7 CF JSR $CFB7 Zeiger auf Cacheanfang setzen C912: A5 96 LDA $96 aktuelle Diskettenseite merken C914: 85 39 STA $39 [Ich sehe keine Verwendung] C916: A5 92 LDA $92 Anzahl der Sektoren merken C918: 85 3A STA $3A Folgesektor im Cache berechnen C91A: A5 21 LDA $21 Sektornummer aus Blockheader C91C: AA TAX merken C91D: C5 93 CMP $93 = groesste Sektornummer ? C91F: 08 PHP (Ergebnis merken) C920: D0 06 BNE $C928 nein, ==> C922: A5 94 LDA $94 1. physikalische Sektornummer holen C924: AA TAX und merken C925: 38 SEC -1 [Der letzte Sektor steht unmittelbar vor C926: E9 01 SBC #$01 dem 1. Sektor. Er ist sozusagen der 0. S.] Einsprung von $C920: C928: 38 SEC - Nummer des 1. physikalischen Sektors C929: E5 94 SBC $94 C92B: 18 CLC +1 (da der Folgesektor gelesen werden soll) C92C: 69 01 ADC #$01 C92E: A4 91 LDY $91 Blockgroesse holen Einsprung von $C934: C930: 88 DEY C931: F0 03 BEQ $C936 y-1 mal: Sektornummer *2 C933: 0A ASL C934: 90 FA BCC $C930 = Zeiger Hi in den Cachepuffer Einsprung von $C931: C936: 20 8D CB JSR $CB8D Zeiger in Cachepuffer setzen physikalischen Folgesektor berechnen C939: 8A TXA C93A: 28 PLP wurde der letzte Sektor der Spur gefunden ? C93B: F0 05 BEQ $C942 ja, ==> C93D: 18 CLC C93E: 69 01 ADC #$01 Sektornummer +1 C940: D0 02 BNE $C944 immer ==> Einsprung von $C93B: C942: A5 94 LDA $94 1. Sektor auf Spur Einsprung von $C940: C944: 8D 02 60 STA $6002 Sektornummer setzen C947: EA .... NOP [20 NOPS] C95A: .... EA NOP Einsprung von $C9AC, $C9CB: C95B: AD DF 01 LDA $01DF Controller-Befehl: Read Sector C95E: 20 F4 CB JSR $CBF4 an Controller uebergeben C961: A4 91 LDY $91 Sektorengroesse C963: C0 03 CPY #$03 1024 Bytes ? C965: D0 02 BNE $C969 nein C967: C8 INY ja, 4 Speicherseiten lesen C968: EA NOP 128-Byte-Sektoren werden nicht unterstuetzt Einsprung von $C965, $C971, $C980, $C985: C969: AD 00 60 LDA $6000 Controller-Status holen C96C: 29 03 AND #$03 C96E: 4A LSR C96F: 90 5D BCC $C9CE b0=0: Controller ready ? ja, ==> C971: F0 F6 BEQ $C969 b1=1: Byte Ready ? nein, ==> C973: 84 82 STY $82 C975: A0 00 LDY #$00 C977: AD 03 60 LDA $6003 Byte von Diskette lesen C97A: 91 4A STA ($4A),Y und in Cachepuffer schreiben C97C: A4 82 LDY $82 C97E: E6 4A INC $4A Cachepufferzeiger erhoehen C980: D0 E7 BNE $C969 C982: E6 4B INC $4B C984: 88 DEY Anzahl zu lesender Speicherseiten -1 C985: D0 E2 BNE $C969 Block noch nicht fertig, ==> C987: 20 3F CD JSR $CD3F auf Lesefehler testen C98A: D0 42 BNE $C9CE Fehler, ==> C98C: C6 3A DEC $3A Anzahl zu lesender Blocks =0 ? C98E: F0 3E BEQ $C9CE ja, ==> C990: AD 02 60 LDA $6002 Nummer des gerade gelesenen Sektors merken C993: EE 02 60 INC $6002 naechsten Sektor lesen C996: EA .... NOP [20 NOPS] C9A9: .... EA NOP C9AA: C5 93 CMP $93 letzter Sektor auf der Spur ? C9AC: D0 AD BNE $C95B nein, ==> C9AE: A5 8C LDA $8C ja, C9B0: 85 4B STA $4B Cache-Zeiger auf Pufferanfang setzen C9B2: A5 94 LDA $94 1. Sektor laden C9B4: 8D 02 60 STA $6002 C9B7: EA .... NOP [20 NOPS] C9CA: .... EA NOP C9CB: 4C 5B C9 JMP $C95B naechsten Sektor lesen Einsprung von $C96F, $C98A, $C98E: C9CE: 20 3F CD JSR $CD3F Controllerstatus pruefen C9D1: D0 0B BNE $C9DE Fehler, ==> C9D3: A5 96 LDA $96 aktuelle Seite C9D5: 85 97 STA $97 merken C9D7: A5 88 LDA $88 aktueller Track C9D9: 85 95 STA $95 als 'Track im Cache' merken C9DB: 4C E2 CD JMP $CDE2 Ende, naechsten Job testen ==> Einsprung von $C9D1: C9DE: 4C CC CD JMP $CDCC Fehlercode in Jobpuffer schreiben Job $a0: WRTVER_DV Einsprung von $C6D4: C9E1: 24 8D BIT $8D E/A-Byte: b7=1: 'Verify ein' ? C9E3: 10 0B BPL $C9F0 nein, ==> C9E5: 20 DC CB JSR $CBDC 1,6 ms warten C9E8: 20 00 CA JSR $CA00 Spur mit Cachedaten vergleichen Einsprung von $C9F3: C9EB: 06 87 ASL $87 Flag: 'Cache veraendert' loeschen C9ED: 4C E2 CD JMP $CDE2 Ende; naechsten Job pruefen ==> Einsprung von $C9E3: C9F0: 20 DC CB JSR $CBDC 1,6 ms warten C9F3: 4C EB C9 JMP $C9EB Flag: 'Cache veraendert' loeschen C9F6: FF .... C9FF: .... FF Spur mit Cachedaten vergleichen Einsprung von $C3CB, $C9E8, $CB4F: CA00: 20 A6 CF JSR $CFA6 Blockheader lesen CA03: A5 88 LDA $88 steht der Kopf auf der richtigen Spur ? CA05: C5 1F CMP $1F (Sollspur mit gefundenem Wert vergleichen) CA07: F0 03 BEQ $CA0C ja, ==> CA09: 4C 88 CB JMP $CB88 nein (MISHD_DV_ER) ==> Einsprung von $CA07: CA0C: 8D 01 60 STA $6001 als aktuelle Spur merken CA0F: 20 B7 CF JSR $CFB7 Cachepufferzeiger auf Cache-Anfang setzen CA12: A5 96 LDA $96 aktuelle Seite merken CA14: 85 39 STA $39 [wozu ???] CA16: A5 92 LDA $92 Anzahl der Sektoren merken CA18: 85 3A STA $3A CA1A: A5 21 LDA $21 aktuelle Sektornummer CA1C: AA TAX merken CA1D: C5 93 CMP $93 = letzter Sektor auf der Spur ? CA1F: 08 PHP (Ergebnis merken) CA20: D0 06 BNE $CA28 nein, ==> CA22: A5 94 LDA $94 1. Sektornummer auf der Spur CA24: AA TAX merken CA25: 38 SEC -1 [Dies ist also praktisch der Sektor, der CA26: E9 01 SBC #$01 vor dem 1. Sektor kommt.] Einsprung von $CA20: CA28: 38 SEC - 1.Sektornummer [Dies ergibt die aktuelle CA29: E5 94 SBC $94 Position im Cache.] CA2B: 18 CLC + 1 [Folgesektor soll gelesen werden.] CA2C: 69 01 ADC #$01 CA2E: A4 91 LDY $91 Blockgroesse holen Einsprung von $CA34: CA30: 88 DEY Sektornummer auf 256-Byte Sektoren CA31: F0 03 BEQ $CA36 umrechnen (a kann nun als Hi-Byte fuer den CA33: 0A ASL Cachepufferzeiger verwendet werden) CA34: 90 FA BCC $CA30 Einsprung von $CA31: CA36: 20 8D CB JSR $CB8D Cachepufferzeiger setzen CA39: 8A TXA aktuelle physikalische Sektornummer CA3A: 28 PLP = letzter physikalischer Sektor der Spur ? CA3B: F0 05 BEQ $CA42 ja, ==> CA3D: 18 CLC Sektornummer +1 CA3E: 69 01 ADC #$01 CA40: D0 02 BNE $CA44 immer ==> Einsprung von $CA3B: CA42: A5 94 LDA $94 1. physikalischen Sektor einlesen Einsprung von $CA40: CA44: 8D 02 60 STA $6002 Sektornummer an Controller uebergeben CA47: EA .... NOP [20 NOPS] CA5A: .... EA NOP Einsprung von $CAB4, $CAD3: CA5B: AD DF 01 LDA $01DF Controller-Befehl: Read-Sector CA5E: 20 F4 CB JSR $CBF4 Kommando in Controller schreiben CA61: A4 91 LDY $91 Blockgroesse holen CA63: C0 03 CPY #$03 =3 (1024 Bytes) ? CA65: D0 02 BNE $CA69 nein, ==> CA67: C8 INY ja: y=4 CA68: EA NOP (Anzahl der Speicherseiten pro Block) Einsprung von $CA65, $CA71, $CA88, $CA8D: CA69: AD 00 60 LDA $6000 Controllerstatus holen CA6C: 29 03 AND #$03 CA6E: 4A LSR CA6F: 90 65 BCC $CAD6 b0=0: 'Controller ready', ==> CA71: F0 F6 BEQ $CA69 b1=0: noch kein 'Byte ready', ==> CA73: A5 9B LDA $9B aktuelles Fuellbyte holen CA75: C9 F5 CMP #$F5 = $f5 ? CA77: D0 08 BNE $CA81 nein, (Sektor mit Fuellbyte vergleichen) ==> CA79: 84 82 STY $82 ja: Spurdaten mit Cachedaten vergleichen CA7B: A0 00 LDY #$00 CA7D: B1 4A LDA ($4A),Y Wert aus dem Cachepuffer holen CA7F: A4 82 LDY $82 Einsprung von $CA77: CA81: CD 03 60 CMP $6003 mit den Daten der Spur vergleichen CA84: D0 56 BNE $CADC Fehler, ==> CA86: E6 4A INC $4A Cachepufferzeiger erhoehen CA88: D0 DF BNE $CA69 naechstes Byte vergleichen, ==> CA8A: E6 4B INC $4B Cachepufferzeiger Hi erhoehen CA8C: 88 DEY Blocklaenge Hi -1 CA8D: D0 DA BNE $CA69 Block noch nicht zu Ende, ==> CA8F: 20 3F CD JSR $CD3F Controllerstatus pruefen CA92: D0 47 BNE $CADB Fehler, ==> CA94: C6 3A DEC $3A Anzahl der Sektoren -1 CA96: F0 3E BEQ $CAD6 sind alle Sektoren geprueft ? ja, ==> CA98: AD 02 60 LDA $6002 aktuelle Sektornummer merken CA9B: EE 02 60 INC $6002 naechsten Sektor anwaehlen CA9E: EA .... NOP [20 NOPS] CAB1: .... EA NOP CAB2: C5 93 CMP $93 wurde letzter Sektor der Spur verglichen ? CAB4: D0 A5 BNE $CA5B nein, ==> CAB6: A5 8C LDA $8C ja: Cachepufferzeiger auf Pufferanfang CAB8: 85 4B STA $4B setzen CABA: A5 94 LDA $94 1. physikalischen Sektor anwaehlen CABC: 8D 02 60 STA $6002 CABF: EA .... NOP [20 NOPS] CAC0: .... EA NOP CAD3: 4C 5B CA JMP $CA5B naechsten Sektor vergleichen Einsprung von $CA6F, $CA96: CAD6: 20 3F CD JSR $CD3F Controllerstatus pruefen CAD9: D0 06 BNE $CAE1 Fehler, ==> Einsprung von $CA92: CADB: 60 RTS Verify-Error ausgeben Einsprung von $CA84: CADC: 20 D1 CF JSR $CFD1 Controller initialisieren CADF: A9 07 LDA #$07 Verify-Error Einsprung von $CAD9: CAE1: 4C CC CD JMP $CDCC ausgeben, alle Jobs nochmal JOB $b8: SEEKPHD_DV CAE4: 20 A6 CF JSR $CFA6 Blockheader lesen und analysieren CAE7: A5 27 LDA $27 ist aktuelle Spur CAE9: C5 88 CMP $88 = Sollspur ? CAEB: D0 19 BNE $CB06 nein, (zur Hauptsteuerroutine) ==> CAED: A0 3C LDY #$3C 60 Versuche, den gesuchten Block CAEF: 84 39 STY $39 auf dieser Spur zu finden Einsprung von $CAFF: CAF1: 20 A6 CF JSR $CFA6 Blockheader lesen und Spurdaten merken CAF4: A4 99 LDY $99 Job-Index fuer 2-Byte Tabellen CAF6: B9 BD 01 LDA $01BD,Y gesuchte Blocknummer mit der gefundenen CAF9: C5 21 CMP $21 Blocknummer vergleichen CAFB: F0 0C BEQ $CB09 gleich, ==> CAFD: C6 39 DEC $39 ansonsten naechsten Versuch CAFF: D0 F0 BNE $CAF1 CB01: A9 02 LDA #$02 MISHD_DV_ER: Blockheader nicht gefunden CB03: 4C CC CD JMP $CDCC Jobauftrag beenden Einsprung von $CAEB: CB06: 4C 00 CE JMP $CE00 Hauptsteuerroutine aufrufen JOB $b0: SEEKHD_DV Einsprung von $CAFB: CB09: 20 A6 CF JSR $CFA6 Blockheader lesen und analysieren CB0C: 4C 8B C3 JMP $C38B Ok. Ende JOB $c0: RESTORE_DV CB0F: AD DA 01 LDA $01DA Controller-Befehl: Restore CB12: 20 F4 CB JSR $CBF4 Kommando an Controller uebergeben CB15: 20 EC CB JSR $CBEC Auf Controller-Ready warten CB18: A5 8E LDA $8E Nummer der 1. physikalischen Spur holen CB1A: 85 27 STA $27 = Aktuelle Kopfposition CB1C: 85 88 STA $88 = Solltrack CB1E: A4 98 LDY $98 Kopfberuhigungszeit CB20: 20 D5 CB JSR $CBD5 Zeit abwarten CB23: 4C 8B C3 JMP $C38B Ok. Ende JOBs $d0, $e0: JUMPC_DV, EXBUF_DV: Programm im Jobpuffer ausfuehren Ruecksprung in das Controllerprogramm mit: - JMP $CDCC: Job beenden, Rueckmeldung in a, alle Jobspeicher nochmal testen Achtung: Alle Rueckmeldungen >1 loeschen den Cachepuffer !!! - Rueckmeldung in Jobpuffer schreiben, JMP $CDE2: naechsten Job testen Der Cachepuffer bleibt immer erhalten. - JMP $CE00: Job beim naechsten IRQ nochmal aufrufen CB26: A6 83 LDX $83 CB28: BD F1 01 LDA $01F1,X Pufferadresse setzen CB2B: 85 49 STA $49 CB2D: A0 00 LDY #$00 Lo-Byte immer 0 CB2F: 84 48 STY $48 CB31: 8A TXA Puffernummer uebergeben CB32: 6C 48 00 JMP ($0048) Programm ausfuehren JOB $f0: FORMATDK_DV CB35: A9 00 LDA #$00 mit Seite 0 anfangen CB37: 85 96 STA $96 Einsprung von $CB58: CB39: A5 96 LDA $96 CB3B: 20 C0 CF JSR $CFC0 zu formatierende Seite auswaehlen CB3E: 20 B7 CF JSR $CFB7 Cachepufferzeiger auf Cache-Anfang setzen CB41: 20 D6 C3 JSR $C3D6 Spur formatieren CB44: 20 3F CD JSR $CD3F Controller-Status pruefen CB47: D0 1C BNE $CB65 Fehler ? ja, ==> CB49: 20 DC CB JSR $CBDC 1,6 ms warten CB4C: 20 B7 CF JSR $CFB7 Cachepufferzeiger auf Cache-Anfang setzen CB4F: 20 00 CA JSR $CA00 Track auf Fehler ueberpruefen CB52: E6 96 INC $96 naechste Seite CB54: A5 96 LDA $96 CB56: C9 02 CMP #$02 sind beide Seiten formatiert ? CB58: 90 DF BCC $CB39 nein, ==> CB5A: A5 88 LDA $88 aktuelle Spur CB5C: C5 8F CMP $8F = letzte Spur ? CB5E: D0 08 BNE $CB68 nein, ==> CB60: A9 01 LDA #$01 01, OK_DV CB62: 2C B $2C CB63: A9 06 LDA #$06 Formatfehler FMT_DV_ER Einsprung von $CB47: CB65: 4C CC CD JMP $CDCC Jobauftrag beenden, alle Jobs nochmal ==> Einsprung von $CB5E: CB68: A4 99 LDY $99 im aktuellen Job: CB6A: B9 BC 01 LDA $01BC,Y zu formatierende Tracknummer erhoehen CB6D: 18 CLC CB6E: 69 01 ADC #$01 CB70: 99 BC 01 STA $01BC,Y CB73: 4C FA CD JMP $CDFA Jobcode bleibt erhalten; Jobs pruefen JOB $b6: DETWP_DV CB76: A9 40 LDA #$40 Schreibschutz Bit abfragen CB78: 2C 01 40 BIT $4001 CB7B: D0 03 BNE $CB80 b6=1: kein Schreibschutz, ==> CB7D: A9 08 LDA #$08 WRTPR_DV_ER CB7F: 2C B $2C Einsprung von $CB7B: CB80: A9 00 LDA #$00 OK_DV CB82: 4C CC CD JMP $CDCC Job-Fehlermeldungen CB85: A9 0E LDA #$0E ungueltiger Jobcode CB87: 2C B $2C Einsprung von $C609, $C709, $C809, $C909, $CA09, $CB9C: CB88: A9 02 LDA #$02 Blockheader nicht gefunden CB8A: 4C CC CD JMP $CDCC Jobauftrag beenden, alle Jobs nochmal Prueft, ob Sektor in Cachepuffer passt, Cachezeiger setzen Einsprung von $C635, $C936, $CA36: CB8D: 18 CLC a: Sektornummer CB8E: 65 8C ADC $8C + Cache-Start CB90: 85 4B STA $4B als Zeiger in Cachepuffer CB92: C9 20 CMP #$20 >= $2000 CB94: B0 01 BCS $CB97 ja, ==> CB96: 60 RTS Einsprung von $CB94: CB97: 68 PLA CB98: 68 PLA CB99: 20 3F CD JSR $CD3F Auf Controller ready warten CB9C: 4C 88 CB JMP $CB88 02: MISHD_DV_ER: Blockheader nicht gefunden Timer setzen und starten Einsprung von $C309: CB9F: AD D7 01 LDA $01D7 Wert in $01d8/$01d7 (!) in CBA2: 8D 07 40 STA $4007 Timer B Laden CBA5: AD D8 01 LDA $01D8 CBA8: 8D 06 40 STA $4006 CBAB: A9 11 LDA #$11 b0=1:Timer B Start; b4=1: Timer neu laden CBAD: 8D 0F 40 STA $400F CBB0: 60 RTS Laufwerksmotor ein-/ausschalten Einsprung von $C396, $CD6B: CBB1: AD 00 40 LDA $4000 b3=0: Motor einschalten CBB4: 29 FB AND #$FB CBB6: 8D 00 40 STA $4000 CBB9: 60 RTS Einsprung von $C3A9, $CE66: CBBA: AD 00 40 LDA $4000 b3=1: Motor ausschalten CBBD: 09 04 ORA #$04 CBBF: 8D 00 40 STA $4000 CBC2: 60 RTS Drive LED ein-/ausschalten CBC3: AD 00 40 LDA $4000 b6=0: LED ausschalten CBC6: 29 BF AND #$BF CBC8: 8D 00 40 STA $4000 CBCB: 60 RTS CBCC: AD 00 40 LDA $4000 b6=1: LED einschalten CBCF: 09 40 ORA #$40 CBD1: 8D 00 40 STA $4000 CBD4: 60 RTS Warten ... . . .zzz . .z .. Einsprung von $CBD9, $C2E9, $C2EE, $CB20, $CD9E, $CE9E: CBD5: 20 DF CB JSR $CBDF <--- y x 1 ms warten CBD8: 88 DEY CBD9: D0 FA BNE $CBD5 CBDB: 60 RTS Einsprung von $C9E5, $C9F0, $CB49: CBDC: A2 03 LDX #$03 <--- 3300 Zyklen warten (1,65 ms) CBDE: 2C B $2C (Angaben in Klammern) Einsprung von $CBD5: CBDF: A2 02 LDX #$02 <--- 2016 Zyklen warten (1 ms) CBE1: 18 CLC CBE2: A9 6F LDA #$6F 6 (10) Einsprung von $CBE6, $CBE9: CBE4: 69 01 ADC #$01 + 145 Durchlaeufe x 5 Takte CBE6: D0 FC BNE $CBE4 + (1 (2) x 255) Durchlaeufe x 5 Takte CBE8: CA DEX + 2 (3) Durchlaeufe x 5 Takte CBE9: D0 F9 BNE $CBE4 CBEB: 60 RTS Auf Controller-Ready warten Einsprung von $C53F, $CB15, $CD3F, $CD90, $CD99, $CE8C, $CFE0: CBEC: A9 01 LDA #$01 Status-Register, b0: Busy-Flag testen Einsprung von $CBF1: CBEE: 2C 00 60 BIT $6000 CBF1: D0 FB BNE $CBEE warten, bis es 0 wird, ==> CBF3: 60 RTS Kommandobyte in Controller schreiben Einsprung von $C3E9, $C65D, $C736, $C836, $C95E, $CA5E, $CB12, $CD10, $CD8D, $CD96, $CE89: CBF4: EA NOP CBF5: 8D 00 60 STA $6000 Befehl ins Befehlsregister schreiben CBF8: A9 01 LDA #$01 b0: Busy-Flag Einsprung von $CBFD: CBFA: 2C 00 60 BIT $6000 CBFD: F0 FB BEQ $CBFA Warten, bis Controller 'busy' ist, ==> CBFF: 4C 34 AD JMP $AD34 kurze Verzoegerung (14 us) CC02: FF .... CCFF: .... FF Blockheader lesen Einsprung von $CFA6: CD00: A2 05 LDX #$05 Blockheaderpuffer loeschen Einsprung von $CD06: CD02: 8A TXA CD03: 95 1F STA $1F,X 6 Bytes: Track,Seite,Sektor,Groesse,CRC1,CRC2 CD05: CA DEX CD06: 10 FA BPL $CD02 CD08: 20 BC CD JSR $CDBC Ist eine Diskette im Laufwerk ? CD0B: B0 2C BCS $CD39 nein, Lesen unmoeglich ==> CD0D: AD E1 01 LDA $01E1 Controller-Befehl: Read Adress CD10: 20 F4 CB JSR $CBF4 Kommando in Controller schreiben CD13: A2 00 LDX #$00 CD15: A0 06 LDY #$06 6 Bytes von Diskette einlesen Einsprung von $CD1F, $CD28: CD17: AD 00 60 LDA $6000 Controller-Status holen CD1A: 29 03 AND #$03 CD1C: 4A LSR CD1D: 90 0B BCC $CD2A Controller ready, ==> CD1F: F0 F6 BEQ $CD17 kein Byte ready, ==> CD21: AD 03 60 LDA $6003 Byte einlesen und CD24: 95 1F STA $1F,X im Blockheader-Puffer speichern CD26: E8 INX CD27: 88 DEY CD28: D0 ED BNE $CD17 noch ein Byte einlesen, ==> Einsprung von $CD1D: CD2A: 20 3F CD JSR $CD3F Controller-Status pruefen CD2D: F0 02 BEQ $CD31 Kein Fehler, ==> CD2F: 38 SEC CD30: 24 B $24 Einsprung von $CD2D: CD31: 18 CLC CD32: 24 8D BIT $8D E/A-Byte abfragen CD34: 50 08 BVC $CD3E b6=0: keine Pruefsumme bilden, ==> CD36: 4C 63 DA JMP $DA63 Pruefsumme bilden ==> Einsprung von $CD0B: CD39: A9 03 LDA #$03 Zwischenspeicher setzen CD3B: 85 7D STA $7D CD3D: 38 SEC Einsprung von $CD34: CD3E: 60 RTS Controller-Status pruefen Einsprung von $C3C3, $C685, $C6CC, $C75F, $C85F, $C987, $C9CE, $CA8F, $CAD6, $CB44, $CB99, $CD2A: CD3F: 20 EC CB JSR $CBEC auf 'Controller ready' warten CD42: 08 PHP CD43: AD 00 60 LDA $6000 Auf 'Lost Data' testen CD46: 4A LSR CD47: 4A LSR CD48: 4A LSR Fehler ? ja, ==> CD49: B0 08 BCS $CD53 ---> Was passiert mit PHP ??? CD4B: 29 0B AND #$0B b0=1: CRC-Fehler CD4D: AA TAX b1=1: Header nicht gefunden CD4E: 28 PLP b3=1: Diskette schreibgeschuetzt CD4F: BD 5A CD LDA $CD5A,X Job-Fehlercode holen CD52: 2C B $2C Einsprung von $CD49: CD53: A9 09 LDA #$09 $09: CRC-Error CD55: 85 7D STA $7D CD57: A5 7D LDA $7D CD59: 60 RTS CD5A: 00 05 02 00 00 00 00 00 Tabelle zur Umrechnung des Controller- CD62: 08 Status in die entsprechende Job-Meldung Wenn der Motor aus war, Motor einschalten und Verzoegerungszeit einstellen Einsprung von $C108: CD63: A5 26 LDA $26 Ist Motor bereits am Anlaufen CD65: 30 13 BMI $CD7A ja, Ende ==> CD67: 29 30 AND #$30 b4=1: ist der Motor am Nachlaufen oder CD69: D0 0B BNE $CD76 b5=1: ist er allgemein schon an ? ja, ==> CD6B: 20 B1 CB JSR $CBB1 Nein, Motor einschalten CD6E: AD D9 01 LDA $01D9 Anlaufverzoegerung setzen CD71: 85 2A STA $2A CD73: A9 A0 LDA #$A0 b7=1: Motor ist am Anlaufen CD75: 2C B $2C Einsprung von $CD69: CD76: A9 20 LDA #$20 b5=1: Laufwerksmotor ist eingeschaltet CD78: 85 26 STA $26 Laufwerksstatus setzen Einsprung von $CD65: CD7A: 60 RTS Anlaufvorgang ueberwachen Einsprung von $C10F: CD7B: A5 26 LDA $26 Ist Anlaufvorgang beendet ? CD7D: 10 04 BPL $CD83 ja, ==> CD7F: A5 2A LDA $2A Anlaufzeit des Motors vorbei ? CD81: D0 34 BNE $CDB7 nein, ==> Einsprung von $CD7D: CD83: AD 00 40 LDA $4000 b7=0: Diskettenwechsel ? CD86: 29 80 AND #$80 CD88: D0 23 BNE $CDAD nein, ==> Schreib-/Lesekopf positionieren, damit er genau auf der Spur liegt und damit das Diskettenwechsel-Flag geloescht wird. CD8A: AD DD 01 LDA $01DD Controller-Befehl: 'Step-in' CD8D: 20 F4 CB JSR $CBF4 Kommando an Controller uebergeben CD90: 20 EC CB JSR $CBEC auf Controller-Ready warten CD93: AD DE 01 LDA $01DE Controller-Befehl: 'Step-out' CD96: 20 F4 CB JSR $CBF4 Kommando an Controller uebergeben CD99: 20 EC CB JSR $CBEC auf Controller-Ready warten CD9C: A4 98 LDY $98 Kopfberuhigungszeit CD9E: 20 D5 CB JSR $CBD5 18 ms Warten CDA1: AD 00 40 LDA $4000 immer noch Diskettenwechsel ? CDA4: 29 80 AND #$80 CDA6: D0 05 BNE $CDAD nein, ==> Einsprung von $CDB0: CDA8: A9 03 LDA #$03 keine Adressmarke gefunden CDAA: 4C CC CD JMP $CDCC Einsprung von $CD88, $CDA6: CDAD: 20 BC CD JSR $CDBC Ist eine Diskette eingelegt ? CDB0: B0 F6 BCS $CDA8 Nein, ==> CDB2: A9 20 LDA #$20 Ja: b7=0: Laufwerk ist bereit CDB4: 85 26 STA $26 b5=1: Motor laeuft CDB6: 60 RTS Einsprung von $CD81: CDB7: 68 PLA Motor ist noch nicht hochgelaufen CDB8: 68 PLA CDB9: 4C 00 CE JMP $CE00 zur Hauptsteuer-Routine ==> Abfragen, ob Diskette eingelegt ist Einsprung von $CD08, $CDAD: CDBC: A0 1E LDY #$1E 30 mal Abfragen: Einsprung von $CDC6: CDBE: AD 00 40 LDA $4000 Ist Diskette eingelegt (b2=0) ? CDC1: 29 02 AND #$02 [30fach haelt besser ???] CDC3: D0 05 BNE $CDCA nein, ==> CDC5: 88 DEY [Ist das vielleicht zum Entprellen ? Die CDC6: D0 F6 BNE $CDBE Hardware verzoegert doch schon um 1/2 sec.] CDC8: 18 CLC Ja, Es ist eine Diskette im Laufwerk CDC9: 24 B $24 Einsprung von $CDC3: CDCA: 38 SEC keine Diskette im Laufwerk CDCB: 60 RTS Jobauftrag beenden, alle Jobs nochmal pruefen Einsprung von $C38D, $C3D3, $C6D1, $C762, $C862, $C9DE, $CAE1, $CB03, $CB65, $CB82, $CB8A, $CDAA, $CFB4, $DAFA: CDCC: A4 83 LDY $83 Rueckmeldung in a CDCE: 99 02 00 STA $0002,Y in entsprechenden Jobpuffer schreiben CDD1: A0 80 LDY #$80 CDD3: C9 02 CMP #$02 Fehler ? CDD5: 90 06 BCC $CDDD nein, ==> CDD7: A9 00 LDA #$00 Fehlerbehandlung: CDD9: 85 87 STA $87 Cache nicht veraendert CDDB: 84 95 STY $95 Aktueller Track im Cache=$80 (Cache leer) Einsprung von $CDD5: CDDD: 84 83 STY $83 letzter aktiver Job=$80 (kein Job aktiv) CDDF: A0 08 LDY #$08 Jobabfrage von Neuem beginnen CDE1: 2C B $2C Ruecksprung von Jobroutine, den selben Job nochmal pruefen Einsprung von $C9DB, $C9ED: CDE2: A4 83 LDY $83 CDE4: A5 26 LDA $26 Drivemodus: Drive inaktiv ? CDE6: F0 12 BEQ $CDFA ja, Ende ==> CDE8: 29 10 AND #$10 Ist Motor am Nachlaufen ? CDEA: D0 0E BNE $CDFA ja, ==> CDEC: A5 26 LDA $26 Nachlaufmodus initialisieren CDEE: 09 10 ORA #$10 CDF0: 85 26 STA $26 CDF2: A9 FF LDA #$FF Zaehler fuer Hochlaufzeit ist nun Lo-Byte CDF4: 85 2A STA $2A der Nachlaufzeit CDF6: A9 04 LDA #$04 Nachlaufzeit (Hi) CDF8: 85 2B STA $2B $04ff: 12,8 sec Nachlaufen Einsprung von $CDE6, $CDEA, $C3A6, $CB73: CDFA: A6 2C LDX $2C Stackpointer auf den Wert setzen, CDFC: 9A TXS den er beim Aufruf der Controller-Routine hatte CDFD: 4C C7 C0 JMP $C0C7 Naechsten Jobpuffer pruefen Hauptsteuerroutine des Controllers Einsprung von $C0DB, $C146, $C3B5, $CB06, $CDB9: CE00: A6 2C LDX $2C Stackpointer vom Controlleraufruf CE02: E8 INX +2 (JSR) CE03: E8 INX CE04: BD 04 01 LDA $0104,X p-Register (Flags) vom IRQ-Aufruf holen CE07: 29 10 AND #$10 b-Flag (BRK) gesetzt ? CE09: D0 66 BNE $CE71 ja, (die folgenden Routinen muessen in festen Zeitabstaenden aufgerufen werden) ==> CE0B: A5 9C LDA $9C Cache-Schreibverzoegerung abzaehlen CE0D: F0 02 BEQ $CE11 [wird bei Busbetrieb gesetzt und von der CE0F: C6 9C DEC $9C Haupt-Warteschleife abgefragt] LEDs-setzen Einsprung von $CE0D: CE11: A5 79 LDA $79 LED-Blinken ? CE13: 29 20 AND #$20 CE15: F0 10 BEQ $CE27 nein ==> CE17: C6 9E DEC $9E Blinkgeschwindigkeit CE19: 10 0C BPL $CE27 warten, dann ==> CE1B: A9 09 LDA #$09 Zaehler neu setzen CE1D: 85 9E STA $9E alle 1/10 sec LED umschalten CE1F: AD 00 40 LDA $4000 LED-umschalten CE22: 49 20 EOR #$20 CE24: 8D 00 40 STA $4000 Einsprung von $CE15, $CE19: CE27: A5 79 LDA $79 Drive LED anschalten ? CE29: 29 40 AND #$40 B6:1 :an CE2B: 25 79 AND $79 CE2D: 85 36 STA $36 CE2F: AD 00 40 LDA $4000 LED ein-/ausschalten CE32: 29 BF AND #$BF CE34: 05 36 ORA $36 CE36: 8D 00 40 STA $4000 Laufwerk behandeln CE39: AD 00 40 LDA $4000 b7=0: wurde die Diskette gewechselt ? CE3C: 29 80 AND #$80 CE3E: D0 0A BNE $CE4A nein, ==> CE40: 85 87 STA $87 Cache nicht zurueckschreiben CE42: A9 80 LDA #$80 $80: Flag fuer 'Cache ist leer' setzen CE44: 85 95 STA $95 CE46: A9 01 LDA #$01 Flag fuer Diskettenwechsel setzen CE48: 85 25 STA $25 Einsprung von $CE3E: CE4A: A5 26 LDA $26 Ist Laufwerk aktiv ? CE4C: F0 1F BEQ $CE6D nein, (Ende) ==> CE4E: A8 TAY CE4F: C9 20 CMP #$20 b5=1: Motor eingeschaltet ? CE51: F0 20 BEQ $CE73 nein, ==> CE53: C6 2A DEC $2A Laufwerk Anfahren (Nachlaufen Lo) CE55: D0 1C BNE $CE73 noch nicht fertig, ==> CE57: 98 TYA CE58: 10 04 BPL $CE5E b7=0: Laufwerk bereit ? ja, ==> CE5A: 29 7F AND #$7F Anlaufvorgang ist abgeschlossen CE5C: 85 26 STA $26 Einsprung von $CE58: CE5E: 29 10 AND #$10 Motor nachlaufen lassen ? CE60: F0 11 BEQ $CE73 nein, ==> CE62: C6 2B DEC $2B Nachlaufzeit abwarten CE64: D0 0D BNE $CE73 noch warten, ==> CE66: 20 BA CB JSR $CBBA Drivemotor ausschalten CE69: A9 00 LDA #$00 0: 'Laufwerk inaktiv' CE6B: 85 26 STA $26 in Drivemodus eintragen Einsprung von $CE4C, $CE76, $CEA1: CE6D: A6 2C LDX $2C Stackpointer zurueckholen CE6F: 9A TXS CE70: 60 RTS Ende der Controllerroutine ==> Schrittmotor ansteuern Einsprung von $CE09: CE71: A4 26 LDY $26 Drivemodus holen Einsprung von $CE51, $CE55, $CE60, $CE64: CE73: 98 TYA soll der Kopf bewegt werden ? CE74: 29 40 AND #$40 CE76: F0 F5 BEQ $CE6D nein, (Ende) ==> CE78: A5 88 LDA $88 Solltrack CE7A: C5 27 CMP $27 = Isttrack ? CE7C: F0 18 BEQ $CE96 Ja, (Schrittmotor-Flag loeschen) ==> CE7E: 8D 03 60 STA $6003 Solltrack uebergeben CE81: A5 27 LDA $27 CE83: 8D 01 60 STA $6001 Isttrack uebergeben CE86: AD DB 01 LDA $01DB Controller-Befehl: SEEK CE89: 20 F4 CB JSR $CBF4 in Controller schreiben CE8C: 20 EC CB JSR $CBEC und Ausfuehrung abwarten [leider ...] CE8F: A5 88 LDA $88 Kopf steht jetzt auf Solltrack CE91: 85 27 STA $27 (= Isttrack) CE93: 8D 01 60 STA $6001 Isttrack an Controller uebergeben Einsprung von $CE7C: CE96: A5 26 LDA $26 b6=0: Schrittmotor ist inaktiv CE98: 29 BF AND #$BF im Drivestatus eintragen CE9A: 85 26 STA $26 CE9C: A4 98 LDY $98 Kopfberuhigungszeit abwarten CE9E: 20 D5 CB JSR $CBD5 (18 ms) CEA1: 4C 6D CE JMP $CE6D Ende ==> Daten zwischen Cache und Puffer transferieren Einsprung von $C5A0: CEA4: 24 39 BIT $39 Modus von BUFMOV_DV CEA6: 50 03 BVC $CEAB b6=0, ==> CEA8: A9 80 LDA #$80 b6=1: Flag: b7=1: Cache wurde veraendert CEAA: 2C B $2C Einsprung von $CEA6: CEAB: A9 00 LDA #$00 Flag: b7=0: Cache wurde nicht veraendert CEAD: 85 87 STA $87 Flag setzen Einsprung von $C5A6: CEAF: A9 20 LDA #$20 b5=1: Transfer durchfuehren ? CEB1: 24 37 BIT $37 [Warum $37 ??? Der Modus steht doch in $39 !!! Dieser Fehler fuehrt dazu, dass normalerweise mit dem BUFMOV-Befehl gar keine Daten kopiert werden koennen. Da $37 aber sonst keine Bedeutung hat, kann man dort das b5 von Hand setzen und den Befehl dann trotzdem verwenden.] CEB3: D0 01 BNE $CEB6 ja, ==> CEB5: 60 RTS Einsprung von $CEB3: CEB6: A4 99 LDY $99 CEB8: B9 0B 00 LDA $000B,Y Sektornummer CEBB: 18 CLC CEBC: 65 8C ADC $8C + Cache-Start CEBE: 85 4B STA $4B = Zeiger in Cache CEC0: A0 00 LDY #$00 Lo-Bytes = 0 CEC2: 84 48 STY $48 Zeiger in DOS-Puffer CEC4: 84 4A STY $4A Zeiger in Cache CEC6: A6 83 LDX $83 Pufferadresse holen CEC8: BD F1 01 LDA $01F1,X CECB: 85 49 STA $49 CECD: A5 39 LDA $39 Modus von BUFMOV_DV CECF: 29 1F AND #$1F Anzahl der zu kopierenden Bloecke merken CED1: AA TAX CED2: 24 39 BIT $39 Modus von BUFMOV_DV: CED4: 10 03 BPL $CED9 b7=0, ==> CED6: 4C 3E D0 JMP $D03E b7=1: Daten vom Puffer in Cache kopieren Einsprung von $CED4: CED9: 4C 58 D5 JMP $D558 b7=0: Daten vom Cache in Puffer kopieren JTRANS_TS: logisches in physikalisches Format umwandeln CEDC: 06 86 ASL $86 Soll umgewandelt werden (b7=0) ? CEDE: B0 6E BCS $CF4E nein, Ende ==> CEE0: A4 99 LDY $99 Index fuer 2-Byte Jobspeicher holen CEE2: 06 85 ASL $85 Sind Parameter sowieso physikalisch (b7=0)? CEE4: 90 44 BCC $CF2A ja, ==> CEE6: A6 83 LDX $83 CEE8: B5 9F LDA $9F,X b7=1: wurde das Format bereits umgewandelt? CEEA: 10 01 BPL $CEED nein, (also umwandeln) ==> CEEC: 60 RTS [ja: Wenigstens die Diskettenseite muesste neu nach $96 geschrieben werden !!!] Einsprung von $CEEA: CEED: B9 0B 00 LDA $000B,Y logische Spur - 1 CEF0: 38 SEC CEF1: E9 01 SBC #$01 CEF3: 99 BC 01 STA $01BC,Y = physikalische Spur CEF6: A5 75 LDA $75 Anzahl Sektoren pro Track CEF8: 4A LSR / 2 = Sektoren pro Spur CEF9: AA TAX = 1. logischer Block auf Rueckseite CEFA: D9 0C 00 CMP $000C,Y Sektornummer >= a ? CEFD: F0 05 BEQ $CF04 ja, (Seite 1) ==> CEFF: 90 03 BCC $CF04 ja, (Seite 1) ==> CF01: A9 00 LDA #$00 Seite 0 waehlen CF03: 2C B $2C Einsprung von $CEFD, $CEFF: CF04: A9 01 LDA #$01 Seite 1 waehlen CF06: 85 96 STA $96 als aktuelle Seite merken CF08: F0 01 BEQ $CF0B Aktuelle Seite =1 ? nein, ==> CF0A: 8A TXA ja: Einsprung von $CF08: CF0B: 85 39 STA $39 als 1. log. Sek. der Seite merken CF0D: A6 83 LDX $83 CF0F: B9 0C 00 LDA $000C,Y logischer Sektor CF12: 38 SEC CF13: E5 39 SBC $39 - 1. log. Sektor der Disk-Seite CF15: 09 80 ORA #$80 b7=1: Flag: 'T&S sind umgewandelt' setzen CF17: 95 9F STA $9F,X als Zeiger (Hi) in Cachepuffer merken CF19: 29 7F AND #$7F physikalische Sektornummer berechnen CF1B: A6 91 LDX $91 Sektorgroesse holen Einsprung von $CF21: CF1D: CA DEX [Wenn ein physikalischer Sektor 512 Byte CF1E: F0 04 BEQ $CF24 gross ist, passen immer 2 logische Sektoren CF20: 4A LSR hinein. Also muss die Sektornummer /2 CF21: 4C 1D CF JMP $CF1D genommen werden (Normalfall).] Einsprung von $CF1E: CF24: 18 CLC CF25: 65 94 ADC $94 + 1. physikalische Sektornummer der Spur CF27: 4C 4A CF JMP $CF4A = phy. Sektornummer ==> es wurden phy. T&S angegeben; Position im Cache berechnen Einsprung von $CEE4: CF2A: A6 83 LDX $83 CF2C: BD CE 01 LDA $01CE,X Seitennummer CF2F: 85 96 STA $96 uebernehmen CF31: B9 0B 00 LDA $000B,Y Tracknummer CF34: 99 BC 01 STA $01BC,Y uebernehmen CF37: B9 0C 00 LDA $000C,Y Sektornummer CF3A: 48 PHA merken CF3B: 38 SEC CF3C: E5 94 SBC $94 - 1. Sektornummer auf der Spur CF3E: A6 91 LDX $91 Sektorgroesse Einsprung von $CF44: CF40: CA DEX [Sektornummer auf 256 Byte grosse Bloecke CF41: F0 04 BEQ $CF47 umrechnen. Bei 512 Byte grossen Sektoren CF43: 0A ASL muss die Sektor nummer also *2 genommen CF44: 4C 40 CF JMP $CF40 werden (Normalfall).] Einsprung von $CF41: CF47: 95 9F STA $9F,X Sektornummer merken CF49: 68 PLA Einsprung von $CF27: CF4A: 99 BD 01 STA $01BD,Y physikalische Sektornummer merken CF4D: 2C B $2C Ende ==> Einsprung von $CEDE: CF4E: 06 85 ASL $85 [Die Routine muss $85 genau 1 mal nach Links CF50: 60 RTS shiften.] Schreiben/Lesen mit Cache-Daten Einsprung von $C0FC: CF51: A4 99 LDY $99 CF53: B9 BC 01 LDA $01BC,Y Befindet sich die physikalische Spur im CF56: C5 95 CMP $95 Cachepuffer ? CF58: D0 09 BNE $CF63 nein, (Ende) ==> CF5A: A5 96 LDA $96 Handelt es sich um die richtige Seite ? CF5C: C5 97 CMP $97 CF5E: D0 03 BNE $CF63 nein, (Ende) ==> CF60: 4C 64 CF JMP $CF64 Ja ==> Einsprung von $CF58, $CF5E: CF63: 60 RTS Einsprung von $CF60: CF64: A6 83 LDX $83 Jobnummer CF66: BD F1 01 LDA $01F1,X Pufferadresse holen und als Copy-Zeiger CF69: 85 49 STA $49 merken CF6B: B5 9F LDA $9F,X Position des Blocks im Cache CF6D: 29 7F AND #$7F b7=0: Flag: 'T&S sind umgewandelt worden' CF6F: 18 CLC ausblenden CF70: 65 8C ADC $8C + Cacheanfang CF72: 85 4B STA $4B Als Zeiger in den Cachepuffer merken CF74: A0 00 LDY #$00 Am Pufferanfang beginnen CF76: 84 48 STY $48 CF78: 84 4A STY $4A CF7A: A2 01 LDX #$01 256 Bytes kopieren CF7C: 06 86 ASL $86 b6=1: keine Daten kopierenn ? CF7E: B0 18 BCS $CF98 ja, ==> CF80: 06 86 ASL $86 b65=01: Daten in Cache schreiben CF82: B0 06 BCS $CF8A ja, ==> CF84: 20 58 D5 JSR $D558 b65=00: Daten aus Cache in Puffer kopieren Einsprung von $CF96, $CF9A: CF87: 4C 99 C3 JMP $C399 Auftrag loeschen, alle Jobs pruefen Einsprung von $CF82: CF8A: AD FA 01 LDA $01FA Schreibschutz an ? CF8D: D0 14 BNE $CFA3 Ja, ==> CF8F: 20 3E D0 JSR $D03E Daten in Cache schreiben Einsprung von $CFA1: CF92: A9 80 LDA #$80 Flag fuer Cache veraendert setzen CF94: 85 87 STA $87 CF96: D0 EF BNE $CF87 immer ==> Einsprung von $CF7E: CF98: 06 86 ASL $86 b65=11: Schreibschutz abfragen CF9A: 90 EB BCC $CF87 nein, ==> CF9C: AD FA 01 LDA $01FA Schreibschutz an ? CF9F: D0 02 BNE $CFA3 ja, ==> CFA1: B0 EF BCS $CF92 immer ==> Einsprung von $CF8D, $CF9F: CFA3: 4C 9B C3 JMP $C39B Schreibschutz-Fehler Blockheader lesen Spurnummer und Sektorgroesse anpassen Einsprung von $C116, $C600, $C6D7, $C700, $C800, $C900, $CA00, $CAE4, $CAF1, $CB09: CFA6: 20 00 CD JSR $CD00 Blockheader lesen CFA9: B0 09 BCS $CFB4 Fehler, ==> CFAB: A5 1F LDA $1F Spurnummer aus Blockheader CFAD: 85 27 STA $27 als aktuelle Kopfposition merken CFAF: A5 22 LDA $22 Sektorgroesse merken CFB1: 85 91 STA $91 CFB3: 60 RTS Einsprung von $CFA9: CFB4: 4C CC CD JMP $CDCC Fehler Copy-Zeiger auf Cachepuffer-Anfang setzen Einsprung von $C3BB, $C3C8, $C612, $C90F, $CA0F, $CB3E, $CB4C: CFB7: A5 8B LDA $8B $8b/$8c: Cachepuffer-Anfang CFB9: 85 4A STA $4A $4a/$4b: Zeiger in Cachepuffer CFBB: A5 8C LDA $8C CFBD: 85 4B STA $4B CFBF: 60 RTS Seite auswaehlen E: a: =0: Seite 0 >0: Seite 1 [Die Routine geht davon aus, dass das a-Register unmittelbar vor dem Funktionsaufruf gesetzt wird, damit das z-Flag stimmt. Das z-Flag alleine reicht aber nicht.] Einsprung von $C12B, $C14F, $CB3B: CFC0: F0 02 BEQ $CFC4 CFC2: A9 01 LDA #$01 a>0, dann a=1 Einsprung von $CFC0: CFC4: 85 36 STA $36 CFC6: AD 00 40 LDA $4000 b0: Bit fuer Seite CFC9: 29 FE AND #$FE in Steuerregister einblenden CFCB: 05 36 ORA $36 CFCD: 8D 00 40 STA $4000 CFD0: 60 RTS Controller initialisieren Einsprung von $C367, $CADC: CFD1: AD E4 01 LDA $01E4 Befehl $d0: 'Force Interrupt' CFD4: 8D 00 60 STA $6000 als Controller-Initialisierung CFD7: 20 2F AD JSR $AD2F 120 us Warten CFDA: 20 2F AD JSR $AD2F ... CFDD: 20 2F AD JSR $AD2F ... CFE0: 4C EC CB JMP $CBEC auf Controller-Ready warten Precompensation ein/ausschalten Einsprung von $C3DB, $C60F: CFE3: 38 SEC a: zu bearbeitende Spur CFE4: E5 94 SBC $94 - ersten Sektor auf Spur [????] CFE6: C9 2B CMP #$2B <43 ? CFE8: 90 12 BCC $CFFC ja, ==> CFEA: AD E0 01 LDA $01E0 ausschalten CFED: 09 02 ORA #$02 CFEF: 8D E0 01 STA $01E0 'Write Sector' CFF2: AD E3 01 LDA $01E3 CFF5: 09 02 ORA #$02 CFF7: 8D E3 01 STA $01E3 'Write Track' CFFA: B0 10 BCS $D00C ==> Einsprung von $CFE8: CFFC: AD E0 01 LDA $01E0 Precompensation einschalten CFFF: 29 FD AND #$FD D001: 8D E0 01 STA $01E0 'Write Sector' D004: AD E3 01 LDA $01E3 D007: 29 FD AND #$FD D009: 8D E3 01 STA $01E3 'Write Track' Einsprung von $CFFA: D00C: 60 RTS Daten vom Puffer in den Cache kopieren E: x : x mal 256 Bytes $4a: Bereich im Cache $48: Pufferanfang Controller-Programm 3 D00D: 41 4D 20 49 20 49 20 5A am i laz D014: 59 3F 3F 3F 2E 2E 2E 4E y???...n D01D: 4F 20 4A 55 53 54 20 57 o just w D024: 41 4E 54 45 44 20 54 4F anted to D02D: 20 53 41 56 45 20 41 20 save a D034: 46 45 57 20 4D 53 2E 2E few ms.. D03D: 2E . Einsprung von $D545, $CED6, $CF8F: D03E: B1 48 LDA ($48),Y D040: 91 4A STA ($4A),Y D042: C8 INY D043: B1 48 LDA ($48),Y D045: 91 4A STA ($4A),Y D047: C8 INY ..... [insgesamt 256 mal] D539: B1 48 LDA ($48),Y D53B: 91 4A STA ($4A),Y D53D: C8 INY D53E: CA DEX schon alle Bloecke kopiert ? D53F: F0 07 BEQ $D548 ja, ==> D541: E6 49 INC $49 Hi-Bytes erhoehen D543: E6 4B INC $4B D545: 4C 3E D0 JMP $D03E Einsprung von $D53F: D548: 60 RTS Daten vom Cache in den Puffer kopieren E: x : x mal 256 Bytes $4a: Bereich im Cache $48: Pufferanfang D549: 54 48 49 53 20 49 53 20 this is D551: 4C 41 5A 59 21 21 21 lazy... Einsprung von $DA5F, $CED9, $CF84: D558: B1 4A LDA ($4A),Y D55A: 91 48 STA ($48),Y D55C: C8 INY ..... [insgesamt 256 mal] DA53: B1 4A LDA ($4A),Y DA55: 91 48 STA ($48),Y DA57: C8 INY DA58: CA DEX schon alle Bloecke kopiert ? DA59: F0 07 BEQ $DA62 ja, ==> DA5B: E6 49 INC $49 Hi-Bytes erhoehen DA5D: E6 4B INC $4B DA5F: 4C 58 D5 JMP $D558 Einsprung von $DA59: DA62: 60 RTS CRC-Pruefsumme des Blockheaders testen Einsprung von $CD36: DA63: A5 38 LDA $38 Vgl. ROM-Test ($ab1d) DA65: 48 PHA DA66: A5 39 LDA $39 Rechenregister retten DA68: 48 PHA DA69: A5 3A LDA $3A DA6B: 48 PHA DA6C: A5 3B LDA $3B DA6E: 48 PHA DA6F: A5 3C LDA $3C DA71: 48 PHA DA72: A5 3D LDA $3D DA74: 48 PHA DA75: A5 3E LDA $3E DA77: 48 PHA DA78: A9 30 LDA #$30 Startwert ist $b230 DA7A: 85 3D STA $3D DA7C: A9 B2 LDA #$B2 DA7E: 85 3E STA $3E DA80: A0 00 LDY #$00 Einsprung von $DAD3: DA82: B9 1F 00 LDA $001F,Y 2-Byte Wert aus Blockheader DA85: 85 39 STA $39 nach $38/$39 holen DA87: AA TAX DA88: C8 INY DA89: B9 1F 00 LDA $001F,Y DA8C: 85 38 STA $38 DA8E: 8A TXA DA8F: A2 10 LDX #$10 16 Bits muessen getestet werden [da91 -- -- lda 39 (zum besseren Verstaendnis) ] Einsprung von $DACE: DA91: 85 3A STA $3A Hi-Byte fuer BIT-Test merken DA93: 18 CLC DA94: 26 38 ROL $38 naechstes Bit zum Testen bereitstellen DA96: 26 39 ROL $39 DA98: A9 00 LDA #$00 DA9A: 85 3B STA $3B DA9C: 85 3C STA $3C DA9E: 24 3A BIT $3A ist das zu testende Bit (b7) =0 ? DAA0: 10 08 BPL $DAAA ja, ($3b/$3c = $0000) ==> DAA2: A9 21 LDA #$21 nein, ($3b/$3c = $1021) DAA4: 85 3B STA $3B DAA6: A9 10 LDA #$10 DAA8: 85 3C STA $3C Einsprung von $DAA0: DAAA: 24 3E BIT $3E ist das MSB der Pruefsumme =1 ? DAAC: 10 0C BPL $DABA nein, ==> DAAE: A5 3B LDA $3B ja, Wert in $3b/$3c austauschen DAB0: 49 21 EOR #$21 DAB2: 85 3B STA $3B (aus $0000 wird $1021, DAB4: A5 3C LDA $3C aus $1021 wird $0000) DAB6: 49 10 EOR #$10 DAB8: 85 3C STA $3C Einsprung von $DAAC: DABA: 18 CLC Pruefsumme *2 DABB: 26 3D ROL $3D DABD: 26 3E ROL $3E DABF: A5 3D LDA $3D $3d/$3e = $3d/$3e eor $3b/$3c DAC1: 45 3B EOR $3B DAC3: 85 3D STA $3D DAC5: A5 3E LDA $3E DAC7: 45 3C EOR $3C DAC9: 85 3E STA $3E DACB: A5 39 LDA $39 DACD: CA DEX muessen noch Bits getestet werden? DACE: D0 C1 BNE $DA91 ja, ==> DAD0: C8 INY DAD1: C0 05 CPY #$05 naechsten 16-Bit-Wert holen ? DAD3: 90 AD BCC $DA82 ja, ==> DAD5: A4 3D LDY $3D Die Pruefsumme muss $0000 ergeben DAD7: A6 3E LDX $3E DAD9: 68 PLA Register zurueckholen DADA: 85 3E STA $3E DADC: 68 PLA DADD: 85 3D STA $3D DADF: 68 PLA DAE0: 85 3C STA $3C DAE2: 68 PLA DAE3: 85 3B STA $3B DAE5: 68 PLA DAE6: 85 3A STA $3A DAE8: 68 PLA DAE9: 85 39 STA $39 DAEB: 68 PLA DAEC: 85 38 STA $38 DAEE: C0 00 CPY #$00 Pruefsumme <> $0000 ? DAF0: D0 06 BNE $DAF8 ja, ==> DAF2: E0 00 CPX #$00 DAF4: D0 02 BNE $DAF8 ja, ==> DAF6: 18 CLC DAF7: 60 RTS Einsprung von $DAF0, $DAF4: DAF8: A9 09 LDA #$09 CRC-Error DAFA: 4C CC CD JMP $CDCC IRQ-Routine DAFD: 48 PHA Prozessor-Register retten DAFE: 8A TXA DAFF: 48 PHA DB00: 98 TYA DB01: 48 PHA DB02: AD 0D 40 LDA $400D ICR: Interrupt-Ursache holen DB05: A8 TAY DB06: 25 76 AND $76 Bus-Modus b3=1: FSM-erlaubt ? DB08: 29 08 AND #$08 und wenn ja: Byte ueber FSM-empfangen ? DB0A: F0 06 BEQ $DB12 nein, ==> DB0C: A5 76 LDA $76 DB0E: 09 20 ORA #$20 FSM-Modus aktivieren DB10: 85 76 STA $76 Einsprung von $DB0A: DB12: 98 TYA DB13: 29 10 AND #$10 ATN aufgetreten ? DB15: F0 06 BEQ $DB1D nein, ==> DB17: A5 76 LDA $76 DB19: 09 01 ORA #$01 Flag fuer ATN merken DB1B: 85 76 STA $76 Einsprung von $DB15: DB1D: 98 TYA DB1E: 29 02 AND #$02 Timer-IRQ aufgetreten ? DB20: F0 03 BEQ $DB25 nein, ==> DB22: 20 39 FF JSR $FF39 Controller-Routine aufrufen Einsprung von $DB20: DB25: BA TSX DB26: BD 04 01 LDA $0104,X BRK-Kommando ? DB29: 29 10 AND #$10 DB2B: F0 03 BEQ $DB30 nein, ==> DB2D: 20 39 FF JSR $FF39 Controller-Routine aufrufen Einsprung von $DB2B: DB30: 68 PLA Prozessor-Register zurueckholen DB31: A8 TAY DB32: 68 PLA DB33: AA TAX DB34: 68 PLA DB35: 40 RTI ROM-Tabellen U0-Befehle: Adressen, Befehlsnr., Name, Drive, Seite DB36: 11 BB W $BB11 $00: Read N0 S0 DB38: FA BA W $BAFA $01: Read (n.v.) N1 S0 DB3A: 01 BC W $BC01 $02: Write N0 S0 DB3C: F9 BB W $BBF9 $03: Write (n.v.) N1 S0 DB3E: B2 BC W $BCB2 $04: Inquire Disk N0 S0 DB40: FA BA W $BAFA $05: Inq.D.(n.v.) N1 S0 DB42: 12 BD W $BD12 $06: Format N0 DB44: 12 BD W $BD12 $07: Format N1 DB46: FC BD W $BDFC $08: (Syntax Error) DB48: FC BD W $BDFC $09: (Syntax Error) DB4A: 06 BE W $BE06 $0a: Query Format N0 S0 DB4C: FA BA W $BAFA $0b: Query (n.v.) N1 S0 DB4E: BB BE W $BEBB $0c: Inquire Stat N0 DB50: FA BA W $BAFA $0d: Inq.S.(n.v.) N1 DB52: F8 BE W $BEF8 $0e: (Syntax Error) DB54: F8 BE W $BEF8 $0f: (Syntax Error) DB56: 11 BB W $BB11 $10: Read N0 S1 DB58: FA BA W $BAFA $11: Read (n.v.) N1 S1 DB5A: 01 BC W $BC01 $12: Write N0 S1 DB5C: F9 BB W $BBF9 $13: Write (n.v.) N1 S1 DB5E: B2 BC W $BCB2 $14: Inquire Disk N0 S1 DB60: FA BA W $BAFA $15: Inq.D.(n.v.) N1 S1 DB62: 12 BD W $BD12 $16: Format N0 DB64: 12 BD W $BD12 $17: Format N1 DB66: CB 89 W $89CB $18: (rts) DB68: CB 89 W $89CB $19: (rts) DB6A: 06 BE W $BE06 $1a: Query Format N0 S1 DB6C: FA BA W $BAFA $1b: Query (n.v.) N1 S1 DB6E: 02 BF W $BF02 $1c: Dump Cache N0 DB70: 02 BF W $BF02 $1d: Dump Cache N1 DB72: 3C AA W $AA3C $1e: ChgUtl DB74: D5 B8 W $B8D5 $1f: Fastload DB76: 06 Anzahl der BAM-Bytes pro Spur DB77: 04 Position des Disknamens im Verzeichnis-Header Diskettenkommandos DB78: 56 49 2F 4D 42 55 50 26 vi/mbup& [Der sowieso nicht verwendbare DB80: 43 52 53 4E crsn Duplicate-Befehl der 1541 ist DB84: 09 0C 0F 12 15 18 1B 1E Lo-Bytes durch den Partition-Befehl '/' DB8C: 21 24 27 2A ersetzt worden.] DB90: FF FF FF FF FF FF FF FF Hi-Bytes DB98: FF FF FF FF Bitmuster zur Ueberpruefung des Befehlsformates b0 : 1: '=' notwendig b1 : 1: '=' verboten b2 : 0: ',' nach '=' erlaubt b3 : 0: '*' nach '=' erlaubt b4 : immer 0 b5 : immer 1 b6 : 0: ',' vor '=' erlaubt b7 : 0: '*' vor '=' erlaubt DB9C: 51 %01010001 Copy DB9D: DD %11011101 Rename DB9E: 1C %00011100 Scratch DB9F: 9E %10011110 New DBA0: 1C %00011100 Laden DBA1: 52 57 41 4D 'RWAM' Filemodi DBA5: 44 53 50 55 4C 43 'DSPULC' Filetypen DBAB: 44 53 50 55 52 43 DSPURC Filetypen DBB1: 45 45 52 53 45 42 EERSEB [senkrecht lesen !] DBB6: 4C 51 47 52 4C 4D LQGRLM DBBD: 00 z-Flag setzen durch BIT-Befehl gezieltes Setzen der nv-Flags durch BIT-Befehl DBBE: 3F 7F BF FF --, -v, n-, nv DBC2: 01 FF FF 01 00 Kopfjustage bei Leseproblemen (n.v.) Patches FSM: Schieberegister initialisieren [Bsp.: Wenn erst der Computer und dann die 1581 eingeschaltet wird, kann es vorkommen, dass im Computer irrtuemlich ein paar Bits 'empfangen' werden. Bei einer Datenuebertragung wuerde der Computer anschliessend alle Bits verschoben empfangen. Beim Umschalten der Datenrichtung des SDR wird deshalb der Schiebezaehler initialisiert und dadurch die Datenuebertragung synchronisiert. Sollen aber z.B. Daten empfangen werden und steht das SDR bereits auf Eingang, findet keine Synchronisation statt, weil sich die Datenrichtung ja nicht aendert. Deshalb wird grundsaetzlich vor einer Datenuebertragung mehrmals die Datenrichtung geaendert und dadurch die Synchronitaet gewaehrleistet.] - FSM auf Eingabe schalten Einsprung von $ACC2: DBC7: 8D 0E 40 STA $400E SDR auf Eingang schalten DBCA: AD 01 40 LDA $4001 Bustreiber auf Ausgang schalten DBCD: 09 20 ORA #$20 [um einen Kurzschluss zwischen Treiber und DBCF: 8D 01 40 STA $4001 SDR zu verhindern] DBD2: AD 0E 40 LDA $400E SDR auf Ausgang schalten DBD5: 09 40 ORA #$40 DBD7: 8D 0E 40 STA $400E SDR auf Eingang schalten DBDA: 29 BF AND #$BF DBDC: 8D 0E 40 STA $400E DBDF: 60 RTS - FSM auf Ausgabe schalten Einsprung von $ACE3: DBE0: 8D 0E 40 STA $400E SDR auf Eingang schalten DBE3: 29 BF AND #$BF DBE5: 8D 0E 40 STA $400E SDR auf Ausgang schalten DBE8: 09 40 ORA #$40 DBEA: 8D 0E 40 STA $400E DBED: 60 RTS Scratch-Erweiterung Einsprung von $86D8: DBEE: 20 15 B5 JSR $B515 BAM speichern DBF1: 4C 01 87 JMP $8701 'Query Disk Format'-Erweiterung: erste Tracknummer feststellen Einsprung von $BE0F: DBF4: 20 9D 95 JSR $959D Job ($c0: 'Restore') ausfuehren DBF7: C9 02 CMP #$02 Fehler ? DBF9: B0 05 BCS $DC00 ( a>=2, ==> ) DBFB: A9 B0 LDA #$B0 SEEKHD_DV: Diskette anmelden DBFD: 20 9D 95 JSR $959D Job ausfuehren Einsprung von $DBF9: DC00: 60 RTS DC01: 28 43 29 31 39 38 37 20 (c)1987 DC09: 43 4F 4D 4D 4F 44 4F 52 commodor DC11: 45 20 45 4C 45 43 54 52 e electr DC19: 4F 4E 49 43 53 20 4C 54 onics lt DC21: 44 2E 2C 20 41 4C 4C 20 d., all DC29: 52 49 47 48 54 53 20 52 rights r DC31: 45 53 45 52 56 45 44 eserved DC38: FF .... FEFF: .... FF Sprungvektoren Einsprung von $A83B, $AEE7, $AFE6: FF00: 6C 90 01 JMP ($0190) $b0f0 JIDLE: Hauptleerlaufschleife FF03: 6C 92 01 JMP ($0192) $dafd JIRQ: Interrupt-Vektor Einsprung von $AD59: FF06: 6C 94 01 JMP ($0194) $afca JNMI: Warmstart-Vektor FF09: 6C 96 01 JMP ($0196) $b262 JVERDIR: VALIDATE-Befehl FF0C: 6C 98 01 JMP ($0198) $8ec5 JINTDRV: INITIALIZE-Befehl FF0F: 6C 9A 01 JMP ($019A) $b781 JPART: PARTITION-Befehl FF12: 6C 9C 01 JMP ($019C) $892f JMEM: M-x -Befehle FF15: 6C 9E 01 JMP ($019E) $8a5d JBLOCK: B-x -Befehle FF18: 6C A0 01 JMP ($01A0) $898f JUSER: Ux -Befehle FF1B: 6C A2 01 JMP ($01A2) $a1a1 JRECORD: Position-Befehl FF1E: 6C A4 01 JMP ($01A4) $a956 JUTLODR: &-Befehl FF21: 6C A6 01 JMP ($01A6) $876e JDSKCPY: COPY-Befehl FF24: 6C A8 01 JMP ($01A8) $88c5 JRENAME: RENAME-Befehl FF27: 6C AA 01 JMP ($01AA) $8688 JSCRTCH: SCRATCH-Befehl Einsprung von $BD79: FF2A: 6C AC 01 JMP ($01AC) $b348 JNEW: NEW-Befehl Einsprung von $876A, $9536, $B9DC, $BB0E: FF2D: 6C AE 01 JMP ($01AE) $a7ae ERROR: Error-Routine des Controllers Einsprung von $AD29, $B10C, $BA61: FF30: 6C B0 01 JMP ($01B0) $abcf JATNSRV: ATN bedienen Einsprung von $AC88: FF33: 6C B2 01 JMP ($01B2) $ad5c JTALK: Daten zum Computer senden Einsprung von $AC75: FF36: 6C B4 01 JMP ($01B4) $aeb8 JLISTEN: Daten vom Computer holen Einsprung von $DB22, $DB2D: FF39: 6C B6 01 JMP ($01B6) $c0be JLCC: Controller-Routine Einsprung von $C0F5: FF3C: 6C B8 01 JMP ($01B8) $cedc JTRANS_TS: log. in phys. Format Einsprung von $8082, $8B5D, $94A5, $94D0, $9ACA, $A19E, $A9E5, $AA01, $B320, $B5BA, $B728, $B743, $B77E, $B84E: FF3F: 6C BA 01 JMP ($01BA) $a7f1 CMDERR: Error-Routine des DOS FF42: FF .... FF53: .... FF FF54: 4C 9D 95 JMP $959D STROBE_CONTROLLER: Aufruf des Controllers FF57: 4C 38 A9 JMP $A938 JCBMBOOT: Autoboot-Routine FF5A: 4C 4C A9 JMP $A94C JCBMBOOTRTN: Beenden des Bootprogramms FF5D: 4C 1D AB JMP $AB1D JSIGNATURE: ROM-Signatur pruefen FF60: 4C 45 91 JMP $9145 JDEJAVU: Selbstladeroutine umschalten FF63: 4C EA AE JMP $AEEA JSPINOUT: SPIN, SPOUT festlegen FF66: 4C 5C 8C JMP $8C5C JALLOCBUFF: Puffer allokieren Einsprung von $B374, $B380, $BEE7, $BEF5: FF69: 4C 60 94 JMP $9460 JDETDSKCHG: Prueft auf Diskettenwechsel Einsprung von $B16F, $BF36: FF6C: 4C E3 BF JMP $BFE3 JTRKWRT: Cachepuffer auf Disk schreiben FF6F: FF .... FF74: .... FF Tabelle der DOS-Funktionen (wird nach $0190-$01BB kopiert) FF75: F0 B0 W $B0F0 Haupt-Leerschleife FF77: FD DA W $DAFD Interrupt-Routine FF79: CA AF W $AFCA Warmstartvector FF7B: 62 B2 W $B262 VALIDATE FF7D: C5 8E W $8EC5 INITIALIZE FF7F: 81 B7 W $B781 Partition FF81: 2F 89 W $892F Memory-Read/Write FF83: 5D 8A W $8A5D Block-Befehle FF85: 8F 89 W $898F USER FF87: A1 A1 W $A1A1 POSITION (RECORD) FF89: 56 A9 W $A956 Utility-Loader (&) FF8B: 6E 87 W $876E COPY FF8D: C5 88 W $88C5 RENAME FF8F: 88 86 W $8688 SCRATCH FF91: 48 B3 W $B348 NEW FF93: AE A7 W $A7AE Error-Routine des Controllers FF95: CF AB W $ABCF ATN-bearbeiten FF97: 5C AD W $AD5C Daten auf ser. Bus FF99: B8 AE W $AEB8 Daten vom ser. Bus FF9B: BE C0 W $C0BE Controller-Routine FF9D: DC CE W $CEDC log. in phys. Format FF9F: F1 A7 W $A7F1 Error-Routine des DOS FFA1: FF .... FFAC: .... FF Einsprung von $AFD0: FFAD: A0 2B LDY #$2B Vektoren initialisieren Einsprung von $FFB6: FFAF: B9 75 FF LDA $FF75,Y FFB2: 99 90 01 STA $0190,Y FFB5: 88 DEY FFB6: 10 F7 BPL $FFAF FFB8: A9 4C LDA #$4C ,01fc 4c 40 ba JMP $BA40 FFBA: 8D FC 01 STA $01FC (Byte auf FSM-Bus ausgeben) FFBD: A9 40 LDA #$40 FFBF: 8D FD 01 STA $01FD FFC2: A9 BA LDA #$BA FFC4: 8D FE 01 STA $01FE FFC7: 60 RTS FFC8: FF .... FFE9: .... FF FFEA: 9A 8B W $8B9A u1 Block lesen FFEC: D7 8B W $8BD7 u2 Block schreiben FFEE: 00 05 W $0500 u3 Spruenge in Puffer 2 FFF0: 03 05 W $0503 u4 " FFF2: 06 05 W $0506 u5 " FFF4: 09 05 W $0509 u6 " FFF6: 0C 05 W $050C u7 " FFF8: 0F 05 W $050F u8 " FFFA: 3C AD W $AD3C u9 NMI: Warmstart / Busmodus aendern FFFC: 24 AF W $AF24 u: RESET: Einschaltvektor FFFE: 03 FF W $FF03 BRK/IRQ -Vektor 1581 ROM Versions: Revision 1 ("old"): Chip #318045-01 (also 312558-01), used until 1992? Revision 2 ("new"): Chip #318045-02, used from 1992? on AAY1581 contains a disassembly of the new version, but differences are also stated. They are at: +-------------+----------------------------------------------------------- | $AF8C | Ignore false ROM checksum | $C160-$C162 | Apply patch at $C5AF in newer version | $C5AF-$C5B2 | Disable interrupts during Job execution +-------------+----------------------------------------------------------- +------------------------------------------------------------------------ | | CBM DOS V10 Error Messages | +------------------------------------------------------------------------ | | Error #00: OK | Error #01: FILES SCRATCHED,XX (,TT,SS on error) | Error #02: PARTITION SELECTED | Error #20: READ ERROR (block header not found),TT,SS | Error #21: READ ERROR (no sync character),TT,SS | Error #22: READ ERROR (data block not present),TT,SS | Error #23: READ ERROR (checksum error in data block),TT,SS | Error #24: READ ERROR (byte decoding error) | Error #25: WRITE ERROR (write-verify error),TT,SS | Error #26: WRITE PROTECT ON,TT,SS | Error #27: READ ERROR (checksum error in header),TT,SS | Error #28: WRITE ERROR (long data block) | Error #29: DISK ID MISMATCH,TT,SS | Error #30: SYNTAX ERROR (general syntax) | Error #31: SYNTAX ERROR (invalid command) | Error #32: SYNTAX ERROR (invalid command) | Error #33: SYNTAX ERROR (invalid file name) | Error #34: SYNTAX ERROR (no file given) | Error #39: SYNTAX ERROR (invalid command) | Error #50: RECORD NOT PRESENT | Error #51: OVERFLOW IN RECORD | Error #52: FILE TOO LARGE | Error #60: WRITE FILE OPEN | Error #61: FILE NOT OPEN | Error #62: FILE NOT FOUND | Error #63: FILE EXISTS | Error #64: FILE TYPE MISMATCH | Error #65: NO BLOCK,TT,SS | Error #66: ILLEGAL TRACK AND SECTOR,TT,SS | Error #67: ILLEGAL SYSTEM T OR S,TT,SS | Error #70: NO CHANNEL (available) | Error #71: DIRECTORY ERROR,TT,SS | Error #72: DISK FULL | Error #73: COPYRIGHT CBM DOS V10 1581 | Error #74: DRIVE NOT READY | Error #75: FORMAT ERROR | Error #76: CONTROLLER ERROR | Error #77: SELECTED PARTITION ILLEGAL | | Not used (hidden messages): | | Error #79: SOFTWARE DAVID SIRACUSA. HARDWARE GREG BERLIN | Error #7A: DEDICATED TO MY WIFE LISA | +------------------------------------------------------------------------ Error Message #00: OK Command was executed successfully. Error Message #01: FILES SCRATCHED,XX (,TT,SS on error) Status message after scratching. XX is the number of deleted files. If an error occured, TT and SS show the block where it appeared. Error Message #02: PARTITION SELECTED Partition was selected successfully. Error Message #20: READ ERROR (block header not found),TT,SS The disk controller is unable to locate the header of the requested data block. Caused by an illegal block number, or the header has been destroyed. Error Message #21: READ ERROR (no sync character),TT,SS The disk controller is unable to detect a sync mark on the desired track. Caused by misalignment of the read/writer head, no diskette is present, or unformatted or improperly seated diskette. Can also indicate a hardware failure. Error Message #22: READ ERROR (data block not present),TT,SS The disk controller has been requested to read or verify a data block that was not properly written. This error message occurs in conjunction with the BLOCK commands and indicates an illegal track and/or block request. Error Message #23: READ ERROR (checksum error in data block),TT,SS This error message indicates that there is an error in one or more of the data bytes. The data has been read into the DOS memory, but the checksum over the data is in error. This message may also indicate grounding problems. Error Message #24: READ ERROR (byte decoding error) The data or header as been read into the DOS memory, but a hardware error has been created due to an invalid bit pattern in the data byte. This message may also indicate grounding problems. Error Message #25: WRITE ERROR (write-verify error),TT,SS This message is generated if the controller detects a mismatch between the written data and the data in the DOS memory. Error Message #26: WRITE PROTECT ON,TT,SS This message is generated when the controller has been requested to write a data block while the write protect switch is depressed. Typically, this is caused by using a diskette with a write a protect tab over the notch. Error Message #27: READ ERROR (checksum error in header),TT,SS The controller has detected an error in the header of the requested data block. The block has not been read into the DOS memory. This message may also indicate grounding problems. Error Message #28: WRITE ERROR (long data block) The controller attempts to detect the sync mark of the next header after writing a data block. If the sync mark does not appear within a predetermined time, the error message is generated. The error is caused by a bad diskette format (the data extends into the next block), or by hardware failure. Error Message #29: DISK ID MISMATCH,TT,SS This message is generated when the controller has been requested to access a diskette which has not been initialized. The message can also occur if a diskette has a bad header. Error Message #30: SYNTAX ERROR (general syntax) The DOS cannot interpret the command sent to the command channel. Typically, this is caused by an illegal number of file names, or patterns are illegally used. For example, two file names may appear on the left side of the COPY command. Error Message #31: SYNTAX ERROR (invalid command) The DOS does not recognize the command. The command must start in the first position. Error Message #32: SYNTAX ERROR (invalid command) The command sent is longer than 58 characters. Error Message #33: SYNTAX ERROR (invalid file name) Pattern matching is invalidly used in the OPEN or SAVE command. Error Message #34: SYNTAX ERROR (no file given) The file name was left out of a command or the DOS does not recognize it as such. Typically, a colon (:) has been left out of the command. Error Message #39: SYNTAX ERROR (invalid command) This error may result if the command sent to command channel (secondary address 15) is unrecognized by the DOS. Error Message #50: RECORD NOT PRESENT Result of disk reading past the last record through INPUT#, or GET# commands. This message will also occur after positioning to a record beyond end of file in a relative file. If the intent is to expand the file by adding the new record (with a PRINT# command), the error message may be ignored. INPUT or GET should not be attempted after this error is detected without first repositioning. Error Message #51: OVERFLOW IN RECORD PRINT# statement exceeds record boundary. Information is cut off. Since the carriage return is sent as a record terminator is counted in the record size. This message will occur if the total characters in the record (including the final carriage return) exceeds the defined size. Error Message #52: FILE TOO LARGE Record position within a relative file indicates that disk overflow will result. Error Message #60: WRITE FILE OPEN This message is generated when a write file that has not been closed is being opened for reading. Error Message #61: FILE NOT OPEN This message is generated when a file is being accessed that has not been opened in the DOS. Sometimes, in this case, a message is not generated; the request is simply ignored. Error Message #62: FILE NOT FOUND The requested file does not exist on the indicated drive. Error Message #63: FILE EXISTS The file name of the file being created already exists on the diskette. Error Message #64: FILE TYPE MISMATCH The file type does not match the file type in the directory entry for the requested file. Error Message #65: NO BLOCK,TT,SS This message occurs in conjunction with the B-A command. It indicates that the block to be allocated has been previously allocated. The parameters indicate the track and sector available with the next highest number. If the parameters are zero (0), then all blocks higher in number are in use. Error Message #66: ILLEGAL TRACK AND SECTOR,TT,SS The DOS has attempted to access a track or block which does not exist in the format being used. This may indicate a problem reading the pointer to the next block. Error Message #67: ILLEGAL SYSTEM T OR S,TT,SS This special error message indicates an illegal system track or block. Error Message #70: NO CHANNEL (available) The requested channel is not available, or all channels are in use. A maximum of five sequential files may be opened at one time to the DOS. Direct access channels may have six opened files. Error Message #71: DIRECTORY ERROR,TT,SS The BAM does not match the internal count. There is a problem in the BAM allocation or the BAM has been overwritten in DOS memory. To correct this problem, reinitialize the diskette to restore the BAM in memory. Some active files may be terminated by the corrective action. Error Message #72: DISK FULL Either the blocks on the diskette are used or the directory is at its entry limit. DISK FULL is sent when two blocks are available on the 1581 to allow the current file to be closed. Error Message #73: COPYRIGHT CBM DOS V10 1581 This message appears after power up and reset. Error Message #74: DRIVE NOT READY An attempt has been made to access the 1581 without any diskettes present in either drive. Error Message #75: FORMAT ERROR Error Message #76: CONTROLLER ERROR The WD177x-circuit does not work properly. Error Message #77: SELECTED PARTITION ILLEGAL 1581 Job Codes: This table contains the addresses (logical Track and Sector, not physical!) and the assigned buffers: +-------+---------+----------+---------------+ | JOB | TRACK | SECTOR | BUFFER | +-------+---------+----------+---------------+ | $02 | $0B | $0C | $0300-$03FF | | $03 | $0D | $0E | $0400-$04FF | | $04 | $0F | $10 | $0500-$05FF | | $05 | $11 | $12 | $0600-$06FF | | $06 | $13 | $14 | $0700-$07FF | | $07 | $15 | $16 | $0800-$08FF | | $08 | $17 | $18 | $0900-$09FF | | $09 | $19 | $1A | $0A00-$0AFF | | $0A | $1B | $1C | $0B00-$0BFF | +-------+---------+----------+---------------+ If a disk controller routine is to be performed in the interrupt, one writes the job code and the track and sector numbers of the block to be processed (if necessary) in the appropriate memory locations. Now the job code can be passed. This job code has a value greater than 127 (the 7th bit is set). In order to wait until the job is finished, only the seventh bit need be tested. If this bit is cleared, the job is completed. The disk controller can perform the following jobs: +--------+--------------+-----------------------------------------------+ | Code | Name | Description | +--------+--------------+-----------------------------------------------+ | $80 | READ_DV | Reads a particular logical sector into the | | | | job queue buffer (only if the disk has not | | | | been changed). If the desired sector is | | | | already in the track cache buffer, then no | | | | disk activity is required (the data is | | | | merely transferred from the track cache | | | | memory to the job queue buffer memory). If | | | | the desired sector is not in the track | | | | cache, then the current track cache is | | | | dumped to disk (only if it has been | | | | modified), the desired track is read into | | | | the track cache, and finally the particular | | | | sector's data is transferred from the track | | | | cache memory to the job queue buffer. | | | | | | $82 | RESET_DV | Resets the disk controller and associated | | | | variables. | | | | | | $84 | MOTON_DV | Turns on the spindle motor (overlays a $01 | | | | in the Job Queue after the spin-up sequence | | | | is complete). | | | | | | $86 | MOTOFF_DV | Turns the spindle motor off after the spin- | | | | down sequence is complete. | | | | | | $88 | MOTONI_DV | Turns the spindle motor on immediately. | | | | | | $8A | MOTOFFI_DV | Turns the spindle motor off immediately. | | | | | | $8C | SEEK_DV | Seeks to a particular physical track | | | | (cylinder). The current physical track | | | | position should be put in the track | | | | parameter of HDRS. | | | | | | $8E | FORMAT_DV | Formats one physical track (one half of a | | | | cylinder). The head must be placed | | | | physically over the proper cylinder, and | | | | the head electronics must be selected for | | | | the side desired. | | | | | | $90 | WRTSD_DV | Writes the job queue's buffer data to a | | | | particular logical track, sector. If the | | | | same track is already in the track cache, | | | | then this involves only transferring the | | | | job queue buffer data to the track cache | | | | buffer. If a different track's data is in | | | | the disk (only if it was modified), the | | | | desired track read into the track cache | | | | buffer, and finally the job queue buffer's | | | | data transferred to the track cache. | | | | | | $92 | DISKIN_DV | Determines if there is a disk inserted in | | | | the drive. | | | | | | $94 | LEDACTON_DV | Turns on the activity LED. | | | | | | $96 | LEDACTOFF_DV | Turns off the activity LED. | | | | | | $98 | ERRLEDON_DV | Enables error LED blinking. | | | | | | $9A | ERRLEDOFF_DV | Disables error LED blinking. | | | | | | $9C | SIDE_DV | Sets up the side select electronics to the | | | | value specified (in SIDS). | | | | | | $9E | BUFMOVE_DV | Moves data between the job queue buffer and | | | | the track cache buffer. The track parameter | | | | in the job queue denotes the position in | | | | the track cache buffer to transfer to/from. | | | | The sector parameter denotes the following: | | | | Bit 7 : Direction (1 = to track cache | | | | buffer) | | | | Bit 6 : Mark Flag (set/clear the 'track | | | | cache modified' flag) | | | | Bit 5 : Transfer (1 = do the transfer) | | | | Bits 4-0:# of 256 byte blocks to transfer | | | | With bit 7 set, the corresponding physical | | | | track position in the job queue (HDRS2) | | | | must be updated for the purpose of telling | | | | the controller what physical track the | | | | track cache buffer belongs to. In addition | | | | the side var (SIDS) must also be updated. | | | | | | $A0 | WRTVER_DV | Verifies the track cache buffer's data | | | | against the specified logical track's data. | | | | | | $A2 | TRKWRT_DV | Dumps the track cache buffer to the disk | | | | (only if the track cache modified flag is | | | | set). | | | | | | $A4 | SP_READ | Reads the specified physical sector | | | | directly into RAM starting at #0 ($0300). | | | | It does not use the track cache buffer. The | | | | sector is always read from the disk | | | | regardless of the current contents of the | | | | track cache. | | | | | | $A6 | SP_WRITE | Writes to the specified physical sector | | | | directly. It does not use the track cache. | | | | Data to be written starts at buffer #0 | | | | ($0300). | | | | | | $A8 | PSEEK_DV | Seeks to the specified physical track. | | | | | | $AA | TREAD_DV | Reads logical address without transferring | | | | to the job queue buffer. | | | | | | $AC | TWRT_DV | Writes a logical address without | | | | transferring from the job queue buffer. | | | | | | $B0 | SEEKHD_DV | Logs in a disk by reading information from | | | | the first header encountered on the disk | | | | into RAM so that it can be used by the DOS. | | | | The track cache buffer is not updated. | | | | | | $B2 | TPREAD_DV | Reads a physical address without | | | | transferring to the job queue buffer. | | | | | | $B4 | TPWRT_DV | Writes a physical address without | | | | transferring from the job queue buffer. | | | | | | $B6 | DETWP_DV | Checks if the disk inserted is write | | | | protected. Returns $00 if disk is not | | | | protected, else $08. | | | | | | $B8 | SEEKPHD_DV | Seeks to a particular logical track, | | | | sector. The track cache is not updated. | | | | | | $C0 | RESTORE_DV | Restores the read/write head to track 0 | | | | ('bump'). | | | | | | $D0 | JUMPC_DV | Executes the code in the corresponding job | | | | queue buffer. | | | | | | $E0 | EXBUF_DV | Executes the code in the corresponding job | | | | queue buffer after the motor is up to speed | | | | and the head is on track. | | | | | | $F0 | FORMATDK_DV | Formats the disk with the default physical | | | | format. | +--------+--------------+-----------------------------------------------+ If the job ends in an error then the memory location with job command code is replaced with and error code. Here is a list of the error numbers: +------+------------------+---------------------------------------------+ | Code | Name | Description | +------+------------------+---------------------------------------------+ | $0x | OK_DV | No error. | | $02 | MISHD_DV_ER | Can't find header block. | | $03 | NOADAM_DV_ER | No address mark detected. | | $04 | MISDBLK_DV_ER | Data block not present. | | $05 | CRCDBLK_DV_ER | CRC error encountered in data block. | | $06 | FMT_DV_ER | Format error. | | $07 | VERERR_DV_ER | Verify error. | | $08 | WRTPR_DV_ER | Attempt to write to a write protected disk. | | $09 | CRCHD_DV_ER | CRC error encountered in header block. | | $0A | | Reserved. | | $0B | DSKCHG_DV_W | Disk was changed/disk ID mismatch. | | $0C | DSKNTLOG_DV_ER | Disk format not logical. | | $0D | CONTROLLER_DV_ER | Floppy disk controller IC error. | | $0E | SYNTAX_DV_ER | Syntax error. Invalid job number. | | $0F | NODSKPRS_DV_ER | No disk is present in the drive. | +------+------------------+---------------------------------------------+ +------------------------------------------------------------------------ | | COMPLEX INTERFACE ADAPTER (CIA) 8520A (similar to CIA6526) | +------------------------------------------------------------------------ | | $4000/16384/CIA+0 Data Port Register A | $4001/16385/CIA+1 Data Port Register B | $4002/16386/CIA+2 Data Direction Register A | $4003/16387/CIA+3 Data Direction Register B | $4004/16388/CIA+4 Timer A: Low-Byte (Clock for FSM) | $4005/16389/CIA+5 Timer A: High-Byte (Clock for FSM) | $4006/16390/CIA+6 Timer B: Low-Byte (Interrupt Timer) | $4007/16391/CIA+7 Timer B: High-Byte (Interrupt Timer) | $4008/16392/CIA+8 Time-of-Day Clock: Low-Byte | $4009/16393/CIA+9 Time-of-Day Clock: Middle-Byte | $400A/16394/CIA+10 Time-of-Day Clock: High-Byte | $400B/16395/CIA+11 Unused | $400C/16396/CIA+12 Synchronous Serial I/O Data Buffer | $400D/16397/CIA+13 CIA Interrupt Control Register | $400E/16398/CIA+14 CIA Control Register A | $400F/16399/CIA+15 CIA Control Register B | +------------------------------------------------------------------------ $4000/16384/CIA+0: Data Port Register A +----------+---------------------------------------------------+ | Bit 7 | 0 = Disk Change (will be reset after the | | | next move of the head) | | Bit 6 | 1 = Drive LED on | | Bit 5 | 1 = Error LED bright | | Bits 4+3 | Position of DIP Switches for Device Number | | Bit 2 | 0 = Motor on | | Bit 1 | 1 = no Disk inserted | | Bit 0 | Side Select | +----------+---------------------------------------------------+ ROM-Reference: LDA $4000 : $AF0A $AFE9 $C57C $CBB1 $CBBA $CBC3 $CBCC $CD83 $CDA1 $CDBE $CE1F $CE2F $CE39 $CFC6 ORA $4000 : $AEFB STA $4000 : $AEFE $AF0F $AF28 $C583 $CBB6 $CBBF $CBC8 $CBD1 $CE24 $CE36 $CFCD $4001/16385/CIA+1: Data Port Register B +-------+---------------------------------------------------+ | Bit 7 | ATN IN | | Bit 6 | 0 = Write protect active | | Bit 5 | Data Direction of the Bus Driver (FSM) | | | 0 = Input, 1 = Output | | Bit 4 | automatic ATN-Response | | Bit 3 | CLOCK OUT | | Bit 2 | CLOCK IN | | Bit 1 | DATA OUT | | Bit 0 | DATA IN | +-------+---------------------------------------------------+ ROM-Reference: BIT $4001 : $AAE4 $AC55 $AC96 $AE58 $BB9A $BC4C $CB78 CMP $4001 : $AD0F $BA43 $BF8A $C02C LDA $4001 : $AAD7 $ABF0 $ABF8 $AC60 $ACC5 $ACD6 $ACE8 $ACF1 $ACFA $AD03 $AD0C $AD1B $AD21 $ADB3 $ADDD $AE87 $BA40 $BB8D $BC3F $BF87 $C029 $DBCA STA $4001 : $AADF $ABF5 $AC65 $AC93 $ACCA $ACDB $ACED $ACF6 $ACFF $AD08 $ADB8 $ADE2 $AEE1 $AF32 $B0F3 $BB95 $BC47 $DBCF $4002/16386/CIA+2: Data Direction Register A +----------+---------------------------------------------------+ | Bit x | 1 = Pin PAx set to Output, 0 = Input | +----------+---------------------------------------------------+ Default Value: $65/101 (%01100101) ROM-Reference: STA $4002 : $AF2D $4003/16387/CIA+3: Data Direction Register B +----------+---------------------------------------------------+ | Bit x | 1 = Pin PAx set to Output, 0 = Input | +----------+---------------------------------------------------+ Default Value: $3A/58 (%00111010) ROM-Reference: STA $4003 : $AF37 $4004/16388/CIA+4: Timer A: Low-Byte (Clock for FSM) Start Value usually = $0006 ROM-Reference: STA $4004 : $AF41 $4005/16389/CIA+5: Timer A: High-Byte (Clock for FSM) Start Value usually = $0006 ROM-Reference: STA $4005 : $AF3C $4006/16390/CIA+6: Timer B: Low-Byte (Interrupt Timer) Start Value usually = $4e20 ROM-Reference: STA $4006 : $CBA8 $4007/16391/CIA+7: Timer B: High-Byte (Interrupt Timer) Start Value usually = $4e20 ROM-Reference: STA $4007 : $CBA2 $4008/16392/CIA+8: Time-of-Day Clock: Low-Byte Bits 0-7 of the TOD (24-Bit-Binary Counter) ROM-Reference: LDA $4008 : $C372 STA $4008 : $C36C $4009/16393/CIA+9: Time-of-Day Clock: Middle-Byte Bits 8-15 of the TOD (24-Bit-Binary Counter) $400A/16394/CIA+10: Time-of-Day Clock: High-Byte Bits 16-23 of the TOD (24-Bit-Binary Counter) $400B/16395/CIA+11: Unused $400C/16396/CIA+12: Synchronous Serial I/O Data Buffer FSM Input / Output Register ROM-Reference: LDA $400C : $AAEE $AE94 $BBA4 $BC56 STA $400C : $ACAC $ADCB $BF9A STX $400C : $BA52 $400D/16397/CIA+13: CIA Interrupt Control Register +-------+------------------------------------------------------+ | Bit 7 | On Read: 1 = Interrupt occured | | | On Write: 1 = Set Int.-Flags, 0 = Clear Int-.Flags | | Bit 4 | FLAG1 IRQ (ATN occured) | | Bit 3 | Serial Port IRQ ($4C0C (FSM) is ready) | | Bit 2 | Time-of-Day Clock Alarm Interrupt | | Bit 1 | Timer B Interrupt (Interrupt Timer) | | Bit 0 | Timer A Interrupt | +-------+------------------------------------------------------+ Standard-Wert: $9A/154 (%10011010) Your CIA does NOT clear this register! You have to do this by simply reading it. ROM-Reference: BIT $400D : $AADC $AAE9 $ACB1 $AD26 $ADC3 $ADD0 $AE42 $BA5B $BB92 $BB9F $BC44 $BC51 $BFA5 LDA $400D : $AE8D $DB02 STA $400D : $AF4B $400E/16398/CIA+14: CIA Control Register A +-------+--------------------------------------------------------+ | Bit 7 | Unused | | Bit 6 | Serial Port ($400C) I/O Mode: 1 = Output, 0 = Input | | Bit 5 | Timer A Counts: 1 = CNT Signals, 0 = System 02 Clock | | Bit 4 | Force Load Timer A: 1 = Now! (Write only Strobe Bit) | | Bit 3 | Timer A Run Mode: 1 = One-Shot, 0 = Continuous | | Bit 2 | Timer A Output Mode to PB6: 1 = Toggle, 0 = Pulse | | Bit 1 | Timer A Output on PB6: 1 = Yes, 0 = No | | Bit 0 | Start/Stop Timer A: 1 = Start, 0 = Stop | +-------+--------------------------------------------------------+ Default Value: $x1/... (%0x000001) ROM-Reference: LDA $400E : $ACBD $ACDE $ADBB $ADD5 $DBD2 STA $400E : $ADC0 $ADDA $AF46 $DBC7 $DBD7 $DBDC $DBE0 $DBE5 $DBEA $400F/16399/CIA+15: CIA Control Register B +----------+--------------------------------------------------------+ | Bit 7 | Set Alarm/TOD-Clock: 1 = Alarm, 0 = Clock | | Bits 6-5 | Timer B Mode Select: | | | 00 = Count System 02 Clock Pulses | | | 01 = Count Positive CNT Transitions | | | 10 = Count Timer A Underflow Pulses | | | 11 = Count Timer A Underflows While CNT | | Bit 4 | Force Load Timer B: 1 = Now! (Write only Strobe Bit) | | | Bit 3 | Timer B Run Mode: 1 = One-Shot, 0 = Continuous | | Bit 2 | Timer B Output Mode to PB7: 1 = Toggle, 0 = Pulse | | Bit 1 | Timer B Output on PB7: 1 = Yes, 0 = No | | Bit 0 | Start/Stop Timer B: 1 = Start, 0 = Stop | +----------+--------------------------------------------------------+ Default Value: $11/17 (%00010001) ROM-Reference: STA $400F : $CBAD +------------------------------------------------------------------------ | | WD 177X-Disc-Controller | +------------------------------------------------------------------------ | | $6000/24576/WD+0 Command- / Status Register | $6001/24577/WD+1 Track Register | $6002/24578/WD+2 Sector Register | $6003/24579/WD+3 Data Register | +------------------------------------------------------------------------ $6000/24576/WD+0: Command- / Status Register ROM-Reference: BIT $6000 : $CBEE $CBFA LDA $6000 : $C3EE $C402 $C416 $C429 $C439 $C449 $C459 $C469 $C479 $C48A $C49E $C4B2 $C4C5 $C4DB $C4FF $C511 $C52D $C667 $C741 $C841 $C969 $CA69 $CD17 $CD43 STA $6000 : $CBF5 $CFD4 $6001/24577/WD+1: Track Register ROM-Reference: CPY $6001 : $C355 LDA $6001 : $C443 STA $6001 : $C3D8 $C60C $C710 $C810 $C90C $CA0C $CE83 $CE93 STY $6001 : $C349 $6002/24578/WD+2: Sector Register ROM-Reference: CPY $6002 : $C35A INC $6002 : $C691 $C993 $CA9B LDA $6002 : $C68E $C990 $CA98 STA $6002 : $C643 $C6B2 $C715 $C815 $C944 $C9B4 $CA44 $CABC STY $6002 : $C34C $6003/24579/WD+3: Data Register ROM-Reference: CMP $6003 : $CA81 CPY $6003 : $C35F LDA $6003 : $C84F $C977 $CD21 STA $6003 : $C3FA $C40E $C422 $C435 $C446 $C455 $C465 $C475 $C485 $C496 $C4AA $C4BE $C4D1 $C4F3 $C50B $C51D $C53A $C677 $C751 $CE7E STY $6003 : $C34F