Inhaltsverzeichnis
Das MINI-DOS ist eine Erweiterung des MAT85 bzw. MAT85+ rund um die Floppy-Baugruppe (4.7. Floppy Disk Baugruppe). Das „Softwarepaket“ wird dabei dynamisch in die Monitor (MAT85) bzw. Monitorerweiterung (MAT85+) eingebunden, da hier bereits Routinen enthalten sind, die eine Erweiterung möglich machen.
Über die Mini-DOS-Erweiterung stehen grundlegende Funktionen zur Verfügung, um Speicherbereiche auf Diskette (5 1/4″ oder 3 1/2″) abzuspeichern. Aus heutige Sicht ist die unterstützte Kapazität mit 320kByte allerdings überschaubar, für damalige Verhältnisse aber ein Meilenstein gegenüber der bisherigen Möglichkeit Speicherbereiche recht mühsam und langsam auf Kassetten abzuspeichern.
;************************************************************************* ; ; ## ## #### ## ## #### ######## ####### ###### ; ### ### ## ### ## ## ## ## ## ## ## ## ; #### #### ## #### ## ## ## ## ## ## ## ; ## ### ## ## ## ## ## ## ####### ## ## ## ## ###### ; ## ## ## ## #### ## ## ## ## ## ## ; ## ## ## ## ### ## ## ## ## ## ## ## ; ## ## #### ## ## #### ######## ####### ###### ; ;************************************************************************* ; VERSION 1.4 ; LETZTE AENDERUNG: 09.10.85 ; COPYRIGHT: BFZ ESSEN ; ALTENESSENER STR.80/84 ; 4300 ESSEN 12 ;************************************************************************* ; ; Aenderungen und Anpassungen ; 2023 thilo.buhl@tau-alpha-c.de ; ;************************************************************************* ; ; 28.05.2022 Anpassung an Visual Studio Code ; ;************************************************************************* ; ... 01/2023 - Kommentare ergaenzt ;************************************************************************* ; ; 26.01.2023 - P01 ; - [P01#01] Routine FORMAT: endet in Dauerschleife (JMP FORM1) ; Ende von FORMAT auf JMP ERROR2 geaendert ; - [P01#02] Routine LINE: Hexadresse des Flag auf CRTFLAG geaendert ; - [P01#03] Unterprogramm SD1: Re-Init des SP auf USRSTK geaendert ; - [P01#04] Adresse des FDC als Variable ; ;************************************************************************* ; Benutzte Assembler-Anweisungen ;************************************************************************* ; ; .target Prozessorsystem ; .format Ausgabeformat ; .org Anfangsadresse setzen ; .equ Zuweisung Variable ; .byte Definiere BYTE ; .word Definiere WORD (Lo/Hi-Byte) ; .text Definiere Textstelle ; .textz Definiere Textstelle mit $0 am Ende ; ;************************************************************************* ;************************************************************************* ;MINI-DOS ;VARIABLEN ;************************************************************************* ;[P01#04] FDCBAS .equ $c0 ; FDC Portadresse FDCCMD .equ FDCBAS ; FDC Kommandoregister FDCSTAT .equ FDCBAS ; FDC Statusregister FDCTRK .equ FDCBAS+1 ; FDC Trackregister (nicht verwendet) FDCSEC .equ FDCBAS+2 ; FDC Sektorregister FDCDAT .equ FDCBAS+3 ; FDC Datenregister FDCPORT .equ FDCBAS+4 ; FDC Steuer-Port ; D0 - Select0 (Laufwerk A) ; D1 - Select1 (Laufwerk B) ; D2 - Density Select ; 0 = Double Density ; 1 = Single Density ; D3 - Side Select ; 0 = Seite 0 ; 1 = Seite 1 FDCSTOP .equ FDCBAS+8 ; FDC Stop-Register ; Eine Ausgabe an dieses Register ; haelt die CPU an (READY-Signal) ;************************************************************************* ; STEP-Rate (Gueltig fuer FCD-Clock: 1 MHz, FDC-Test-Anschluss auf H-Pegel) ; ; SR-Wert-Rate in ms ; 0 6 ; 1 12 ; 2 20 ; 3 30 SR .equ $0 ;************************************************************************* ; Steuer-Worte ;************************************************************************* CREST .equ %00000000+SR ; Restore - Step-Rate entspricht SR CRESTV .equ %00000100+SR ; Restore - Verify Track Number ; Step-Rate entspricht SR CSTPIN .equ %01010000+SR ; Step-In - Update Track-Register ; Step-Rate entspricht SR CSEEK .equ %00010100+SR ; Seek - Verify ; - Delay ; - Step-Rate entspricht SR CWRTRK .equ %11110000 ; Write Track CWSEC .equ %10100000 ; Write Sector - Single Record ; - No Side Compare ; - No Delay ; - DAM not deleted CRSEC .equ %10000000 ; Lese Sector - No Delay ; - No Side Compare ;************************************************************************* ; Fehler-Masken ;************************************************************************* MREST .equ %11011100 ; Restore ; B7=1 -> not Ready ; B6=1 -> Write protect ; B5 ; B4=1 -> Seek Error ; B3=1 -> CRC-Error ; B2=1 -> Track 0 ; B1 ; B0 MWRTRK .equ %10000100 ; Write Track ; B7=1 -> not Ready ; B6 ; B5 ; B4 ; B3 ; B2=1 -> Lost Data ; B1 ; B0 MWSEC .equ %11011100 ; Write Sector ; B7=1 -> not Ready ; B6=1 -> Write protect ; B5 ; B4=1 -> Record not Found ; B3=1 -> CRC-Error ; B2=1 -> Lost Data ; B1 ; B0 MRSEC .equ %10011100 ; Read Sector ; B7=1 -> not Ready ; B6 ; B5 ; B4=1 -> Record not Found ; B3=1 -> CRC-Error ; B2=1 -> Lost Data ; B1 ; B0 MVERI .equ %00011000 ; Verify Sector ; B7 ; B6 ; B5 ; B4=1 -> Record not Found ; B3=1 -> CRC-Error ; B2 ; B1 ; B0 MSEEK .equ %11011000 ; Seek Track ; B7=1 -> not Ready ; B6=1 -> Write protect ; B5 ; B4=1 -> Record not Found ; B3=1 -> CRC-Error ; B2 ; B1 ; B0 ;************************************************************************* ; Definition der Konstanten ;************************************************************************* HEADIDLE .equ 15 ; Idle-Time fuer Kopf Ruhezeit (15msec) MAXTRY .equ $03 ; Maximale Anzahl der Verify-Versuche BELL .equ $07 ; ASCII BELL BS .equ $08 ; ASCII BACKSPACE CR .equ $0D ; ASCII WAGENRUECKLAUF LF .equ $0A ; ASCII ZEILENVORSCHUB DEL .equ $7F ; ASCII DELETE DRV_DELAY .equ 83 ; Drive Delay ; CPU-Takt: 2 MHz ; CPU-Takt: 4 MHz: 164 DRV_WAIT .equ 1000 ; Wartezeit fuer Motoranlauf ($0800) i.V.m. DRV_DELAY BLOCKSIZE .equ 4096 ; Blockgroesse IMASK .equ %00001110 ; Interrupt-Maske (RST 5.5 Enable) SPACE .equ $20 ; Leerzeichen JUMP .equ $C3 ; Mnemonic-Code für JMP RETURN .equ $C9 ; Mnemonic-Code für RET PRTOFF .equ $089F ; Printer Off-Flag SPS .equ $272E ; SPS-Einsprung SRET1 .equ $27E9 ; Marke im SPS-Programm CMDINP .equ $27F0 ; Marke im SPS-Programm CHROK .equ $2841 ; Marke im SPS-Programm ZULKMD .equ $28BE ; Marke im SPS-Programm BASIC .equ $3091 ; Basic-Neustart BASBUF .equ $8013 ; Basic Input-Buffer TXTUNF .equ $8064 ; Zeiger auf Basic-PGM-Ende + 1 TXTBGN .equ $806F ; Basic-Programm Anfangsadresse FBUFFER .equ $E000 ; Track-Buffer fuer Formatbefehl SPS_PT_END .equ $E003 ; PGMEND Zeiger auf SPS-Programmende SPS_RAM_PROG .equ $E0ED ; PGMANF SPS Programm-Anfangsadresse MONSTK .equ $FC80 ; [FEHLER] Monitor-Stack [FC80 statt $FC00] USRSTK .equ $FC32 ; USER-STACK-POINTER PRTST .equ $FC84 ; Printer-Status-Flag (Ein/Aus) RSTVEK .equ $FC95 ; RST 5.5 Sprung-Vektor BCKFLG .equ $FCC7 ; Flag fuer MAT85 CRTFLG .equ $FCC8 ; CRT / PRINTER-FLAG GROFLG .equ $FCC9 ; Flag fuer MAT85 M85BE .equ $FCF2 ; Ende MAT85-Input-Buffer PCWERT .equ $FCD7 ; MAT85: GO-Adresse DIRKOM .equ $FD16 ; Basic-Direktkommando-Flag STARTA .equ $FD6F ; Zwischenspeicher fuer Start-Adresse STOPA .equ $FD71 ; .. Stop-Adresse ;************************************************************************* ; Unterprogramm aus MAT85 ; KMD .equ $0040 ; MAT85-KMDRoutine RCHAR .equ $0043 ; Lese Zeichen in den Akku WCHAR .equ $0052 ; Zeichen im Akku ausgeben PHL .equ $005B ; HL als HEX-Wert ausgeben WBIN .equ $005E ; Akku als Binaerwert ausgeben WDEZ .equ $0061 ; Akku als Dezimalwert ausgeben PTXT .equ $006D ; Text ausgeben PTXTCR .equ $0073 ; Text ausgeben, vorher CR/LF EXEC .equ $01EB ; Kommando ausfuehren PSTAR .equ $0228 ; Print "***" + TEXT + "***" PKLIST .equ $03B8 ; Kommandoliste ausgeben SERO .equ $089F ;SERO PRT-Flag HSTART .equ $0A74 ; Hole Start-Adresse Ersatz durch die MAT85-Einsprungadressen WBLNKI .equ $0B93 ; Wiederhole " " X-Mal (Anzahl nach CALL) BUFCLR .equ $0CAA ; Loesche MAT85-Input-Buffer BREAD .equ $0D0A ; Lese Text aus Buffer Ersatz durch die MAT85-Einsprungadressen TEST .equ $0EB0 ; Pruefe ob Zeichen in einer Tabelle GROSS .equ $0EE9 ; Zeichen in Grossbuchstaben umwandeln SUB2 .equ $1039 ; HL=HL-DE ;************************************************************************* ; Unterprogramme aus SP1 ; HSTSPA .equ $215B ; Hole START/STOP-Adresse ;R4 .equ $31F4 ; CMPHD .equ $31F4 ; Vergleiche HL-DE CMPDH .equ $31FA ; Vergleiche DE-HL R5 .equ $320B ; Suche naechstes Zeichen ungleich " " CLEAR .equ $348C ; Loesche Basic-Programm und Variablen BCLEAR .equ $3FD6 ; Bildschirm loeschen ;************************************************************************* ; Labels fuer MINI-DOS-Erweiterungen ; SIEHE BESCHREIBUNG IN UMG ; L5000 .equ $5000 L5001 .equ $5001 L5004 .equ $5004 L5005 .equ $5005 L5008 .equ $5008 L5009 .equ $5009 L5010 .equ $5010 L500D .equ $500D L5800 .equ $5800 L5801 .equ $5801 L5804 .equ $5804 L5805 .equ $5805 L5808 .equ $5808 L5809 .equ $5809 L5810 .equ $5810 L580D .equ $580D ;************************************************************************* ; * ; ** ; *** ; ********************************** .ORG $4000 ; ******* MINI-DOS - ANFANGS-ADRESSE ; ********************************** ; *** ; ** ; * ;************************************************************************* ; ;DAS BFZ-MINI-DQS KANN VON MAT85, SPS UND BASIC AUS AUFGERUFEN WERDEN ;BEI UNBEKANNTEN BEFEHLEN (WIE Z.B. "F" FUER FLOPPY) PRUEFEN DIESE ;PROGRAMME, OB EINE ERWEITERUNG VORLIEGT. ; ;EIN BEISPIEL: ;GIBT MAN BEI SPS DEN BUCHSTABEN "F" ALS KOMMANDO EIN, ;SO PRUEFT DAS SPS-PROGRAMM. OB IN DER SPEICHERZEILE ;4003H DER WERT C3H STEHT (DIE ADRESSE 4003H IST IM ;SPS-PROGRAMM FEST VORGEGEBEN). C3H IST DER CODE FUER ;DEN SPRUNG-BEFEHL "JMP". FINDET SPS DIESEN CODE, SO ;VERZWEIGT ES ZU DER ADRESSE 4003H UND FUERT DEN DORT ;STEHENDEN SPRUNG-BEFEHL AUS. DIE PROGRAMME MATS5 UND ;BASIC PRUEFEN DIE SPEICHERZEILEN 4000H BZW. 4006H. ; ;************************************************************************* MAT85DOS: VEKT_FMAT: JMP FMAT ;WIRD FUER MAT85/MAT85+ BENOEGETIGT VEKT_FSPS: JMP FSPS ;WIRD FUER SPS BENOETIGT VEKT_FBAS: JMP FBAS ;WIRD FUER BASIC BENOETIGT ;************************************************************************* ;DAS BFZ-MINI-DOS ENTHAELT ZLEI UNTERPROGRAMME, DIE RELATIVE SPRUENGE UND ;RELATIVE UNTERPROGRAMM-AUFRUFE ERMOEGLICHEN. PROGRAMME , DIE NUR RELATIVE ;VERZWEIGUNGEN ENTHALTEN, SIND IN JEDEM SPEICHERBEREICH LAUFFAEHIG. ;"DIESE UNTERPROGRAMME "RELJMP" UND "RELCAL" VERAENDERN DEN INHALT DES ;HL—REGISTERPAARES. ;************************************************************************* ;ANWENDUNGS-BEISPIELE: ; RELATIVER UNTERPROGRAMM-AUFRUF ! RELATIVER SPRUNG ; .. ! .. ; LXI B, NACH-VON ! LXI B,NACH-VON ; CALL RELCAL. ! CALL REL JMP ;VON: .. ! VON: .. ; .. ! .. ;NACH: ;NTERPROGRAMM-ANFANG ! NACH: ;SPRUNG-ZIEL ; ;SIND DEM ASSEMBLER DIE WERTE "VON" UND "NACH" NICHT BEKANNT, MUSS ;DIE SUBTRAKTION VOM PROGRAMMIERER DURCHGEFUEHRT WERDEN. ;************************************************************************* RELCAL: JMP RCAL ;RELATIVER UNTERPROGRAMM-AUFRUF RELJMP: JMP RJMP ;RELATIVER SPRUNG ;************************************************************************* ;AUFRUF VON UNTERPROGRAMMEN NUTZT MAN IM ALLGEMEINEN DEN CALL-BEFEHL ;IN DER FORM " CALL 1234".. UNTERPROGRAMME IM BFZ-MINI-DOS KOENNEN EBENFALLS ;AUF DIESE ART AUFGERUFEN WERDEN„ IN EVEN TL. SPAETEREN BFZ-MINI-DOS-VERSIONEN ;KOENNEN DIESE UNTERPROGRAMME ABER EVENTUELL IN ANDEREN ADRESSBEREICHEN LIEGEN. ;DIE CALL-BEFEHLE VERZWEIGEN DANN NICHT MEHR ZUM RICHTIGEN UNTERPROGRAMM. ;ABHILFE KANN MAN DURCH DIE VERWENDUNG VON "FUNKTIONS-CODES" SCHAFFENS ;HIERBEI WIRD NUR NOCH EINE EINZIGE UEBERGEORDNETE ROUTINE AUF GERUFEN. ;LIEBER EINEN CODE (DEN FUNKTIONS-CODE) IM C-REGISTER DER CPU GIBT MAN ;DABEI ANw WELCHES UNTERPROGRAMM ABGEARBEITET WERDEN SOLL. DIE EINSPRUNG- ;ADRESSE DER UEBERGEQRDNETEN ROUTINE MUSS DABEI NATUERLICH IN SAEMTLICHEN ;VERSIONEN DES BFZ-MINI-DOS BEIBEHALTEN WERDEN. DIE EINSPRUNG-ADRESSEN DER ;ANDEREN UNTERPROGRAMME KOENNEN SICH ABER AENDERN. ;EIN ANWENDUNGS-BEISPIEL ; MVI C,FUNKTIONS-CODE ; FUNKTIONSCODE IN DAS C-REGISTER LADEN ; CALL ENTRY ; UEBERGEORDNETES PROGRAMM AUFRUFEN ;************************************************************************* ;DIE HEXADEZIMALEN FUNKTIONS-CODES FINDEN SIE IN DEM KOMMENTAR ZUR VEKTOR- ;TABELLE "VT AB" (S.U.). DIE FUNKTION DER EINZELNEN UNTERPROGRAMME ENTNEHMEN ;SIE BITTE DEREN BESCHREIBUNG IM PROGRAMM-LISTING ;************************************************************************* ENTRY: PUSH H PUSH D PUSH PSW ;DAS BFZ-MINI-DOS KANN ERWEITERT WERDEN. DIESE ERWEITERUNGEN ;KOENNEN EIGENE VEKTOR-TABELLEN "VTAB" BESITZEN. DAMIT DAS BFZ- ;MINI-DOS DIESE NEUEN TABELLEN VERWENDET. MUSS DIE ERWEITERUNG ;EINEN BESTIMMTEN CODE ENTHALTEN. ;SIE MUSS ENTWEDER IN DER SPEICHERZEILE 500CH (ERWEITERUNGS- ;STUFE 1) ODER IN DER SPEICHERZEILE 580CH (ERWEITERUNGSSTUFE 2) ;DEN WERT EDH (ERWEITERTES DOS) ENTHALTEN. FINDET DAS BFZ-MINI- ;DOS DIESEN WERT, SO VERWENDET ES DIE NEUE TABELLE. DIE TABELLE ;DER STUFE 2 IST DER STUFE 1 UEBERGEORDNET. DIE ERWEITERUNG MUSS ;DIE ANFANGS-ADRESSEN DER TABELLEN IN BESTIMMTEN SPEICHERZEILEN ;BEREITHALTEN: ; ERW-STUFE EDH-CODE IN TABELLEN-ADR IN ; 1 500C 500D,500E ; 2 500C 580D,580E ;DIE NEUEN TABELLEN MUESSEN DEN GLEICHEN AUFBAU BESITZEN, WIE ;DIE TABELLE "VTAB". LHLD L580D ;LADE ADR DER VEKTOR-TABELLE <ERWEIT. 2) LDA L580D - 1 ; LIEGT ERUEITERUNG VOR ? CPI $ed JZ TABOK ;JA —> TABOK LHLD L500D ;LADE ADR DER OEKTGR-TABELLE (ERWEIT. 1) LDA L500D - 1 ;LIEGT ERUEITERUNG VOR ? CPI $ed JZ TABOK ;JA —> TABOK LXI H,VTAB ;LADE- ADR DER VEKTOR-TABELLE (GRUNDVERSION) TABOK: MOV A,M ;A=MAX. FUNKTIONS-C0DE CMP C ;VERGLEICHE MIT CODE IN C-REGISTER JC VRET0 ;SPRINGE, WENN MAX-CODE UEBERSCHRITTEN MOV A,C ;FUNKTIONS-CODE NACH A VRET0: ADD A ;FUNKTIONS-CODE MAL ZWEI MVI D,$00 ;MSB (DE)=00 MOV E,A ;(Funktions-Code * 2) nach E INX H ;ZEIGER AUF 1. VEKTOR DER TABELLE DAD D ;ZEIGER AUF RICHTIGEN VEKTOR MOV E,M ;* VEKTOR NACH HL INX H ;* MOV D,M ;* XCHG ;* POP PSW ;RESTORE AKKU UND FLAGS POP D ;RESTORE DE-REGISTERPAAR XTHL ;HL=HL.ALT, STACK=VEKTOR VRET: RET ;SPRUNG ZUR AUFGERUFENEN FUNKTION ;************************************************************************* VTAB: .byte $11 ;MAXIMALER FUNKTIONS-CODE PLUS EINS (17) ;CODES SIND HEXADEZIMAL ANGEGEBEN .word RESTORE ;VEKTOR-TABELLE (CODE 00) .word STEPIN ; (CODE 01) .word SEEK ; (CODE 02) .word WSEC ; (CODE 03) .word RSEC ; (CODE 04) .word WTRK ; (CODE 05) .word VERIX ; (CODE 06) .word SELECT ; (CODE 07) .word DESEL ; (CODE 08) .word DREADY ; (CODE 09) .word DELAY ; (CODE 0A) .word REPCHR ; (CODE 0B) .word WAITSP ; (CODE 0C) .word INTINT ; (CODE 0D) .word TSTCHR ; (CODE 0E) .word LETTER ; (CODE 0F) .word TSTBS ; (CODE 10) .word VRET ; (CODE 11) ;************************************************************************* ;DIE ROUTINEN "RCAL" UND "RJMP" WERDEN BEI ANWENDUNG DER RELATIVEN ;VERZWEIGUNGEN (UNTERPROGRAMME "RELCAL" UND "RELJMP") AUFGERUFEN. ;************************************************************************* RCAL: POP H ;"VON" NACH HL. PUSH H ;RETTE RUECKSPRUNG-ADR PUSH H ;ZUM AUSGLEICH DES FOLGENDEN "POP'S" RJMP: POP H ;"VON" NACH HL DAD B ;ADDIERE OFFSET PCHL ;SPRINGE NACH "NACH" ;************************************************************************* ; DAS PROGRAMM VERZWEIGT ZU DIESER STELLE, WENN EIN UNBEKANNTES ; MAT85--KOMMANDO EINGEGEBEN WURDE. ;DAS BFZ-MINI--DOS KANN ERWEITERT WERDEN. DIESE ERWEITERUNG KANN IN DER ;SPEICHERZEILE 5OOOH (ERWEITERUNGSSTUFE 1 > ODER 5800H (ER WEITERUNGS- ;STUFE 2) DEN WERT EDH ENTHALTEN. DAS PROGRAMM PRUEFT IM UNTERPROGRAMM ;"UMG", OB DIESER WERT VORLIEGT. DABEI IST DIE STUFE 2 DER STUFE 1 UEBER- ;GEORDNET. WIRD EDH GEFUNDEN, SO VERZWEIGT DAS UNTERPROGRAMM "UMG". DIE ;RUECKSPRUNG—ADRESSE BLEIBT DABEI IM STACK! ; ERW-STUFE EDH-GEFUNDEN BEI "UMG" VERZWEIGT NACH ; 1 5000 5001 ; 2 5800 5801 ; ; BEI 5001 BZW 5801 MUSS EIN SPRUNGBEFEHL STEHEN! ;************************************************************************* FMAT: LXI H,L5800 ;ADRESSE DES 2. UMGEHUNGS-FLAGS CALL UMG ;SPRINGE, WENN UMGEHUNGS-FLAG GESETZT FX: MOV A,C ;EINGABE-ZEICHEN NACH A CPI "F" ;FLOPPY? JZ FM ;JA -> FM ;************************************************************************* ;HIER, WENN NICHT "F" ;************************************************************************* LDA L5001 ;MAT85-ERWEITERUNG AB 5001H CPI JUMP ;* JZ L5001 ;JA -> 5001H RET ;NEIN —> RETURN (FEHLER) ;************************************************************************* ;HIER WENN "F" ;************************************************************************* FM: LXI H,$0000 ;VORSCHLAGS-ADRESSE SHLD STARTA ;START/STOP AUF SHLD STOPA ;0000H SETZEN ;************************************************************************* ;RAM-VEKTOREN VERAENDERH ;************************************************************************* MVI A,JUMP ;JMP-OPCODE STA XSTSP ;EINSETZEN STA XLAD1 ; STA XLAD2 LXI H,GSTSP ;ADRESSE SHLD XSTSP+1 ;EINSETZEN LXI H,GSTART SHLD XLAD1+1 LXI H,MATLAD SHLD XLAD2+1 MVI A,RETURN ;RETURN OPCODE STA XSAV1 ;EINSETZEN LXI H,KMD ;SRUNGZIEL FUER DOS-QUIT: KMD MVI A,1 ;FLAG: DOS-AUFRUF VON MAT85 JMP DOS1 ;************************************************************************* ;DIESES UNTERPROGRAMM WIRD VOM DOS BEIM LADEN VON PROGRAMMEN AUFGERUFEN, ;WENN DAS DOS VON MAT85 AUS AUFGERUFEN WURDE. ;************************************************************************* MATLAD: LHLD STARTA ;START-ADRESSE SHLD PCWERT ;ALS GO-ADRESSE EINSETZEN RET ;************************************************************************* ;DAS BFZ-MINI-DOS KANN ERWEITERT WERDEN. DIESE "ERWEITERUNG KANN IN DER ;SPEICHERZEILE 5004H (ERWEITERUNGSSTUFE 1) ODER IN DER SPEICHERZEILE ;5804H (ERWEITERUNGSSTUFE 2) DEN WERT EDH ENTHALTEN. ;DAS PROGRAMM PRUEFT IM UNTERPROGRAMM "UMG", OB DIESER WERT VORLIEGT. ;WIRD EDH GEFUNDEN, SO VERZWEIGT DAS UNTERPROGRAMM "UMG". DIE RUECK- ;SPRUNGADRESSE BLEIBT DABEI IM STACK! ; ERW-STUFE EDH-GEFUNDEN BEI "UMG" VERZWEIGT NACH ; 1 5004 5005 ; 2 5804 5805 ; ;BEI 5005 BZW- 5805 MUSS EIN SPRUNGBEFEHL STEHEN! ;************************************************************************* FSPS: LXI H,L5804 ;ADR DES 2. UMGEHUNGS-FLAGS CALL UMG ;SPRINGE, WENN UMGEHUNGS-FLAG GESETZT ;************************************************************************* ;FSPS KANN VON MAT85+SPS UND DER EPROMMER-SOFTWARE AUS AUFGERUFEN ;WERDEN. ES MUSS FESTGESTELLT WERDEN, OB DER AUFRUF VON SPS AUS ERFOLGTE. ;DIES IST Z.B. MOEGLICH, INDEM MAN PRUEFT, OB "ZULKMD" IM STACK STEHT. ;************************************************************************* POP H ;WERT AUS STACK PUSH D ;RETTE EINGABE-ZEICHEN (D) LXI D,ZULKMD ;ZEIGER AUF TABELLE DER ZULAESSIGEN ;KOMMANDOS (MAT85+ SPS) CALL CMPHD ;HL=DE? POP D ;RESTORE EINGABE-ZEICHEN (D) PUSH H ;WERT ZURUECK IN DEN STACK JNZ SP1EXP ;HL <> DE -> SP1EXP ;************************************************************************* ;HIER, WENN DER AUFRUF VON SPS AUS ERFOLGTE ;************************************************************************* MOV A,D ;EINGABEZEICHEN NACH A CPI "F" ;FLOPPY ? JZ SPSDOS ;JA -> SPS-DOS ;************************************************************************* ;HIER, WENN DER AUFRUF NICHT VON SPS AUS ERFOLGTE ;ODER WENN NICHT "F" EINGEGEBEN WURDE. ;************************************************************************* SP1EXP: LDA L5005 ;SPS ERWEITERUNG AB 5005H ? CPI JUMP ; JNZ CHROK ;FEHLER (Z-FLAG = 0 !) JMP L5005 ;JA —> 5005H ;************************************************************************* ;HIER, WENN DER AUFRUF VON SPS AUS ERFOLGTE ;UND "F" EINGEGEBEN WURDE. ;************************************************************************* SPSDOS: CALL PTXT ;PRINT "F" .byte "F",$0 SDOSO: CALL RCHAR ;LESE ZEICHEN VON TASTATUR CPI CR ;CR JZ SDOS ;JA -> SDOS CALL TSTBS ;PRINT BS,SPACE,BS WENN BS ODER DEL JNZ SDOSO ;WEDER BS NOCH DEL -> SDOS0 ;************************************************************************* ;HIER, WENN BS ODER DEL EINGEGEBEN WURDE ;************************************************************************* SD1: DI ;DISABLE INTERRUPT POP H ;HL-ZEIGER AUF ZUL. EINGABE-ZEICHEN (SPS) SD2: LXI SP,USRSTK ;REINIT STACKPOINTER ;[P01#03] Originalcode: LXI SP,$FC00 SD3: LXI B,SRET1 ;RUECKSPRUNG-ADR SD4: PUSH B ; IN DEN STACK JMP CMDINP ; GEBE NEUES KOMMANDO EIN (CMDINP) ;************************************************************************* ;HIER, WENN DER AUFRUF VON SPS AUS ERFOLGTE ;UND DIE EINGABE "F" MIT <CR> ABGESCHLOSSEN WURDE ; ;DAS PROGRAMM AENDERT NUN RAM-VEKTOREN ;************************************************************************* SDOS: ; Vormals Teil von SDOS, Routine wird oefters benutzt ; und deshalb als Unterprogramm ausgelagert MVI A,RETURN ;RET-OPCODE EINSETZEN ; DOS Vektoren setzen fuer externe Programme STA XSTSP ;EINSETZEN MVI A,JUMP ;JMP -OPCODE STA XSAV1 ;EINSETZEN STA XLAD1 STA XLAD2 LXI H,LENSPS ;ADRESSE EINSETZEN SHLD XSAV1+1 LXI H,SLAD1 SHLD XLAD1+1 LXI H,SLAD2 SHLD XLAD2+1 LXI H,SPS_RAM_PROG ; Lade SPS-Speicher Anfangs-Adresse SHLD STARTA ; Anfangsadresse abspeichern LHLD SPS_PT_END ; Lade SPS-Speicher End-Adresse SHLD STOPA ; Endadresse abspeichern LXI H,SPS ; Ruecksprungvektor fuer DOS-Ende MVI A,2 ; FLAG: DOS-AUFRUF VON SPS (Dateityp 2 = SPS) JMP DOS1 ; Einsprung ins DOS ;************************************************************************* ;DIE FOLGENDEN DREI UNTERPROGRAMME WERDEN VOM BFZ-MINI-DOS AUS AUFGERUFEN ; ;TEST, OB SPS-PROGRAMMSPEICHER LEER.. (BEI "SAVE") ;************************************************************************* LENSPS: LHLD SPS_PT_END ;PROGRAMM-SPEI CHER LEER? LXI D,SPS_RAM_PROG ; CALL CMPHD ; CZ CODE16 ;JA —> CODE16 RET ;************************************************************************* ;LOESCHE. ALTES SPS-PROGRAMM IM SPEICHER. (BEI "LOAD") ;************************************************************************* SLAD1: LXI H,SPS_RAM_PROG ;LOESCHE ALTES PROGRAMM MVI M,$FF ; SHLD SPS_PT_END ; RET ;************************************************************************* ;UEBERNEHME NEUE SPS-PROGRAMM-STOPADRESSE. (BEI "LOAD") ;************************************************************************* SLAD2: LHLD STOPA ;UEBERTRAGE NEUE STOP-ADR SHLD SPS_PT_END ; RET ;************************************************************************* ; DAS PROGRAMM VERZWEIGT ZU DIESER STELLE, WENN EIN UNBEKANNTES ; BASIC-KOMMANDO EINGEGEBEN WURDE. ;DAS BFZ—MINI—DOS KANN ERWEITERT WERDEN. DIESE ERWEITERUNG KANN IN DER ;SPEICHERZEILE 5008H (ERWEITERUNGSSTUFE 1) ODER IN DER SPEICHERZEILE ;580SH (ERWEITERUNGSSTUFE 2) DEN WERT EDH ENTHALTEN. ;DAS PROGRAMM PRUEFT IM UNTERPROGRAMM "UMG", OB DIESER WERT VORLIEGT. ;DABEI IST DIE STUFE 2 DER STUFE 1 UEBERGEORDNET. WIRD EDH GEFUNDEN, ;SO VERZWEIGT DAS UNTERPROGRAMM "UMG"- DIE RUEGKSPRUMGADRESSE BLEIBT ;DABEI IM STACK! ; ; ERW-STUFE EDH-GEFUNDEN BEI "UMG" VERZWEIGT NACH ; 1 5008 5009 ; 2 5808 5809 ; ;************************************************************************* ;BEI 5009 BZW 5809 MUSS EIN SPRUNGBEFEHL STEHEN! ;************************************************************************* FBAS: LXI H,L5808 ;ADRESSE DES 2. UMGEHUNGS-FLAGS CALL UMG ;SPRINGEv WENN UMGEHUNGS-FLAG GESETZT ;************************************************************************* ;DAS BASIC-KOMMANDO "FLOPPY" IST NUR IM DIREKT—MODUS (NICHT IN EINEM ;PROGRAMM) ZULAESSIG. ES MUSS GEPRUEFT WERDEN, OB DER DIREKT-MODUS ;VORLIEGT. ;************************************************************************* LDA DIRKOM ;DIREKT-KOMMANDO ? ORA A ; JNZ BASEXP ;NEIN —> BASEXP ;************************************************************************* ;DER DIREKT-MODUS LIEGT VOR. WURDE ABER AUCH "FLOPPY" EINGEGEBEN ? ;************************************************************************* LXI H,BASBUF ;ZEIGT DE AUF BASIC-INPUT-BUFFER ? CALL CMPHD ; JNZ BASEXP ;NEIN —> BASEXP LXI H,FLOPPY ;ZEIGER AUF "FLOPPY " (VERGLEICHSTEXT) MVI B,6 ;6 ZEICHEN PRUEFEN PBAS: LDAX D ;ZEICHEN AUS BUFFER NACH A CMP M ;VERGLEICHE MIT ZEICHEN AUS "FLOPPY" JNZ BASEX0 ;UNGLEICH —> BASEX0 INX D ; STELLE ZEIGER WEITER INX H ; DCR B ;6 ZEICHEN GEPRUEFT ? JNZ PBAS ;NEIN —> PBAS ;************************************************************************* ;HIER, WENN "FLOPPY" EINGEGEBEN WURDE.# ;FOLGEN WEITERE ZEICHEN ? ;(JA —> GILT IN DER JETZIGEN VERSION NICHT ALS BFZ-MINI-DOS-AUFRUF) ;IST DIE EINGABE MIT CR ABGESCHLOSSEN? ;************************************************************************* CALL R5 ;WELCHES ZEICHEN (AUSSER " ") FOLGT ? CPI CR ;CR ? JZ BDOS ;JA -> BDOS BASEX0: LXI D,BASBUF ;ZEIGER AUF ANFANG DES INPUT-PUFFERS BASEXP: LDA L5009 ; BASIC ERWEITERUNG AB 5009H ? CPI JUMP ; * RNZ ;NEIN —> RETURN (FEHLER) JMP L5009 ;JA —> 5009H ;************************************************************************* ;VERGLEICHS-TEXT (FLOPPY-BEFEHL) ;************************************************************************* FLOPPY: .byte "FLOPPY" ;FLOPPY-BEFEHL (BASIC-BEFEHL) ;************************************************************************* ;HIER, WENN "FLOPPY" OHNE WEITERE ZEICHEN IM DIREKTMODUS EINGEGEBEN WURDE ; ;DAS PROGRAMM VERAENDERT RAM-VEKTOREN! ;************************************************************************* BDOS: MVI A,RETURN ;RET -OPCODE STA XSTSP ;EINSETZEN MVI A,JUMP ;JMP-OPCODE STA XSAV1 ;EINSETZEN STA XLAD1 STA XLAD2 LXI H,CHKLEN ;ADRESSE EINSETZEN SHLD XSAV1+1 LXI H,BLAD1 SHLD XLAD1+1 LXI H,BLAD2 SHLD XLAD2+1 LXI H,TXTBGN ;PROGRAMM-ANFANG SHLD STARTA ;EINSETZEN LHLD TXTUNF ;PROGRAMM-ENDE DCX H ; Ende - 1 SHLD STOPA ;EINSETZEN LXI H,BASIC ;SPRUNGZIEL FUER DOS-"QUIT": BASIC MVI A,3 ;FLAGS DOS-AUFRUF VON BASIC (Dateityp 3 = BAS) JMP DOS1 ;RUFE DOS AUF ;************************************************************************* ;DIE FOLGENDEN DREI UNTERPROGRAMME WERDEN VOM BFZ-MINI-DOS AUFGERUFEN ; ;TEST, OB BASIC-PROGRAMMSPEICHER LEER (BEI "SAVE") ;************************************************************************* CHKLEN: LHLD TXTUNF ;PROGRAMM -SPEICHER LEER ? LXI D,TXTBGN ; CALL CMPHD CZ CODE16 ; JA -> CODE16 RET ;************************************************************************* ;LOESCHE ALTES BASIC-PROGRAMM IM SPEICHER (BEI "LOAD") ;************************************************************************* BLAD1: CALL CLEAR ;LOESCHE ALTES PROGRAMM RET ;************************************************************************* ;UEBERNEHME NEUE BASIC-PROGRAMM-STOPADRESSE (BEI "LOAD") ;************************************************************************* BLAD2: LHLD STOPA ;UEBERTRAGE NEUE STOP-ADR INX H SHLD TXTUNF RET ;************************************************************************ ;* * ;* DOS-INITIALISIERUNGS-TEIL * ;* * ;************************************************************************ DOS1: LXI SP,USRSTK ;(RE)-INIT SP DOS2: CALL BCLEAR ;LOESCHE BILDSCHIRM DOS3: STA EFROM ;RETTE FLAG (ENTERED FROM) DOS4: SHLD DOSRET ;RETTE SPRUNGZIEL FUER "QUIT" ; ;DAS BFZ-MINI-DOS KANN ERWEITERT WERDEN. DIESE ERWEITERUNG ;KANN EINE EIGENE INFO-TABELLE HABEN (S.U.). DAMIT DAS BFZ- ;MINI-DOS DIE NEUE INFO-TABELLE VERWENDET, MUSS DIE ERWEITERUNG ;ENTWEDER IN DER SPEICHERZEILE 500FH (ERWEITERUNGSSTUFE 1) ODER ;IN DER SPEICHERZEILE 580FH (ERUIEITERUNGSSTUFE 2) DEN WERT EDH ;ENTHALTEN. DAS PROGRAMM SUCHT NACH DIESEM WERT. BEI DER SUCHE ;IST STUFE 2 DER STUFE 1 UEBERGEORDNET. WIRD EDH GEFUNDEN, SO ;WIRD DIE INFO-TABELLE AUS DER ERWEITERUNG VERWENDET. DIE INFO- ;TABELLE SELBST MUSS DEN GLEICHEN AUFBAU HABEN WIE DIE TABELLE ;IN DER BFZ-MINI-DOS-GRUNDVERSION. DIE ZWEI SPEICHERZEILLEN, ;DIE DEM ED-CODE FOLGEN, MUESSEN DIE ADRESSE DER INFO-TABELLE ;ENTHALTEN: ; ERW-STUFE EDH-GEFUNDEN BEI "UMG" VERZWEIGT NACH ; 1 500F 5010,5011 ; 2 580F 5810,5811 ; LHLD L5810 ;ADR DER INFO-TABELLE (STUFE 2) LDA L5810 - 1 ; DOS-EEWEITERUNG AB 580FH ? CPI $ED ; STUFE 2 JZ DOS ;JA — > DOS (TABELLE STUFE 2) LHLD L5010 ;ADR DER INFO-TABELLE (STUFE 1) LDA L5010 - 1 ; DOS-EEWEITERUNG AB 500FH ? CPI $ED ; STUFE 2 JZ DOS ;JA — > DOS (TABELLE STUFE 1) LXI H,INFOT ;ADR DER INFO-TABELLE (GRUNDVERSION) ;************************************************************************* ;DAS PROGRAMM ENTNIMMT DER INFO-TABELLE NUN MEHRERE ANGABEN ; ;1. ZEIGER AUF TYP-TABELLE (TABELLE DER FILE-TYPEN WIE: MAT, SPS, BAS) ;************************************************************************* DOS: MOV E,M ;LADE ZEIGER AUF TYP-TABELLE INX H ;NACH HL MOV D,M ; INX H ; XCHG ; SHLD PTYPT ;RETTE ZEIGER AUF TYP-TABELLE ;************************************************************************* ;2. ZEIGER AUF ERROR-VEKTOR-TABELLE (WELCHE MELDUNG BEI WELCHEM FEHLER) ;************************************************************************* XCHG ;LADE ZEIGER AUF ERROR-VEKTOR-TABELLE MOV E,M ;NACH HL INX H ; MOV D,M ; INX H ; XCHG ; SHLD PEVT ;RETTE ZEIGER AUF ERROR-VEKTOR-TABELLE ;************************************************************************* ;3. VERSIGNS-NUMMER ;************************************************************************* XCHG ; SHLD PVNR ;RETTE ZEIGER AUF VERSIONSNUMMER ;************************************************************************* ;4. TABELLE DER ZULAESSIGEN EINGABE-ZEICHEN ;************************************************************************* INX H ;STELLE ZEIGER AUF TABELLE DER INX H ;ZULAESSIGEN EINGABE-ZEICHEN SHLD PTZZ ;RETTE ZEIGER ;************************************************************************* ;5. ZEIGER AUF KOMMANDO-TABELLE (WELCHE ROUTINE BEI WELCHER EINGABE) ;************************************************************************* DOS5: MOV A,M ;SUCHE NACH ENDE DER TABELLE INX H ;DER ZULAESSIGEN EINGABE-ZEICHEN ORA A ; JNZ DOS5 ; SHLD PMENUE ;RETTE ZEIGER AUF KOMMANDO-TABELLE ;************************************************************************* ;TRITT BEI DER AUSFUEHRUNG EINES KOMMANDOS EIN FEHLER AUF, SO VERZWEIGT ;DAS PROGRAMM NACH "XERR" IM RAM. DORT WIRD AN DIESER STELLE EIN SPRUNG ;NACH "ERROR" EINGESETZT. ;************************************************************************* MVI A,JUMP ;SETZE "JMP ERROR" EIN STA XERR ; LXI H,ERROR ; SHLD XERR+1 ; ;************************************************************************* ;DAS BFZ-MINI-DOS MELDET SICH NUN ;************************************************************************* CALL PTXTCR ;PRINT TEXT .byte LF,"BFZ-MINI-DOS V",00 LHLD PVNR ;ZEIGER AUF VERSIONS-NUMMER MOV A,M ;GEBE 1. ZIFFER DER CALL WCHAR ;VERSIONS-NUMMER AUS MVI A,"." ;GEBE "." AUS CALL WCHAR ; INX H ;GEBE 2. ZIFFER DER MOV A,M ;VERSIONS-NUMMER AUS CALL WCHAR ; CALL PTXTCR ;PRINT TEXT .byte LF,"(C) 1985 BY BFZ, ESSEN, W. GERMANY",00 ;ORIGINAL-CODE AN DIESER STELLE: .byte 00,00,00,00,00,00,00 ;Nicht zwingend erforderlich ;************************************************************************* ;TRITT EIN FEHLER AUF, SO ARBEITET DAS DOS DIE "ERROR"—ROUTINE AB. ;DIESE ENDET MIT EINEM SPRUNG ZU DER ADRESSE, DIE UNTER "ERRRET" IM ;RAM STEHT. DAS PROGRAMM TRAEGT HIER "MENUE" EIN. ;************************************************************************* MENUE: DI ;INTERRUPT DEAKTIVIEREN LXI H,MENUE ;RETURN-ADR VON ERROR SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;AUSGABE DES MENUES ;************************************************************************* CALL PTXTCR ;PRINT TEXT .byte LF,"MENUE:",LF,CR,00 LHLD PMENUE ;ZEIGER AUF KOMMANDO-TABELLE CALL PKLIST ;GEBE TABELLE AUS ;************************************************************************* ;LESE EINGABE ;************************************************************************* ;DOSKMD: CALL GETCHR ;LESE ZEICHEN LHLD PTZZ ;ZEIGER AUF TABELLE DER ZULAESSIGEN ZEICHEN CALL TEST ;ZEICHEN UNGUELTIG? CC CODE0 ;NEIN -> CODE 0 ;************************************************************************* ;HIER, WENN EINGABEZEICHEN GUELTIG ;************************************************************************* MOV C,A ;ZEICHEN NACH C LHLD PMENUE ;ZEIGER AUF KOMMANDO-TABELLE JMP EXEC ;FUEHRE KOMMANDO AUS ;************************************************************************* ;INFO-TABELLE DER GRUNDVERSION ;************************************************************************* INFOT: .word TYPT ;ZEIGER AUF TYP-TABELLE .word ERRVEK ;ZEIGER AUF ERROR-VEKTOR-TABELLE INFOTV: DOSVER: .byte "14" ;14 wird vom Editor geprueft! .byte "DEFLSQ" ;TABELLE DER ZULAESSIGEN ZEICHEN .byte 00 ;KOMMANDO-LISTE ;AUFBAU: ;1. KOMMANDO-NAME ;2. 00H ;3. ADR DER ROUTINE, DIE BEI EINGABE DES KOMMANDOS ; ABGEARBEITET WERDEN SOLL .byte "DIRECTORY",00 ;DIR .word DIR .byte "ERASE",00 ;ERASE .word ERASE .byte "FORMAT",00 ;FORMAT .word DSKFORM .byte "LOAD",00 ;LOAD .word DSKLOAD .byte "SAVE",00 ;SAVE .word DSKSAVE .byte "QUIT",00 ;QUIT .word QUIT .byte 00 ; KOMMANDO-TABELLE MUSS MIT 00 BEENDET WERDEN. ;************************************************************************* ; ;DOS-BEFEHL QUIT ; ;************************************************************************* ;HIER, WENN "Q" QUIT EINGEGEBEN WURDE ;************************************************************************* QUIT: LHLD DOSRET ;LADE RUECKSPRUNG-ADR PCHL ;BEENDE BFZ-MINI-DOS ;************************************************************************* ; ;DOS-BEFEHL DIR ; ;************************************************************************* ;HIER, WENN "D" QUIT EINGEGEBEN WURDE ;************************************************************************* ;TRITT EIN FEHLER AUF, SO ARBEITET DAS DOS DIE ROUTINE "ERROR" AB. ;DIESE ENDET MIT EINEM SPRUNG ZU DER ADRESSE, DIE UNTER "ERRRET" IM ;RAM STEHT. DAS PROGRAMM TRAEGT HIER "DIRE" EIN. ;************************************************************************* DIR: LXI H,DIRE ;RETURN-ADR VON ERROR SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;VON WELCHEM LAUFWERK SOLL DAS DIRECTORY ANGEZEIGT WERDEN? ;************************************************************************* DIRE: CALL LAUFW ;LESE LAUFWERK-NAME ;PRUEFE IHN ;BERECHNE SELECT-MASKE ;************************************************************************* ;BEI FEHLERN IM WEITEREN PROGRAMM-ABLAUF RUECKKEHR NACH "MENUE" ;************************************************************************* LXI H,MENUE ;RETURN-ADR VON ERROR SHLD ERRRET ;ABSPEICHERN CALL PTXT ;PRINT 2 x LINE-FEED .byte LF,LF,00 ; MVI A,$01 ;SETZE FLAG: "DISPLAY DIRECTORY" STA DSPLD CALL LINE1 ;PRINT UEBERSCHRIFT, INIT ZEICHENZAEHLER CALL SEINTR ;LESE DIRECTORY UND ZEIGE EINTRAEGE AN CPI 79 ;79 FREIE EINTRAEGE? JNZ NLEER ;NEINE -> NLEER (NICHT LEER) ;************************************************************************* ;HIER, WENN DIRECTORY LEER ;************************************************************************* LHLD PRTST ;LADE AKTUELLES DRUCKER "FLAG" PUSH H ; RETTE HL (FLAG) LXI H,SERO ;DRUCKER-AUS-FLAG // LXI H,$089F ; PRTOFF ???? // ; Muesste geaendert werden da ser-io ; bei Drucker nicht richtig funktioniert! SHLD PRTST ;SETZE FLAG EIN (DRUCKER AUS) CALL PTXT ;GEBE STEUERZEICHEN AUS .byte $0b," ",CR,00 ;LOESCHE KOPFZEILE POP H ;ALTES DRUCKER-FLAG HOLEN SHLD PRTST ; WIEDERHESTELLEN CALL PTXT ;TEXT AUSGEBEN .byte "*** KEIN EINTRAG IM DIRECTORY ***",LF,LF,CR,00 ;************************************************************************* ;HIER, WENN DIRECTORY NIGHT LEER ;BZW. WENN "KEIN EINTRAG IM DIRECTORY" AUSGEGEBEN WURDE ;ANZEIGE DER FREIEN 4K-BYTE—BLOECKE ;************************************************************************* NLEER: CALL CRLF ;PRINT CR,LF CALL WDEZ ;PRINT ANZAHL CALL PTXT ;TEXT AUSGEBEN .byte " FREIE 4K-BYTE-BLOECKE",LF,CR,00 ;************************************************************************* ;BEENDE ROUTINE ;DIE ROUTINE WIRD DURCH "JMP ERR0R2" BEENDET, OBWOHL KEIN FEHLER ;AUFGETRETEN IST. ES WERDEN BEFEHLE IN DER "ERROR"-ROUTINE GENUTZT ;UND DADURCH SPEICHERPLATZ GESPART. ;************************************************************************* JMP ERROR2 ;DESELECT LAUFWERK ;WARTE, BIS SPACE EINGEGEBEN WURDE ;************************************************************************* ; ;DOS-BEFEHL ERASE ; ;************************************************************************* ;HIER, WENN "E" ERASE EINGEGEBEN WURDE ; ;TRITT EIN FEHLER AUF, SO VERZWEIGT DAS BFZ-MINI-DOS ZU DER ROUTINE ;"ERROR"- DIESE WIRD MIT EINEM SPRUNG ZU DER ADRESSE BEENDET, DIE ;UNTER "ERRRET" IM RAM STEHT. DAS PROGRAMM TRAEGT HIER "ERERR" ;(ERASE-ERROR) EIN.. ;************************************************************************* ERASE: LXI H,ERERR ;RETURN-ADR VON ERROR SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;AUF WELCHEM LAUFWERK SOLL GELOESCKT WERDEN ? ;************************************************************************* ERERR: CALL LAUFW ;LESE LAUFWERKSNAME ;************************************************************************* ;BEI FEHLERN IM WEITEREN PROGRAMMABLAUF RUECKKEHR NACH "MENUE" ;************************************************************************* LXI H, MENUE ;RETURN-ADRESSE VON ERROR SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;START DES LOESCHVORGANGS ;FILE—EINTRAG IM DIRECTORY SUCHEN ;************************************************************************* XRA A ;LOESCHE FLAG STA DSPLD ;—> DIRECTORY NICHT ANZEIGEN CALL GETNAM ;LESE FILE-NAME CALL SEINTR ;SUCHE EINTRAG ;************************************************************************* ;WIEVIELE DIRECTORY—EINTRAEGE BESITZT DER FILE ? ;(NULL EINTRAEGE = FILE NICHT IM VERZEICHNIS) ;************************************************************************* LDA ZAEHLV ;ANZAHL DER ZU LOESCHENDEN EINTRAEGE ORA A ;NULL? CZ CODE11 ;JA —> FILE NICHT IM VERZEICHNIS ;************************************************************************* ;BEIM LOESCHEN (ERASE) WIRD NICHT DER EIGENTLICHE FILE GELOESCHT ;ES WIRD IM DIRECTORY-EINTRAG NUR EIN BYTE VERAENDERT ;(AUFBAU DES DIRECTORY'S: SIEHE UNTERPROGRAMM "SEINTR") ;DAZU MUSS AUF DIE DISKETTE GESCHRIEBEN WERDEN ;************************************************************************* CALL RESTORE ;KOPF IST SCHON AUF SPUR NULL ;DIENT NUR ZUR AKTUALISIERUNG ;DES FDC-STATUS-REGISTERS ANI %10011100 ;ALLES OK ? CPI %00000100 ; CNZ CODE1 ;NEIN —> CODE1 MOV A,E ;STATUS ERNEUT NACH A ANI %01000000 ;WRITE PROTECT ? CNZ CODE4 ;JA —> CODE4 ;************************************************************************* ;DER EIGENTLICHE LOESCHVORGANG WIRD VOM UNTERPROGRAMM "DELETE" AUSGEFUEHRT ;************************************************************************* LDA ZAEHLV ;ANZAHL DER ZU LOESCHENDEN EINTRAEGE CALL DELETE ;DELETE EINTRAEGE ;************************************************************************* ;LOESCHVORGANG BEENDET ;************************************************************************* CALL PSTAR ;TEXT AUSGEBEN .byte "FILE GELOESCHT",00 ;************************************************************************* ;ROUTINE BEENDEN ;DIE ROUTINE WIRD DURCH EINEN SPRUNG NACH "ERET" BEENDET OBWOHL KEIN ;FEHLER AUFGETRETEN IST. DURCH DIE NUTZUNG EINIGER BEFEHLE DER "ERROR"- ;ROUTINE WIRD SPEICHERPLATZ GESPART ;************************************************************************* JMP ERET ;FERTIG ;************************************************************************* ;DOS-BEFEHL FORMAT ;HIER, WENN "F" FORMAT EINGEGEBEN WURDE ;************************************************************************* DSKFORM: LXI SP,USRSTK ;RE-INIT STACKPOINTER ;************************************************************************* ;WENN EIN FEHLER AUFTRITT, WIRD DIE ROUTINE "ERROR" ABGEARBEITET., DIESE ;ENDET MIT EINEM SPRUNG ZU DER ADRESSE, DIE UNTER "ERRRET" IM RAM STEHT- ;DAS PROGRAMM SETZT HIER "F0RM1" EIN. ;************************************************************************* LXI H,FORM1 ;RETURN-ADR VON ERROR-ROUTINE SHLD ERRRET ;ABSPEICHERN ;WARNUNG AUSGEBEN CALL PTXTCR ;TEXT AUSGEBEN .byte 07,LF .byte "A C H T U N G !",LF,CR .byte "PROGRAMME IM BEREICH E000 - FFFF (Z. B. SPS)",LF,CR .byte "UND DATEN AUF DER DISKETTE WERDEN ZERSTOERT !",00 ;************************************************************************* ;IN WELCHEM LAUFWERK SOLL FORMATIERT WERDEN ? ;************************************************************************* FORM1: CALL LAUFW ;LAUFWERK-NAME EINLESEN, MASKE ERSTELLEN ;BITTE DISKETTE EINLEGEN CALL PTXTCR ;TEXT AUSGEBEN .byte "DISKETTE IN LAUFWERK ",$22,$00 LDA CHAR ;LAUFWERK-BUCHSTABE NACH A CALL WCHAR ;PRINT BUCHSTABE CALL PTXT ;TEXT AUSGEBEN .byte $22,", DANN <SPACE>",00 CALL WAITSP ;WARTEN, BIS <SPACE> EINGEBEN WURDE CALL CRLF ;PRINT CR,LF MVI D,40 ;40 STRICHE (LINIE) CALL PLINE ;AUSGEBEN ;************************************************************************* ;LAUFWERK SELEKTIEREN ;************************************************************************* XRA A ;SEITE = 0 STA SEITE ; CALL SELECT ; SELECT LAUFWERK ;************************************************************************* ;"ERRRET" MUSS ERNEUT MIT "FORM!" GELADEN WERDEN. ;DA DER WERT DURCH EIN UNTERPROGRAMM VERAENDERT WURDE. ;************************************************************************* LXI H,FORM1 ;RETURN-ADR VON ERROR-ROUTINE SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;LAUFWERK BEREIT? ;************************************************************************* CALL DREADY ;LAUFWERK BEREIT ? CC CODE3 ;FEHLER, WENN LAUFWERK NICHT BEREIT ;************************************************************************* ;INITIALISIERUNG DER INTERRUPT-ROUTINE ;(DAS BFZ—MINI—DOS NUTZT DIE FDC—SIGNALE "DRQ" UND "INTRQ" ZUR ;SYNCHRONISIERUNG DER DATENUEBERTRAGUNG). ;************************************************************************* CALL INTINT ;INTERRUPT-ROUTINE INITIALISIEREN ;************************************************************************* ;KOPF AUF SPUR 0 ;************************************************************************* CALL RESTORE ;RESTORE ANI %01000000 ;WRITE PROTECT ? CNZ CODE4 ;JA -..........> FEHLER-MELDUNG MOV A,E ;STATUS NACH A ANI %11000100 ;ALLES OK ? CPI %00000100 ; CNZ CODE1 ;NEIN —> RESTORE ERROR LXI H,HEADIDLE ;15 MS VERZOEGERUNG, DAMIT DER KOPF CALL DELAY ;NACH RESTORE RUHIG STEHT ;************************************************************************* ;TRACK IM RAM AUFBAUEN ;************************************************************************* LXI H,VERTAB ;INIT ZEIGER AUF VERSATZTABELLE MOV E,M ;LESE ERSTEN EINTRAG SHLD VERPTR ;RETTE POINTER LXI H,FBUFFER ;ZEIGER AUF TRACK BUFFER ;************************************************************************* ;SPUR-VORSPANN ;"VOR--GAP" ;************************************************************************* MVI A,$4E ;80 * 4Eh MVI B,80 ; CALL REPCHR ; MVI A,0 ;12 * 00h MVI B,12 ; CALL REPCHR ; MVI A,$F6 ;3 * F6h (SCHREIBT C2, FEHLENDER ; CLOCK ZWISCHEN BIT 3 UND 4) MVI B,3 ; CALL REPCHR ; MVI M,$FC ;1 * FCh (INDEX-MARKE) INX H ; MVI A,$4E ;50 * 4Eh MVI B,50 ; CALL REPCHR ; ;************************************************************************* ;DIE SEKTOREN ;"GAP" ;************************************************************************* SECTOR: MVI A,0 ;12 * 00h MVI B,12 ; CALL REPCHR ; MVI A,$F5 ;3 * F5h MVI B,3 ; CALL REPCHR ; ;************************************************************************* ;MARKE ;************************************************************************* MVI M,$FE ;1 * FEh INX H ; ;************************************************************************* ;SEKTOR-KENNUNGSFELD ;************************************************************************* INX H ;BLEIBT FREI FUER TRACK-NUMMER INX H ;BLEIBT FREI FUER SEITEN—NUMMER MOV M,E ;SEKTOR-NUMMER INX H MVI M,02 ;CODE: 512 BYTES / SEKTOR INX H MVI M,$F7 ;1 * F7h (ERZEUGT ZWEI CRC BYTES) INX H ;************************************************************************* ; "GAP" ;************************************************************************* MVI A,$4E ;22 * 4Eh MVI B,22 ; CALL REPCHR ; MVI A,0 ;12 * 00h MVI B,12 ; CALL REPCHR ; MVI A,$F5 ;3 * F5h (SCHREIBT Al, FEHLENDER CLOCK ; ZWISCHEN BIT 4 UND 5) MVI B,3 CALL REPCHR ;************************************************************************* ;"MARKE" ;************************************************************************* MVI M,$FB ;1 * FBh (DATA ADDRESS MARK) INX H ;************************************************************************* ;DATENBLOCK EINES SEKTORS ;************************************************************************* MVI A,$E5 ;512 * E5h (512 DATEN-BYTES) MVI C,2 MVI B,0 FDATA: CALL REPCHR DCR C JNZ FDATA ;************************************************************************* ;PRUEFBYTES ;************************************************************************* MVI M,$F7 ;1 * F7h (ERZEUGT 2 CRC-BYTES) INX H ;************************************************************************* ;"GAP" ;************************************************************************* MVI A,$4E ;54 * 4Eh MVI B,54 ; CALL REPCHR ; ;************************************************************************* ;8 SEKTOREN IN SPUR-PUFFER EINGETRAGEN ? ;NEIN —> LESE NAECHSTE SEKTOR-NUMMER AUS DER OERSATZ-TABELLE ; UND TRAGE DEN SEKTOR IM SPUR-PUFFER EIN ;JA --> WEITER BEI "TRKEND" ;************************************************************************* MOV A,E ;SEKTOR-NUMMER NACH A CPI 8 ;SEKTOR 8 (TRACK-ENDE) ? JZ TRKEND ;JA —> TRKEND PUSH H ;RETTE BUFFER-ZEIGER LHLD VERPTR ;HL-POINTER AUF VERSATZ TABELLE INX H ;STELLE ZEIGER WEITER MOV E,M ;LESE TABELLEN-EINTRAG SHLD VERPTR ;RETTE POINTER AUF OERSATZ-TABELLE POP H ;RESTORE BUFFER-ZEIGER JMP SECTOR ;************************************************************************* ;NACH "GAP" ;************************************************************************* TRKEND: MVI A,$4E ;FUELLE BUFFER MIT 4E MVI B,0 MVI D,6 TRKE0: CALL REPCHR DCR D JNZ TRKE0 ;************************************************************************* ;GEBE <CR> AUS <CURSOR AUF ANFANG DER "----------"-ZEILE) ;************************************************************************* MVI A,CR ;SPRUNG AUF ANFANG DER ZEILE CALL WCHAR ;ZEICHEN AUSGEBEN ;************************************************************************* ;SCHREIBE TRACK FUER TRACK AUF DIE DISKETTE ;************************************************************************* ;VORBEREITUNG LOOP0: MVI D,0 ;INIT TRACK-ZAEHLE LOOP: XRA A ;SEITE NULL STA SEITE ; MOV H,A ; MOV L,D ;TRACK-NUMMER SHLD FBUFFER+162 ; SPUR- UND SHLD FBUFFER+788 ; TRACK-NUMMER SHLD FBUFFER+1414 ; IM SPUR-PUFFER SHLD FBUFFER+2040 ; EINTRAGEN SHLD FBUFFER+2666 ; SHLD FBUFFER+3292 ; SHLD FBUFFER+3918 ; SHLD FBUFFER+4544 ; ; ;************************************************************************* ; MVI A,MAXTRY ;INIT VERSUCHSZAEHLER FUER VERIFY STA RETRY ; LOOP10: CALL WTRK ;SCHREIBE TRACK (SEITE 0) ANI MWRTRK ;ALLES OK CNZ CODE2 ;NEIN —> WRITE ERROR ;************************************************************************* ;PRUEFE TRACK. BEI FEHLERN WIRD TRACK NEU GESCHRIEBEN (BIS MAXTRY MAL) ;************************************************************************* CALL VERIFY ;PRUEFE TRACK JZ LOOP11 ;ALLES OK —> LOOP11 LDA RETRY ;ANZAHL DER VERSUCHE DCR A ;-1 CZ CODE5 ;0 —> VERIFY-ERROR STA RETRY ;NICHT 0 —> SPEICHERE NEUEN ZAEHLER JMP LOOP10 ;NEUER SCHREIB-VERSUCH ;************************************************************************* ;VORBEREITUNG ZUM SCHREIBEN DES TRACKS AUF SEITE 1 ;************************************************************************* LOOP11: MVI A,1 ;SEITE 1 STA SEITE ; STA FBUFFER+163 STA FBUFFER+789 STA FBUFFER+1415 STA FBUFFER+2041 STA FBUFFER+2667 STA FBUFFER+3293 STA FBUFFER+3919 STA FBUFFER+4545 ;************************************************************************* ;AKTUELLEN TRACK AUF SEITE 1 SCHREIBEN ;************************************************************************* MVI A,MAXTRY ;INIT VERSUCHSZAEHLER FUER VERIFY STA RETRY ; LOOP13: CALL WTRK ;PRUEFE TRACK ANI MWRTRK ;ALLES OK ? CNZ CODE2 ;NEIN -> WRITE ERROR ;************************************************************************* ;PRUEFE TRACK. BEI FEHLERN WIRD TRACK NEU GESCHRIEBEN (BIS MAXTRY MAL) ;************************************************************************* CALL VERIFY ;PRUEFE TRACK JZ LOOP12 ;ALLES OK _> LOOP!"" LDA RETRY ;ANZAHL DER VERSUCHE DCR A ;-1 CZ CODE5 ;0 -> VERIFY-ERROR STA RETRY ;NICHT 0 -> SPEICHERE NEUEN ZAEHLER JMP LOOP13 ;NEUER SCHREIB-VERSUCH ;************************************************************************* ;SEINEN TRACK PRO SEITE GESCHRIEBEN. GEBE "+" AUS ;************************************************************************* LOOP12: CALL PPLUS ;PRINT "+" ;************************************************************************* ;40 TRACKS PRO SEITE GESCHRIEBEN ? ;************************************************************************* INR D ;NAECHSTE TRACK-NUMMER MOV A,D ;TRACK-NUMMER NACH A CPI 40 ;TRACK 40 ? JZ FERTIG ;JA —> FERTIG ;************************************************************************* ;ES MUESSEN NOCH TRACKS GESCHRIEBEN ;************************************************************************* CALL STEPIN ;STEP IN (KOPF UM EINE SPUR NACH INNEN) LXI H,HEADIDLE ;15 MS VERZOEGERUNGw DAMIT DER CALL DELAY ;NACH STEPIN RUHIG STEHT JMP LOOP ;SCHREIBE NAECHSTEN TRACK ;************************************************************************* ;DISKETTE IST FORMATIERT, DIRECTORY ANLEGEN ;************************************************************************* FERTIG: XRA A ;A=0 (DIRECTORY WIRB AUF SEITE 0 GESCHR.) STA SEITE ;SEITE 0 MOV B,A ; SECTOR-PUFFER (512 BYTES) LXI H,SECB ; MIT 00h FUELLEN. CALL REPCHR ; CALL REPCHR ; ;************************************************************************* ;DIREKTORY WIRB AUF SPUR 0 GESSCHRIEBEN. DAHER "RESTORE" (KOPF AUF SPUR 0) ;************************************************************************* CALL RESTORE ;TRACK 0 ANI MREST ; ALLES OK ? CPI %00000100 ; CNZ CODE1 ;NEIN -> CODE1 ;************************************************************************* ;DAS DIRECTORY BELEGT AUF DER SPUR DIE SEKTOREN 1 - 5 ;SCHREIBE DEN INHALT DES SEKTOR-PUFFERS (ALLES 00H) IN DIE 5 SEKTOREN ;(OOH —> DIRECTORY LEER) ;************************************************************************* MVI A,1 ;SEKTOR-NUMMER INITD: OUT FDCSEC ; AN FDC MOV B,A ;RETTE SEKTOR-NUMMER MVI D,MAXTRY ;MAXIMALE ANZAHL DER VERSUCHE INITD1: CALL WVSEC ;SCHREIBE UND PRUEFE SEKTOR JZ INITD0 ;KEIN FEHLER —> INITD0 DCR D ;NOCH WEITERE VERSUCHE ERLAUBT ? JNZ INITD1 ;JA —> INITD1 JMP ERROR ;SPRINGE WENN MEHR ALS "MAXTRY" INITD0: MOV A,B ;SEKTOR-NUMMER NACH A INR A ;NAECHSTER SEKTOR CPI 6 ;BEREITS 5 SEKTOREN GESCHRIEBEN JNZ INITD ;NEIN —> INITD ;************************************************************************* ;FERTIG ;************************************************************************* DI ;DISABLE INTERRUPT CALL DESEL ;DESELECT LAUFWERK CALL PTXTCR ;TEXT AUSGEBEN .byte LF,"*** DISKETTE FORMATIERT UND GEPRUEFT",LF,CR .byte "*** VERZEICHNIS ANGELEGT",LF,CR,00 ; JMP FORM1 ; ?? ; [P01#01] JMP ERROR2 ; Ruecksprung ueber ERROR2 ;************************************************************************* ; ;DOS-BEFEHL LOAD ; ;************************************************************************* ;HIER, WENN "L" LOAD EINGEGEBEN WURDE ; ;TRITT EIN FEHLER AUF, SO ARBEITET DAS BFZ-MINI-DOS DIE ROUTINE "ERROR" AB. ;DIESE ENDET MIT EINEM SPRUNG ZU DER ADRESSEv DIE IM RAM UNTER "ERRRET" STEHT, ;DAS PROGRAMM TRAEGT HIER "LER" (LOAD-ERROR) EIN ;************************************************************************* DSKLOAD: LXI H,LER ;RETURN VON ERROR SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;VON WELCHEM LAUFWERK SOLL GELADEN WERDEN? ;************************************************************************* LER: CALL LAUFW ;LESE LAUFWERK-NAME CALL CRLF ;PRINT CR,LF ;************************************************************************* ;BEI FEHLERN IM WEITEREN PROGRAMMABLAUF RUECKKEHR NACH "MENUE" ;************************************************************************* LXI H,MENUE ;RETURN-ADR SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;DAS FILE IN DEM DIRECTORY GESUCHT WIRD, SOLL DAS DIRECTORY ;NICHT ANGEZEIGT WERDEN ;************************************************************************* XRA A ;DIRECTORY NICHT ANZEIGEN STA DSPLD ; ;************************************************************************* ;LESE FILE-NAME UND SUCHE IHN IN DEM DIRECTORY ;************************************************************************* CALL GETNAM ;LESE FILE-NAME CALL SEINTR ;SUCHE EINTRAG ;************************************************************************* ;WENN FILE VORHANDEN, MUSS MINDESTENS EIN EINTRAG IM DIRECTORY ;VORHANDEN SEIN ;("ZAEHLV" =ANZAHL DER VORHANDENEN EINNTRAEGE FUER DAS GESUCHTE FILE) ;************************************************************************* LDA ZAEHLV ;FILE VORHANDEN ? ORA A ; CZ CODE11 ;NEIN —> CODE 11 ;************************************************************************* ;HIER, WENN FILE VORHANDEN ;************************************************************************* LHLD TVORH ;LESE POSITION DES 1. EINTRAGS MOV A,H ;SEKTOR-NUMMER NACH A OUT FDCSEC ;SEKTOR-NUMMER AN FDC MOV C,L ;EINTRAGS-NUMMER NACH C CALL RRS ;LESE SEKTOR (MAXTRY VERSUCHE) MOV A,C ;EINTRAGS-NUMMER NACH A CALL ANFEIN ;HL ALS ZEIGER AUF EINTRAGS-ANFANG ;************************************************************************* ;STIMMEN FILE-TYP (MAT,SPS,BAS,) UND AKTUELLER "EFROM" -CODE UEBEREIN ? ; ;DOS-AUFRUF VON ZUM LADEN ERFORDERLICHER FILE-TYP "EFROM"-CODE ; ; MAT85 MAT ODER SPS ODER BAS 1 ; SPS SPS 2 ; BASIC BAS 3 ; UNBEKANNT ??? 7 ; ;************************************************************************* LKENN: MOV A,M ;LESE KENN-BYTE ANI %01111111 ;LOESCHE BIT 7 MOV E,A ;KENNUNG NACH E LDA EFROM ;LESE ENTERED-FROM-CODE CPI 01 ;DOS OON MAT AUFGERUFEN ? JZ KENNOK ;JA —> KENNUNG OK CMP E ;VERGLEICHE MIT KENNUNG CNZ CODE12 ;<> —> FALSCHER FILE-TYP ;************************************************************************* ;HIER, WENN KENNUNG OK ;LESE START-ADRESSE UND LAENGE AUS DEM DIRECTORY-EINTRAG ;************************************************************************* KENNOK: LXI D,$000D ;OFFSET ZUR START-ADR (IM DIR-EINTRAG) DAD D ;ADDIERE OFFSET —> ZEIGER AUF START-ADR MOV E,M ;LESE START-ADR INX H ; MOV D,M ; XCHG ; SHLD STARTA ;RETTE START-ADR XCHG ;LESE LAENGE INX H ; MOV E,M ; INX H ; MOV D,M ; XCHG ; SHLD LAENGE ;RETTE LAENGE ;************************************************************************* ;STIMMT DIE ANZAHL DER DIRECTORY-EINTRAEGE MIT DER ANZAHL UEBEREIN, DIE SICH ;AUS DER FILE-LAENGE BERECHNEN LAESST ? ;************************************************************************* CALL ANZAHL ;BERECHNE ANZAHL DER BENOETIGTEN EINTRAEGE LDA ZAEHLV ;LADE ANZAHL DER VORHANDENEN EINTRAEGE CMP B ;VERGLEICHE MIT ANZAHL DER BENOETIGTEN EINTRAEGE CNZ CODE13 ;NICHT GLEICH —> DIRECTORY-FEHLER ;************************************************************************* ;DOS-AUFRUF VON MAT85 FORDERE START-ADRESSE AN ;DOS-AUFRUF VON SPS ODER BASIC LOESCHE ALTES SPS/BASIC-PROGRAMM IM SPEICHER ;************************************************************************* CALL XLAD1 ;MAT: FORDERE START-ADR AN ;SPS,BASIC: LOESCHE ALES PROGRAMM ;************************************************************************* ;WIEVIELE EINTRAEGE MUESSEN EINGELESEN WERDEN ? DRUCKE DIE ENTSPRECHENDE ;ANZAHL VON STRICHEN ;************************************************************************* LDA ZAEHLV ;ANZAHL DER ZU LESENDEN EINTRAEGE MOV D,A ;ANZAHL NACH D CALL PLINE ;PRINT D-MAL "-" ;************************************************************************* ;VORBEREITUNG: ;SPEICHER VORBELEGEN ;BERECHNUNG DER STOP-ADRESSE ;RAM-VEKTOREN AENDERN ;************************************************************************* LHLD STARTA ;START-ADRESSE SHLD TEINT ;ZEIGER FUER MOVE-ROUTINE XCHG ;START-ADR NACH DE LHLD LAENGE ;LANGE NACH HL DAD D ;START-ADR PLUS LAENGE DCX H ;HL = STOP-ADRESSE SHLD STOPA ;RETTE STOP-ADRESSES LXI H,TVORH ;INIT ZEIGER AUF "TVORH" SHLD PTVORH ; LXI H,PTVORH ;ZEIGER AUF TABELLEN-POINTER SHLD ZWSP4 ; MVI A,JUMP ;JUMP-OPCODE STA XGP1 ;EINSETZEN STA XGP2 STA XGP3 LXI H,RRS ;ADRESSEN EINSETZEN SHLD XGP1+1 ; LXI H,MOVE ; SHLD XGP2+1 ; LXI H,PPLUS ; SHLD XGP3+1 ; ;************************************************************************* ;PRINT <CR> (CURSOR AUF DEN ANFANG DER "--------"-ZEILE) ;************************************************************************* CALL PTXT ;TEXT AUSGEBEN .byte CR,00 ;CR ;************************************************************************* ;LESE FILE EIN ;************************************************************************* CALL GETPUT ;LESE FILE ;************************************************************************* ;DOS-AUFRUF VON SPS BZW. BASIC: SETZE START-/STOP-POINTER ;DOS-AUFRUF MAT85: SETZE GO-ADRESSE ; ;************************************************************************* CALL XLAD2 ;SPS, BASIC: SETZE START-/STOP-POINTER ;MAT85: SETZE GO-ADRESSE ;************************************************************************* ;VOLLZUGSMELDUNG ;************************************************************************* CALL PSTAR ;TEXT AUSGEBEN .byte "FILE GELADEN",00 ;************************************************************************* ;ROUTINE BEENDEN ;DIE ROUTINE WIRD DURCH EINE SPRUNG NACH "ERET" BEENDET, OBWOHL KEIN FEHLER ;AUFGETRETEN IST. DURCH DIE VERWENDUNG EINIGER BEFEHLE DER "ERROR" — ROUTINE ;WIRD SPEICHERPLATZ GESPART ;************************************************************************* JMP ERET ; ;************************************************************************* ; ;DOS-BEFEHL SAVE ; ;************************************************************************* ;HIER, WENN "S" SAVE EINGEGEBEN WURDE ; ;DOS-AUFRUF VON SPS ODER BASIC: IST DER PROGRAMM-SPEICHER LEER (FEHLER) ? ;DOS-AUFRUF VON MAT85 : ----------------------------------------- ;************************************************************************* DSKSAVE: CALL XSAV1 ;BAS, SPS:: FEHLER , WENN PGM-SPEICHER LEER ;************************************************************************* ;TRITT BEI DER PROGRAMMAUSFUEHRUNG EIN FEHLER AUF, SO VERZWEIGT DAS PROGRAMM ;ZUR "ERROR"-ROUTINE. DIESE ENDET MIT EINEM SPRUNG ZU DER ADRESSE, DIE IM ;RAM UNTER "ERRRET" GESPEICHERT IST. DAS PROGRAMM TRAEGT HIER "SAVER" EIN ;************************************************************************* LXI H,SAVER ;RETURN VON ERROR SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;MIT WELCHEM LAUFWERK SOLL GESPEICHERT WERDEN ? SAVER: CALL LAUFW ;LESE LAUFWERK-NAME CALL CRLF ;PRINT CR,LF ;************************************************************************* ;BEI WEITEREN FEHLERN IM PROGRAMMABLAUF RUECKKEHR NACH "MENUE" LXI H,MENUE ;RETURN-ADR SHLD ERRRET ;ABSPEICHERN ;************************************************************************* ;DOS-AUFRUF VON MAT85: HOLE START/STOP-ADR ;DOS-AUFRUF VON SPS ODER BASIC: --------------- ;************************************************************************* CALL XSTSP ; Hole Start/Stop-Adresse Sprung ueber Vektor ; (MAT85+) in MAT85 ;MAT: HOLE START/STOP-ADRESSE ;BAS, SPS: NOP ;************************************************************************* ;BERECHNE LAENGE ;************************************************************************* LHLD STARTA ;HL=START-ADR XCHG ;DE=START-ADR LHLD STOPA ;HL=STOP-ADR CALL SUB2 ; BERECHNE LAENGE INX H ; MOV A,H ; HL=0000 ? ORA L ; CZ CODE10 ;JA —> CODE10 SHLD LAENGE ;RETTE LAENGE ;************************************************************************* ;BEIM FOLGENDEN AUFRUF VON "SEINTR" SOLL DAS DIRECTORY NICHT ANGEZEIGT WERDEN ;************************************************************************* XRA A ;DIRECTORY NICHT ANZEIGEN STA DSPLD ; ;************************************************************************* ;UNTER WELCHEM NAMEN SOLL DER FILE GESPEICHERT WERDEN ? ;************************************************************************* CALL GETNAM ;LESE FILE-NAME ;************************************************************************* ;PRUEFE OB FILE BEREITS VORHANDEN UND OB DER FREIE SPEICHERPLATZ AUF DER ;DISKETTE ZUM SPEICHERN AUSREICHT ;************************************************************************* CALL SEINTR ;SUCHE EINTRAG ;************************************************************************* ;WIEVIELE EINTRAEGE WERDEN ZUM ABSPEICHERN BENOETIGT ? ;************************************************************************* CALL ANZAHL ;BERECHNE ANZ. DER BENOET. EINTRAEGE PUSH B ;RETTE ANZAHL DER BENOETIGTEN EINTRAEGE ;************************************************************************* ;GIBT ES AUF DER DISKETTE NUTZBARE EINTRAEGE ? ;(FREIE EINTRAEGE BZW. EINTRAEGE, DIE EINEM FILE GLEICHEN NAMENS ;ZUGEORDNET SIND) ;************************************************************************* LDA ZAEHL ;NUTZBARE EINTRAEGE ? ORA A ; CZ CODE8 ;NEIN —> DISK VOLL ;************************************************************************* ;HIER, WENN MINDESTENS EIN NUTZBARER EINTRAG. ;DIESER EINTRAG IST: - ENTWEDER FREI ; - ODER ER IST EINEM FILE MIT GLEICHEM NAMEN ZUGEORDNET ;************************************************************************* CMP B ;VERGLEICHE MIT DEN BENOETIGTEN PLATZ CC CODE15 ;—> SPEICHERPLATZ REICHT NICHT AUS ;************************************************************************* ;HIER, WENN SPEICHERPLATZ AUSREICHT ;DER NUTZBARE SPEICHERPLATZ IST: - ENTWEDER FREI ; - ODER ER IST EINEM FILE MIT GLEICHEM ; NAMEN ZUGEORDNET ;IST DAS FILE BEREITS VORHANDEN ? ;************************************************************************* LDA ZAEHLV ;IST DAS FILE BEREITS VORHANDEN ? ORA A ; JZ NEW ;NEIN —> NEW ;************************************************************************* ;HIER, UIENN FILE BEREITS VORHANDEN ;GEBE WRNUNG AUS ;************************************************************************* SAVER2: CALL PTXTCR ;PRINT TEXT .byte LF,07 .byte "*** FILE BEREITS VORHANDEN !",CR,LF .byte "*** ALTES FILE UEBERSCHREIBEN ?",CR,LF .byte "*** J = JA, N = NEIN",00 CALL DESEL ;DESELECT LAUFWERK ;************************************************************************* ;SOLL DER VORHANDENE FILE UEBERSOHRIEBEN WERDEN ? ;************************************************************************* CALL GETCHR ;JA/NEIN-ANTWORT LESEN CPI "N" ;NEIN ? JZ ERET ;N -> ERET CPI "J" ;JA ? JNZ SAVER2 ;WEDER NOCH J/N -> SAVE2 ;************************************************************************* ;HIER, WENN DER VORHANDENE FILE UEBERSOHRIEBEN WERDEN SOLL ;************************************************************************* CALL CRLF ;PRINT CR,LF LDA ZAEHLV ;ANZAHL DER LOESCHENDNEN EINTRAEGE CALL DELETE ;LOESCHE ALTE EINTRAEGE ;************************************************************************* ;ABSPEICHERUNG DES FILES ;IST DIE DISKETTE SCHREIBGESCHUETZT ;************************************************************************* NEW: CALL WPTST ;WRITE-PROTECT-TEST CNZ CODE4 ;SCHREIBGESCHUETZT —> CODE4 ;************************************************************************* ;HIER, WENN DIE DISKETTE NICHT SCHREIBGESCHUETZT IST ;************************************************************************* POP PSW ;ANZAHL DER BENOETIGTEN EINTRAEGE STA ZWSP2 ;ANZAHL NACH ZWSP2 MOV D,A ;ANZAHL NACH D CALL PLINE ;DRUCKE D-MAL "-" LXI H,TEINT ;INIT ZEIGER AUF SHLD PTEINT ;TEINTS-TABELLE LHLD STARTA ;START—ADR FUER FILE SHLD ZWSP1 ;START-ADR FUER AKTUELLEN EINTRAG CALL SELECT ;RE-SELECT LAUFWERK CALL DREADY ;LAUFWERK BEREIT ? CC CODE3 ;NEIN -> CODE3 ;************************************************************************* ;PRINT <CR>. (CURSOR AN DEN ANFANG DER "-------"-ZEILE) ;************************************************************************* MVI A,CR ;WAGENRUECKLAUF CALL WCHAR ; LXI H,PTEINT ;ZEIGER INITIALISIEREN SHLD ZWSP4 ; MVI A,JUMP ;LADE JMP-OPCODE STA XGP1 ;SETZE OP-CODE EIN STA XGP3 MVI A,RETURN ;LADE RETURN-OPCODE STA XGP2 ;SETZE OP-CODE EIN LXI H,RWVSEC ;SETZE ADRESSE EIN SHLD XGP1+1 LXI H,PPLUS SHLD XGP3+1 ;************************************************************************* ;EIGENTLICHER SAVE-VORGANG ;************************************************************************* CALL GETPUT ;SCHREIBE FILE AUF DISKETTE ;************************************************************************* ;EINTRAEGE FUER FILE IM DIRECTORY VERMERKEN ;************************************************************************* SAVE0: LXI H,TEINT ;INIT ZEIGER AUF "TEINT" SHLD ZWSP1 ; MVI A,JUMP ;JMP OP-CODE STA XDIR ;EINSETZEN LXI H,VEINTR ;ADRESSE EINSETZEN SHLD XDIR+1 ; CALL MDIR ;VERMERKE EINTRAEGE IN DIRECTORY ;************************************************************************* ;FERTIG ;************************************************************************* DEB0: CALL CRLF ;PRINT CR,LF CALL PSTAR ;PRINT TEXT .byte "FILE ABGESPEICHERT",00 ;************************************************************************* ;ROUTINE BEENDEN ;DIE ROUTINE WIRD DURCH EINEN SPRUNG NACH "ERET" BEENDET, OBWOHL KEIN ;FEHLER AUFGETRETEN IST. DURCH DIE VERWENDUNG EINIGER BEFEHLE DER ;"ERROR" - ROUTINE WIRD SPEICHERPLATZ GESPART ;************************************************************************* JMP ERET ; ;****************************************************************** ;* CODE-TEIL * ;* WIRD BEI FEHLERN LUE EIN UNTERPROGRAMM AUFGERUFEN - * ;* HIER WIRD DEM C-REGISTER EIN CODE ZUGEWIESEN, DER * ;* DIE ART DES FEHLERS ANGIBT.. * ;****************************************************************** ;LADE C-REGISTER MIT FEHLER-CODE. EINSPRUNG JE NACH FEHLER. ;DURCH DIE ANWEISUNG "DB 21h" SIEHT DER PROZESSOR NACH DER ERSTEN ;"MVI C, .."-ANWEISUNG NUR "LXI H,..."-ANWEISUNGEN (21h = LXI H,..) ;DER WERT DES C-REGISTERS WIRD DADURCH NICHT VERAENDERT. ;VORTEIL: BYTE-ERSPARNIS, DA SONST JEDEM "MVI C,.. " EIN SPRUNG ZUR ;"XERR"-ROUTINE FOLGEN MUESSTE. ; ;BEISPIEL: A) 0E EINSPRUNG BEI A) DIE CPU "SIEHT" DAS BEFEHLSBYTE ; 00 OE "MVI C,.." UND DEN OPERANDEN 00. ; 21 DIES ERGIBT "MVI C,00". DAS FOLGENDE ; B) 0E BYTE (21) NIMMT DIE CPU ALS BEFEHLS- ; 01 BYTE FUER "LXI H,...". DIE FOLGENDEN ; 21 BYTES (0E UND 01) ERGEBEN "LXI H,010E" ; ' FUER DIE CPU FOLGT NUN WIEDER EIN BE- ; ' FEHLSBYTE (21). DAS BEDEUTET, ERNEUT ; ' DER BEFEHL "LXI H,..." USW. ; ' EINSPRUNG BEI B) DIE CPU SIEHT DAS BEFHLSBYTE 0E ; ' "MVI C,..". WEITERER ABLAUF WIE OBEN. ;WERTE BEI "JMP XERR": C = FEHLER-CODE ; H = MAXIMAL MOEGLICHER FEHLER—CODE ; L = 0Eh (CODE FUER "MVI C,...") ; ;************************************************************************* ;CODE CODE0: MVI C,0 ;FALSCHE EINGABE .byte $21 CODE1: MVI C,1 ;RUECKSTELL-FEHLER .byte $21 CODE2: MVI C,2 ;SCHREIB-FEHLER .byte $21 CODE3: MVI C,3 ;LAUFWERK NICHT BEREIT .byte $21 CODE4: MVI C,4 ;DISKETTE SCHREIBGESCHUETZT .byte $21 CODE5: MVI C,5 ;PRUEF—FEHLER .byte $21 CODE6: MVI C,6 ;SUCH—FEHLER .byte $21 CODE7: MVI C,7 ;LESE-FEHLER .byte $21 CODE8: MVI C,8 ;DISKETTE VOLL .byte $21 CODE9: MVI C,9 ;UNERLAUBTER NAME .byte $21 CODE10: MVI C,10 ;FILE > 65535 (DEZ.. > BYTES .byte $21 CODE11: MVI C,11 ;FILE NICHT IM VERZEICHNIS .byte $21 CODE12: MVI C,12 ;FALSCHER FILE-TYP .byte $21 CODE13: MVI C,13 ;DIRECTORY-FEHLER .byte $21 CODE14: MVI C,14 ;SPEICHER-FEHLER .byte $21 CODE15: MVI C,15 ;SPEICHERPLATZ AUF DER DISKETTE ZU KLEIN .byte $21 CODE16: MVI C,16 ;PROGRAMM-SPEICHER LEER JMP XERR ;SPRUNG LIEBER RAM—VEKTOR ;(WIRD VOM BFZ-MINI-DOS ALS ;"JMP ERROR" INITIALISIERT) ;************************************************************************* ;PROGRAMM-SEGMENT "ERROR" ;WIRD BEI DOS—FEHLERN VOM CODE-TEIL AUFGERUFEN ;DESELECTIERT LAUFWERK UND GIBT FEHLERMELDUNG AUS ; ;WERTE BEIM AUFRUF: C = FEHLER-CODE ; ;RETTE FEHLER-STELLE IM RAM UNTER "ERRP". WIRD VOM DOS NICHT GENUTZT«. ;NUTZUNG DES "ERRP"—WERTES DURCH ANDERE PROGRAMME ABER MOEGLICH ;************************************************************************* ERROR: DI ;DISABLE INTERRUPT POP H ;RETURN-ADR (FEHLER-STELLE) SHLD ERRP ;RETTE ADRESSE ;************************************************************************* ;GEBE "*** FEHLER ***" AUS ;************************************************************************* CALL PTXTCR ;TEXT AUSGEBEN .byte LF,BELL,"*** FEHLER: ",00 ;************************************************************************* ;PRUEFE OB FEHLER-CODE OK ;NEIN —> LADE C-REGISTER MIT SPIELLEN CODE FUER "UNGUELTIGER FEHLERCODE" ;************************************************************************* LHLD PEVT ;LADE POINTER AUF ERROR-VEKTOR-TABELLE MOV A,M ;LESE MAXIMALEN FEHLER-CODE CMP C ;VERGLEICHE MIT TATSAECHLICHEM CODE JNC ECOK ;SPRINGE, WENN ERROR-CODE OK MOV C,A ;LADE CODE FUER: INR C ;"UNGUELTIGER FEHLER-CODE" ;************************************************************************* ;LADE ZEIGER AUF FEHLERMELDUNG ;************************************************************************* ECOK: INX H ;ZEIGER AUF 1. VEKTOR MVI B,0 ;HIGH (BC) = 0 DAD B ;STELLE ZEIGER AUF DAD B ;RICHTIGEN EINTRAG MOV C,M ;EINTRAG NACH BC INX H ; MOV B,M ; ;************************************************************************* ;GEBE FEHLERMELDUNG AUS ;************************************************************************* ERROR1: LDAX B ;TEXT-ZEICHEN NACH A ORA A ;TEXT ENDE ? JZ ERROR2 ;JA — > ERROR2 CALL WCHAR ;PRINT ZEICHEN INX B ;STELLE ZEIGER WEITER JMP ERROR1 ;NAECHSTES ZEICHEN ;************************************************************************* ;DESELEKT LAUFWERK. WARTE AUF <SPACE> (FEHLER—QUITTIERUNG) ;************************************************************************* ERROR2: CALL DESEL ;DESELECT LAUFWERK CALL PTXTCR ;PRINT TEXT .byte "==> SPACE",00 CALL WAITSP ;WARTE AUF SPACE ;************************************************************************* ;DESELEKT LAUFWERK. RE-INITIALISIERE STACKPOINTER. RETURN (ERRRET) ;************************************************************************* ERET: CALL DESEL ;DESELECT LAUFWERK LXI SP,USRSTK ;RE-INIT STACKPOINTER LHLD ERRRET ;"RETURN"-ADRESSE (WURDE VOM PROGRAMM PCHL ;BEI "ERRRET" EINGESETZT) ;************************************************************************* ;************************************************************************ ;* * ;* U N T E R P R O G R A M M E * ;* * ;************************************************************************ ;UNTERPROGRAMM "RESTORE" ;GIBT DAS KOMMANDO "RESTORE" (FAHRE KOPF NACH TRACK 0) AN DEN FDC. ;SACKGASSEN-UNTERPROGRAMM. WIRD DURCH DEN INTERRUPT VERLASSEN, DEN ;DER FDC NACH DER AUSFUEHRUNG DES KOMMANDOS ERZEUGT. ; ;WERTE BEIM AUFRUF: ---- ;WERTE NACH RETURN: SIEHE INTERRUPT-SERVICE-ROUTINE ISR ;************************************************************************* RESTORE: MVI A,CREST ;RESTORE OUT FDCCMD ;KOMMANDO AN FDC HLT ;WARTE AUF INTERRUPT ;************************************************************************* ;UNTERPROGRAMM "STEP IN" ;GIBT AN DEN FDC DEN BEFEHL "STEP IN" AUS. ;SACKGASSEN-UNTERPROGRAMM. WIRD PER INTERRUPT VERLASSEN ;WERTE BEIM AUFRUF: --- ;WERTE NACH INTERRUPT: SIEHE IINTERRUPT-SERVICE-ROUTINE ISR ;************************************************************************* STEPIN: MVI A,CSTPIN ;STEP IN OUT FDCCMD ;KOMMANDO AN DEN FCD HLT ;WARTE AUF INTERRUPT ;************************************************************************* ;UNTERPROGRAMM "SEEK" ;GIBT AN DEN FDC DEN BEFEHL "SEEK" AUS. ;SACKGASSEN-UNTERPROGRAMM. WIRD PER INTERRUPT VERLASSEN ;WERTE BEIM AUFRUF: SOLL-TRACK IM FDC-DATENREGISTER ;WERTE NACH INTERRUPT: SIEHE INTERRUPT-SERVICE-ROUTINE ISR ;************************************************************************* SEEK: MVI A,CSEEK ;SEEK OUT FDCCMD ;KOMMANDO AN DEN FDC HLT ;WARTE AUF INTERRUPT ;************************************************************************* ;UNTERPROGRAMM "USED" ;SCHREIBT EINEN SEKTOR AUF DISKETTE. NACH DER AUSGABE DES ;"WRITE SECTOR"-KOMMANDOS AN DEN FDC HAELT SICH DIE CPU DURCH ;"OUT STOP" AN (READY GEHT AUF L-PEGEL). WENN DER FDC DAS ERSTE ;DATEN-BYTE ANFORDERT, GIBT ER AM ANSCHLUSS DRQ EIN SIGNAL AUS, DAS ;DIE CPU WIEDER STARTET (READY GEHT AUF H). DIE CPU GIBT DAS ;DATEN-BYTE AN DEN FDC UND HAELT SICH ERNEUT AN. ;DURCH DIE STEUERUNG UEBER DAS READY-SIGNAL ENTFAELLT DAS ABFRAGEN ;DES FDC—STATUS. DIE CPU KANN SCHNELLER AUF EINE DATEN-ANFORDERUNG ;(DRQ,DATA REQUEST) DES FDC REAGIEREN. SO IST TROTZ DER RELATIV ;NIEDRIGEN CPU-TAKTFREQUENZ VON 2 MHZ DOUBLE-DENSITY-BETRIEB MOEGLICH. ;SACKGASSEN-UNTERPROGRAMM. WIRD PER INTERRUPT VERLASSEN ;WERTE BEI AUFRUF HL—ZEIGT AUF DAS ERSTE BYTE DER ZU SCHREIBENDEN DATEN ; (TRACK BEREITS ANGEFAHRENy SEKTOR-NUMMER IM SEKTOR-REG.) ;WERTE NACH INTERRUPT: HL=VERAENDERT ; (SIEHE AUCH: INTERRUPT-SERVICE-ROUTINE ISR) ; ;************************************************************************* WSEC: MVI A,CWSEC ;WRITE SECTOR OUT FDCCMD ;KOMMANDO AN DEN FDC WSEC0: OUT FDCSTOP ;WARTE AUF DRQ MOV A,M ;ZEICHEN IN AKKU OUT FDCDAT ;ZEICHEN AN DN FDC INX H ;ZEIGER WEITERSTELLEN JMP WSEC0 ;NAECHSTES ZEICHEN ;************************************************************************* ;UNTERPROGRAMM "RSEC" ;LIEST EINEN SEKTOR VON DISKETTE. NACH DER AUSGABE DES "READ SECTOR"- ;KOMMANDOS AN DEN FDC HAELT SICH DIE CPU DURCH "OUT STOP" AN (READY ;GEHT AUF L-PEGEL). WENN DER FDC DAS ERSTE DATEN-BYTE VON DER DISKETTE ;GELESEN HAT, GIBT ER AM ANSCHLUSS DRQ EIN SIGNAL AUS, DAS DIE CPU WIEDER ;STARTET (READY GEHT AUF H). DIE CPU LIEST DAS DATEN-BYTE AUS DEM FDC- ;DATENREGISTER UND HAELT SICH ERNEUT AN. ;DURCH DIE STEUERUNG LIEBER DAS READY-SIGNAL ENTFALLET DAS ABFRAGEN ;DES FDC—STATUS - DIE CPU KANN SCHNELLER AUF EINE DATEN-ANFORDERUNG ;(DRQ., DATA REQUEST) DES FDC REAGIEREN.. SO IST TROTZ DER RELATIV ;NIEDRIGEN CPU-TAKTFREQUENZ VON 2 MHZ DOUBLE-DENSITY-BETEIEB MOEGLICH- ;SACKGASSEN-UNTERPROGRAMM- WIRD PER INTERRUPT VERLASSEN ;WERTE BEI AUFRUF: HL-ZEIGT AUF ANFANG DES SPEICHERBEREICHS, IN DEM DIE ; GELESENEN BYTES GESPEICHERT WERDEN SOLLEN. ; (TRACK BEREITS ANGEFAHREN, SEKTOR-NUMMER IM ; SEKTOR-REGISTER) ; ;WERTE NACH INTERRUPT HL=VERAENDERT ; (SIEHE AUCH INTERRUPT-SERVICE-ROUTINE) ; ;************************************************************************* RSEC: MVI A,CRSEC ;READ SECTOR OUT FDCCMD ;BEFEHL AN FDC RSEC0: OUT FDCSTOP ;WARTE AUF DRQ IN FDCDAT ;ZEICHEN IN AKKU MOV M,A ;ZEICHEN IN BUFFER INX H ;ZEIGER WEITEESTELLEN JMP RSEC0 ;NAECHSTES ZEICHEN ;************************************************************************* ;UNTERPROGRAMM "WTRK" ;SCHREIBT EINEN TRACK AUF DIE DISKETTE. NACH DER AUSGABE DES ;"WRITE TRACK"-KOMMANDOS AN DEN FDC, HAELT SICH DIE CPU DURCH ;"OUT STOP" AN (READY GEHT AUF L-PEGEL). WENN DER FDC DAS ERSTE ;DATEN-BYTE ANFORDERT, GIBT ER AM ANSCHLUSS DRQ EIN SIGNAL AUS, DAS ;DIE CPU WIEDER STARTET (READY GEHT AUF H). DIE CPU GIBT DAS ;DATEN-BYTE AN DEN FDC UND HAELT SICH ERNEUT AN. ;DURCH DIE STEUERUNG UEBER DAS READY-SIGNAL ENTFAELLT DAS ABFRAGEN ;DES FDC-STATUS. DIE CPU KANN SCHNELLER AUF EINE DATEN-ANFORDERUNG ;(DRQ, DATA REQUEST) DES FDC REAGIEREN. SO IST TROTZ DER RELATIV ;NIEDRIGEN CPU-TAKTFREQUENZ VON 2 MHZ DOUBLE-DENSITY-BETRIEB MOEGLICH. ;DIES IST EIN SACKGASSEN-UNTERPRQGRAMM. WENN DER FDC DEN BEFEHL ;WRITE TRACK" ABGEARBEITET HAT, ERZEUGT ER EIN INTERRUPT-SIGNAL ;DAS UNTERPROGRAMM WIRD DURCH DIESEN INTERRUPT VERLASSEN. ;WERTE BEIM AUFRUF: TRACK BEREITS ANGEFAHREN ;WERTE NACH INTERRUPT: HL=VERAENDERT ; (SIEHE AUCH INTERRUPT-SERVICE-ROUTINE ISR) ;************************************************************************* WTRK: LXI H,FBUFFER ;ZEIGER AUF TRACK BUFFER CALL SELECT ;SELECT LAUFWERK MVI A,CWRTRK ;WRITE TRACK OUT FDCCMD ; WARTE: OUT FDCSTOP ;WARTE BIS DRQ MOV A,M ;LESE DATEN AUS BUFFER OUT FDCDAT ;GEBE DATEN AN FDC INX H ;STELLE BUFFER-ZEIGER WEITER JMP WARTE ; ;************************************************************************* ;UNTERPROGRAMM "WVSEC" ;SCHREIBT DEN INHALT DES SECTOR-BUFFERS (SECB) AUF DISKETTE UND ;PRUEFT DEN GESCHRIEBENEN SEKTOR. ;BEIM AUFRUF MUESSEN TRACK- UND SEKTOR-NUMMER BEREITS AN DEN FDC ;UEBERGEBEN WORDEN SEIN, DER KOPF MUSS SICH UEBER DER RICHTIGEN SPUR ;BEFINDEN. ;KEIN FEHLER: Z-FLAG = 1, C = 5 ; FEHLER: Z-FLAG = 0, C = 5 (VERIFY-ERROR) ; Z-FLAG = 0, C = 2 (WRITE-ERROR) ;FEHLER: Z-FLAG = 0, C ;************************************************************************* WVSEC: LXI H,SECB ;ZEIGER AUF SECTOR-BUFFER WVSEC0: CALL SELECT ;RE-SELECT DRIVE CALL WSEC ;SCHREIBE SEKTOR MVI C,2 ;CODE FUER "SCHREIB—FEHLER" ANI MWSEC ;ALLES OK ? RNZ ;NEIN —> RETURN CALL VERIX ;VERIFY SECTOR MVI C,5 ;CODE FUER "PRUEF-FEHLER" RET ;************************************************************************* ;UNTERPROGRAMM "RWVSEC" ;SCHREIBT EINEN SEKTOR AUF DISKETTE UND PRUEFT DEN GESCHRIEBENEN SEKTOR» ;BEI FEHLERN WIRD DER SCHREIBVORGANG "MAXTRY" MAL WIEDERHOLT. ;WERTE BEIM AUFRUF: BEIM AUFRUF MUESSEN TRACK- UND SEKTOR-NUMMER BEREITS ; AN DEN FDC UEBERGEBEN WORDEN SEIN. DER KOPF MUSS SICH ; UEBER DER RICHTIGEN SPUR BEFINDEN. ; HL: SEKTOR—PUFFER-ZEIGER ;************************************************************************* RWVSEC: MVI D,MAXTRY ;MAX ANZAHL DER SCHREIB-VERSUCHE SHLD ZWSP3 ;RETTE ZEIGER RWVS0: CALL SELECT ;RE—SELECT DRIVE LHLD ZWSP3 ;LESE ZEIGER CALL WVSEC0 ;SCHREIBE SEKTOR RZ ;RETURN, WENN OK DCR D ;WEITERE VERSUCHE ERLAUBT ? JNZ RWVS0 ;JA —> RWVSEC CALL CODE2 ;NEIN —> CODE2 ;************************************************************************* ;UNTERPROGRAMM "SAVSEC" ;SCHREIBT DEN INHALT DES SEKTOR-PUFFERS (SECB) AUF DISKETTE UND PRUEFT ;DEN GESCHRIEBENEN SEKTOR. ;BEI FEHLERN WIRD DER SCHREIBVORGANG "MAXTRY" MAL WIEDERHOLT. ;WERTE BEIM AUFRUF: BEIM AUFRUF MUESSEN TRACK- UND SEKTOR-NUMMER ; AN DEN FDC UEBERGEBEN WORDEN SEIN. DER KOPF ; UEBER DER RICHTIGEN SPUR BEFINDEN. ;************************************************************************* SAVSEC: MVI D,MAXTRY ;ANZAHL DER VERSUCHE NTRY: CALL SELECT ;RE-SELECT DRIVE CALL WVSEC ;SPEICHERE SEKTOR AUF DISK RZ ;RETURN, WENN ALLES OK DCR D ;WEITERE VERSUCHE ERLAUBT ? JNZ NTRY ;JA —> NTRY CALL CODE2 ;NEIN —> CODE2 ;************************************************************************* ;UNTERPROGRAMM "RRS" ;LIEST EINEN SEKTOR IN DEN SEKTOR-PUFFER (SECB). ;BEI FEHLERN WIRD DER LESEVORGANG "MAXTRY" MAL WIEDERHOLT. ;WERTE BEIM AUFRUFS: BEIM AUFRUF MUESSEN TRACK- UND SEKTOR-NUMMER BEREITS ; AN DEN FDC UEBERGEBEN WORDEN SEIN. DER KOPF MUSS SICH ; UEBER DER RICHTIGEN SPUR BEFINDEN. ;************************************************************************* RRS: MVI D,MAXTRY ;MAXIMALE ANZAHL DER LESE-VERSUCHE RRS0: CALL SELECT ;RE-SELECT DRIVE LXI H,SECB ;BUFFER-ADR CALL RSEC ;LESE SEKTOR ANI MRSEC ;ALLES OK ? RZ ;JA —> RETURN DCR D ;NOCH EIN VERSUCH ERLAUBT ? JNZ RRS0 ;JA —> RRSO CALL CODE7 ;NEIN —> LESE-FEHLER ;************************************************************************* ;UNTERPROGRAMM "VERIFY" ;PRUEFT DIE EINZELNEN SEKTOREN EINES TRACKS IN DER REIHENFOLGE ;1,2,3,4,5,6,7,8. WENN EIN FEHLERHAFTER SEKTOR GEFUNDEN WIRD, ;WIRD DAS UNTERPROGRAMM VERLASSEN. DAS B-REGISTER ENTHAELT DANN ;DIE NUMMER DES FEHLERHAFTEN SEKTORS UND DAS Z-FLAG IST NICHT ;GESETZT. ;IST EIN SEKTOR FEHLERFREI, SO WERDEN DIE WEITEREN SEKTOREN IN DER ;OBEN ANGEGEBENEN REIHENFOLGE GEPRUEFT. ;WERTE BEIM AUFRUF: TRACK-NUMMER IM TRACK-REGISTER DES FDC ; KOPF MUSS BEREITS UEBER DER SPUR STEHEN ;WERTE NACH RETURN: ALLE SEKTOREN FEHLERFREI ! FEHLERHAFTER SEKTOR ; -------------------------+-------------------- ; A = 9 ! A = ? ; B = 8 ! B = NR DES FEHLERH. SECKTORS ; Z-FLAG = 1 (GESETZT) ! Z-FLAG = 0 (NICHT GESETZT) ;************************************************************************* VERIFY: CALL SELECT ;RETRIGGER MOTOR-ON-OFF MVI A,1 ;1. SEKTOR VERI0: OUT FDCSEC ;AN FDC SEKTOR-REGISTER MOV B,A ;SECTOR ZAEHLER NACH B CALL VERIX ;VERIFY SECTOR RNZ ;RETURN, WENN FEHLER (Z=0) MOV A,B ;SEKTOR-ZAEHLER NACH A INR A ;+1 CPI 9 ;ALLE SEKTOREN GEPRUEFT ? RZ ;RETURN, WENN ALLE SEKTOREN OK (Z=1) JMP VERI0 ;************************************************************************* ;UNTERPROGRAMM "VERIX" ;PRUEFT SEKTOR. TRACK- UND SEKTOR-NUMMER MUESSEN BEREITS AN FDC ;UEBERGEBEN WORDEN SEIN. DER TRACK MUSS ANGEFAHREN SEIN. ;KEIN FEHLER: Z = 1 ; FEHLER: Z = 0 ;************************************************************************* VERIX: CALL VERI1 ;READ SECTOR ANI MVERI ;ALLES OK ? JA -- Z = 1 ; NEIN -- Z = 0 RET ;************************************************************************* ;“UNTERPROGRAMM "VERI1" ;LIEST EINEN SEKTOR EIN OHNE IHN IM RAM ZU SPEICHERN. WIRD ZUM PRUEFEN ;DER SEKTOREN BENUTZT.. WICHTIG SIND DIE STATUS-FLAGS "RECORD NOT FOUND" ;UND "CRC-ERROR" DES FDC NACH DEM EINLESEN. ;SACKGASSEN-UNTERPROGRAMM. WIRD DURCH DEN INTERRUPT VERLASSEN, DEN DER FDC ;NACH DEM EINLESEN DES SEKTORS ERZEUGT. ;ZUM VERSTAENDNIS VON "OUT STOP": SIEHE WTRK (WRITE TRACK) ;WERTE BEIM AUFRUF: SEKTOR- UND TRACK-NUMMER BEREITS AN FDC UEBERGEBEN ; TRACK ANGEFAHREN ;WERTE NACH RETURN: SIEHE IINTERRUPT-SERVICE-ROUTINE ISR ;************************************************************************* VERI1: MVI A,CRSEC ;READ SECTOR OUT FDCCMD ;GEBE KOMMANDO AN DEN FDC AUS VERI2: OUT FDCSTOP ;WARTE BIS DRQ IN FDCDAT ;LESE DATE (RESET DRQ) JMP VERI2 ;LOOP ;************************************************************************* ;UNTERPROGRAMM "COMPSM" ;BERECHNET DIE SELECT-MASKE UND SPEICHERT SIE IN SELMSK AB ;WERTE BEIM AUFRUF: A = 0 (LAUFWERK A) BZW. 1 (LAUFWERK B) ;WERTE NACH RETURN: A = 1 (LAUFWERK A) BZW. 2 (LAUFWERK B) ;************************************************************************* COMPSM: INR A ;ERGIBT SELECT-MASKE STA SELMSK ;RETTE SELECT-MASKE RET ;************************************************************************* ;UNTERPROGRAMM "SELECT" ;WAEHLT LAUFWERK UND SEITE AUS. DAS MOTOR—ON—OFF AUF DER FDC-KARTE ;WIRD DURCH "OUT PORT" FUER ETWA 3 SEC. GESETZT. ;WERTE BEIM AUFRUF: (SEITE) = SEITENNUMMER 0 ODER 1 (BINAER) ; (SELMSK) = SELECT-MASKE - LAUFWERK A = 1 ; - LAUFWERK B = 2 ;WERTE NACH RETURN: A = 00000001B, 01h (LAUFWERK A, SEITE 0, DOUBLE DENSITY) ; A = 00001001B, 09h (LAUFWERK A, SEITE 1, DOUBLE DENSITY) ; A = 00000010B, 02h (LAUFWERK B, SEITE 0, DOUBLE DENSITY) ; A = 00001010B, 0Ah (LAUFWERK B, SEITE 1, DOUBLE DENSITY) ; *) S = SEITE, 0 = SEITE 0 ; 1 = SEITE 1 ; *) D = DENSITY, 0 = DOUBLE DENSITY ; 1 = SINGLE DENSITY ; ; B = LAUFWERK B, (WENN 1) ; A = LAUFWERK A, (WENN 1) ; ;DER AUSGEGEBENE WERT WIRD IM RAM UNTER "LSEL" GESPEICHERT. ;************************************************************************* SELECT: PUSH B ;RETTE B-REGISTER LDA SEITE ;LESE SEITEN-NUMMER ADD A ;SCHIEBE BIT IN POSITION D1 ADD A ;SCHIEBE BIT IN POSITION D2 ADD A ;SCHIEBE BIT IN POSITION D3 MOV B,A ;RETTE BIT IN B LDA SELMSK ;LESE SELECT-MASKE ORA B ;SETZE SEITEN—BIT OUT FDCPORT ;SELCT LAUFWERK STA LSEL ;RETTE AUSGABEWERT POP B ;RESTORE B-REGISTER RET ;************************************************************************* ;UNTERPROGRAMM "DESEL " ;DESELEKTIERT LAUFWERK. ;IST DER LETZTE AUSGABEWERT (LSEL) = 00H ERFOLGT SOFORT EIN RETURN ;(IN DIESEM FALL IST KEIN LAUFWERK AKTIV). DIES VERHINDERT DAS ER- ;HEUTE ANLAUFEN DER MOTOREN. ;IST "LSEL" UNGLEICH 00H, SO WIRD 00H AUSGEGEBEN. DIESER WERT WIRD UNTER ;"LSEL" GESPEICHERT. ;NACH RETURN: A = 00 ;************************************************************************* DESEL: LDA LSEL ;LETZTER AUSGABEWERT ORA A ;NULL ? RZ ;JA —> RETURN XRA A ;DESELECT LAUFWERK OUT FDCPORT ;KOMMANDO AN FDC AUSGEBEN STA LSEL ;RETTE AUSGABEWERT RET ;************************************************************************* ;UNTERPROGRAMM "DREADY" ;DAS UNTERPROGRAMM GIBT DEM MOTOR DES DISKETTENLAUFWERKS 1 SEKUNDE ;ZEIT UM SEINE NENNDREHZAHL VON 300 UPM ZU ERREICHEN. DANACH WIRD DAS ;NOT-READY-BIT IM FDC-STATUS-REGISTER ABGEFRAGT. DAS UNTERPROGRAMM ;WIRD UEBER DEN "RET"-BEFEHL VERLASSEN. DAS CARRY-FLAG GIBT DEN ;LAUFWERK-ZUSTAND AN: ; NICHT BEREIT CARRY = 1 (GESETZT) ; BEREIT CARRY = 0 (NICHT GESETZT) ;WERTE BEIM AUFRUF: --- ; ;WERTE NACH RETURN: A = UNBESTIMMT ; HL = 0000 ; CARRY-FLAG: SIEHE OBEN ;************************************************************************* DREADY: LXI H,DRV_WAIT ;$0800 minimum für Motor Anlaufzeit (1 sec) CALL DELAY ;(MOTOR HOCHLAUF-ZEIT) IN FDCSTAT ;LESE STATUS RLC ;READY RET ;RETURN (CARRY = 0 -> BEREIT) ; (CARRY = 1 -> NICHT BEREIT) ;************************************************************************* ;UNTERPROGRAMM "DELAY" ; ;VERZOEGERUNGSSCHLEIFE. LAUFZEIT ETWA HL*1 MS (BEI 2 MHZ TAKT) ;WERTE BEIM AUFRUF: HL = LAUFZEIT IN MILLISEKUNDEN ;************************************************************************* DELAY: PUSH H ;RETTE ZAEHLER LXI H,DRV_DELAY ; 83 bei 2MHz CPU-Takt ; LXI H,164 ;164 bei 4MHz CPU-Takt DELAY0: DCX H ;LAUFZEIT ETWA 1 MSEC MOV A,H ;BEI 2 MHz TAKT ORA L ; JNZ DELAY0 ;LOOP POP H ;RESTORE ZAEHLER DCX H ;VERMINDERE ZAEHLER UM EINS MOV A,H ;HL = 0000 ? ORA L ; JNZ DELAY ;NEIN -> DELAY RET ;************************************************************************* ;UNTERPROGRAMM "GETPUT" ;SPEICHERT / LIEST FILES ;FUNKTION WIRD DURCH RAM-VEKTOREN FESTGELEGT. DAS DOS INITIALISIERT ;DIE VEKTOREN WIE FOLGT: ; ; VEKTOR LOAD SAVE ; XGP1 CALL RRS CALL RWVSEC ; XGP2 CALL MOVE RET ; XGP3 CALL PPLUS CALL PPLUS ; ;WERTE BEIM AUFRUF: LAENGE = FILE-LAENGE ; ZWSP4 = ZEIGER AUF TABELLE DER NUTZBAREN DIR-EINTR ; (SIEHE AUCH UNTERPROGRAMM "SEINTR") ; ZWSP1 = START-ADR (NUR FUER WRITE) ; SEL.MSK = SELECT-MASKE DES AUSGEW. LAUFWERKS ;************************************************************************* GETPUT: LHLD LAENGE ;REST = LAENGE SHLD REST ; GETP0: LHLD ZWSP4 ;ZEIGER AUF TABELLEN--POINTER CALL GETPOS ;LESE POSITION AUS TABELLE CALL POS ;POSITIONIERE KOPF MVI B,0 ;SEKTOR 1 MINUS EINS GPNXT: LHLD ZWSP1 ;ANFANG DIESES TEILS (NUR FUER WRITE) INR B ;NAECHSTER SEKTOR MOV A,B ;SEKTOR-NUMMER AN FDC OUT FDCSEC ;AN DEN FDC CALL XGP1 ;LOAD: LESE SEKTOR ;SAVE: SCHREIBE SEKTOR GPOK: SHLD ZWSP1 ;RETTE ZEIGER (NUR FUER WRITE) CALL XGP2 ;LOAD: MOVE SEKTOR-BUFFER-INHALT ; ZUM ZIEL-SPEICHER ;SAVE: NOP LHLD REST ;REST-LAENGE LXI D,512 ;SEKTOR-LAENGE CALL SUB2 ;REST-LAENGE MINUS SEKTOR-LAENGE JC GP0 ;REST < 0000 —> GPO MOV A,L ;REST = 0000 ? ORA H ; JZ GP0 ;REST = 000 -> GPO SHLD REST ;RETTE NEUE REST-LAENGE MOV A,B ;AKTUELLE SEKTOR-NUMMER NACH A CPI 8 ;SEKTOR-NUMMER = 8 JNZ GPNXT ;NEIN -> NAECHSTER SEKTOR, ; GLEICHE SPUR CALL XGP3 ;LOAD, SAVE: PRINT "+" JMP GETP0 ;NAECHSTER EINTRAG GP0: CALL XGP3 ;LOAD, SAVE: PRINT "+" RET ;************************************************************************* ;UNTERPROGRAMM "POSDIR" ;UEBERGIBT DEM FDC DIE DATEN ZUR KOPF-POSITIONIERUNG UEBER DER ;DIRECTORY. IN "SEMSK" MUSS DIE SELECT-MASKE DES GEWUENSCHTEN LAUFWERKS ;STEHEN. IST DAS LAUFWERK NACH 1 SEKUNDE NICHT BEREIT, VERZWEIGT DAS ;PROGRAMM NACH "CODE3" (LAUFWERK NICHT BEREIT). SONST GEHT DAS PROGRAMM ;OHNE RETURN IN DAS UNTERPROGRAMM "WPTST" UEBER. (SIEHE AUCH DORT) ;************************************************************************* POSDIR: XRA A ;A = 0 STA SEITE ;SEITE 0 CALL SELECT ;SELECT LAUFWERK CALL DREADY ;LAUFWERK BEREIT ? CC CODE3 ;NEIN -> CODE3 ;************************************************************************* ;UNTERPROGRAMM "WPTST" ;DAS UNTERPROGRAMM STELLT DEN KOPF DES SELEKTIERTEN LAUFWERKS UEBER ;SPUR 0 UND PRUEFT, OB DIE DARIN ENTHALTENE DISKETTE SCHREIBGESCHUETZT IST. ;TRETEN BEIM RESTORE-BEFEHL FEHLER AUF, VERZWEIGT DAS PROGRAMM NACH "CODE1" ; ;WERTE NACH RETURN: Z—FLAG = 0 (NICHT GESETZT): DISKETTE SCHREIBGESCHUETZT ; Z—FLAG = 1 ( GESETZT ) DISKETTE NICHT SCHR.-GESCHUETZT ;************************************************************************* WPTST: CALL INTINT ;INTERRUPT-ROUTINE INITIALISIEREN CALL RESTORE ;KOPF AUF SPUR NULL ANI %10011100 ;OK ? CPI %00000100 ; CNZ CODE1 ;NEIN -> CODE1 MOV A,E ;RESTORE STATUS ANI %01000000 ;WRITE PROTECTED ? RET ;Z-FLAG = 0 -> JA ;Z-FLAG = 1 -> NEIN ;************************************************************************* ;UNTERPROGRAMM "POS" ;DAS UNTERPROGRAMM POSITIONIERT DEN KOPF ENTSPRECHEND DEN WERTEN IM ;B- UND C-REGISTER UEBER EINEN FILE. ; ;WERTE BEIM AUFRUF B=NUMMER DES DIRECTORY-SEKTORS IN DEM DER FILE- ; EINTRAG STEHT ; C=RELATIVE NUMMER DES EINTRAGS INNERHALB DES ; DIR.-SEKTORS ; ; (B- UND C-WERTE: SIEHE AUCH UNTERPROG. "SEINTR") ; ; "SELMSK" MUSS DIE SELECT-MASKE DES AUSGEUAEHLTEN ; LAUFWERKS ENTHALTEN ;************************************************************************* POS: MOV H,B ;SEKTOR-NUMMER NACH H MOV L,C ;EINTRAGS—NUMMER NACH L CALL CTS ;BERECHNE TRACK UND SEITE CALL SELECT ;SELEKTIERE LAUFWERK UND SEITE LDA SPUR ;POSITIONIERE KOPF AUF SPUR OUT FDCDAT ; CALL SEEK ; ANI %10011000 ;SEEK ERROR ? CNZ CODE6 ;JA —> CODE6 MOV A,E ;RESTORE STATUS RET ;************************************************************************* ;UNTERPROGRAMM "CTS" (COMPUTE TRACK AND SIDE) ;DIESES UNTERPROGRAMM ERMITTELT DIE SPUR (TRACK) UND DIE DISKETTENSEITE, ;AUF DER SICH EIN FILE (BZW. EIN 4K-BLOCK DAVON) BEFINDET. ;BEIM AUFRUF DIESES UNTERPROGRAMMS MUESSEN DIE REGISTER B UND C FOLGENDE ;ANGABEN ENTHALTEN: ;B-REGISTER: NUMMER DES DIRECTORY-SEKTORS, IN DEM DER EINTRAG ZU DEM FILE ; STEHT (1..5) ;C—REGISTER: RELATIVE NUMMER DES EINTRAGS IM DIRECTORY-SEKTOR (1..16) ; ;DIE ERRECHNETEN WERTE FUER SPUR UND SEITE WERDEN UNTER "SPUR" BZW- "SEITE" ;IM RAM GESPEICHGERT. ; ;NACH RETURN SIND DIE INHALTE FOLGENDER REGISTER VERAENDERT: ; A = (SPUR) ; B = 00 ;************************************************************************* CTS: MVI A,$F0 ;-16 ;BERECHNE ABSOLUTE ADDSEC: ADI 16 ;NUMMER DES EINTRAGS DCR B ;(1..79) JNZ ADDSEC ; ADD C ; PUSH PSW ;RETTE EINTRAGS-NUMMER (1...79) ANI %00000001 ;MASKIERE SEITEN-BIT ;GERADE EINTRAGS-NUMMER = SEITE 0 ;UNGERADE EINTRAGS-NUMMER = SEITE 1 STA SEITE ;RETTE SEITEN-NUMMER POP PSW ;RESTORE EINTRAGS-NUMMER (1...79) ORA A ;CLEAR CARRY RAR ;BERECHNE RELATIVE SPUR-NUMMER ;(0 .. 39) AUF DER SEITE STA SPUR ;RETTE SPUR-NUMMER RET ;************************************************************************* ;UNTERPROGRAMM "GETPOS" ;DAS BFZ—MIMI—DOS TEILT FILES IN 4K-BYTE-BL0ECKE EIN. FUER JEDEN DIESER ;BLOECKE WIRD EIN DIRECTORY-EINTRAG BENOETIGT. DIE POSITIONEN DER EINTRAEGE ;EINES FILES KANN MAN AUCH EIN EINER TABELLE ANGEBEN. SOLCHE TABELLEN WERDEN ;Z.B. VOM UNTERPROGRAMM "SEINTR" AUFGESTELLT. ;DIE TABELLEN BESITZEN FOLGENDEN AUFBAU: ; ;REL. POSITION DES EINTRAGS IM DIR.-SEKTOR ) ANFANG FUER DEN ;NUMMER DES DIRECTORY-SEKTORS ) 1. EINTRAG ; ;REL. POSITION DES EINTRAGS IM DIR.-SEKTOR ) ANFANG FUER DEN ;NUMMER DES DIRECTORY-SEKTORS ) 2. EINTRAG ; ; USW. ; ;WILL MAN Z.B. EINEN FILE LESEN, SO MUESSEN DER REIHE NACH ALLE ZU DEN ;EINZELNEN EIMTRAEGEN GEHOERENDEN BLOECKE EINGELESEN WERDEN. ;ES EXISTIERT EIN ZEIGER, DER ZU BEGINN AUF DEN TABELLENANFANG ZEIGT. ;LIEST MAN DIE ANGABEN FUER EINEN EINTRAG AUS DER TABELLE, SO WIRD DER ;ZEIGER AUF DIE NAECHSTEN ANGABEN WEITERGESTELLT. ; ;MIT HILFE DIESES UNTERPROGRAMMS KOENNEN DIE EINZELNEN ANGABEN AUS DER ;TABELLE GELESEN WERDEN. DAS PROGRAMM STELLT DEN TABELLENZEIGER AUTOMATISCH ;WEITER. ; ;DA MEHRERE TABELLEN EXISTIEREN KOENNEN, DIENT DAS HL—REGISTERPAAR BEIM ;UNTERPROGRAMMAUFRUF AUCH ALS ZEIGER. ES ZEIGT AUF DEN GERADE AKTUELLEN ;TABELLENZEIGER: ; HL -> TABELLENZEIGER -> TABELLE ; ;DIE ANGABEN AUS DER TABELLE WERDEN BEIM AUSLESEN IN DIE REGISTER B UND C ;GELADEN: ; ;B-REGISTER: DIRECTORY-SEKTOR ;C—REGISTER: REL. NUMMER DES EINTRAGS IM DIR„-SEKTOR ; ;NACH RETURN SIND FOLGENDE REGISTER VERAENDERT:; ; ;BC = (SIEHE OBEN) ;DE = NEUER WERT DES TABELLENZEIGERS ;************************************************************************* GETPOS: MOV E,M ;E=LOW (TABELLEN-ZEIGER) INX H ;ZEIGER AUF HIGH(TAB-ZEIGER) MOV D,M ;D=HIGH (TAB-ZEIGER) XCHG ;HL-TAB-ZEIGER, DE-ZEIGER AUF H(TAB—ZEIGER) MOV C,M ;C=LOW (TAB-EINTRAG) INX H ;ZEIGER AUF HIGH(TAB-EINTRAG) MOV B,M ;B=HIGH (TAB-EINTRAG) INX H ;ZEIGER AUF LOW (NAECHST. TAB-EINTRAG) XCHG ;DE=TAB-ZEIGER, HL-ZEIGER AUF H(TAB-ZEIGER) MOV M,D ; SPEICHERE NEUEN TAB-ZEIGER DCX H ; MOV M,E ; RET ; ;************************************************************************* ;UNTERPROGRAMM "GSTART" ;DRUCKT START-ADRESSEN-VORSCHLAG (STEHT IN STARTA) UND HOLT EVTL. ;NEUE ADRESSE. DIE (NEUE) START-ADR WIRD IN "STARTA" GESPEICHERT ;DAS AUSGEWAEHLTE LAUFWERK (SELEKT-MASKE IN "SELMSK") WIRD SELEKTIERT. ;FALLS ES NICHT BEREIT IST, VERZWEIGT DAS PROGRAMM NACH "CODE3" ;************************************************************************* GSTART: CALL DESEL ;DESELECT LAUFWERK CALL BUFCLR ;LOESCHE MAT85-INPUT-BUFFER LHLD STARTA ;LADE START-ADR CALL HSTART ;NEUE START-ADR ? SHLD STARTA ;SPEICHERE (NEUE) START-ADR CALL CRLF ;PRINT CR,LF CALL SELECT ;SELECT LAUFWERK CALL DREADY ;LAUFWERK BEREIT ? CC CODE3 ;NEIN -> CODE3 RET ;************************************************************************* ;UNTERPROGRAMM "GSTSP" ;DRUCKT VORSCHLAGS-ADRESSEN FUER START/STOP (ADRESSEN AUS "STARTA" BZW. ;"STOPA"), HOLT NEUE ADRESSEN UND SPEICHERT SIE IN "STARTA" BZW. "STOPA" ;AB. ;WERTE NACH RETURN: DE = START-ADRESSE ; HL = STOP-ADRESSE ;************************************************************************* GSTSP: CALL BUFCLR ;LOESCHE MAT85-INPUT—BUFFER CALL HSTSPA ;HOLE START/STOP-ADR SHLD STARTA ;RETTE START-ADR XCHG ;HL=STOP—ADR SHLD STOPA ;RETTE STOP-ADR RET ;************************************************************************* ;UNTERPROGRAMM "MOVE" ;DIESES UNTERPROGRAMM KOPIERT DIE DATENBYTES AUS DEM SEKTOR-PUFFER "SECB" ;IN DEN ZIEL-SPEICHER. ES PRUEFT, OB DAS BYTE ERFOLGREICH IN DEN ZIEL- ;SPEICHER GESCHRIEBEN WURDE. ;BEI EINEM FEHLER, VERZWEIGT DAS PROGRAMM NACH "CODE14". ; ;WERTE BEIM AUFRUF: (TEINT) = ANFANG DES ZIELSPEICHERS ; (REST) = ANGABE UEBER DIE ANZAHL DER ZU ; KOPIERENDEN BYTES: ; (REST) >= 512 -> 512 BYTES KOPIEREN ; (REST) < 512 -> (REST) BYTES KOPIEREN ; ;WERTE NACH RETURN: (TEINT) = ALTER WERT + ANZ. DER KOPIERTEN BYTES ; ;VERAENDERTE REGISTER: A = 00 ; ;************************************************************************* MOVE: PUSH B ;RETTE REGISTER PUSH D ; PUSH H ; LHLD REST ;LADE REST-LAENGE XCHG ;REST-LAENGE NACH DE LXI H,512 ;SEKTOR-LAENGE CALL CMPHD ;REST > SEKTOR-LAENGE JNC MOVE0 ;NEIN —> MOVE0 XCHG ;DE=SEKTOR-LAENGE (512) MOVE0: LHLD TEINT ;ZIEL-ADR NACH HL LXI B,SECB ;ZEIGER AUF SEKTOR-BUFFER MOVE1: LDAX B ;ZEICHEN AUS BUFFER IN AKKU MOV M,A ;ZEICHEN IN ZIEL-SPEICHER CMP M ;ZEICHEN IN ZIEL-SPEICHER ? CNZ CODE14 ;NEIN —> CODE14 INX H ;ZEIGER WEITERSTELLEN INX B ; DCX D ;EIN BYTE UEBERTRAGEN MOV A,D ;ZAEHLER = 0000 ? ORA E ; JNZ MOVE1 ;NEIN —> NAECHSTES BYTE SHLD TEINT ;RETTE NEUE ZIEL-ADR POP H ;RESTORE REGISTER POP D ; POP B ; RET ;************************************************************************* ;UNTERPROGRAMM "DELETE" ;BEREITET DAS UNTERPROGRAMM "MDIR" ZUM LOESCHEN VON DIRECTORY-EINTRAEGEN ;VOR. DAS UNTERPROGRAMM "DELETE" GEHT OHNE RETURN IN DAS UNTERPROGRAMM ;"MDIR" UEBER. ; ;WERTE BEIM AUFRUF: ANZAHL DER ZU LOESCHENDEN EINTRAEGE ; DIE POSITIONEN DER EINTRAEGE MUESSEN IN DER TABELLE ; "TVORH" STEHEN. ; AUFBAU DER TABELLEN-ANGABEN: ; DIE TABELLE ENTH. FUER JEDEN EINTRAG EINE 2-BYTE ANGABE ; LOW-BYTE: POSITION DES EINTRAGS INNERHALB DES DIR—SEKTORS ; HIGH-BYTE: NUMMER DES DIRECTORY-SEKTORS ; ;************************************************************************* DELETE: STA ZWSP2 ;ANZAHL DER ZU LOESCHENDEN EINTRAEGE LXI H,TVORH ;ZEIGER AUF "TVORH" INITIALISIEREN SHLD ZWSP1 ; LXI H,$0036 ;CODE: "MVI M,00" SHLD XDIR ;EINSETZEN MVI A,RETURN ;RET-OPCODE STA XDIR+2 ;EINSETZEN ;************************************************************************* ;UNTERPROGRAMM "MDIR" (MODIFIZIERE DIRECTORY) ; ;DIESES UNTERPROGRAMM MODIFIZIERT DAS DIRECTORY. DIE ART DER MODIFIKATION ;(EINTRAG ERSTELLEN, EINTRAG LOESCHEN) MUSS VOR DEM UNTERPROGRAMM-AUFRUF ;DURCH MODIFIKATION DES VEKTORS "XDIR" FESTGELEGT WERDEN. ; ;EINTRAG LOESCHEN: XDIR = MVI M,00 ; RET ; ;EINTRAG ERSTELLEN: XDIR = CALL VEINTR ; ;WERTE BEIM AUFRUF: (ZUSP1) = ZEIGER AUF EINEN TABELLENZEIGER ; (ZUSPl) = TAB.-ZEIGER --> TABELLE ; DIE TABELLE ENTHAELT ANGABEN UEBER DIE POSITION ; DER ZU MODIFIZ. EINTRAEGE INNERHALB DES DIRECTORY. ; PRO EINTRAG ENTH. DIE TABELLE EINE 2—BYTE—ANGABE: ; LOW-BYTE: POS. DES EINTRAGS INNERN. DES DIR.-SEKTORS ; HIGH-BYTE: NUMMER DES DIRECTORY-SEKTORS ; ; (ZUSP2) - ANZAHL. DER ZU MODIFIZIERENDEN EINTRAEGE ; ;************************************************************************* MDIR: CALL POSDIR ;POSITIONIERE KOPF AUF DIRECTORY LXI H,ZWSP1 ;ZEIGER AUF TABELLEN-POINTER CALL GETPOS ;LESE POSITION AUS TABELLE MDIR1: MOV A,B ;SEKTOR-NUMMER NACH A OUT FDCSEC ;SEKTOR-NUMMER AN FDC CALL RRS ;LESE SEKTOR (MAXTRY VERSUCHE) MDIR0: CALL SELECT ;KEEP DRIVE ROTATING MOV A,C ;EINTRAGS-NUMMER NACH A CALL ANFEIN ;ZEIGER AUF EINTRAGS-ANFANG CALL XDIR ;MODIFIZI ERE DI RECTORY-SEKTOR LXI H,ZWSP2 ;ZEIGER AUF ZAEHLER DCR M ;ZAEHLER MINUS EINS JZ MDEND ;SPRINGEv WENN ALLE EINTRAEGE MODIFIZIERT MOV A,B ;ALTE SEKTOR-NUMMER NACH A LXI H,ZWSP1 ;ZEIGER AUF TABELLEN-POINTER CALL GETPOS ;LESE POSITION AUS TABELLE CMP B ;GLEICHER SEKTOR WIE LETZTER EINTRAG ? JZ MDIR0 ;JA —> MDIR0 PUSH B ;RETTE SEKTOR-NR. (B) UND EINTRAGS-NR.(C) CALL SAVSEC ;SCHREIBE GEAENDERTEN DIRECTORY-SEKTOR POP B ;RESTORE SEKTOR- (B) UND EINTRAGS-NR. (C) JMP MDIR1 ;LESE ZU AENDERNDEN SEKTOR EIN MDEND: CALL SAVSEC ;SCHREIBE GEAENDERTEN DIRECTORY-SEKTOR RET ;************************************************************************* ; ;UNTERPROGRAMM "ANZAHL" ; ;DIESES UNTERPROGRAMM BERECHNET AUS DER FILE-LAENGE WIEVIELE 4K-BYTE- ;BLOECKE ZUM ABSPEICHERN BENOETIGT WERDEN. ; ;WERTE BEIM AUFRUF: HL = FILE-LAENGE ; ;WERTE NACH RETURN: HL = REST (FILELAENGE / 4096) ; ; WENN HL = 0000 WENN HL <> 0000 ; B=FILELAENGE/4096 B=FILELAENGE/4096 + 1 ; ;************************************************************************* ANZAHL: MVI B,0 ;BERECHNE: LHLD LAENGE ;WIEVIELE VOLLE TRACKS LXI D,BLOCKSIZE ;A 4k-BYTE WERDEN ZUM ANZ1: CALL SUB2 ;ABSPEICHERN BENOETIGT JC ANZ0 ;RECHNUNG: HL/1000H INR B ;ERGEBNIS: B JMP ANZ1 ;REST: HL ANZ0: DAD D ; MOV A,H ;REST = 0000 ? ORA L ; RZ ;JA —> RETURN INR B ;PLUS EIN EINTRAG FUER DEN REST RET ; ;************************************************************************* ;UNTERPROGRAMM "VEINTRAG" (VERMERKE DIRECTORY-EINTRAG) ; ;WIRD VON "MDIR"UEBER DEN VEKRTOR "XDIR" AUFGERUFEN, WENN NEUE DIRECTORY- ;EINTRAEGE ERSTELLT WERDEN SOLLEN. ; ;WERTE BEIM AUFRUF: (EFROM) = ENTERED-FROM-CODE (VON WO WURDE DAS DOS ; AUFGERUFEN?) 01=MAT85, 02= SPS, 03=BASIC ; (ZWSP2) = ANZAHL DER BENOETIGTEN EINTRAEGE ; (EIN FILE BENOETIGT FUER JEDEN 4K-BYTE-BL0CK ; EINEN EINTRAG. DIESES UNTERPROGRAMM ERZEUGT ; NUR EINEN EINTRAG UND MUSS DESHALB ENTSPRECHEND ; OFT AUFGERUFEN WERDEN. WIRD DER LETZTE EINTRAG ; EINES FILES ERZEUGT, SO ERHAELT DIESER EINE BESONDERE ; MARKIERUNG. UM ERKENNEN ZU KOENNEN, DASS ES SICH ; UM DEN LETZTEN EINTRAG HANDELT, MUSS DER INHALT ; VON "ZWSP2" DANN DEN WERT "01" HABEN.) ; ; (START) = START-ADRESSE DES FILES ; ; (LAENGE) = LAENGE DES FILES ; ; MAT85-INPUT-PUFFER = FILE—NAME (RUECKWAERTS) ; (EVENTUELL MIT 80H AUF 12 ZEICHEN AUFGEFUELLT) ;************************************************************************* VEINTR: PUSH B ;RETTE BC LDA EFROM ;LESE ENTERED-FROM-CODE: 01 = MAT ; 02 = SPS ; 03 = BASIC MOV D,A ;RETTE CODE IN D LDA ZWSP2 ;ANZAHL DER BENOETIGTEN EINTRAEGE DCR A ;ANZAHL MINUS EINS JZ LASTE ;SPRINGE, WENN LETZTER EINTRAG MVI A,%10000000 ;SETZE BIT 7, LOESCHE BIT 1 ... BIT 6 LASTE: ORA D ;VERKNUEPFE MIT ENTERED-FROM-CODE MOV M,A ;SETZE KENNBYTE EIN INX H ;ZEIGER AUF NAMENS-FELD LXI D,M85BE-1 ;MAT85-INPUT-BUFFER (FILE-NAME) MVI B,12 ;LAENGE (NAME) NXTCHR: LDAX D ;ZEICHEN IN AKKU MOV M,A ;ZEICHEN IN BUFFER INX H ;STELLE ZEIGER WEITER DCX D ; DCR B ;ALLE ZEICHEN UEBERTRAGEN ? JNZ NXTCHR ;NEIN —> NXTCHR XCHG ;DE = BUFFER-ZEIGER LHLD STARTA ;HL = START-ADR XCHG ;DE = START-ADR, HL = BUFFER-ZEIGER MOV M,E ;SETZE START-ADR EIN INX H ; MOV M,D ; INX H ; XCHG ;DE = BUFFER-ZEIGER LHLD LAENGE ;HL = LAENGE XCHG ;DE = LAENGE, HL = BUFFER—ZEIGER MOV M,E ;SETZE LAENGE EIN INX H ; MOV M,D ; POP B ;RESTORE BC RET ; ;************************************************************************* ;UNTERPROGRAMM "ANFEIN" ; ;DIESES UNTERPROGRAMM STELLT DEN ZEIGER IM HL-REGISTERPAAR UEBER DEN ;ANFANG EINES BESTIMMTEN DIRECTORY-EINTRAGS. DER DIRECTORY-SEKTOR MUSS ;DAZU IM SEKTOR-PUFFEF "SECB" STEHEN UND DER AKKUMULATOR MUSS DIE NUMMER ;DES EINTRAGS (1...16) INNERHALB DES SEKTORS ENTHALTEN ; ;************************************************************************* ANFEIN: LXI H,SECB-32 ;BUFFER-ANFANG MINUS 32 LXI D,32 ;OFFSET VON EINTRAG ZU EINTRAG DADOFS: DAD D ;ADD OFFSET DCR A ;SO OFT WIE NOETIG JNZ DADOFS ; RET ;************************************************************************* ;UNTERPROGRAMM "GETNAM " ;LIEST FILE-NAME UND PRUEFT IHN AUF GUELTIGKEIT ; ;GEBE ANFORDERUNG AUS ; ;************************************************************************* GETNAM: CALL PTXTCR ;TEXT AUSGEBEN .byte LF,"NAME: ",00 ;************************************************************************* ;VORBEREITUNG ;ERWARTET WERDEN MAXIMAL 12 ASCII-ZEICHEN (KEIN "+", KEIN "-") ;WANDLE ALLE EINGEGEBENEN BUCHSTABEN IN GROSSBUCHSTABEN UM ; ;************************************************************************* XRA A ;A=0 STA GROFLG ;NUR GROSSBUCHSTABEN STA BCKFLG ;KEIN +,- MOV C,A ;ASCII MVI B,12 ;MAX 12 ZEICHEN CALL BUFCLR ;LOESCHE EINGABE-BUFFER ;************************************************************************* ;LESE FILE-NAME EIN ;************************************************************************* CALL BREAD ;LESE NAME CALL CRLF ;PRINT CR,LF ;************************************************************************* ;PRUEFE NAME AUF GUELITIGKEIT ;(ER STEHT RUECKUAERTS IM MAT85-INPUT-PUFFER, EINE MAT85-EIGENART) ;************************************************************************* TSTNAM: LXI H,M85BE-1 ;ZEIGER AUF 1. ZEICHEN MOV A,M ;LESE 1. ZEICHEN CALL TSTCHR ;BUCHSTABE ODER ZIFFER ? CNC CODE9 ;NEIN —> CODE9 MVI C,7 ;MAX 7 WEITERE ZEICHEN BIS "." TNAM0: DCX H ;ZEIGER AUF NAECHSTES ZEICHEN MOV A,M ;LESE ZEICHEN CALL TSTCHR ;BUCHSTABE ODER ZIFFER ? JNC TNAM1 ;NEIN -> TNAM1 ("." ODER ENDE) DCR C ;ZAEHLER MINUS EINS JNZ TNAM0 ; DCX H ;ZEIGER AUF NAECHSTES ZEICHEN MOV A,M ;LESE ZEICHEN TNAM1: ORA A ;BIT 7 GESETZT (ENDE) ? RM ;JA — > RETURN CPI "." ;PUNKT ? CNZ CODE9 ;NEIN —> C0DE9 DCX H ;ZEIGER AUF NAECHSTES ZEICHEN MOV A,M ;LESE ZEICHEN CALL TSTCHR ;BUCHSTABE ODER ZIFFER ? CNC CODE9 ;NEIN —> CODE9 MVI C,2 ;MAX 2 WEITERE ZEICHEN TNAM2: DCX H ;ZEIGER AUF NAECHSTES ZEICHEN MOV A,M ;LESE ZEICHEN ORA A ;BIT 7 GESETZT (ENDE) ? RM ;JA —> RETURN CALL TSTCHR ;BUCHSTABE ODER ZIFFER ? CNC CODE9 ;NEIN —> CODE? DCR C ;ZAEHLER MINUS EINS JNZ TNAM2 ; DCX H ;ZEIGER AUF NAECHSTES ZEICHEN MOV A,M ;LESE ZEICHEN ORA A ;BIT 7 GESETZT (ENDE) ? RM ;JA —> RETURN CALL CODE9 ;NEIN —> CODE? ;************************************************************************* ;UNTERPROGRAMM "SEINTR" (SUCHE EINTRAG) ; ;FUNKTION: 1. WENN (DSPLD) = 00 ; ES WERDEN ALLE DIRECTORY-EINTRAEGE GEZAEHLT, DIE ENTWEDER ; FREI SIND ODER, DEREN NAMEN MIT DEM IM MAT85-INPUT—PUFFER ; UEBEREINSTIMMEN. ; DER ZAEHLER WIRD IN "ZAEHL" ABGESPEICHERT. ; DIE ERSTEN 16 EINTRAEGE WERDEN IN DER TABELLE "TEINT" VERMERKT. ; ANZAHL DER GUELTIGEN EINTRAEGE IN "TEINT": ; (ZAEHL) < 17 : (ZAEHL) GIBT DIE ANZAHL AN. ; (ZAEHL) >= 17 : 16 GUELTIGE EINTRAEGE. ; ; AUSSERDEM WERDEN ALLE EINTRAEGE GEZAEHLTy DEREN NAMEN MIT DEM ; IM MAT85-INPUT-BUFFER UEBEREINSTIMMEN (IM GEGENSATZ ZUM ERSTEN ; ZAEHLER WERDEN FREIE EINTRAEGE NICHT MITGEZAEHLT). DA FUER ; JEDEN 4K-BYTE-BLOCK EIN EINTRAG BESTEHT UND DA DIE MAXIMALE ; FILE-LAENGE 65535 BYTE BETRAEGT, KANN DER ZAEHLER MAXIMAL DEN ; WERT 16 ANNEHMEN. ; ; DER ZAEHLER WIRD IN "ZAEHLV" ABGESPEICHERT. ; DIE EINTRAEGE WERDEN IN DER TABELLE "TVORH" VERMERKT. ; "ZAEHLV" GIBT DIE ANZAHL DER GUELTIGEN EINTRAEGE IN DIESER ; TABELLE AN. ; ; 2. WENN (DSPLD) <> 00 ; DAS INHALTSVERZEICHNIS WIRD ANGEZEIGT. ; ES WERDEN DANN NUR DIE FREIEN EINTRAEGE IN "ZAEHL" GEZAEHLT. ; DIE ERSTEN 16 DIESER EINTRAEGE WERDEN IN DER TABELLE "TEINT" ; VERMERKT. ; ; ANZAHL DER GUELTIGEN EINTRAEGE IN "TEINT": ; (ZAEHL) < 17 : (ZAEHL) GIBT DIE ANZAHL AN. ; (ZAEHL) >= 17 : 16 GUELTIGE EINTRAEGE. ; ;DAS INHALTSVERZEICHNIS IST WIE FOLGT AUFGEBAUT: ;ES BESTEHT AUS DEN SEKTOREN 1,2,3,4 UND 5 AUF SPUR 0, SEITE 0. ;JEDER SEKTOR BESTEHT AUS 16 EINTRAEGEN MIT JE 32 BYTE. ;DER LETZTE EINTRAG IM 5. SEKTOR WIRD NICHT GENUTZT. ;DAMIT ERGIBT SICH EINE ANZAHL VON 79 GENUTZTEN EINTRAEGEN. ; ;FUER JEDES FILE WIRD PRO ANGEFANGENE 4K—BYTE EIN EINTRAG BELEGT. ;FILES, DIE MEHR ALS EINEN EINTRAG BELEGEN (LAENGE > 4K—BYTE), WERDEN ;ALS "MEHRFACH-EINTRAG" BEZEICHNET. FILES, DIE NUR EINEN EINTRAG BELEGEN ;(LAENGE <= 4K-BYTE), WERDEN ALS "EINZEL-EINTRAG" BEZEICHNET. ; ;BEI MEHRFACH-EINTRÄEGEN BEFINDEN SICH DIE EINTRAEGE ZU DEN EINZELNEN ;4K-BYTE-BL0ECKEN IN DER REIHENFOLGE, IN DER DIE EINZELNEN BLOECKE BEIM ;ABSPEICHERN IM SPEICHER STANDEN. ; ;EIN EINTRAG ENTHAELT FOLGENDE INFORMATION: ; 1. BYTE : KENNBYTE ; 2. - 13. BYTE : FILE-NAME INCL. ".", RECHTS MIT 80h AUFGEFUELLT ; 14. - 15. BYTE : START-ADR (BEI MEHRFACH-EINTRAEGEN START-ADR DES 1. BLOCKS) ; 16. - 17. BYTE : LAENGE (BEI MEHRFACH—EINTRAEGEN LAENGE DES GESAMT-FILES) ; 18. - 32. BYTE : OHNE BEDEUTUNG ; ;DAS KENNBYTE HAT FOLGENDE BEDEUTUNG: ;0000 0000 - EINTRAG FREI ; ;SONST: ;1XXX XXXX - TEIL 1 ... N EINES N-TEILIGEN MEHRFACH-EINTRAGS ;0XXX XXXX - TEIL N EINES N-TEILIGEN MEHRFACH-EINTRAGS ; ODER EINZEL-EINTRAG ; ;BEI EINEM BELEGTEN EINTRAG GEBEN DIE BITS 0 BIS 6 AUSKUNFT ;UEBER DEN FILE-TYP: ;X000 0001 - MAT ;X000 0010 - SPS ;X000 0011 - BAS ; ;DER TYP GIBT AN, VON WO DAS DOS VOR DEM ABSPEICHERN EINES FILES ;AUFGERUFEN WURDE. ; ;BEISPIEL: TYP = "BAS": DAS DOS WURDE VON BASIC AUFGERUFEN ; DAS FILE IST SOMIT EIN BASIC-PROGRAMM ; ;DIE POSITION EINES EINTRAGS INNERHALB DES VERZEICHNISES GIBT ;AUSKUNFT DARUEBER, WO DER IM EINTRAG ANGEGEBENE FILE AUF DER ;DISKETTE GESPEICHERT IST. ; ;DAZU WERDEN DIE EINZELNEN DIRECTORY-EINTRAEGE UEBER ALLE DIRECTORY- ;SEKTOREN VON 1 BIS 79 DURCHNUMMERIERT. ; ;STELLT MAN DIE EINTRAGS-NUMMER (1 ... 79) BINAER DA, SO GIBT BIT 0 ;DIE SEITE AN: ;XXXX XXX0 - SEITE 0 ;XXXX XXX1 - SEITE 1 ; ;DIE BITS 1 BIS 7 GEBEN DIE SPUR AN: ; ;BEISPIELE: EINTRAGS-NUMMER BINAER-DARSTELLUNG SEITE SPUR ; 1 0000 0001 1 0 ; 2 0000 0010 0 1 ; 3 0000 0011 1 1 ; 4 0000 0100 0 2 ; 5 0000 0101 1 2 ; . ; . ; 78 0100 1110 0 39 ; 79 0100 1111 1 39 ; ;SEITE 0, SPUR 0 IST DURCH DAS VERZEICHNIS BELEGT. ; ;NACH RETURN: 1. WENN (DSPLD) = 00 ; (ZAEHL) = ANZAHL DER FREIEN EINTRAEGE ; + ANZAHL DER EINTRAEGE MIT DEM FILE-NAMEN, ; DER IM MAT85-INPUT-PUFFER STEHT. ; A = ZAEHL ; WENN (ZAEHL) = 00 IST DAS Z-FLAG GESETZT. ; ; (ZAEHLV) = ANZAHL DER EINTRAEGE MIT DEM FILE-NAMEN, ; DER IM MAT85-INPUT-PUFFER STEHT ; ; DIE ERSTEN 16 EINTRAEGE, DIE ENTWEDER ; - FREI SIND ODER ; - DEREN NAME MIT DEM IM MAT85-INPUT-BUFFER UEBEREIMSTIMMT ; WERDEN IN DER TABELLE "TEINT" VERMERKT. ; ; ANZAHL DER GUELTIGEN EINTRAEGE IN "TEINT": ; (ZAEHL) < 17 : (ZAEHL) GIBT DIE ANZAHL AN ; <ZAEHL> >= 17 : 16 GUELTIGE EINTRAEGE ; ; DIE EINTRAEGE, DEREN NAME MIT DEM IM MAT85-INPUT-PUFFER ; UEBEREINSTIMMT, WERDEN IN DER TABELLE "TVORH" VERMERKT. ; (ZAEHLV) GIBT DIE ANZAHL DER GUELTIGEN EINTRAEGE IN ; DIESER TABELLE AN. ; ; 2. WENN (DSPLD) <> 00 ; (ZAEHL) = ANZAHL DER FREIEN EINTRAEGE ; A = ZAEHL ; WENN (ZAEHL) = 00 IST DAS Z-FLAG GESETZT ; ; DIE ERSTEN 16 EINTRAEGE, DIE FREI SIND, WERDEN IN DER ; TABELLE "TEINT" VERMERKT. ; ANZAHL DER GUELTIGEN EINTRAEGE IN "TEINT": ; (ZAEHL) < 17 : (ZAEHL) GIBT DIE ANZAHL AN. ; (ZAEHL) >= 17 : 16 GUELTIGE EINTRAEGE. ; ;DIE EINTRAEGE IN DEN TABELLEN "TEINT" UND "TVORH" BESTEHEN AUS JE ZWEI BYTES: ; - LOW BYTE: NUMMER DES RELATIVEN DIRECTORY-EINTRAGS <1 ... 16) ; - HIGH BYTE: NUMMER DES DIRECTORY-SEKTORS (1 ... 5) ; ;************************************************************************* ;VORBEREITUNG ;************************************************************************* SEINTR: XRA A ;A = 0 STA SEITE ;SEITE 0 STA ZAEHL ;ZAEHLER AUF NULL STA ZAEHLV ; LXI H,TEINT ;ZEIGER AUF DIE TABELLEN SHLD PTEINT ;"TEINT" UND LXI H,TVORH ;"TVORH" SHLD PTVORH ;INITIALISIEREN ;************************************************************************* ;KOPF LIEBER DIREKTORY POSITIONIEREN ;************************************************************************* CALL POSDIR ;POSITIONIERE KOPF AUF DIRECTORY ;************************************************************************* ;LESE DIRECTORY-SEKTOR EIN ;************************************************************************* MVI B,1 ;SEKTOR-NUMMER NEXT2: CALL SELECT ;RE—SELECT LAUFWERK MOV A,B ;SEKTOR—NUMMER NACH A OUT FDCSEC ;AN FDC CALL RRS ;READ SECTOR (MAXTRY VERSUCHE) ;************************************************************************* ;PRUEFE DIE EINTRAEGE ;************************************************************************* LXI H,SECB ;ZEIGER AUF SECTOR-BUFFER MVI C,1 ;1. EINTRAG DES SEKTORS NEXT1: SHLD ZWSP1 ;RETTE ZEIGER MOV A,M ;LESE ERSTES BYTE DES EINTRAGS ORA A ;EINTRAG FREI ? JNZ EBEL ;NEIN -> EBEL ;************************************************************************* ;HIER, WENN EINTRAG FREI ;************************************************************************* EFREI: LDA ZAEHL ;LADE ZAEHLER FUER "TEINT" INR A ;PLUS EINS STA ZAEHL ;RETTE NEUEN ZAEHLER-STAND LHLD PTEINT ;LADE ZEIGER AUF "TEINT" CALL REINTR ;REGISTRIERE EINTRAG SHLD PTEINT ;RETTE NEUEN ZEIGER JMP NEXT ; ;************************************************************************* ;HIER, WENN EINTRAG BELEGT ;SOLL DAS DIRECTORY ANGEZEIGT WERDEN ? ;************************************************************************* EBEL: MOV D,A ;RETTE KENN-BYTE IN D LDA DSPLD ;DISPLAY DIRECTORY ? ORA A ; JZ NODSPL ;NEIN —> NODSPL ;************************************************************************* ;HIER, WENN DIRECTORY ANGEZEIGT WERDEN SOLL ;************************************************************************* MOV A,D ;RESTORE KENN-BYTE ORA A ;BIT 7 GESETZT ? JM NEXT ;JA —> NEXT ;(TEIL 1 ... N-l EINES N—TEILIGEN ;MEHRFACH-EINTRAGS. BEI MEHRFACH- ;EINTRAEGEN WIRD NUR DER LETZTE ;EINTRAG ANGEZEIGT. ;************************************************************************* ;EINTRAG ANZEIGEN ;************************************************************************* PUSH B ;RETTE SEKTOR-NR. (B) UND EINTRAGS-NR. (C) MVI B,12 ;12 ZEICHEN ANZEIGEN DISPL: INX H ;ZEIGER AUF NAECHSTES ZEICHEN MOV A,M ;LESE ZEICHEN ORA A ;BIT 7 GESETZT (80H) ? JP NOB0 ;NEIN —> NOB0 MVI A," " ;LADE SPACE NOB0: CALL WCHAR ;PRINT ZEICHEN DCR B ;12 ZEICHEN GEDRUCKT ? JNZ DISPL ;NEIN —> DISPL ;************************************************************************* ;DRUCKE ZUSATZINFORMATIONEN ; 1. FILE-TYP (MAT,SPS,BASIC) ;************************************************************************* CALL WBLNKI ;PRINT 3 BLANKS .byte 3 CALL TYP ;PRINT FILE-TYP ;************************************************************************* ;2. START-ADRESSE ;************************************************************************* CALL WBLNKI ;PRINT 6 BLANKS .byte 6 ; INX H ;START-ABR LESEN MOV E,M ; INX H ; MOV D,M ; XCHG ; PUSH H ;RETTE START-ADR CALL PHL ;PRINT START-ADR ;************************************************************************* ;3. STOP-ADRESSE (WIRD AUS START-ADRESSE UND LAENGE BERECHNET) ;************************************************************************* CALL WBLNKI ;PRINT 10 BLANKS .byte 10 XCHG ;HL = BUFFER-ZEIGER INX H ;LAENGE LADEN MOV E,M ; INX H ; MOV D,M ; XCHG ; SHLD LAENGE ;RETTE LAENGE POP D ;RESTORE START-ADR DAD D ;HL-START-ADR PLUS LAENGE DCX H ;HL=STOP-ADR CALL PHL ;PRINT STOP-ADR ;************************************************************************* ;4. ANZAHL DER BLOECKE ;************************************************************************* CALL WBLNKI ;PRINT 7 BLANKS .byte 7 ; CALL ANZAHL ;BERECHNE ANZAHL DER BLOECKE MOV A,B ;ANZAHL NACH A CALL WDEZ ;PRINT ANZAHL ;************************************************************************* ;NAECHSTE ZEILE. PRUEFE, OB BILDSCHIRM VOLL (UNTERPROB. "LINE"). ;************************************************************************* CALL CRLF ;PRINT CR,LF CALL LINE ;ZAEHLE DIE AUSGEGEBENEN ZEILEN CALL SELECT ;KEEP DRIOE ROTATING JMP NEXT0 ;NAECHSTER EINTRAG ;************************************************************************* ;HIER, WENN DIRECTORY NICHT ANGEZEIGT WERDEN SOLL ; ;IST DER FILE-NAME IM DIRECTORY-EINTRAG IDENTISCH MIT DEM IM EINGABE-PUFFER ? ;************************************************************************* NODSPL: PUSH B ;RETTE SEKTOR-NR <B> UND EINTRAGS-NR. (C) MVI B,12 ;PRUEFE 12 ZEICHEN LXI D,M85BE-1 ;ZEIGER AUF FILE-NAMEN EBEL0: INX H ;STELLE ZEIGER AUF NAECHSTES ZEICHEN LDAX D ;ZEICHEN DES FILE-NAMENS NACH A CMP M ;VERGLEICHE MIT ZEICHEN AUS DIRECTORY JNZ NEXT0 ;SPRINGE, WENN UNGLEICH DCX D ;STELLE MAT85-BUFFER-ZEIGER WEITER DCR B ;12 ZEICHEN GEPRUEFT ? JNZ EBEL0 ;NEIN -> EBEL0 ;************************************************************************* ;HIER, WENN EINTRAGS-NAME = NAME (MAT85-INPUT-PUFFER) ; ;ZAEHLE EINTRAG UND REGISTRIERE IHN. ;************************************************************************* LDA ZAEHLV ;LADE ZAEHLER INR A ;ERHOEHE ZAEHLER STA ZAEHLV ;RETTE NEUEN ZAEHLER-STAND POP B ;RESTORE SEKTOR- (B) UND EINTRAGS-NR. (C) LHLD PTVORH ;ZEIGER AUF "TVORH" CALL REINTR ;REGISTRIERE EINTRAG SHLD PTVORH ;RETTE NEUEN ZEIGER PUSH B ; ;************************************************************************* ;NAECHSTER EINTRAG ;************************************************************************* NEXT0: POP B ;RESTORE SEKTOR- <B> UND EINTRAGS-NR. (C) NEXT: LXI D,32 ;OFFSET ZUM NAECHSTEN EINTRAG LHLD ZWSP1 ;ALTEM ZEIGER LADEN DAD D ;OFFSET ADDIEREN INR C ;NAECHSTER EINTRAG MVI A,17 ;MAX EINTRAG + EINS CMP C ;C-MAX EINTRAG + EINS ? JNZ NEXT1 ;NEIN —> NEXT1 ;************************************************************************* ;HIER, WENN NAECHSTER EINTRAG IM NAECHSTEN SEKTOR ;************************************************************************* INR B ;NAECHSTER SEKTOR MVI A,6 ;MAX SEKTOR + EINS CMP B ;B-MAX SEKTOR + EINS ? JNZ NEXT2 ;NEIN —> NEXT2 LDA ZAEHL ;KORRIGIERE ZAEHLER DCR A ; STA ZAEHL ; RET ;************************************************************************* ;UNTERPROGRAMM "REINTR" (REGISTRIERE EINTRAG) ; ;REGISTRIERT GEFUNDENEN EINTRAG IN TABELLE. (ALLERDINGS MAX. 16 EINTRAEGE) ; ;WERTE BEI AUFRUF: A = ANZAHL DER BEREITS REGISTR. EINTRAEGE + EINS ; B = NUMMER DES DIRECTORY-SEKTORS (1...5) ; C = REL. NUMMER DES EINTRAGS IM DIR.-SEKTOR (1...16) ; HL = ZEIGER AUF DIE TABELLENPOSITION, IN DER DER EINTRAG ; REGISTRIERT WERDEN SOLL. ;************************************************************************* REINTR: CPI 17 ;BEREITS 16 EINTRAEGE IN TABELLE ? RNC ;JA —> RETURN MOV M,C ;RETTE EINTRAGS-NUMMER INX H ;STELLE ZEIGER WEITER MOV M,B ;RETTE SEKTOR-NUMMER INX H ;STELLE ZEIGER WEITER RET ;************************************************************************* ;UNTERPROGRAMM "TYP" ; ;GIBT BEI DER ANZEIGE DES DIRECTORY DEN FILE-TYP ENTSPRECHEND DEM ;CODE ALS TEXT AUS: 01 = MAT, 02 = SPS, 03 = BAS. ;FUER CODES >3 WIRD "???" AUSGEGEBEN. ; ;SIEHE AUCH TYP-TABELLE. ;************************************************************************* TYP: PUSH H ;RETTE HL—REGISTERPAAR LHLD ZWSP1 ;HL = ZEIGER AUF KENN-BYTE MOV A,M ;KENN-BYTE: NACH A ANI %01111111 ;BIT 7 AUF 0 SETZEN LHLD PTYPT ;HL-ZEIGER AUF TYP-TABELLE CMP M ;VERGLEICHE MIT MAX TYP-CODE + EINS JC TYPOK ;SPRINGE, WENN TYP-CODE OK MOV A,M ;LADE MAX TYP-CODE TYPOK: DCX H ;KORRIGIERE ZEIGER DCX H ; MOV E,A ;CODE NACH LSB(DE) MVI D,0 ; MSB(DE) = 00 DAD D ;STELLE ZEIGER AUF RICHTIGEN DAD D ;TABELLEN-EINTRAG DAD D ; MVI D,3 ;3 ZEICHEN SIND AUSZUGEBEN NTYPZ: MOV A,M ;LESE ZEICHEN CALL WCHAR ;PRINT ZEICHEN INX H ;STELLE ZEIGER WEITER DCR D ;3 ZEICHEN AUSGEGEBEN ? JNZ NTYPZ ;NEIN —> NTYPZ POP H ;RESTORE HL-REGISTERPAAR RET ;************************************************************************* ;UNTERPROGRAMM "LINE" ;WIRD NUR ABGEARBEITET, WENN DRUCKER AUS. ; ;WEBERWACHT BEI DEM DIRECTORY DIE ANZAHL DER AUSGEGEBENEN ZEILEN ;WENN DER BILDSCHIRM VOLL IST, WIRD DIE ANZEIGE DES DIRECTORY UNTER- ;BRUCHEN. ES WIRD DANN DIE EINGABE VON <SP> FUER "WEITER" BZW. <CR> ;FUER "ABBRUCH" ERWARTET UND ENTSPRECHEND VERFAHREN. ;************************************************************************* LINE: LDA CRTFLG ;RETURN, WENN DRUCKER AN ;[P01#02] Hexadresse auf CRTFLG geaendert DCR A ; RZ ; LXI H,LCOUNT ;ZEIGER AUF ZEILEN-ZAEHLER DCR M ;ZEILEN-ZAEHLER MINUS EINS RNZ ;RETURN, WENN NICHT NULL CALL PTXTCR ;PRINT TEXT .byte "SPACE = WEITER, CR = ABBRUCH",00 CALL DESEL ;DESELECT LAUFWERK LINE0: CALL RCHAR ;LESE ZEICHEN CPI CR ;CR ? JZ ERET ;JA —> ABBRUCH CPI " " ;SPACE ? JNZ LINE0 ;NEIN —> LINE0 LINE1: CALL PTXT ;PRINT TEXT .byte CR .byte "--- NAME --- TYP START (HEX) STOP (HEX)" .byte " BLOECKE" .byte CR,LF,00 MVI A,12 ;RE-INIT ZEILENZAEHLER STA LCOUNT ; CALL SELECT ;RE-SELECT LAUFWERK CALL DREADY ;LAUFWERK BEREIT ? CC CODE3 ;NEIN -> CODE3 RET ;************************************************************************* ;UNTERPROGRAMM "LAUFW" ; ;FORDERT ZUR EINGABE DER LAUFWERKSBEZEICHNUNG (BZW. "M" FUER "MENUE) AUF ;PRUEFT EINGABE UND BERECHNET DIE SELECTMASKE (UNTERPROGRAMM "DRIVE") ; ;************************************************************************* LAUFW: CALL PTXTCR ;PRINT TEXT .byte LF .byte "A = LAUFWERK A",LF,CR .byte "B = LAUFWERK B",LF,CR .byte "M = MENUE",00 CALL DRIVE ;LESE BUCHSTABEN ;UND PRUEFE AUF GUELTIGKEIT ;BERECHNE MASKE RET ;************************************************************************* ;UNTERPROGRAMM "TSTCHR / LETTER" ; ;EINSPRUNG "TSTCHR": PRUEFT OB ZEICHEN IM AKKU ZIFFER ODER BUCHSTABE IST. ; WENN JA, DANN CARRY = 1 ; ;EINSPRUNG "LETTER": PRUEFT OB ZEICHEN IM AKKU EIN BUCHSTABE IST ; WENN JA, DANN CARRY = 1 ; ;************************************************************************* TSTCHR: CPI "9" + 1 ;>= "9" + 1 JNC LETTER ;JA -> LETTER CPI "0" ;< "0" ? CMC ;KOMPL. CARRY (C = 1, ZIFFER) RC ;RETURN WENN ZIFFER LETTER: CPI "Z" + 1 ;>= "Z" + 1 ? RNC ;JA -> RETURN CPI "A" ;< "A" ? CMC ;KOMPL. CARRY (C = 1, BUCHSTABE) RET ; ;************************************************************************* ;UNTERPROGRAMM "DRIME" ; ;LIEST ZEICHEN DER TASTATUR. BEI "M" VERZWEIGUNG ZUM "MENUE" ;BEI EINGABE VON "A" BZW. "B" WIRD DER SELECT-CODE DES LAUFWERKS ;BERECHNET. ;ANDERE EINGABEN ALS "A", "B" ODER "M" FUEHREN ZU DER ;FEHLERMELDUNGs "FALSCHE EINGABE" ; ;************************************************************************* DRIVE: CALL GETCHR ;ZEICHEN LESEN CPI "M" ;ZURUECK ZUM MENUE ? JZ MENUE ;JA -> HAUPT-MENUE DRIVE0: SUI "A" ;AUS "A" WIRD 0, AUS "B" WIRD 1 CPI 02 ;MAXIMAL-WERT UEBERSCHRITTEN ? CNC CODE0 ;JA —> FALSCHE EINGABE CALL COMPSM ;BERECHNE SELECT-MASKE RET ;************************************************************************* ;UNTERPROGRAMM "GETCHR" ; ;FORDERT ZUR EINGABE EINES BUCHSTABENS AUF. EINGABEZEICHEN WERDEN ;GEPRUEFT. DABEI WERDEN NUR BUCHSTABEN AKZEPTIERT. KLEINBUCHSTABEN ;WERDEN IN GROSSBUCHSTABEN UMGEWANDELT. DER EINGEGEBENE BUCHSTABE ;WIRD ANGEZEIGT. DIE EINGABE KANN UEBER DIE TASTEN <BS> UND <DEL> ;KORRIGIERT WERDEN. ;DIE EINGABE MUSS DURCH <CR> ABGESCHLOSSEN WERDEN. ; ;************************************************************************* GETCHR: CALL PTXTCR ;PRINT TEXT .byte LF,"BITTE BUCHSTABE EINGEBEN: ",00 GETC0: CALL RCHAR ;LESE ZEICHEN VON DER TASTATUR CALL GROSS ;WANDLE IN GROSS-BUCHSTABEN CPI "A" ;< "A" JC GETC0 ;JA —> GETC0 CPI "Z" + 1 ;> "Z" JNC GETC0 ;JA —> GETC0 STA CHAR ;RETTE ZEICHEN CALL WCHAR ;DRUCKE BUCHSTABEN GETC1: CALL RCHAR ;LESE ZEICHEN VON DER TASTATUR CALL TSTBS ;<BS> ODER <DEL> ? -> BS,SPACE,BS JZ GETC0 ;<BS> ODER <DEL> ? -> GETC0 CPI CR ;CD ? JNZ GETC1 ;NEIN -> GETC1 LDA CHAR ;ZEICHEN NACH A RET ; ;************************************************************************* ;UNTERPROGRAMM "REFPCHR" ; ;SETZT DAS ZEICHEN IM AKKU B-MAL IM SPEICHER EIN. HL DIENT ALS ZEIGER ;UND WIRD NACH JEDEM EINSETZEN UM EINS ERHOEHT. ; ;WERTE BEIM AUFRUF: A = EINZUSETZEMHES ZEICHEN ; B = ANZAHL (WIE OFT EINSETZEN) ; HL = ZEIGER AUF ERSTE EINSETZ-STELLE ; ;WERTE NACH RETURN: B = 0 ; HL = ZEIGER AUF LETZTE EINSETZ-STELLE + EINS ; ;************************************************************************* REPCHR: MOV M,A ;SETZE ZEICHEN EIN INX H ;STELLE ZEIGER WEITER DCR B ;ALLE ZEICHEN EINGESETZT ? JNZ REPCHR ;NEIN -> REPCHR RET ;JA -> RETURN ;************************************************************************* ;UNTERPROGRAMM "WAITSPACE" ; ;WARTESCHLEIFE, BIS <SPACE> BETAETIGT WIRD. ; ;WERTE BEIM AUFRUF: --- ; ;WERTE NACH RETURN: A = 20H (ASCII SPACE) ; ;************************************************************************* WAITSP: CALL RCHAR ;LESE ZEICHEN VON TASTATUR CPI " " ;SPACE ? JNZ WAITSP ;NEIN —> WAITSP RET ;JA —> RETURN ;************************************************************************* ;UNTERPROGRAMM "TSTBS" ; ;PRUEFT, OB DAS ZEICHEN IM AKKU = 08H (BACKSPACE) ODER 7FH (DELETE) IST ; ;WENN JA, WIRD DIE ZEICHENFOLGE "BACKSPACE, SPACE, BACKSPACE" AUSGEGEBEN ;UND DAS ZERO-FLAG WIRD GESETZT. ; ;WERTE BEIM AUFRUF: A = ZU PRUEFENDES ZEICHEN ; ;WERTE NACH RETURN: (WENN NICHT BS ODER DEL) ! (WENN BS ODER DEL) ; ----------------------------------------------- ; A = ZU PRUEFENDES ZEICHEN ! A = 0 ; Z-FLAG = 0 (NICHT GESETZT) ! Z-FLAG = 1 (GESETZT) ; ;************************************************************************* TSTBS: CPI BS ;BS ? JZ TSTBS0 ;JA —> TSTBS0 CPI DEL ;DEL ? RNZ ;WEDER BS NOCH DEL -> RET TSTBS0: CALL PTXT ;PRINT TEXT .byte BS,SPACE,BS,00 XRA A ;SET ZERO-FLAG RET ;************************************************************************* ;UNTERPROGRAMM "PPLUS" ; ;GIBT DAS ZEICHEN "+" AUS ; ;************************************************************************* PPLUS: CALL PTXT ;PRINT "+" .byte "+",00 RET ;************************************************************************* ;UNTERPROGRAMM "PLINE" ; ;GIBT DAS ZEICHEN AUS. DIE ANZAHL DER STRICHE, DIE AUSGEGEBEN WERDEN ;SOLLEN, MUSS IM D-REGISTER STEHEN. ; ;************************************************************************* PLINE: CALL PTXT ;PRINT TEXT .byte "-",00 DCR D ;NOCH EIN "-" ? JNZ PLINE ;JA -> PLINE RET ;NEIN -> FERTIG ;************************************************************************* ;UNTERPROGRAMM "CRLF" ; ;GIBT DIE ZEICHENFOLGE CR, LF AUS ; ;WERTE BEIM AUFRUF: ----- ; ;WERTE NACH RETURN: ----- ; ;************************************************************************* ; Kein Ersatz durch MAT85-Routine CRLF, da CRTTEST enthalten CRLF: CALL PTXTCR ;PRINT CR,LF .byte 00 RET ;************************************************************************* ;UNTERPROGRAMM "UMG" ; ;PRUEFT, OB DAS DOS ERWEITERT IST UND DAS UMGEHUNGSFLAG "EDH" GESETZT IST. ; ;WERTE BEIM AUFRUF: HL = ZEIGER AUF POSITION DES UMGEHUNGSFLAGS ; ;REAKTION FLAG = EDh --> SPRUNG NACH (HL)+1 (EIN BYTE HINTER DEM FLAG) ; ; FLAG <> EDh --> HL = HL - 800h ; ERNEUTER TEST ; WENN "EDH" --> SPRUNG WIE OBEN ; WENN NICHT "EDH" --> RETURN ; ;************************************************************************* UMG: MVI A,$ED ;UMGEHUNGS-FLAG UMG1: CMP M ;UMGEHUNGS-FLAG GESETZT ? JZ UMG0 ;JA —> UMG0 PUSH B ;RETTE BC LXI B,$F800 ;BERECHNE ADRESSE DES NAECHSTEN FLAGS ; -800 DAD B ; POP B ;RESTORE BC CMP M ;UMGEHUNGS-FLAG GESETZT ? RNZ ;NEIN -> RETURN UMG0: INX H ;HL ZEIGT AUF SPRUNG-ZIEL PCHL ;SPRINGE NACH (HL) ;************************************************************************* ;UNTERPROGRAMM "INTINT" ; ;INITIALISIERT DEN RAM-VEKTOR FUER DEN RST5.5-INTERRUPT AUF "JMP ISR" ; ;************************************************************************* INTINT: MVI A,JUMP ;LADE OP-CODE JMP STA RSTVEK ;EINSETZEN LXI H,ISR ;ZEIGER AUF ISR SHLD RSTVEK+1 ;IN RST-VEKTIOR EINSETZEN MVI A,IMASK ;INTERRUPT-MASKE SIM ;SETZEN EI ;ENABLE INTERRUPT RET ; ; ;************************************************************************ ;* * ;* INTERRUPT-SERVICE-ROUTINE * ;* * ;************************************************************************ ; ;NACH DER AUSFUEHRUNG EINES KOMMANDOS LOEST DER FDC EINEN INTERRUPT AUS ;UND DIE CPU VERZWEIGT DANN ZU DIESER ROUTINE. ; ;DA SICH DIE CPU BEIM AUFRUF DER ISR DIE ADRESSE DES UNTERBROCHENEN PRO- ;GRAMMS IM STACK MERKT, WUERDE DIESES PROGRAMM NACH DEM RETURN-BEFEHL ;(IN DER ISR) FORTGESETZT. ; ;DURCH DEN BEFEHL "POP PSW" WIRD DIE RUECKSPRUNG-ADR ZUM UNTERBROCHENEN ;PROGRAMM AUS DEM STACK ENTFERNT. BEDINGT DURCH DIE STRUKTUR DES BFZ- ;MINI-DOS TRITT EIN INTERRUPT NUR DANN AUF, WENN DIE CPU EIN UNTERPROGRAMM ;ABARBEITET. WIRD NUN (NACH "POP PSW") DER RETURN-BEFEHL AUSGEFUEHRT, SO ;KEHRT DIE CPU INS HAUPTPROGRAMM ZURUECK. ; ;DAS INTERRUPT-SIGNAL, DAS VOM FDC AUSGEGEBEN WIRD, WIRD DURCH DAS ;LESEN DES FDC-STATUS ABGESCHALTET. DA ES DABEI ABER ZU ZEIT-PROBLEMEN ;KOMMEN KANN, WIRD IN DER ISR DER STATUS SOLANGE GELESEN BIS DER FDC ;NICHT—BUSY IST.. ; ;DER STATUS STEHT NACH DEM RETURN IM AKKU UND IM E-REGISTER ;ER WIRD AUSSERDEM IM RAM UNTER "LASTST" GESPEICHERT. DAS BFZ-MINI-DOS ;NUTZT DIESEN GESPEICHERTEN WERT NICHT. ER KANN ABER VON ANDEREN ;PROGRAMMEN VERWENDET WERDEN. ;WERTE BEIM AUFRUF: --- ;WERTE NACH RETURN: A = STATUS ; E = STATUS ; ;************************************************************************* ISR: POP PSW ;SAEUBERE STACK ;URSPRUENGLICHE RUECKSPRUNGADRESSE ENTFERNEN ISR0: IN FDCSTAT ;LESE STATUS, LOESCHE INTERRUPT-SIGNAL MOV E,A ;STATUS NACH E RAR ;BUSY ? JC ISR0 ;JA —> ISR0 (LESE STATUS ERNEUT) MOV A,E ;A = STATUS STA LASTST ;RETTE STATUS EI ;ENABLE INTERRUPT RET ;RETURN (UEBER STACK - 1) ;************************************************************************* ;VEKTOR-TABELLE AUF DIE FEHLER-MELDUNGEN ;DIE ZIFFER GIBT DEN FEHLER-CODE AN ;************************************************************************* ERRVEK: .byte 16 ;MAXIMALER FEHLERCODE .word ERR0 .word ERR1 .word ERR2 .word ERR3 .word ERR4 .word ERR5 .word ERR6 .word ERR7 .word ERR8 .word ERR9 .word ERR10 .word ERR11 .word ERR12 .word ERR13 .word ERR14 .word ERR15 .word ERR16 .word ERR17 ;************************************************************************* ;FEHLERMELDUNGEN ;DIE ZIFFER HINTER DEM LABEL GIBT DEN FEHLER-CODE AN ;************************************************************************* ERR0: .textz "FALSCHE EINGABE" ERR1: .textz "RUECKSTELL-FEHLER" ERR2: .textz "SCHREIB-FEHLER" ERR3: .textz "LAUFWERK NICHT BEREIT" ERR4: .textz "DISKETTE SCHREIBGESCHUETZT" ERR5: .textz "PRUEF-FEHLER" ERR6: .textz "SUCH-FEHLER" ERR7: .textz "LESE-FEHLER" ERR8: .textz "DISKETTE VOLL" ERR9: .textz "UNERLAUBTER NAME" ERR10: .textz "FILE > 65535 (DEZ.) BYTES" ERR11: .textz "FILE NICHT IM VERZEICHNIS" ERR12: .textz "FALSCHER FILE-TYP" ERR13: .textz "DIRECTORY-FEHLER" ERR14: .textz "SPEICHER-FEHLER" ERR15: .textz "SPEICHERPLATZ AUF DER DISKETTE ZU KLEIN" ERR16: .textz "PROGRAMM-SPEICHER LEER" ERR17: .textz "UNGUELTIGER FEHLER-CODE" ;************************************************************************* ; DATEITYPEN ;************************************************************************* TYPT: ;Verschiedene Dateitypen .byte 04 ;Anzahl der verschiedenen Dateitypen .byte "MAT" ;MAT85-Systemcode .byte "SPS" ;SPS-Programme .byte "BAS" ;BASIC-Programme .byte "???" ;Unbekannter Dateitypen ;************************************************************************* ; VERSATZTABELLE ;************************************************************************* VERTAB: .byte 1,5,2,6,3,7,4,8 ;REIHENFOLGE DER EINZELNEN SEKTOREN ;************************************************************************* ; ENDE MINI-DOS ;************************************************************************* .byte $FF,$FF ;Ende Mini-DOS ;Ohne Bedeutung ;************************************************************************* ; RAM-Reservierungen ;************************************************************************* ; .org $F800 SECB: .equ $F800 ; DS 512, Byte Sektorpuffer LAENGE: .equ $FA00 ; WORD, Laenge des Files PTEINT: .equ $FA02 ; WORD, Zeiger fuer TEINIT ZAEHL: .equ $FA04 ; BYTE, Zaehler TEINT: .equ $FA05 ; WORD, Eintrag 1 ; WORD, Eintrag 2 ; WORD, Eintrag 3 ; WORD, Eintrag 4 ; WORD, Eintrag 5 ; WORD, Eintrag 6 ; WORD, Eintrag 7 ; WORD, Eintrag 8 ; WORD, Eintrag 9 ; WORD, Eintrag 10 ; WORD, Eintrag 11 ; WORD, Eintrag 12 ; WORD, Eintrag 13 ; WORD, Eintrag 14 ; WORD, Eintrag 15 ; WORD, Eintrag 16 PTVORH: .equ $FA25 ; WORD, Zeiger fuer TVORH ZAEHLV: .equ $FA27 ; BYTE, Zaehler TVORH: .equ $FA28 ; WORD, Eintrag 1 ; WORD, Eintrag 2 ; WORD, Eintrag 3 ; WORD, Eintrag 4 ; WORD, Eintrag 5 ; WORD, Eintrag 6 ; WORD, Eintrag 7 ; WORD, Eintrag 8 ; WORD, Eintrag 9 ; WORD, Eintrag 10 ; WORD, Eintrag 11 ; WORD, Eintrag 12 ; WORD, Eintrag 13 ; WORD, Eintrag 14 ; WORD, Eintrag 15 ; WORD, Eintrag 16 ;************************************************************************* ZWSP1: .equ $FA48 ; WORD, Zwischenspeicher ZWSP2: .equ $FA4A ; WORD, Zwischenspeicher ZWSP3: .equ $FA4C ; WORD, Zwischenspeicher ZWSP4: .equ $FA4E ; WORD, Zwischenspeicher REST: .equ $FA50 ; WORD, Rest-Laenge eines zu speichernden Files SPUR: .equ $FA52 ; BYTE, Zwischenspeicher fuer Spur-Nummer (0-79) CHAR: .equ $FA53 ; BYTE, Zwischenspeicher fuer Eingabe-Zeichen DSPLD: .equ $FA54 ; BYTE, Zwischenspeicher FLAG (00 = Suche Directory-Eintrag) ; Sonst: Display Directory) LCOUNT: .equ $FA55 ; BYTE, Zwischenspeicher Zeilenzaehler fuer Directory-Anzeige VERPTR: .equ $FA56 ; WORD, Zwischenspeicher fuer Zeiger auf Versatztabelle ERRRET: .equ $FA58 ; WORD, Returnadresse von Error-Routine ERRP: .equ $FA5A ; WORD, Adresse des letzten Fehlers DOSRET: .equ $FA5C ; WORD, Return-Adresse von DOS PTYPT: .equ $FA5E ; WORD, Zeiger auf TYP-Tabelle PEVT: .equ $FA60 ; WORD, Zeiger auf Error-Vektor-Tabelle PVNR: .equ $FA62 ; WORD, Zeiger auf Versionsnummer PTZZ: .equ $FA64 ; WORD, Zeiger auf zulaessige Zeichen PMENUE: .equ $FA66 ; WORD, Zeiger auf Kommando-Liste XSAV1: .equ $FA68 ; BYTE, OP-Code ; WORD, Adresse XSTSP: .equ $FA6B ; BYTE, OP-Code ; WORD, Adresse XDIR: .equ $FA6E ; BYTE, OP-Code ; WORD, Adresse XGP1: .equ $FA71 ; BYTE, OP-Code ; WORD, Adresse XGP2: .equ $FA74 ; BYTE, OP-Code ; WORD, Adresse XGP3: .equ $FA77 ; BYTE, OP-Code ; WORD, Adresse XLAD1: .equ $FA7A ; BYTE, OP-Code ; WORD, Adresse XLAD2: .equ $FA7D ; BYTE, OP-Code ; WORD, Adresse XERR: .equ $FA80 ; BYTE, OP-Code ; WORD, Adresse EFROM: .equ $FA83 ; BYTE, ENTERED FROM gibt auskunft darueber ; von wo das DOS aufgerufen wurde ; 01 = MAT85 ; 02 = SPS ; 03 = BASIC ; 04 = ??? ; SEITE: .equ $FA84 ; BYTE, Zwischenspeicher fuer Seitennummer ; Seite = 0h, Seite 1 = 1h SELMSK: .equ $FA85 ; BYTE, Zwischenspeicher fuer Select-Maske ; Laufwerk A = 1h, Laufwerk B = 2h LSEL: .equ $FA86 ; BYTE, LAST SELECT Wert, der als letzter an ; "PORT" ausgegeben wurde LASTST: .equ $FA87 ; BYTE, Letzter Status RETRY: .equ $FA88 ; BYTE, Zwischenspeicher fuer VERIFY-Zaehler ;************************************************************************* ; Anhang zm BFZ-Mini-DOS ; DOS-Erweiterungen ; ; Adresse (Stufe 1) Adresse (Stufe 2) Inhalt Bemerkung ; 5000 5800 ED 1 ; 5801 C3 2 ; 5002 5802 XX ; 5003 5803 XX ; 5004 5804 ED 3 ; 5005 5805 C3 4 ; 5006 5806 XX ; 5007 5807 XX ; 5008 5808 ED 5 ; 5009 5809 C3 6 ; 500A 580A XX ; 500B 580B XX ; 500C 580C ED 7 ; 500D 580D XX 8 ; 500E 580E XX 9 ; 500F 580F ED 10 ; 5010 5810 XX 11 ; 5011 5811 XX 12 ; ; ERLAEUTERUNG: ; ; 1. ERKENNT MAT85 EINEN BEFEHL NICHT, UND ENTHAELT DIE UNTER 1. ANGEGEBENE ; SPEICHERZEILE DEN WERTE "ED", SO FUEHRT DAS PROGRAMM DEN UNTER ; 2. ANGEGEBENEN SPRUNG-BEFEHL AUS. DER IN DER JETZIGEN DOS-VERSION ; ENTHALTENE TEST AUF "F" WIRD UMGANGEN. ; ; 2. SIEHE 1. ZUSAETZLICHE WIRD EIN UNBEKANNTES MAT85-KOMMANDO EINGEGEBEN, ; SO PRUEFT DAS DOS, OB ES SICH UM DAS "F"-KOMMANDO HANDELT. IST DIES ; NICHT DER FALL, SO PRUEFT ES, OB UNTER 2. (STUFE 1> DER WERT "C3" STEHT. ; WENN JA, WIRD DER SPRUNG-BEFEHL AUSGEFUERT. NEIN —> FEHLERMELDUNG ; ; 3. ERKENNT SP1 (AUSSER BASIC —> SPS, MAT85+ EPROMMER) EINEN BEFEHL NICHT, ; UND ENTHAELT DIE UNTER 3. ANGEGEBENE SPEICHERZEILE DEN WERT "ED", SO ; FUEHRT DAS PROGRAMM DEN UNTER 4. ANGEGEBENEN SPRUNG-BEFEHL AUS. DER ; IN DER JETZIGEN DOS-VERSIQN VORHANDENE TEST (WURDE "F" VON SPS AUS ; EINGEGEBEN > WIRD UMGANGEN. ; ; 4. SIEHE 3. ZUSAETZLICHE WIRD EIN UNBEKANNTES SP1 EINGEGEBEN, SO PRUEFT ; DAS DOS, OB ES SICH UM DAS "F"-KOMMANDO HANDELT UND OB DIESES KOMMANDO ; VON SPS AUS EINGEGEBEN WURDE. IST ES NICHT DAS "F"-KOMMANDO ODER WURDE ; ES NICHT VON SPS AUS EINGEGEBEN, PRUEFT DAS DOS, OB DIE UNTER 4. (STUFE 1) ; ANGEGEBENE ADRESSE "C3" ANTHAELT. WENN JA, WIRD DER SPRUNG AUSGEFUEHRT. ; WENN NEIN, ERFOLGT EINE FEHLERMELDUNG. ; ; 5. ERKENNT BASIC EINEN BEFEHL NICHT, UND ENTHAELT DIE UNTER 6. ANGEGEBENE ; SPEICHERZEILE DEN WERT "ED", SO FUEHRT DAS PROGRAMM DEN UNTER 4. ANGE— ; GEBENEN SPRUNG-BEFEHL. AUS. DER IN DER JETZIGEN DOS-VERSIGN VORHANDENE ; TEST (WURDE "FLOPPY" IM DIREKTMODUS EINGEGEBEN) WIRD UMGANGEN. ; ; 6. SIEHE 5. ZUSAETZLICHE WIRD EIN UNBEKANNTES BASIC-KOMMANDO EINGEGEBEN, ; SO PRUEFT DAS DOS. OB ES DAS "FLOPPY"-KOMMANDO IST UND OB ES IM DIREKT- ; MODUS EINGEGEBEN WURDE. TRIFFT EINE DER BEIDEN BEDINGUNGEN NICHT ZU, SO ; PRUEFT DAS DOSv OB DIE UNTER 6. (STUFE 1) ANGEGEBENE ADRESSE "C3" ENT- ; HAELT. WENN JA, WIRD DER SPRUNG AUSGEFUEHRT. WENN NEIN, ERFOLGT EINE ; FEHLERMELDUNG. ; ; 7. EIN "ED" IN DER UNTER 7. ANGEGEBENEN ADRESSE ZEIGT DEM DOS AN, DASS NICHT ; DIE VEKTOR-TABELLE DER GRUND-VERSION GENUTZT WERDEN SOLL. DIE ADRESSE DER ; NEUEN VEKTOR-TABELLE MUSS UNTER 8. UND 9. ANGEGEBEN SEIN. ; ; 8. LOW-BYTE DER ADRESSE FUER DIE NEUE VEKTOR-TABELLE ; ; 9. HIGH-BYTE DER ADRESSE FUER DIE NEUE VEKTOR-TABELLE ; ;10. EIN "ED" IN DER UNTER 10. ANGEGEBENEN ADRESSE ZEIGT DEM DOS AN, DASS NICHT ; DIE INFO-TABELLE DER GRUND-VERSION GENUTZT WERDEN SOLL. DIE ADRESSE DER ; NEUEN INFO-TABELLE MUSS UNTER 11. UND 12. ANGEGEBEN SEIN. ; ;11. LOW-BYTE DER ADRESSE FUER DIE NEUE INFO-TABELLE ; ;12. HIGH-BYTE DER ADRESSE FUER DIE NEUE INFO-TABELLE ; ; DIE ERWEITERUNGS-STUFE 2 IST DER STUFE 1 UEBERGEORDNET. ; EINE ERWEITERUNG MUSS MINDESTENS EIN "ED" BZW. MINDESTENS EINEN "C3 XX XX"- ; BEFEHL ENTHALTEN. ; ;--------------------------------------------------------------------------------------------------- ; ; ######## ## ## ######## ######## ## ## #### ## ## #### ######## ####### ###### ; ## ### ## ## ## ## ### ### ## ### ## ## ## ## ## ## ## ## ; ## #### ## ## ## ## #### #### ## #### ## ## ## ## ## ## ## ; ###### ## ## ## ## ## ###### ## ### ## ## ## ## ## ## ####### ## ## ## ## ###### ; ## ## #### ## ## ## ## ## ## ## #### ## ## ## ## ## ## ; ## ## ### ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ; ######## ## ## ######## ######## ## ## #### ## ## #### ######## ####### ###### ; ;--------------------------------------------------------------------------------------------------- ;