;****************************************************************** ;*** *** ;*** PROF-80 Monitor Version: 1.7 *** ;*** *** ;*** letzte Aenderung am: 29.02.1988 (c) Joachim Hanst *** ;*** *** ;****************************************************************** ; TITLE 'PROF-80 MONITOR VERSION 1.7' ; ; ; MACLIB Z80 MACLIB CDEF ;BENUTZE CDEF.LIB FUER ALLE C-SYSTEM MODULE ; BELL EQU 07H CNGPRMT EQU '-' ; ; ORG EPROM MONITOR: ;SPRUNGVEKTOR FUER MONITOR SERVICE-ROUTINEN ; JMP INIT ;MONITOR-EINGANG NACH RESET JMP START ;MONITOR WARM-START CS JMP UMLEIT$CONST ;CONSOLEN STATUS,EIN-UND AUSGABE CI JMP UMLEIT$CONIN ;GEHEN ERST UEBER SPRUNG IM RAM CO JMP UMLEIT$CONOUT ;AUF IHRE VERTEILER JMP SETSEC$CNT ;SETZE ANZAHL DER SEKTOREN JMP BOOTERR ;DRUCKE FEHLERMELDUNG JMP SETCMDT ;SETZE CMDTAB ENTSPRECHEND TEST JMP RECAL ;SETZE AUSGEWAEHLETES DRIVE AUF TRACK 0 JMP SELDSK ;WAEHLE DRIVE AUS JMP SETTRK ;SETZE SPUR FUER AUSGEWAEHLTES DRIVE JMP SETSEC ;SETZE SEKTOR FUER AUSGEWAEHLTES DRIVE JMP SETDMA ;SETZE DMA ADRESSE FUER READ/WRITE JMP READ ;LESE DISK JMP WRITE ;SCHREIBE DISK JMP START ;IN ALTEN VERSIONEN WAR HIER GETMINIMAX JMP START ; ; JMP CONST ;CONSOLEN STATUS-VERTEILER SERNR DW 28028 ;SERIEN NUMMER RSTART7 JMP RST$VERTEILER ;RST 7 EINSPRUNG (MUSS 38H SEIN) JMP CONIN ;CONSOLEN EINGABE-VERTEILER JMP CONOUT ;CONSOLEN AUSGABE-VERTEILER JMP TEST ;TESTE DISK-FORMAT JMP MOTO ;WARTE AUF READY UND GEBE DISK-BEFEHL JMP CMFD ;SENDE DISK-BEFEHL OHNE READY JMP RESULT ;ERGEBNISPHASE DES UPD 765 JMP SEEK ;POSITIONIERE AUF SPUR JMP NEXT ;LESE EIN RESULT-BYTE AUS UPD 765 JMP MULTIP ;MULTIPLIKATION JMP START ;DIVISION WURDE ENTFERNT JMP INT$SERVICE ;EINLESEN EINES ZEICHENS NACH INT. JMP GRAFIN ;VIDEO KARTE EINGABE JMP GRAFOUT ;VIDEO KARTE AUSGABE JMP GRAFIST ;VIDEO KARTE EIN STATUS VERSIONNR DB 17H ;VERSIONS NUMMER JMP UMLEIT$NMI ;SPRUNG AUF NMI ROUTINE JMP GRAFOST ;VIDEO KARTE AUS STATUS JMP SOFTIN ;SOFT SCHNITTSTELLE EINGABE JMP SOFTOUT ;SOFT SCHNITTSTELLE AUSGABE JMP SOFTIST ;SOFT SCHNITTSTELLE EIN STATUS JMP SOFTOST ;SOFT SCHNITTSTELLE AUS STATUS USER1IN JMP SAIN ;UNIO-SIO-A EINGABE USER1OUT JMP SAOUT ;UNIO-SIO-A AUSGABE USER1IST JMP SAIST ;UNIO-SIO-A EIN STATUS USER1OST JMP SAOST ;UNIO-SIO-A AUS STATUS USER2IN JMP SBIN ;UNIO-SIO-B EINGABE USER2OUT JMP SBOUT ;UNIO-SIO-B AUSGABE USER2IST JMP SBIST ;UNIO-SIO-B EIN STATUS USER2OST JMP SBOST ;UNIO-SIO-B AUS STATUS USERINIT RET ;BENUTZER INITIALISIERUNG NOP ; NOP ; JMP DISKERR ;FLOPPY-FEHLERMELDUNG JMP SOFTPRNTOUT ;SIMPLEX SCHNITTSTELLE JMP SOFTPRNTOST ;SIMPLEX BEREIT JMP SET$PHYS$TIME ;SETZE ZEIT JMP READ$PHYS$TIME ;LESE ZEIT JMP SET$SHIFT ;SETZE SHIFT-REGISTER JMP SET$DUPLEX$BAUD ;SETZE BAUDRATE DUPLEX JMP SET$SIMPLEX$BAUD;SETZE BAUDRATE SIMPLEX JMP SPECD ;SETZE DISKPARAMETER ; ;DIE NACHFOLGENDEN DATEN WERDEN ;NACH EINEM RESET IN DIE ;SYSTEMPAGE UEBERNOMMEN. ;DIE DATEN BEFINDEN SICH AB VERS 1.4 ;IMMER AN DEN GLEICHEN EPROM ;ADRESSEN, SO DASS SIE VOM ;BENUTZER LEICHT GEPATCHT WERDEN ;KOENNEN. ; XSPECD$WORD DW HLOS*256+256+SRTS*16+HUTS ;STEPRATE, HLT, HUT ;DIESE DATEN GEBEN DIE DEFAULT ;EINSTELLUNG AN, SIE WERDEN DURCH ;DEN U-BEFEHL UEBERDECKT XSEEKNR DB 000H ;DOUBLESTEPVEKTOR XREADY$BYTE DB 0FFH ;READYBYTE KANN VORDEFINIERT WERDEN. XTE$TIME DB 010H ;WARTEZEIT NACH WRITE-DISK (IN 100 US) XPRNT$BAUD DB 003H ;BAUDRATE SIMPLEX STIBAUD DB 003H ;BAUDRATE UNIO-STI XSTEP$WAIT DB 000H ;WARTEZEIT VOR STEP WENN MOTOR AUS WAR ; ;SPRUNGVEKTOR FORTSETZUNG CENT1OUT JMP C1OUT ; CENT1OST JMP C1OST ; CENT2OUT JMP C2OUT ; CENT2OST JMP C2OST ; STIIN JMP STIN ; STIOUT JMP STOUT ; STIIST JMP STIST ; STIOST JMP STOST ; STIINIT JMP STINIT ; SIOAINIT JMP SAINIT ; SIOBINIT JMP SBINIT ; ; ; ; RST$VERTEILER: ;PRUEFT OB INTERRUPT-BETRIEB DER SOFT-SCHNITTSTELLE ;WENN NEIN, DANN SPRUNG ZUM MONITOR, SONST EINLESEN ;DES SERIELLEN ZEICHENS ; PUSH PSW ;RETTE AKKU LDA IO$JUMPERBYTE ;IST INT.-BETRIEB DCR A ; JRNZ RST$V1 ;SPRUNG WENN KEIN INT.-BETRIEB POP PSW ; JMP INT$SERVICE ;SPRUNG ZUR INTERUPTROUTINE RST$V1 POP PSW ;SPRUNG ZUM MONITOR JMP START ; ; ; ; START: ;----------------------------------------------ANFANG REGISTER RETTEN----- SHLD LSAVE POP H SHLD PSAVE SSPD SSAVE ;RETTE STACKPOINTER LXI SP,LSAVE;JETZT RETTEN DURCH PUSHBEFEHLE MOEGLICH PUSH PSW PUSH B PUSH D PUSHIX ;ZUSAETZLICH Z80 REGISTER PUSHIY EXAF EXX ;SCHALTE REGISTER UM PUSH PSW PUSH B PUSH D PUSH H EXX ;REGISTER ZURUECK SCHALTEN EXAF LDAI ;SAVE I UND R REGISTER MOV B,A LDAR MOV C,A PUSH B ;--------------------------------------------------ENDE REGISTER RETTEN---- ; ; LXI H,SGNON ;GEBE MONITOR-MELDUNG AUS CALL SOUT ; ; GETCM: ; LXI H,MSTAK ; SPHL ; MVI C,':' ; CALL ECHO ; GTC03: ; CALL GETCH1 ; CALL ECHO ; MOV D,C ;SAVE COMMAND LXI H,CMDMSG ;ZEIGE AUF TEXT GTC01 MOV A,D ; CMP M ;GLEICH JRZ GTC04 ; GTC02 INX H ; MOV A,M ;GLEICH 00H CPI 0 ; JZ ERROR ;DANN FEHLER CPI '$' ; JRNZ GTC02 ;SUCHE $ INX H ;VERGLEICHE NAECHSTES KOMMANDO JR GTC01 ; GTC04 INX H ;GEFUNDEN GEBE AUS CALL SOUT ; MOV A,D ; MOV C,D ; LXI B,NCMDS ;C ENTHAELT SCHL.U.INDEXZAEHLER LXI H,CTAB ; GTC05: ; CMP M ; JZ GTC10 ; INX H ; DCR C ; JNZ GTC05 ; JMP ERROR ; GTC10: ; LXI H,CADR ; DAD B ; DAD B ; MOV A,M ; INX H ; MOV H,M ; MOV L,A ; PCHL ; ; CRGETCM: CALL CROUT JR GETCM ; ; ; DCMD: CALL GETHX ;LESE STARTADRESSE MOV H,B ; MOV L,C ; MOV A,D ; JRC DCM30 ; CPI 0DH ; LHLD DISPADR ; JRNZ DCM33 ;SPRUNG WENN NOCH ENDADRESSE KOMMT DCM31 LXI D,00FFH ;KEINE ENDADRESSE, 100H WEITER PUSH H ;SAVE ANFAANG DAD D ; XCHG ; POP H ; JR DCM05 ;AUSGABE KANN BEGINNEN DCM30 CPI 0DH ; JRZ DCM31 ;KEINE ENDADRESSE DCM33 CALL GETHX ;LESE ZWEITE ADRESSE MOV A,D ; CPI 0DH ; JNZ ERROR ; MOV D,B ; MOV E,C ; CALL HILO ; JRNC DCM05 ;HL>DE MOV D,H ; MOV E,L ; DCM05: ; CALL CROUT ; CALL HLOUT ; MVI B,000H ;ZAEHLER FUER ASCII AUSGABE DCM10: ; INR B ;EIN ZEICHEN WEITER MVI C,' ' ; CALL ECHO ; MOV A,M ; CALL NMOUT ; CALL BREAK ; JC DCM12 ; CALL HILO ; JNC DCM15 ; DCM12: ; INX H ; CALL DCM20 ; CALL CROUT ; SHLD DISPADR ; JMP GETCM ; DCM15: ; INX H ; MOV A,L ; ANI 0FH ; JNZ DCM10 ; CALL DCM20 ; JR DCM05 ; ; DCM20 PUSH D ;SAVE D PUSH H ;SAVE H MVI C,' ' ; CALL CO ; MVI C,'>' ; CALL CO ; MOV C,B ; DCM23 DCX H ; DJNZ DCM23 ; MOV B,C ; DCM21 MOV A,M ; CPI 20H ; JRC DCM22 ; CPI 07FH ; JRNC DCM22 ; JR DCM24 ; DCM22 MVI A,'.' ;DEFAULT FOR NON ASCII DCM24 MOV C,A ; CALL CO ; INX H ; DJNZ DCM21 ; POP H ; POP D ; RET ; ; ; ; GCMD: CALL GETHX JNC GCM05 MOV A,D CPI 0DH JNZ ERROR LXI H,PSAVE MOV M,C INX H MOV M,B JMP GCM10 GCM05: MOV A,D CPI 0DH JNZ ERROR GCM10: JMP RSTTF ; ; ; MCMD: MVI C,3 CALL GETNM POP B POP H POP D MCM05: PUSH H MOV H,D MOV L,E MOV A,M MOV H,B MOV L,C MOV M,A INX B MOV A,B ORA C JZ GETCM INX D POP H CALL HILO JNC GETCM JMP MCM05 ; ; ; SCMD: CALL GETHX PUSH B POP H SCM05: MOV A,D CPI ' ' JZ SCM10 CPI ',' JNZ GETCM SCM10: MOV A,M CALL NMOUT MVI C,CNGPRMT CALL ECHO CALL GETHX JNC SCM15 MOV M,C SCM15: INX H JMP SCM05 ; ; ; XCMD: CALL GETCH MOV C,A CALL ECHO MOV A,C CPI 0DH JNZ XCM05 CALL REGDS JMP GETCM XCM05: MOV C,A CALL RGADR PUSH B POP H MVI C,' ' CALL ECHO MOV A,C STA TEMP XCM10: LDA TEMP CPI ' ' JZ XCM15 CPI ',' JNZ GETCM XCM15: MOV A,M ORA A JNZ XCM18 JMP CRGETCM XCM18: PUSH H MOV E,M MVI D,(REGS AND 0FF00H) SHR 8 ;SAVE ADRESSE INX H MOV B,M PUSH D PUSH D POP H PUSH B MOV A,M CALL NMOUT POP PSW PUSH PSW ORA A JZ XCM20 DCX H MOV A,M CALL NMOUT XCM20: MVI C,CNGPRMT CALL ECHO CALL GETHX JNC XCM30 MOV A,D STA TEMP POP PSW POP H ORA A JZ XCM25 MOV M,B DCX H XCM25: MOV M,C XCM27: LXI D,3 POP H DAD D JMP XCM10 XCM30: MOV A,D STA TEMP POP D POP D JMP XCM27 ; ; ; CCMD: ;TESTET PLATTE IM ANGEGEBENEN LAUFWERK ;UND GIBT ERGEBNISSE AUF DEM BILDSCHIRM AUS ; CALL DISKDA ;BEFEHL ERLAUBT? CALL SPECD ;SETZE DISK-TIMING CALL GETCH1 ;WELCHES LAUFWERK? CALL ECHO ;GEBE ZEICHEN AUF CONSOLE MOV A,C ;ZEICHEN IN AKKU SUI 'A' ;WANDLE LW. CHR. IN NUMMER JC ERROR ;WENN KLEINER, FEHLER CPI 4 ;GROESSER 'D' JNC ERROR ;SPRUNG WENN JA MOV C,A ;RETTE ALTE UNIT LDA UNIT ; PUSH PSW ; MOV A,C ; STA UNIT ;ZU TESTENDES LAUFWERK MVI B,5 ;ANZAHL DER VERSUCHE CCMD1 PUSH B ; LHLD UNIT ;RETTE UNIT UND TRACK PUSH H ; CALL TEST ; POP H ; SHLD UNIT ; POP B ;GET ZAEHLER ORA A ;FEHLER AUFGETRETEN? JRZ CCMD2 ;SPRUNG, WENN OK DJNZ CCMD1 ;NOCH EIN VERSUCH? ; POP PSW ;HOLE ALTE UNIT STA UNIT ; CCMD5: ;HIER AUCH EINSPRUNG FUER BOOT ERROR LXI H,CHKERR ;DRUCKE FEHLERMELDUNG CALL SOUT ; JMP GETCM ;NEUE EINGABE ; CHKERR DB 0DH,0AH,BELL DB ' Disk not correct' DB 0DH,0AH,24H ; CCMD2: ; ;GEBE ART DER PLATTE AUS POP PSW ;SETZE STACK RICHTIG LXI H,CTXT1 ; CALL SOUT ; LDA TEST$TYPE ; ANI 20H ;MINI ODER MAXI LXI H,CTXT11 ; JRZ CCMD3 ; LXI H,CTXT12 ; CCMD3 CALL SOUT ; ; LXI H,CTXT2 ; CALL SOUT ; LDA TEST$TYPE ;NUMBER OF SURFACES RLC ; ANI 01H ; ADI '1' ;WANDLE IN ASCII MOV C,A ; CALL CO ;UND GEBE SEITENZAHL AUS ; LXI H,CTXT3 ; CALL SOUT ; LDA TEST$TYPE ; LXI H,CTXT31 ; ANI 040H ; JRZ CCMD4 ; LXI H,CTXT32 ; CCMD4 CALL SOUT ; ; LXI H,CTXT4 ;GEBE SEKTORGROESSE AUS CALL SOUT ; LDA TEST$TYPE ; ANI 0FH ; MVI H,0 ; MOV L,A ; DAD H ; DAD H ; DAD H ; LXI D,SEKTXT ; DAD D ; CALL SOUT ; ; LXI H,CTXT5 ;GEBE SEKTOREN/SPUR AUS CALL SOUT ; LDA TEST$MSEK ; CALL DEZOUT ; ; LXI H,CTXT6 ;GEBE AUS OB DAS LAUFWERK CALL SOUT ;DAS READY SIGNAL LIEFERT CALL READY$MASK ; ANI 0FH ; LXI H,CTXT62 ; JRNZ CCMD6 ; LXI H,CTXT61 ; CCMD6 CALL SOUT ; ;SETZE CMDTAB CALL SETCMDT ; ; JMP CRGETCM ; ; CTXT1 DB 0DH,0AH,' Disk format...: $' CTXT2 DB 0DH,0AH,' Heads.........: $' CTXT3 DB 0DH,0AH,' Density.......: $' CTXT4 DB 0DH,0AH,' Sector size...: #$' CTXT5 DB 0DH,0AH,' Sectors/Track.: #$' CTXT6 DB 0DH,0AH,' Ready signal..: $' CTXT31 DB 'single$' CTXT32 DB 'double$' SEKTXT DB '128 $' DB '256 $' DB '512 $' DB '1024 $' CTXT11 DB 'maxi$' CTXT12 DB 'mini$' CTXT61 DB 'yes$' CTXT62 DB 'simulated by index$' ; ; ; OCMD: CALL GETHX ;LESE PORTADRESSE MOV A,D ;WAR TRENNZEICHEN CR? CPI 0DH JZ ERROR ;FEHLER WENN JA PUSH B ;SAVE INTEGER CALL GETHX ;LESE DATA BYTE MOV A,D ;WAR TRENNZEICHEN CR? CPI 0DH JNZ ERROR ;FEHLER WENN NEIN MOV L,C POP B ;RESTORE PORTADR. OUTP L ;GEBE AUS JMP GETCM ; RCMD: ;LIEST AB IN CMDTAB ANGEGEBENEN SEKTOR CALL DISKDA CALL PRINT$DRIVE CALL RWINP ;SETZE DMA ADRESSE UND LAENGE CALL READ ;LESE JMP GETCM ; WCMD: CALL DISKDA CALL PRINT$DRIVE CALL RWINP CALL WRITE JMP GETCM ; ICMD: MVI C,1 CALL GETNM POP B ;IN C STEHT PORT INP A ;LESE NACH A MVI C,' ' ;GEBE BLANK AUS PUSH PSW CALL CO POP PSW PUSH PSW CALL NMOUT ;GEBE HEX AUS MVI C,' ' ;GEBE BLANK AUS CALL CO POP PSW MOV D,A ;IN D FUER BITOUT CALL BITOUT JMP CRGETCM ; ; ; ACMD: ;ZEIGT UND VERAENDERT TRACK, SECTOR UND HEAD ;DES EINGELOGTEN LAUFWERKS CALL DISKDA ;BEFEHL ERLAUBT? CALL PRINT$DRIVE ; LXI H,ATXT1 ;DISPLAY TRACK CALL SOUT LDA TRACK CALL NMOUT CALL ACMD4 ;LESE NEUEN WERT JRNC ACMD1 ;KEINE EINGABE? STA TRACK ACMD1 CALL ACMD5 ; LXI H,ATXT2 ;DISPLAY HEAD CALL SOUT LDA HEAD CALL NMOUT CALL ACMD4 JRNC ACMD2 ANI 03H ;MASK UPPER 6 BITS STA HEAD ACMD2 CALL ACMD5 ; LXI H,ATXT3 ;DISPLAY SECTOR CALL SOUT LDA SECTOR CALL NMOUT CALL ACMD4 JRNC ACMD3 STA SECTOR ACMD3 CALL ACMD5 ; JMP CRGETCM ; ACMD4 MVI C,CNGPRMT CALL ECHO CALL GETHX MOV A,C RET ; ACMD5 MOV A,D CPI 0DH JZ GETCM RET ; ATXT1 DB 0DH,0AH,' Track..: $' ATXT2 DB 0DH,0AH,' Head...: $' ATXT3 DB 0DH,0AH,' Sector.: $' ; ; ; BCMD: ;EINSPRUNG BOOTROUTINE ; CALL DISKDA ;BEFEHL ERLAUBT? XRA A ; STA TEST$TRACK ;ERSTE TESTSPUR IST 0 BCMD2: STA UNIT ;OK, IN CMDTAB CALL SPECD ;SETZT DISK TIMING MVI B,5 ;TESTE PLATTE MAX. 5 MAL BCMD3 PUSH B ; CALL TEST ;SETZT CONTROLLER AUF MINI ODER MAXI POP B ; ORA A ;FEHLER AUFGETRETEN? JRZ BCMD4 ;SPRUNG WENN NEIN DJNZ BCMD3 ;NOCH EIN VERSUCH? JMP CCMD5 ;GEBE FEHLER MELDUNG AUS BCMD4: ; CALL SETCMDT ;SETZE CMDTABELLE XRA A ;SETZE SPUR NULL STA TRACK ; STA HEAD ;HEAD NULL INR A ; STA SECTOR ;SEKTOR EINS LXI H,BOOTADR ; SHLD DMAADR ; MVI A,01H ;UEBERTRAGE EINEN SECTOR STA SECTCNT ; ;OK, ALLE WERTE SIND GESETZT CALL READ ;LESE ORA A ;FEHLER AUFGETRETEN? JNZ BOOTERR ; LXI H,BOOTADR ;KOPIERE DIE ERSTEN 128 BYTE LXI D,BOOTADR+380H ;NACH HINTEN LXI B,128 ; LDIR ; JMP BOOTADR+380H ; ; ; ; LCMD: ;ZEIGE DATUM UND ZEIT AN LDA CLKFLG ;IST DIE UHR UEBERHAUPT DA? ORA A JZ GCMD1 CALL DISP$TIME JMP GETCM ; GCMD1: LXI H,CLKERR$TXT CALL SOUT JMP GETCM ; CLKERR$TXT: DB 0DH,0AH,BELL,' Clock failure',0DH,0AH,'$' ; ; ; NCMD: ;SETZE UHRZEIT UND DATUM LDA CLKFLG ORA A JZ GCMD1 LXI H,CITXT1 ;LESE DATUM EIN CALL SOUT CALL GETDEZ CPI '/' JNZ ERROR ;FALSCHES TRENNZEICHEN MOV A,L CALL DEZHEX RLC ;IN RICHTIGE POSITION RLC RLC RLC ANI 0F0H CPI 0 ;MONAT ZWISCHEN 1 UND 12 JZ ERROR CPI 0C1H JNC ERROR STA PHYS$TIME+4 ;MONAT WEG CALL GETDEZ CPI '/' JNZ ERROR MOV A,L CPI 0 JZ ERROR CPI 32H JNC ERROR STA PHYS$TIME+3 ;TAG WEG CALL GETDEZ CPI 0DH JNZ ERROR MOV A,L CPI 80H JC ERROR CPI 9AH JNC ERROR STA TEMP ;JAHR ZWISCHEN SPEICHERN ; ;UHRZEIT EINLESEN LXI H, CITXT2 CALL SOUT CALL GETDEZ CPI ':' JNZ ERROR MOV A,L CPI 24H JNC ERROR STA PHYS$TIME+2 CALL GETDEZ CPI ':' JNZ ERROR MOV A,L CPI 60H JNC ERROR STA PHYS$TIME+1 CALL GETDEZ CPI 0DH JNZ ERROR MOV A,L CPI 60H JNC ERROR STA PHYS$TIME ; ;SETZE DIE ZEIT LXI H,CITXT3 CALL SOUT CALL GETCH ;WARTE AUF IRGEND EIN ZEICHEN CALL SET$PHYS$TIME ; LDA TEMP ;SETZE NOCH JAHR CALL DEZHEX ;WANDLE IN DEZIMALZAHL SUI 80 ;ZIEHE 80 AB ANI 1FH ;MASKIERE MOV B,A ; LDA SHIFT$CONT+4 ; ANI 0E0H ; ORA B ; STA SHIFT$CONT+4 ; CALL SET$SHIFT ; CALL CROUT ; JMP CRGETCM ; ; CITXT1: DB 0DH,0AH,0AH,' Enter today''s date (MM/DD/YY): $' CITXT2: DB ' Enter the time (HH:MM:SS): $' CITXT3: DB ' Press any key to set time$' ; ; ; FCMD: MVI C,3 ;HOLE 3 WERTE VON DER CONSOLE CALL GETNM POP B ;FUELL BYTE POP D ;END WERT POP H ;ANFANGSWERT FCMD1 MOV M,C ;FUELLE BYTE CALL HILO ;ENDE ERREICHT? JC GETCM INX H JMP FCMD1 ; ; ; VCMD: ;VERGLEICHT ZWEI SPEICHERBEREICHE MITEINANDER MVI C,3 ;LESE DREI ADRESSEN EIN CALL GETNM POP B ;ZWEITER BLOCKANFANG POP D ;ERSTES BLOCKENDE POP H ;ERSTER BLOCKANFANG VCMD1 LDAX B ;LESE BYTE AUS BLOCK 2 CMP M ;VERGLEICHE MIT ERSTEM BLOCK CNZ VCMD2 ;GEBE UNGLEICHE ADDRESSEN AUS CALL HILO ;ENDE ERREICHT ? JC GETCM ;OK, ENDE INX H INX B JMP VCMD1 ;VERGL. NAECHSTES BYTE ; ; ; TCMD MVI C,2 ;LESE ANFANG UND ENDADDRESSE CALL GETNM POP D POP H TCMD1 MOV C,M MOV A,C ;LESE SPEICHERSTELLE CMA ;NEGIERE MOV M,A ;SCHREIBE IN ZELLE MVI B,15 ;WARTE ETWAS TCMD2 DJNZ TCMD2 ; MOV A,M ;LESE WIEDER MOV M,C ;ORGINAL BYTE ZURUECK CMA ;A SOLL GLEICH C SEIN XRA C ;SETZE ALL UNGLEICHEN BITS CNZ FBYTOUT ;GEBE FEHLERHAFTES BYTE AUS CALL HILO ;ENDE? JC GETCM ;SPRUNG WENN JA INX H ;TESTE NAECHSTES BYTE JR TCMD1 ;LOOP ; ; ; ; ; ; VCMD2 PUSH H PUSH D PUSH B ;RETTE ALLE ADRESSEN CALL DISPMEM MVI C,' ' CALL ECHO POP H PUSH H CALL DISPMEM CALL CROUT CALL BREAK JC GETCM POP B POP D POP H RET ; DISPMEM: ;INPUT: HL ;ZEIGT HL UND (HL) AUF DEM BILDSCHIRM AN ;ZERSROERT A,B,C,FF'S CALL HLOUT MVI C,'=' CALL ECHO MOV A,M CALL NMOUT RET ; ; ; FBYTOUT PUSH H ; PUSH D ; MOV D,A ;RETTE AKKU CALL HLOUT ; MVI C,' ' ;GEBE NACH ADRRESE TRENNZEICHEN AUS CALL CO ; CALL BITOUT ;GEBE BITFOLGE AUS CALL CROUT ; CALL BREAK ;ABBRUCH JC GETCM ;SPRUNG ZUM MONITOR WENN JA POP D ; POP H ; RET ; ; ; ; BITOUT: ;GIBT 8 BIT IN REG.D AUS ;ZERSTOERT A,B,C,D,E MVI B,8 ;GEBE 8 BIT AUS BITOUT1 RLCR D ;SCHIEBE IN CARRY MVI A,'0' ;ASSCI 0 MVI E,0 ADC E MOV C,A CALL CO DJNZ BITOUT1 RET ; ; ; KCMD: ;GIBT ALLE KONSOLENEINGABEN UNVERAENDERT AUS ;ESCAPE MIT CONTROL-C LXI H,KCMDTXT CALL SOUT KCMD1: CALL CI ;LESE ZEICHEN CPI 3 ;CONTROL-C? JRZ KCMD2 ;DANN ENDE MOV C,A ; CALL CO ;SONST GEBE ZEICHEN AUS JR KCMD1 ; KCMD2: JMP CRGETCM ; KCMDTXT DB ' (escape with ^C)',0dh,0ah,0dh,0ah,'$' ; ; ; UCMD: ;SETZE DISK-TIMING ;UND ANZAHL DER STEP-IMPULSE LXI H,UTXT1 ;LESE STEPRATE CALL SOUT ; CALL UCMD3 ; DCR A ; MOV C,A ; ANI 0F0H ;TESTE OB KLEINER 10H JNZ ERROR ;GROESSER, DANN FEHLER MOV A,C ; CMA ;BILDE KOMPLEMENT PUSH PSW ;RETTE AKKU LXI H,UTXT2 ;LESE HEADUNLOAD TIME CALL SOUT ; CALL UCMD3 ; RRC ; RRC ; RRC ; RRC ; ANI 0FH ;MASKIERE MOV C,A ;RETTE IN C POP PSW ;GET STEPRATE RLC ; RLC ; RLC ; RLC ; ANI 0F0H ;MASKIERE ORA C ;UNLOAD TIME DAZU STA SHIFT$CONT+2 ; LXI H,UTXT3 ;LESE HEAD LOAD TIME CALL SOUT ; CALL UCMD3 ; ANI 0FEH ; STA SHIFTCONT+3 ; LXI H,UTXT4 ;DOPPELSTEP VEKTOR UND CALL SOUT ;TWOSIDED BITS CALL UCMD3 ; STA SHIFT$CONT+1 ; ;BOOT UNIT LXI H,UTXT5 ; CALL SOUT ; CALL GETCH1 ; MVI C,00100000B ; CPI 'F' ; JRZ UCMD20 ; MVI C,00000000B ; CPI 'H' ; JRZ UCMD20 ; JMP ERROR ; UCMD20: ; PUSH PSW ; RETTE ZEICHEN LDA SHIFT$CONT+4 ; ; ANI 11011111B ; ORA C ; STA SHIFT$CONT+4 ; ; ORI 1FH ;BERECHNE PRUEFSUMME LXI H,SHIFT$CONT+3 ; MVI B,3 ; UCMD1 ADD M ; DCX H ; DJNZ UCMD1 ; CMA ;BILDE KOMPLEMENT INR A ; MOV M,A ; CALL UCMD2 ; CALL SPECD ; CALL SET$SHIFT ; POP PSW ;ZEICHEN FUER DEFAULTBOOT MOV C,A ; CALL ECHO ;MUSS NOCH AUSGEGEBEN WERDEN JMP CRGETCM ; ; UCMD2: LHLD SHIFT$CONT+2 ;SETZE DISKTIMING NEU MOV A,H ; ORI 1 ; MOV H,A ; SHLD SPECD$WORD ; LDA SHIFT$CONT+1 ;SETZE SEEKNR (ANZAHL DER STEPIMPULSE) STA SEEKNR ;UND TWO-SIDED-BITS ; LDA SHIFT$CONT+4 ;SETZE BOOT UNIT ANI 00100000B ; STA BOOTFLG ; ; RET ; ; UCMD3: CALL GETHX ; MOV A,D ; CPI 0DH ; JZ ERROR ; MOV A,C ; RET ; ; UTXT1 DB 10,13,' Steprate ...........: $' UTXT2 DB 10,13,' Head unload time ...: $' UTXT3 DB 10,13,' Head load time .....: $' UTXT4 DB 10,13,' Double step vector .: $' UTXT5 DB 10,13,' Default boot unit ..: $' ; ; ; ;-------------------------------------------------------INITIALISIERUNG------ ; INIT: ; ;*** LXI H,6000 ;VERZOEGERUNG ZUM WARM WERDEN INIT7 DCX H ; MVI A,PAD$TX OR 1 ;SETZE TX DUPLEX LEITUNG AUF 1 OUT P$LS259 ; MVI A,PAD$RTS OR 1 ;SETZE RTS INAKTIV OUT P$LS259 ; MVI A,PAD$TXP OR 1 ;SETZE TX SIMPLEX LEITUNG AUF 1 OUT P$LS259 ; MVI A,PAD$POLEN OR 80H ;AKTIVIERE DRIVE DECODER OUT P$LS259 ; MVI A,5 ;UNIO STROBE 1 HIGH OUT CONTR ; MVI A,7 ;UNIO STROBE 2 HIGH OUT CONTR ; MVI A,9 ;UNIO INIT HIGH OUT CONTR ; MOV A,H ; ORA L ; JNZ INIT7 ; ; ;*** MVI A,PAD$MOTOR OR 80H OUT P$LS259 MVI A,PAD$MOTAB OR 1 OUT P$LS259 ;*** ; MVI B,00 ;INITIALISIERE EPROM MVI C,P$RAM$TABLE ;PORTADRESSE DER RAM-TABELLE MVI D,16 ; MVI E,0 ;EPROM BANK-ADRESSE OUTP E ;GEBE BANKADRESSE FUER KACHEL 0 AUS MOV A,D ;NAECHSTE KACHEL ADD B ; MOV B,A ; OUTP E ; ;OK, EPROM-KACHELN AKTIV MOV A,D ;JETZT LOGISCHE RAM-BANK 0 ADD B ; MOV B,A ; MVI E,02H ;PHYS.-BANK 13 IST LOG.-BANK 0 INIT8 OUTP E ;INITIALISIERE RESTL. KACHELN MOV A,D ; ADD B ; MOV B,A ; CPI 80H ; JRNZ INIT16 ; MVI E,0AH ; INIT16 ORA A ; JRNZ INIT8 ; ;RAM-TABELLE OK MVI A,PAD$INIT OR 1 ;AKTIVIERE-BANKLEITUNGEN OUT P$LS259 ; ;OK, RAM IST AKTIV ;TESTE BANK 0 LXI H,MSTAK-80 ;SCHREIBE 256 BYTES XRA A ;IN STACK INIT13 MOV M,A ; INX H ; INR A ; JRNZ INIT13 ; LXI H,0 ;VERZOEGERE ETWAS INIT15 DCX H ; MOV A,H ; ORA L ; JRNZ INIT15 ; LXI H,MSTAK-80 ; XRA A ; INIT12 CMP M ;UND VERGLEICHE WIEDER JRNZ INIT9 ;UNGLEICH, SETZE FLAG INX H ;EINEN WERT HOEHER INR A ; JRNZ INIT12 ; XRA A ;FLAG FUER BANK 0 OK JR INIT10 ; INIT9 MVI A,01H ;FLAG FUER BANK 0 NICHT OK INIT10 STAI ;RETTE FLAG IN INT.REGISTER ; MVI B,20H ;SCHALTE BANK 1 EIN MVI C,P$RAM$TABLE ; MVI D,16 ; MVI E,03H ; INIT11 OUTP E ;SETZE KACHEL MOV A,D ;EINS WEITER ADD B ; MOV B,A ; CPI 80H ;OBERE HAELFTE JRNZ INIT27 ; MVI E,0BH ;DANN E NEU SETZEN INIT27 ORA A ;IST AKKU GLEICH NULL JRNZ INIT11 ;ALLES BANK1 VOLLSTAENDIG EINGESCHALTET ; LXI H,MSTAK-80 ;TESTE BANK 1 XRA A ; INIT17 MOV M,A ;SCHREIBE 256 BYTES VOLL INX H ; INR A ; JRNZ INIT17 ; LXI H,0 ;WARTE ETWAS INIT18 DCX H ; MOV A,H ; ORA L ; JRNZ INIT18 ; LXI H,MSTAK-80 ;UND VERGLEICHE WIEDER XRA A ; INIT19 CMP M ; JRNZ INIT20 ;FEHLER INX H ; INR A ; JRNZ INIT19 ; MVI B,0 ;FLAG FUER KEIN FEHLER JR INIT21 ; INIT20 MVI B,02H ;FLAG FUER FEHLER INIT21 LDAI ;LADE FLAG VON BANK 0 ORA B ;UND PACKE FLAK VON BANK 1 DAZU STAI ;WIEDER IN INTERRUPT REGISTER ; CPI 3 ;SPRUNG WENN KEINE BANK JRZ BLINK$LOOP ;IN ORDNUNG IST CPI 1 ;LASSE BANK 1 EINGESCHALTET JRZ INIT22 ;WENN BANK 0 FEHLERHAFT IST ; MVI B,20H ;ANSONSTEN SCHALTE MVI C,P$RAM$TABLE ;WIEDER BANK 0 EIN MVI D,16 ; MVI E,02H ; INIT23 OUTP E ; MOV A,D ; ADD B ; MOV B,A ; CPI 80H ;OBERE HAELFTE JRNZ INIT24 ; MVI E,0AH ; INIT24 ORA A ;ALLES EINGESCHALTET? JRNZ INIT23 ; INIT22 JR INIT14 ;DANN WEITER ; BLINK$LOOP: MVI B,80H ;BESETZE MVI C,PAD$INUSE ;REGISTER LXI H,0 ;VOR EXX ; MVI B,MASK$RX ; MVI C,MASK$CTS ; MVI D,PAD$TX ; MVI E,PAD$RTS ; MVI H,01H ; MVI L,0FFH ; EXX ; BLINK$LOOP1: DCX H ;HL EINS WENIGER ; MOV A,H ; ADD A ; ADD A ; ANA B ;SETZE LED GLEICH ORA C ;DEM DRITTHOECHSTEN OUT P$LS259 ;BIT DES H-REGISTERS ; EXX ; ; IN P$IN$LS258$A ;SETZE TX-LEITUNG ANA B ;AUF DEN ADD L ;PEGEL DER CMC ;RX-LEITUNG RAL ; ANA H ; ORA D ; OUT P$LS259 ; ; IN P$IN$LS258$A ;SETZE RTS-LEITUNG ANA C ;AUF DEN ADD L ;PEGEL DER CMC ;CTS-LEITUNG RAL ; ANA H ; ORA E ; OUT P$LS259 ; ; IN P$IN$LS258$A ;SETZE TXP-LEITUNG ANI MASK$CTSP ;AUF DEN ADD L ;PEGEL DER CMC ;CTSP-LEITUNG RAL ; ANA H ; ORI PAD$TXP ; OUT P$LS259 ; ; EXX ; ; JR BLINK$LOOP1 ; ; INIT14: ;OK, MONITOR KANN LAUFEN ; ;*** LXI SP,MSTAK ;SETZE STACKPOINTER ;*** LXI H,DISKPAGE ;COPIERE ALS ALLERERSTES NACH RAM EIN LXI D,SYSTEMPAGE ;DIE DISKPAGE AUF DIE SYSTEMPAGE LXI B,256 ; LDIR ; ;*** LDAI ;SPEICHER BANKFEHLERBYTE IN STA BANK$ERR$BYTE ;SYSTEMPAGE ;*** CALL FLOPPY$RESET ;SETZE FLOPPY-CONTROLER ;ZURUECK ;*** ;SETZE UMLEITUNGS SPRUENGE IM RAM MVI A,0C3H ;JUMP BEFEHL IN AKKU LXI H,GETCM ;UMLEITUNGSADRESSE IN HL STA UMLEIT$GETCM ; SHLD UMLEIT$GETCM+1 ; LXI H,CONST ; STA UMLEIT$CONST ; SHLD UMLEIT$CONST+1 ; LXI H,CONIN ; STA UMLEIT$CONIN ; SHLD UMLEIT$CONIN+1 ; LXI H,CONOUT ; STA UMLEIT$CONOUT ; SHLD UMLEIT$CONOUT+1 ; LXI H,START ; STA UMLEIT$NMI ; SHLD UMLEIT$NMI+1 ; ;*** ;BESETZE SPEICHERZELLEN VOR ; XRA A ;BESETZE BYTE MIT 0 STA HEAD ; STA DERMSG ;FLOPPY-FEHLERMELDUNG AKTIV MVI A,1 ;BESETZE BYTE MIT 1 STA TEST$TRACK ; STA TRACK ; STA SECTOR ; MVI A,2 ; STA WRITE$PRECOM ;PRECOMPENSATIONSZEIT AUF FESTEN WERT MVI A,10 ; STA RWRETRY ;ANZAHL VERSUCHE FUER FLOPPY R/W LXI H,0 ;BESETZE WORT MIT 0 SHLD DISPADR ; LXI H,IN$BUFF$ZEIG ;SETZE ZEIGER FUER SOFTIN BUFFER SHLD IN$BUFF$ZEIG ; ; LDA XSEEKNR ;VORBESTZUNG WIE IM EPROM EINGEPATCHT STA SEEKNR ; LDA XREADY$BYTE ; STA READY$BYTE ; LDA XTE$TIME ; STA TE$TIME ; LDA XSTEP$WAIT ; STA STEP$WAIT ; LHLD XSPECD$WORD ; SHLD SPECD$WORD ; ; LXI D,KENNUNG ;SETZE KENNUNGSTEXT LXI H,KENNUNGSTEXT ; LXI B,7 ; LDIR ; LDA VERSIONNR ;SETZE MONITOR VERSIONSNUMMER STA MON$VERS ;IM RAM ; ;*** CALL USERINIT ;INITIALISERE BENUTZER SCHNITSTELLEN ;*** CALL GET$SPEED ;IST UHR DA? UND WELCHE TAKTRATE IM SYS. STA CLKFLG ;FLAG FUER UHR DA, NICHT DA ;WENN KEINE UHR DA, WIRD 4MHZ SYS.TAKT IF NOT ACHTMHZ ;ANGENOMMEN. ORA A ; JRNZ INIT3 ;DIES ENTSPRICHT 8MHZ BEI ENDIF ;ACHTMHZ=JA. LXI H,40000 ; INIT3: SHLD SYSTEMTAKT ;LEGE SYSTEMTAKT AB ; ;*** CALL GET$JUMPER ;SETZE BEIDE JUMPERBYTE CALL SET$SOFT$BAUD ;SETZE DIE VERZOEGERUNGSZEIT IN SOFTVERZ ;IN ABHAENIGKEIT VON BAUD$JUMPER$BYTE ;UND DEN EINTRAEGEN IN SOFT$BAUD$TAB LDA XPRNT$BAUD ; CALL SET$SIMPLEX$BAUD ;SETZE SIMPLEX VERZOEGERUNG ; CALL UNIOINIT ;INITIALISIERE UNIO ; ;*** ; LXI H,INITXT0 ;GEBE KOPFTEXT AUS CALL SOUT ; LHLD SERNR ;GEBE SERIENNUMMER CALL PDEC ;ALS DEZIMALZAHL AUS CALL CROUT ; ; ;*** LDA BANK$ERR$BYTE ;GEBE GROESSE DES RAMBEREICHES AUS LXI H,INITXT9 ;128K CPI 0 ; JRZ INIT26 ; LXI H,INITXT6 ;64K (NUR BANK 1) CPI 1 ; JRZ INIT26 ; LXI H,INITXT7 ;64K (NUR BANK 0) INIT26 CALL SOUT ; ; ;*** LDA CLKFLG ;GEBE TAKTRATE AUS, WENN ORA A ;UHR UEBERHAUPT DA? JRZ NOCLK ;GEBE MELDUNG AUS, WENN UHR DA LXI H,INITXT1 ; CALL SOUT ; IF NOT ACHTMHZ ; LHLD SYSTEMTAKT ;GEBE ERMITTELTE TAKT FREQUENZ AUS CALL PDEC ; LXI H,INITXT2 ; CALL SOUT ; ENDIF ; CALL DISP$TIME ;GEBE UHRZEIT AUS JR NOCLK2 ; NOCLK: IF ACHTMHZ ; LXI H,INITXT1 ; CALL SOUT ; ENDIF ; LXI H,INITXT4 ;GEBE MELDUNG AUS CALL SOUT ;WENN UHR NICHT DA NOCLK2: ; ; ;*** IM1 ;INTERRUPT MODE 1 EI ;ENABLE INTERRUPTS LDA IO$JUMPERBYTE ;INTERRUPTBETRIEB DER SOFT-EINGABE? DCR A ;WENN JA GEBE RTS FREI JRNZ INIT28 ; MVI A,PAD$RTS ; OUT P$LS259 ; INIT28: ; ; ;*** LDA CLKFLG ;SETZE DISKTIMING NEU, WENN ORA A ;A) UHR OK UND B) CHECKSUMME JZ INIT29 ;DES SCHIFTREGISTERS STIMMT. LXI H,SHIFT$CONT+4 ;BERECHNE PRUEFSUMME MOV A,M ; ORI 00011111B ;MASKIERE JAHRESZAHL MVI B,4 ;ADDIERE DIE RESTLICHEN 4 BYTE INIT30 DCX H ; ADD M ; DJNZ INIT30 ; ORA A ;PRUEFSUMME MUSS 0 SEIN MVI A,0 ;FALLS SPRUNG, DANN A=0 JNZ INIT29 ;SONST DEFAULT WERTE CALL UCMD2 ;SETZE NEUES TIMING MVI A,0FFH ;FLAG FUER PROMT INIT29: STA TEMP ; ; ;*** ; CALL INIFDC ;IST FLOPPY CONTROLLER IN ORDNUNG? ;WENN JA SETZE SOFT RESET LDA DISKFLG ;WAR ZUGRIFF AUF FLOPY CONTROLER MOEGLICH? ORA A ; JRZ INIT4 ;SPRUNG WENN FLOPY NICHT OK CALL SPECD ;SET DRIVE PAR. + DMA-MODE JR INIT5 ; INIT4: ; LXI H,INITXT5 ;GEBE MELDUNG FUER FLOPPY FEHLER AUS CALL SOUT ; LDA BOOT$FLG ;DEFAULT BOOT VON HARDDISK ORA A ;JA, WENN NULL JNZ START ;SONST KEIN BOOT MOEGLICH, ZUM MONITOR INIT5: ; ; ;*** ; LDA TEMP ;GEBE MELDUNG AUS OB NON-DEFAULT LXI H,INITXTA ;DISKTIMING INR A ; CZ SOUT ; ; ;*** ; LXI H,INITXT3 ;MONITOR ODER BOOT CALL SOUT ; LXI H,INITXTC ; LDA BOOT$FLG ; ORA A ; JNZ INITA ; LXI H,INITXTB ; INITA: CALL SOUT ; CALL GETCH1 ; PUSH PSW ; CALL CROUT ;GEBE AUF JEDEN FALL CR LF AUS POP PSW ; CPI 0DH ;MONITOR? JZ START ;NEIN BOOT ; LDA BOOT$FLG ;TESTE, OB BOOT VON ORA A ;HARDDISK ODER JZ HCMD ;FLOPPY JMP BCMD ; ; ;*** ; INITXT0 DB 0CH,0DH,0AH,'PROF-80, EPROM version 1.7 serial no. #$' IF ACHTMHZ INITXT1 DB 0DH,0AH,'System speed 8.00 MHz assumed',0DH,0AH,'$' ELSE INITXT1 DB 0DH,0AH,'System speed $' INITXT2 DB '00 (Hz)',0DH,0AH,'$' ENDIF INITXTA DB 0DH,0AH,'user defined disk timing',0Dh,0Ah,'$' INITXT3 DB 0DH,0AH,' => Monitor, => boot from $' INITXTC DB 'Floppy $' INITXTB DB 'Harddisk $' INITXT4 DB 0DH,0AH,'Clock failure' IF NOT ACHTMHZ DB ', 4 MHz system speed is assumed' ENDIF DB 0DH,0AH,'$' INITXT5 DB 0DH,0AH,'Floppy failure',0DH,0AH,'$' INITXT6 DB 0DH,0AH,' 64K RAM (Bank 1 only)',0DH,0AH,'$' INITXT7 DB 0DH,0AH,' 64K RAM (Bank 0 only)',0DH,0AH,'$' INITXT9 DB 0DH,0AH,' 128K RAM',0DH,0AH,'$' ; ;----------------------------------------------------ENDE INITIALISIERUNG---- ; ;----------------------------------------------------EIN-AUSGABEROUTINEN----- ; ; ; GRAFIST: ;TERMINAL EINGABE STATUS ;AKKU 0 UND Z WENN KEIN ZEICHEN ;AKKU FF UN NZ WENN ZEICHEN IN GRIPC ANI GRIPIN$MASK RZ MVI A,0FFH ORA A ;RESET ZERROFLAG RET ; ; ; GRAFOST: ;TERMINAL AUSGABE STATUS IN GRIPC ANI GRIPOUT$MASK RZ MVI A,0FFH ORA A RET ; ; ; GRAFIN: ;TERMINAL EINGABE IN GRIPC ANI GRIPIN$MASK ;ZEICHEN DA ? JRZ GRAFIN ;WARTE AUF ZEICHEN IN GRIPD RET ; ; GRAFOUT: ;TERMINAL AUSGABE IN GRIPC ANI GRIPOUT$MASK JRZ GRAFOUT ;WARTE BIS BUFFER LEER MOV A,C ;AUSGABE ZEICHEN NACH A OUT GRIPD RET ; ; ; ;EIN-AUSGABE FUER DIE DUPLEX SCHNITTSTELLE AUF DER CPU-KARTE ; ; SOFTOUT: ; GEBE INHALT VON REGISTER C IM SERIELLEN FORMAT AUS ; PUSH B ;RETTE BC PUSH D ;RETTE DE PUSH H ;RETTE HL SOFTOUT4: IN P$IN$LS258$A ;WARTE AUF FREIGABE ANI MASK$CTS ; JRZ SOFTOUT4 ; MVI A,PAD$RTS OR 1 ;SPERRE EINGABE OUT P$LS259 ; DI ;SPERRE INTERRUPTS RLCR C ;BITS RICHTIG FUER AUSGABE MVI D,PAD$TX ;ADRESSE DES TXD BITS AM LS259 XRA A ;STARTBIT IN AKKU MVI B,9 ;GEBE 9 BITS AUS SOFTOUT1: ANI 001H ;MASKIERE BIT FUER AUSGABE <7> ORA D ;PACKE ADRESSE DAZU <4> OUT P$LS259 ;GEBE BIT AUS <11> LHLD SOFTVERZ ;LADE VERZOEGERUNGSZEIT <16> SOFTOUT2: DCX H ;VERZOEGERUNG <6> MOV A,H ;GLEICH NULL? <4> ORA L ; <4> JNZ SOFTOUT2 ; <10> ; RRCR C ;SCHIEBE C UM EIN BIT NACH RECHTS <8> MOV A,C ; <4> DJNZ SOFTOUT1 ; <13> ; MVI A,PAD$TX OR 1 ;GEBE STOPBIT AUS OUT P$LS259 ; LHLD SOFTVERZ ; DAD H ;ZWEI STOPBITS SOFTOUT3: DCX H ;VERZOEGERUNG FUER MOV A,H ;STOPBIT ORA L ; JNZ SOFTOUT3 ; ; EI ;GEBE INTERRUPTS FREI LDA IO$JUMPERBYTE ;KANN EINGABE FREI GEGEBEN WERDEN? DCR A ;JA WENN INT.BETRIEB JRNZ SOFTOUT5 ; MVI A,PAD$RTS ;GEBE EINGABE FREI OUT P$LS259 ; SOFTOUT5: POP H ;RETTE HL POP D ;RETTE DE POP B ;RETTE BC MOV A,C ;ZEICHEN IN AKKU RET ; ; ; SOFTIN: ;EINLESEN EINES ZEICHENS SOWOHL IM INTERRUPT ;BETRIEB (INTERRUPT BETRIEB IST DANN, WENN DIE ;SOFTSCHNITTSTELLE DIE KONSOLE TREIBT) ;ALS AUCH IM NICHT INTERRUPT BETRIEB ; PUSH B PUSH D PUSH H LDA IO$JUMPERBYTE ;IST INTERRUPT-BETRIEB? DCR A ;INT. WENN A=1 JRZ SOFTIN8 ;SPRUNG BEI INTERRUPT MVI A,PAD$RTS ;GEBE RTS FREI OUT P$LS259 ; CALL SOFTIN1 ;ANSONSTEN WARTE AUF STARTBIT UND LESE EIN PUSH PSW ; MVI A,PAD$RTS OR 1 ; OUT P$LS259 ; POP PSW ; POP H ; POP D ; POP B ; RET ; ; SOFTIN8: ;IM INTERRUPT-BETRIEB WIRD GEWARTET BIS ;DIE INTERRUPT SERVICE ROUTINE EIN ZEICHEN ;IN DEN BUFFER SCHREIBT ; EI ;VORSICHTSHALBER INT. ENABLE MVI A,PAD$RTS ; OUT P$LS259 ; MVI C,IN$BUFF$ZEIG AND 0FFH SOFTIN9 LDA IN$BUFF$ZEIG ;WARTE BIS EIN ZEICHEN KOMMT CMP C ;WENN GLEICH, DANN NOCH KEIN ZEICHEN JRZ SOFTIN9 ; MVI A,PAD$RTS OR 1 ;RTS INAKTIV OUT P$LS259 ; DI ;OK, ZEICHEN DA, SPERRE INT. LDA IN$BUFF$ZEIG-1 ;LADE ZEICHEN IN AKKU LHLD IN$BUFF$ZEIG ; INX H ;UND ERHOEHE ZEIGER SHLD IN$BUFF$ZEIG ; LXI D,IN$BUFF$ZEIG-1;SCHIEBE ZEICHEN EINS HOCH LXI H,IN$BUFF$ZEIG-2; LXI B,IN$BUFF$ZEIG-1-IN$BUFF$END ; LDDR ; EI ;INTERRUPTS ENABLE PUSH PSW ; MVI A,PAD$RTS ;GEBE EINGABE FREI OUT P$LS259 ; POP PSW ; POP H ; POP D ; POP B ; RET ; ; ; ; INT$SERVICE: ;NACH EINEM INTERRUPT UND WENN DIE SOFTSCHNITTSTELLE DIE KONSOLE ;BEDIENT, WIRD DIESE INTERRUPT-SERVIE-ROUTINE ANGESPROCHEN. ;SIE LIEST EIN ZEICHEN IN DIE SPEICHER ZELLE UNTER DIE IN$BUFF$ZEIG ;ZEIGT. IST DER BUFFER VOLL (11 BYTES), WIRD KEIN ZEICHEN ;MEHR EINGELESEN. ; PUSH PSW ; PUSH B ; PUSH D ; PUSH H ; CALL SOFTIN2 ;LESE ZEICHEN EIN MOV C,A ;RETTE ZEICHEN IN C LHLD IN$BUFF$ZEIG ;LADE BUFFER-ZEIGER MVI A,IN$BUFF$END AND 0FFH CMP L ;ZEIGER SCHON AM ENDE? JRZ INT$SERVICE1 ;DANN GEHT ZEICHEN VERLOREN DCX H ;SONST LEGE ZEICHEN IN BUFFER MOV M,C ; SHLD IN$BUFF$ZEIG ;UND SETZE ZEIGER NEU INT$SERVICE1: ; POP H ; POP D ; POP B ; POP PSW ; EI ;GEBE INT. FREI RET ; ; ; ; SOFTIN1: ;LESE ZEICHEN UEBER 74LS258 EIN ; IN P$IN$LS258$A ; ANI MASK$RX ;WARTE AUF STARTBIT JRZ SOFTIN1 ;DER LS258 NEGIERT SOFTIN2: ; LHLD SOFTVERZ ;LADE VERZOEGERUNG SRLR H ;TEILE DURCH ZWEI RARR L ;UM IN DER BIT MITTE ABZUTASTEN SOFTIN5 DCX H ;VERZOEGERUNGSSCHLEIFE MOV A,H ;FUER EIN HALBES BIT ORA L ; JNZ SOFTIN5 ; ; MVI B,8 ;LESE 8 BITS EIN SOFTIN3: LHLD SOFTVERZ ;ERST EIN BIT VERZOEGERN <16> SOFTIN4 DCX H ;VERZOEGERUNGSSCHLEIFE MOV A,H ; ORA L ; JNZ SOFTIN4 ; ; IN P$IN$LS258$A ;LESE BIT EIN <11> ANI MASK$RX ; <7> ADI 0FFH ;SETZE CARRY WENN EINS <7> RARR C ;UND LEGE IN CHARPUF. <8> DJNZ SOFTIN3 ;LESE 8 BITS EIN <13> ; MOV A,C ;ERGEBNISS IN AKKU CMA ;NEGIERE, DA LS258 AUCH NEGIERT SOFTIN7 ANI 7FH ;STRIPP OF PARITY ; PUSH PSW ; LHLD SOFTVERZ ;WARTE STOP BIT AB SOFTIN10: DCX H ; MOV A,H ; ORA L ; JNZ SOFTIN10 ; POP PSW ; ; RET ; ; ; SOFTIST: ;PRUEFE, OB IM INT.-BETRIEB EIN ZEICHEN IM BUFFER IST ;WENN EINS GEKOMMEN IST, SETZE A AUF FF ;SONST AUF 0 ;IST KEIN INTERRUPT BETRIEB, DANN AKKU IMMER 0 ; PUSH H PUSH D PUSH B LDA IO$JUMPERBYTE ;INT. BETRIEB? DCR A ; JRNZ SOFTST1 ;SPRUNG WENN KEIN INT.-BETRIEB LDA IN$BUFF$ZEIG ;LADE ZEIGER MVI C,IN$BUFF$ZEIG AND 0FFH CMP C ;VERGLEICHE JRZ SOFTST1 ;SPRUNG WENN KEIN ZEICHEN DA MVI A,0FFH ; JR SOFTST2 ; SOFTST1 MVI A,0 ; SOFTST2 POP H POP D POP H ORA A ;SETZE ZEROFLAG RET ; ; ; SOFTOST: IN P$IN$LS258$A ;LESE CTS EIN ANI MASK$CTS ;MASKIERE RZ ;RETURN WENN NICHT BEREIT MVI A,0FFH ;SONST BEREIT ORA A ;RESET ZERRO-FLAG RET ; ; ; ; SOFTPRNTOST: IN P$IN$LS258$A ;LESE CTSP EIN ANI MASK$CTSP ; RZ ; MVI A,0FFH ; ORA A ; RET ; ; ; SOFTPRNTOUT: ; GEBE INHALT VON REGISTER C IM SERIELLEN FORMAT ; AUF DER SIMPLEX SCHNITTSTELLE AUS ; PUSH B ;RETTE BC PUSH D ;RETTE DE PUSH H ;RETTE HL SOFTPRNTOUT4: IN P$IN$LS258$A ;WARTE AUF FREIGABE ANI MASK$CTSP ; JRZ SOFTPRNTOUT4 ; MVI A,PAD$RTS OR 1 ;SPERRE EINGABE VON DUPLEX SCHNITTSTELLE OUT P$LS259 ; DI ;SPERRE INTERRUPTS RLCR C ;BITS RICHTIG FUER AUSGABE MVI D,PAD$TXP ;ADRESSE DES TXD BITS AM LS259 XRA A ;STARTBIT IN AKKU MVI B,9 ;GEBE 9 BITS AUS SOFTPRNTOUT1: ANI 001H ;MASKIERE BIT FUER AUSGABE <7> ORA D ;PACKE ADRESSE DAZU <4> OUT P$LS259 ;GEBE BIT AUS <11> LHLD SOFTPRNTVERZ ;LADE VERZOEGERUNGSZEIT <16> SOFTPRNTOUT2: DCX H ;VERZOEGERUNG <6> MOV A,H ;GLEICH NULL? <4> ORA L ; <4> JNZ SOFTPRNTOUT2 ; <10> ; RRCR C ;SCHIEBE C UM EIN BIT NACH RECHTS <8> MOV A,C ; <4> DJNZ SOFTPRNTOUT1 ; <13> ; MVI A,PAD$TXP OR 1 ;GEBE STOPBIT AUS OUT P$LS259 ; LHLD SOFTPRNTVERZ ; DAD H ;ZWEI STOPBITS SOFTPRNTOUT3: DCX H ;VERZOEGERUNG FUER MOV A,H ;STOPBIT ORA L ; JNZ SOFTPRNTOUT3 ; ; EI ;GEBE INTERRUPTS FREI MVI A,PAD$RTS ;GEBE EINGABE FREI DUPLEX OUT P$LS259 ;SCHNITTSTELLE FREI POP H ;RETTE HL POP D ;RETTE DE POP B ;RETTE BC MOV A,C ;ZEICHEN IN AKKU RET ; ; ; GET$JUMPER: LXI H,PATAB ; LXI B,PDTAB ; MVI E,P$LS259 ; MVI D,P$IN$LS258$B ; CALL JUMPIN ; STA BAUD$JUMPERBYTE ;SPEICHERE AB MOV A,D ; STA IO$JUMPERBYTE ; RET ; ; ; JUMPIN: ;DIESES PROGRAMM LIEST DIE BEIDEN ;JUMPER AUF DER UNIO- BZW PROF-KARTE ;EIN. FOLGENDE REGISTER MUESSEN BELEGT SEIN ;E=PORTADRESSE DES 74 LS259 ;D=PORTADRESSE DES EINGANGS PORTS ;BC=ADRESSE DER DECODER TABELLE ;HL=ADRESSE DER AUSGANGS BITS ;AUSGABE ;AKKU=JUMPER 1, D=JUMPER2 ; PUSH B ;RETTE DECODER TABELLE MOV C,E ; MVI B,3 ;ERSTES BITMUSTER AUSGEBEN OUTIR ; MOV A,C ;TAUSCHE PORTADRESSE MOV C,D ; MOV D,A ; INP A ;LESE ERSTES BITPAAR EIN RAR ;SCHIEBE BITS NACH RECHTS RAR ; RAR ; RAR ; ANI 00000011B ;MASKIERE MOV E,A ;UND NACH E ; MOV A,C ;TAUSCHE PORTADRESSE MOV C,D ; MOV D,A ; MVI B,2 ;ZWEITES BITMUSTER AUSGEBEN OUTIR ; MOV A,C ;TAUSCHE PORTADRESE MOV C,D ; MOV D,A ; INP A ;LESE ZWEITES BITPAAR EIN EIN RAR ;EINMAL NACH RECHTS SCHIEBEN RAR ; ANI 00001100B ;MASKIEREN ORA E ;UND ZU E PACKEN MOV E,A ; ; MOV A,C ;TAUSCHE PORTADRESSE MOV C,D ; MOV D,A ; MVI B,2 ;DRITTES BITMUSTER AUSGEBEN OUTIR ; MOV A,C ;TAUSCHE PORTADRESSE MOV C,D ; MOV D,A ; INP A ;LESE DRITTES BITPAAR EIN ANI 00110000B ;MASKIEREN UND ZU E PACKEN ORA E ; MVI B,3 ;TRENNE BEIDE JUMPERFELDER JUMPI1 RAR ; RALR D ; RAR ; RALR E ; DJNZ JUMPI1 ; POP H ;HOLE DECODER TABELLE PUSH H ; MVI B,0 ; MOV A,D ; ANI 00000111B ; MOV C,A ; DAD B ; MOV D,M ; POP H ;HOLE DECODER TABELLE MOV A,E ; ANI 00000111B ; MOV C,A ; DAD B ; MOV A,M ; RET ; ; ; ; UDTAB DB 6,8,12,14 ;DECODIER TABELLE FUER UNIO JUMPER DB 10,14,14,14 ; ; PDTAB DB 0,0,0,2 ;DECODIER TABELLE FUER PROF JUMPER DB 0,3,4,1 ; ; UATAB DB 0BH,0CH,0EH ; DB 0AH,0DH ; DB 0CH,0FH ; ; PATAB DB 080H,010H,020H ; DB 000H,090H ; DB 010H,0A0H ; ; ; ; ; ES FOLGEN UNIO TREIBER-ROUTINEN ; ; ; UNIOINIT: ;DIESE ROUTINE WIRD BEI INITIALISIERUNG DES MONITORS ;AUFGERUFEN. STROBE UND INIT FUER UNIO-CENTRONICS ;WURDEN VON INIT SCHON AUF HIGH GESETZT. ;UNIOINIT LIEST DIE BEIDEN SIO-BAUDRATEN-JUMPER EIN ;UND INITIALISIERT BEIDE SIO- UND DEN STI KANAL. ; LXI H,UATAB ;LESE UNIO BAUD JUMPER LXI B,UDTAB ; MVI E,CONTR ; MVI D,STAT ; CALL JUMPIN ; STA SIOBBAUD ; MOV A,D ; STA SIOABAUD ; ; LDA STIBAUD ;INITIALISIERE STI CALL STINIT ; LDA SIOABAUD ; CALL SAINIT ; LDA SIOBBAUD ; CALL SBINIT ; RET ; ; ; ; STI INITIALISIEREN, IN AKKU STEHT NUMMER FUER BAUDRATE ; FALLS OBERE 4 BIT VON AKKU .NE. 0 DANN WIRD BAUDRATE FUER ; RECEIVER UND TRANSMITTER GETRENNT EINGESTELLT ; STINIT: PUSH PSW ;RETTE AKKU ANI 0FH ;NUR TRANSMITTER BAUDRATE CALL STITINIT ; POP PSW ;JETZT RECEIVER BAUDRATE MOV B,A ; ANI 0F0H ;WENN OBERES HALBBYTE = 0 JRZ STINIT1 ;DANN GLEICHE BAUDRATE MOV A,B ; ANI 0FH ;38400 BAUD NUR AUF BEIDEN KANAELEN JRZ STINIT2 ;GLEICHZEITIG MOEGLICH MOV A,B ; RAR ; RAR ; RAR ; RAR ; STINIT3 ANI 0FH ; CALL STIRINIT ; RET ; STINIT1 MOV A,B ; JR STINIT3 ;BEIDE KANAELE GLEICHE BAUDRATE STINIT2 XRA A ; JR STINIT3 ;BEIDE KANAELE 38400 BAUD ; STITINIT: LXI H,SERTAB ;ZEIGER FUER TABELLE BERECHNEN MOV C,A ; MVI B,0 ; DAD B ; DAD B ; MVI A,2 ;POINTER AUF TIMER C DATA OUT STI8 ; MOV A,M ;TIMER C DATA OUT STI0 ; INX H ; MVI A,7 ;TIMER C UND D CONTROL OUT STI8 ; MOV A,M ;PRESCALE ANI 0F0H ;NUR OBERES HALBBYTE MOV B,A ; IN STI0 ;TIMER C CONTROL LOESCHEN ANI 0FH ; ORA B ; OUT STI0 ; RET ; ; STIRINIT: LXI H,SERTAB ; MOV C,A ; MVI B,0 ;ZEIGER FUER TABELLE BERRECHNEN DAD B ;2 EINTRAEGE PRO WERT DAD B ; MVI A,1 ;POINTER AUF TIMER D DATA OUT STI8 ; MOV A,M ;TIMER D DATA OUT STI0 ; INX H ; MVI A,7 ;TIMER C UND D CONTROL OUT STI8 ; MOV A,M ;PRESCALE ANI 0FH ;NUR UNTERES HALBBYTE MOV B,A ; IN STI0 ;ALTE TIMER C UND D CONTROL DATEN ANI 0F0H ;TIMER D CONTROL LOESCHEN ORA B ;NEUES TIMER D CONTROL EINTRAGEN OUT STI0 ; MOV A,C ; ORA A ; MVI A,10001000B ;USART CONTROL: 8 DATA BIT, NO PAR, 1 STOP JRNZ STINIT4 ; ANI 01111111B ;SCALE/1 BEI 38.4 BAUD STINIT4 OUT STIC ; MVI A,1 ; OUT STID ;RECEIVER ENABLE MVI A,95H ; OUT STIE ;TRANSMITTER ENABLE RET ; ; ; ; ; SIO A INITIALISIERUNG, IN AKKU STEHT NUMMER FUER BAUDRATE ; SAINIT: LXI H,SERTAB ; MOV E,A ; MVI D,0 ;ZEIGER FUER TABELLE BERRECHNEN DAD D ;2 EINTRAEGE PRO WERT DAD D ; MOV A,M ;TIMER B DATA OUT STIA ; INX H ; MOV A,M ;PRESCALE ANI 0FH ;NUR UNTERES HALBBYTE MOV B,A ; IN STI9 ;ALTE TIMER A UND B CONTROL DATEN ANI 0F0H ;TIMER B CONTROL LOESCHEN ORA B ;NEUE TIMER B CONTROL DATEN OUT STI9 ; LXI H,SIOTAB ;TABELLE FUER SIO INITIALISIERUNG MOV B,M ;TABELLEN LAENGE INX H ; MVI C,SIOAC ; OUTIR ;TABELLE AN SIO UEBERGEBEN MOV A,E ; ORA A ; MVI A,01000100B ;SIO WR-REG.4: CLOCK/16, 1 STOP, NO PAR. JRNZ SAINIT1 ; ANI 10111111B ;CLOCK/1 BEI 38.4 BAUD SAINIT1 OUT SIOAC ; RET ; ; ; ; ; SIO B INITIALISIERUNG, IN AKKU STEHT NUMMER FUER BAUDRATE ; SBINIT: LXI H,SERTAB ; MOV E,A ; MVI D,0 ;ZEIGER FUER TABELLE BERRECHNEN DAD D ;2 EINTRAEGE PRO WERT DAD D ; MOV A,M ;TIMER A DATA OUT STIB ; INX H ; MOV A,M ;PRESCALE ANI 0F0H ;NUR OBERES HALBBYTE MOV B,A ; IN STI9 ;ALTE TIMER A UND B CONTROL DATEN ANI 0FH ;TIMER A CONTROL LOESCHEN ORA B ;NEUE TIMER A CONTROL DATEN OUT STI9 ; LXI H,SIOTAB ;TABELLE FUER SIO INITIALISIERUNG MOV B,M ;TABELLEN LAENGE INX H ; MVI C,SIOBC ; OUTIR ;TABELLE AN SIO UEBERGEBEN MOV A,E ; ORA A ; MVI A,01000100B ;SIO WR-REG.4: CLOCK/16, 1 STOP, NO PAR. JRNZ SBINIT1 ; ANI 10111111B ;CLOCK/1 BEI 38.4 BAUD SBINIT1 OUT SIOBC ; RET ; ; ; ; ; STI OUT ; STOUT CALL STOST ;BEREIT ? JRZ STOUT ; MOV A,C ; OUT STIF ; RET ; ; ; ; ; STI OUT STATUS ; STOST IN STIE ; ANI 10000000B ; RZ ; ORI 0FFH ; RET ; ; ; ; ; STI IN ; STIN CALL STIST ; JRZ STIN ; IN STIF ; RET ; ; ; ; ; STI INPUT STATUS ; STIST IN STID ; ANI 10000000B ; RZ ; ORI 0FFH ; RET ; ; ; ; ; SIO A OUT ; SAOUT CALL SAOST ; JRZ SAOUT ;NOCH NICHT BEREIT MOV A,C ; OUT SIOAD ;ZEICHEN SENDEN RET ; ; ; ; ; SIO A OUT STATUS ; SAOST IN SIOAC ;LESE STATUS ANI 00000100B ; RZ ; ORI 0FFH ; RET ; ; ; ; SIO A IN ; SAIN CALL SAIST ; JRZ SAIN ;NOCH KEIN ZEICHEN EMPFANGEN IN SIOAD ; RET ; ; ; ; ; SIO A IN STATUS ; SAIST IN SIOAC ;LESE STATUS ANI 00000001B ; RZ ; ORI 0FFH ; RET ; ; ; ; ; SIO B OUT ; SBOUT CALL SBOST ; JRZ SBOUT ;NOCH NICHT BEREIT MOV A,C ; OUT SIOBD ;ZEICHEN SENDEN RET ; ; ; ; ; SIO B OUT STATUS ; SBOST IN SIOBC ;LESE STATUS ANI 00000100B ; RZ ; ORI 0FFH ; RET ; ; ; ; SIO B IN ; SBIN CALL SBIST ; JRZ SBIN ;NOCH KEIN ZEICHEN EMPFANGEN IN SIOBD ; RET ; ; ; ; ; SIO B IN STATUS ; SBIST IN SIOBC ;LESE STATUS ANI 00000001B ; RZ ; ORI 0FFH ; RET ; ; ; ; ; CENTRONICS 1 OUT ; C1OUT CALL C1OST ;BEREIT FUER NAECHSTES ZEICHEN? JRZ C1OUT ; MOV A,C ; OUT CENT1 ; MVI A,4 ;/STB1 = LOW OUT CONTR ; MVI A,5 ;/STB1 = HIGH OUT CONTR ; MOV A,C ;GESENDETES ZEICHEN IN A RET ; ; ; ; ; CENTRONICS 1 OUT STATUS ; C1OST IN STAT ;CENTRONICS 1 STATUS CMA ; ANI 01000000B ; RZ ; ORI 0FFH ; RET ; ; ; ; ; CENTRONICS 2 OUT ; C2OUT CALL C2OST ;BEREIT FUER NAECHSTES ZEICHEN? JRZ C2OUT ; MOV A,C ; OUT CENT2 ; MVI A,6 ;/STB2 = LOW OUT CONTR ; MVI A,7 ;/STB2 = HIGH OUT CONTR ; MOV A,C ;GESENDETES ZEICHEN IN A RET ; ; ; ; ; CENTRONICS 2 OUT STATUS ; C2OST IN STAT ;CENTRONICS 2 STATUS CMA ; ANI 10000000B ; RZ ; ORI 0FFH ; RET ; ; ; ; ; SERTAB: DB 8,11H ;38400 BAUD DB 96,33H ; 50 BAUD DB 64,33H ; 75 BAUD DB 175,11H ; 110 BAUD DB 143,11H ; 134.5 BAUD DB 128,11H ; 150 BAUD DB 64,11H ; 300 BAUD DB 32,11H ; 600 BAUD DB 16,11H ; 1200 BAUD DB 11,11H ; 1745 BAUD DB 8,11H ; 2400 BAUD DB 5,11H ; 3840 BAUD DB 4,11H ; 4800 BAUD DB 3,11H ; 6400 BAUD DB 2,11H ; 9600 BAUD DB 1,11H ;19200 BAUD ; ; ; SIOTAB: DB SIOTAL-SIOTAB-1 DB 1,0 DB 3,11100001B DB 5,11101010B DB 4 SIOTAL EQU $ ; ; ; ;-------------------------------------------------ENDE DER E/A-ROUTINEN----- ; ; ; CONST: ;VERTEILER FUER CONSOLEN STATUS ;DIE ROUTINEN MUESSEN A=FF UND KEIN ZERO-FLAG SETZEN ;FALLS EIN ZEICHEN DA IST SONST AKKU= 0 UND ZERO-FLAG ; LDA IO$JUMPERBYTE ;LESE JUMPERBYTE EIN CALL VERTEILER ; DW GRAFIST ; DW SOFTIST ; DW USER1IST ; DW USER2IST ; DW DUMMYIST ; ; ; ; CONIN: ;VERTEILER FUER CONSOLEN EINGABE ;DIE ROUTINE MUSSEN AUF EIN ZEICHEN VON DER KONSOLE WARTEN ;UND DIESES IM AKKU UEBERGEBEN ;ALLE ANDEREN REGISTER BLEIBEN UNVERAENDERT ; LDA IO$JUMPERBYTE ; CALL VERTEILER ; DW GRAFIN ; DW SOFTIN ; DW USER1IN ; DW USER2IN ; DW DUMMYIN ; ; ; ; CONOUT: ;VERTEILER FUER CONSOLEN AUSGABE ;DAS ZEICHEN IN REG C. WIRD VON DEN ROUTINEN AUSGEGEBEN ;UND IN AKKU KOPIERT, ALLE ANDEREN REGISTER BLEIBEN UNVERAENDERT ; LDA IO$JUMPERBYTE ; CALL VERTEILER ; DW GRAFOUT ; DW SOFTOUT ; DW USER1OUT ; DW USER2OUT ; DW DUMMYOUT ; ; ; ; VERTEILER: ;VERZEIGT AUF EINE DER ADRESSEN DIE DER RETURNADRESSE FOLGEN ; XTHL ;LEGE RETURNADRESSE IN HL VERTEILER1: DCR A ;WAR AKKU NULL? JM VERTEILER2 ;DANN ZEIGT HL AUF DIE RICHTIGE RETURN ADR. INX H ;ANSONSTEN EINE ADRESSE WEITER INX H ; JR VERTEILER1 ; VERTEILER2: MOV A,M ;LADE ADRESSE DER ROUTINE IN HL INX H ; MOV H,M ; MOV L,A ; XTHL ; LADE ALTES HL UND LEGE ADRESSE DER ROUTINE ; AUF DEN STACK RET ; SPRINGE IN DIE RICHTIGE ROUTINE ; ; ; DUMMYIST: MVI A,0FFH ORA A RET ; ; ; DUMMYIN: MVI A,'7' RET ; ; ; DUMMYOUT: MOV A,C RET ; ; ; BREAK: ;PRUEFT OB EIN ZEICHEN EINGELESEN WURDE ; CALL CS ; JZ FRET ; CALL CI ;LESE ZEICHEN ANI 7FH ; CPI 1BH ;GLEICH ESCAPE JZ SRET ;JA ENDE BREAK1 CALL CS ;WARTE AUF NEUES ZEICHEN JRZ BREAK1 ; CALL CI ;LESE NEUES ZEICHEN ANI 7FH ; CPI 1BH ; JZ SRET ;WAR BREAK JMP FRET ;WAR ETWAS ANDERES ; ; ; CNVBN: MOV A,C ; SUI '0' ; CPI 0AH ; RM ; SUI 7 ; RET ; ; ; SOUT: ;GEBE STRING AUS ;ANFANG IN HL, ENDE DURCH 24HEX MOV A,M ;LESE ZEICHEN CPI '$' ;STRING ENDE RZ ;RETURN WENN $ MOV C,A ;IN C FUER AUSGABE CALL CO ;GEBE ZEICHEN AUF CONSOLE INX H ;ZEIGER AUF NAECHSTES ZEICHEN JR SOUT ;WIEDERHOLE ; ; ; CROUT: PUSH B ; MVI C,0DH ; CALL ECHO ; POP B ; RET ; ; ; ECHO: PUSH B ; MOV B,C ; MVI A,1BH ; CMP B ; JRNZ ECH05 ; MVI C,'$' ; ECH05: CALL CO ; MVI A,0DH ; CMP B ; JRNZ ECH10 ; MVI C,0AH ; CALL CO ; ECH10: POP B ; MOV A,C ; RET ; ; ; ERROR: LXI H,SYNERRTXT CALL SOUT JMP GETCM ; SYNERRTXT DB ' What?',BELL,0DH,0AH,'$' ; ; ; FRET: STC CMC RET ; ; ; ; GETCH1: ;LESE EIN ZEICHEN VON KONSOLE, UND WANDLE IN GROSSBUCHSTABEN CALL CI ANI 7FH MOV C,A CPI 'a' RC SUI 'a'-'A' MOV C,A RET ; ; ; GETCH: CALL CI ANI 7FH MOV C,A RET ; ; ; GETHX: PUSH H LXI H,0 MVI E,0 L0228: CALL GETCH1 MOV C,A CALL VALDL JNC L0241 CALL ECHO MOV D,C PUSH H POP B POP H MOV A,E ORA A JNZ SRET JZ FRET L0241: CALL VALDG JNC L0228 CALL ECHO CALL CNVBN MVI E,0FFH DAD H DAD H DAD H DAD H MVI B,0 MOV C,A DAD B JMP L0228 ; ; ; GETDEZ: ;LESE DEZIMALZAHLEN NACH HL ;ALS TRENNZEICHEN WERDEN '/',':' UND ERKANNT ;TRENNZEICHEN WIRD IN AKKU UEBERGEBEN ; MVI B,0 LXI H,0 ;LOESCHE AKKU GETDEZ1 CALL GETCH1 ;LESE ZEICHEN CPI '/' JRZ GETDEZ2 CPI ':' JRZ GETDEZ2 CPI 0DH JRZ GETDEZ2 SUI '0' ;ZAHL ? JRC GETDEZ1 CPI 0AH JRNC GETDEZ1 MOV C,A DAD H DAD H DAD H DAD H DAD B MVI A,'0' ;GEBE ZAHL AUS ADD C MOV C,A CALL ECHO JR GETDEZ1 GETDEZ2 MOV C,A CALL ECHO MOV A,C RET ; ; ; DEZHEX: ;WANDELT DEZIMAL ZAHL IM AKKU IN HEXWERT UM PUSH B CPI 0 ;IST SCHON 0? JRZ DEZHEX1 MVI B,0 DEZHEX2 INR B DCR A DAA JNZ DEZHEX2 MOV A,B DEZHEX1 POP B RET ; ; ; GETNM: MVI L,3 MOV A,C ANI 3 RZ MOV H,A L025E: CALL GETHX JNC ERROR PUSH B DCR L DCR H JZ L0273 MOV A,D CPI 0DH JZ ERROR JMP L025E L0273: MOV A,D CPI 0DH JNZ ERROR LXI B,0FFFFH MOV A,L ORA A JZ L0286 L0281: PUSH B DCR L JNZ L0281 L0286: POP B POP D POP H CALL HILO JNC L0291 MOV D,H MOV E,L L0291: XTHL PUSH D PUSH B PUSH H L0295: DCR A RM POP H XTHL JMP L0295 HILO : PUSH B MOV B,A PUSH H MOV A,D ORA E JZ L02BD INX H MOV A,H ORA L JZ L02BD ;02BDH POP H PUSH D MVI A,0FFH XRA D MOV D,A MVI A,0FFH XRA E MOV E,A INX D MOV A,L ADD E MOV A,H ADC D POP D MOV A,B POP B RET L02BD: POP H MOV A,B POP B JMP SRET ; ; ; PDEC: ;GEBE HL REGISTER AL DEZIMALZAHL AUS LXI B,TABLE10 LXI D,-10000 PNEXT: MVI A,'0'-1 PDECL: PUSH H INR A DAD D JRNC STOPLOOP INX SP INX SP JR PDECL STOPLOOP: PUSH D PUSH B MOV C,A CALL ECHO POP B POP D NEXTDIGIT: POP H LDAX B MOV E,A INX B LDAX B MOV D,A INX B MOV A,E ORA D JRNZ PNEXT RET ; TABLE10: DW -1000,-100,-10,-1,0 ; ; ; DEZOUT: ;WANDLE AKKU IN DEZIMALZAHL UND GEBE AKKU AUS ORA A ;AKKU NULL JRZ DEZOUT2 ;DANN IST SCHON ALLES OK MOV B,A XRA A DEZOUT1: INR A DAA DJNZ DEZOUT1 DEZOUT2: CALL NMOUT RET ; ; HLOUT: MOV A,H CALL NMOUT MOV A,L ; NMOUT: PUSH H PUSH B PUSH PSW RRC RRC RRC RRC ANI 0FH MOV C,A CALL PRVAL CALL ECHO POP PSW ANI 0FH MOV C,A CALL PRVAL CALL ECHO POP B POP H RET ; ; ; SET$SOFT$BAUD: ;SETZE DIE BAUDRATE DER SOFT-SCHNITTSTELLE ;ENTSPRECHEND DER STELLUNG VON BAUD$JUMPERBYTE ;NEHME DAZU DEN ENTSPRECHENDEN WERT AUS ;SOFT$BAUD$TAB UND KORRIGIERE IHN MIT DER ;SYSTEMFREQUENZ ; LDA BAUD$JUMPERBYTE ;STELLUNG VON BAUD$JUMPER SET$DUPLEX$BAUD: ;EINSPRUNG ZUM NEU SETZEN MVI H,0 ;SOFT$BAUD$TAB EINTRAG MOV L,A LXI D,SOFT$BAUD$TAB DAD H ;MAL ZWEI DAD D MOV E,M ;SOFT$BAUD$TAB-EINTRAG IN DE INX H MOV D,M LBCD SYSTEMTAKT ;SYSTEMTAKT IN BC CALL MULTIP ;MULTIPLIZIERE SHLD SOFTVERZ ;UND TEILE DURCH 65536 ;DA NUR DIE OBEREN 16 BITS GENUTZT WERDEN RET ; ; ; SET$SIMPLEX$BAUD: ;BERRECHNE DIE VERZOEGERUNGSZEIT FUER DIE SIMPLEX SCHNITTSTELLE ;DER WERT IM AKKU GIBT DEN LISTEN-EINTRAG DER SOFT$BAUD$TAB AN ; MVI H,0 ;SOFT$BAUD$TAB EINTRAG MOV L,A ; LXI D,SOFT$BAUD$TAB ; DAD H ;MAL ZWEI DAD D ; MOV E,M ;TABELLEN EINTRAG IN DE INX H ; MOV D,M ; LBCD SYSTEMTAKT ;KORRIGIERE MIT SYSTEMTAKT CALL MULTIP ;MULTIPLIZIERE SHLD SOFTPRNTVERZ ;TEILE DURCH 65536 UND LEGE AB RET ; ; ; MULTIP: ;MULTIPLIZIERT BC*DE 32BIT ERGEBNIS IN HLDE LXI H,0 ;INITIALISIERE HL MVI A,-16 ;SCHLEIFENZ[HLER MUL7 DAD H ;SCHIEBE DEHL UM 1BIT XCHG ;NACH LINKS DADC H ;LSB=0 XCHG JRNC MUL2 ;1AUS DE DAD B ;DANN ADDIERE BC JRNC MUL2 ;]BERTRAG ENTSTANDEN? INX D ;DANN DE EINS HOEHER MUL2 INR A ;16 DURCHLAEUFE? JM MUL7 ;SPRUNG WENN NEIN XCHG ;DIE HOEHEREN BITS IN HL RET ; ; ; PRVAL: PUSH PSW MOV A,C ORI 0F0H DAA ADI 0A0H ACI 040H MOV C,A POP PSW RET ; ; ; RWINP: ;LIEST DMA ADRESSE UND ANZAHL DER SEKTOREN EIN CALL GETHX ;LESE DMA ADRESSE JNC ERROR MOV A,D ;KEIN CR CPI 0DH JZ ERROR ;SPRUNG WENN DOCH SBCD DMAADR ;ABSPEICHERN CALL GETHX ;LESE ANZAHL DER SEKTOREN JNC ERROR MOV A,D CPI 0DH ;MUSS CR SEIN JNZ ERROR MOV A,C STA SECTCNT ;ABSPEICHERN RET ; ; ; PRINT$DRIVE: ;GIBT DEN LAUFWERK BUCHSTABEN UND EIN BLANK AUF DER ;KONSOLE AUS LDA UNIT ;WELCHES LAUFWERK? ANI 03H ;MASKIERE OBER 6 BITS ADI 'A' ;WANDLE IN ASCII MOV C,A CALL CO MVI C,' ' CALL CO RET ; ; ; REGDS: LXI H,RTAB L02E9: MOV C,M MOV A,C ORA A JNZ L02F3 CALL CROUT RET L02F3: CPI 'a' ;SOLL NEUE ZEILE ANFANGEN? JRNZ REGDS1 ;SPRUNG WENN NEIN PUSH PSW PUSH B CALL CROUT POP B POP PSW REGDS1: CALL ECHO MVI C,'=' CALL ECHO INX H MOV E,M MVI D,(REGS AND 0FF00H) SHR 8 INX H LDAX D CALL NMOUT MOV A,M ORA A JZ L030E DCX D LDAX D CALL NMOUT L030E: MVI C,' ' CALL ECHO INX H JMP L02E9 ; ; ; RGADR: LXI H,RTAB LXI D,3 ;LAENGE DER TABELLEN EINTRAEGE L031D: MOV A,M ORA A JZ ERROR CMP C JZ L032A DAD D JMP L031D L032A: INX H MOV B,H MOV C,L RET ; ;-----------------------------------------------REGISTER ZURUECKLADEN------ ; RSTTF: DI LXI SP,MSTAK POP B ;LADE I UND R REGISTER MOV A,C STAR MOV A,B STAI EXX EXAF ;ERST ZWEITREGISTERSATZ LADEN POP H POP D POP B POP PSW EXAF EXX ;JETZT NORMALER REGISTERSATZ POPIY POPIX POP D POP B POP PSW LSPD SSAVE LHLD PSAVE PUSH H LHLD LSAVE EI ;----------------------------------------ENDE REGISTER ZURUECKLADEN-------- RET ; ; ; SETCMDT: ;NEHME WERTE AUS TEST$TYPE UND TEST$MSEK ;UND TRAGE SIE IN CMDTAB EIN ; LDA TEST$MSEK ;ANZAHL DER SEKTOREN/SPUR STA EOT ; LDA TEST$TYPE ;LADE TEST$TYPE MOV C,A ;UND RETTE IN C ANI 40H ;MASKIERE UND STA CMDTAB ;SETZE MFM BIT IN CMDTAB MOV A,C ; ANI 0FH ;SETZE SEKTORGROESSE STA SECSZ ; ORA A ; MVI A,0FFH ;SETZE DTL AUF 80 BEI 128 BYTES/SEKTOR JRNZ CMDS1 ;SONST AUF 0FFH MVI A,80H ; CMDS1 STA DTLL ; MOV A,C ;SETZE GAP-LAENGE IN ABHAENGIGKEIT ANI 0FH ;VON DER SEKTORGROESSE MOV C,A ; MVI B,0 ; LXI H,GAPTAB ; DAD B ; MOV A,M ; STA GAPLL ; RET ; ; GAPTAB: ;DIESE TABELLE GIBT DIE GAPLAENGE FUER JEDE ;SEKTORGROESE AN DB 007H ; GAPLAENGE FUER 128 BYTES/SEKTOR DB 00EH ; GAPLAENGE FUER 256 BYTES/SEKTOR DB 01BH ; GAPLAENGE FUER 512 BYTES/SEKTOR DB 035H ; GAPLAENGE FUER 1024 BYTES/SEKTOR ; ; ; SRET: STC RET ; ; ; VALDG: MOV A,C CPI '0' JM FRET CPI '9' JM SRET JZ SRET CPI 'A' JM FRET CPI 'G' JP FRET JMP SRET ; ; ; VALDL: MOV A,C CPI ',' JZ SRET CPI 0DH JZ SRET CPI ' ' JZ SRET JMP FRET ; ; ; DISP$TIME: ;GEBE UHRZEIT UND DATUM AUF DEN BILDSCHIRM CALL READ$PHYS$TIME ;LESE ZEIT AUS UHR LXI H,TIMTXT1 ;DATUM TEXT AUS CALL SOUT LDA PHYS$TIME+4 ;MONAT RRC RRC RRC RRC ANI 0FH DCR A CPI 12 ;MONAT UNGUELTIG JRC DISP$TIME1 XRA A ;DANN LOESCHE AKKU DISP$TIME1: MOV L,A MVI H,0 DAD H DAD H LXI B,MONTXT DAD B CALL SOUT MVI C,' ' CALL ECHO LDA PHYS$TIME+3 ;TAG CALL NMOUT MVI C,' ' ;GEBE 19 AUS CALL ECHO MVI A,19H CALL NMOUT LDA SHIFT$CONT+4 ;JAHRESZAHL ANI 1FH ;NUR DIE UNTEREN 5 BIT MVI B,80 ;ADDIERE 80 DAZU ADD B CALL DEZOUT ;GEBE AUS ; LXI H,TIMTXT2 ;GEBE TIME AUS CALL SOUT LDA PHYS$TIME+2 ;STUNDE CALL NMOUT MVI C,':' CALL ECHO LDA PHYS$TIME+1 ;MINUTE CALL NMOUT MVI C,':' CALL ECHO LDA PHYS$TIME ;SEKUNDE CALL NMOUT CALL CROUT LDA IO$JUMPERBYTE ;IST GRIP ALS KONSOLE DEFINIERT? ORA A RNZ ;RETURN WENN NICHT LXI H,SETTT ;SONST, SETZE GRIP-UHR CALL SOUT LDA PHYS$TIME+2 ADI 20H MOV C,A CALL ECHO LDA PHYS$TIME+1 ADI 20H MOV C,A CALL ECHO LDA PHYS$TIME ADI 20H MOV C,A CALL ECHO RET ; SETTT DB 27,27,'U$' TIMTXT1 DB 0DH,0AH,' Date $' TIMTXT2 DB 0DH,0AH,' Time $' MONTXT DB 'Jan$' DB 'Feb$' DB 'Mar$' DB 'Apr$' DB 'May$' DB 'Jun$' DB 'Jul$' DB 'Aug$' DB 'Sep$' DB 'Oct$' DB 'Nov$' DB 'Dec$' ; ; ; ;************************************************************ ; ;ES FOLGEN NUN SERVICE ROUTINE FUER BOOT ROUTINE ; ;************************************************************ ; ; ; SETSEC$CNT: ;SETZE ANZAHL DER ZU UEBERTRAGENDEN SEKTOREN MOV A,C STA SECTCNT RET ; SELDSK: ;SETZT UNIT BYTE MOV A,C STA UNIT RET ; SETTRK: ;SETZT TRACK BYTE MOV A,C STA TRACK RET SETSEC: ;SETZT SECTOR BYTE MOV A,C STA SECTOR RET ; SETDMA: SBCD DMAADR RET ; GETMINIMAX: ;WENN AKKU=0 DANN MAXI ;WENN AKKU=0FFH DANN MINI LDA TEST$TYPE ANI 20H RZ MVI A,0FFH RET ; ; ; ;************************************************************ ; ;ES FOLGEN NUN DISK ROUTINEN FUER UPD 765 ; ;************************************************************ ; ; ; BOOTERR: ;GEBE FEHLERMELDUNG BEI BOOT AUS ;UND GEHE ZUM MONITOR ZURUECK LXI H,BERMSG CALL SOUT JMP CRGETCM ; BERMSG DB ' Can not boot',24H ; ; ; SPECD: ;SETZT DISK PARAMETER FUER NON DMA BETRIEB LHLD UNIT PUSH H ;RETTE CMDTAB LHLD SPECD$WORD MVI A,1 ORA H MOV H,A LXI B,0303H SHLD UNIT CALL CMFD POP H SHLD UNIT RET ; ; ; FLOPPY$RESET: ;GEBE HARDWARE-RESET ;AUF FLOPPY-CONTROLER PUSH B MVI A,PAD$RESF OR 1 OUT P$LS259 MVI B,20 FLOPPY$RESET1: DJNZ FLOPPY$RESET1 MVI A,PAD$RESF OUT P$LS259 POP B RET ; ; ; INIFDC: ;SOFT RESET DES UPD 765 ;FALS KEIN FLOPPY CONTROLLER VORHANDEN IST, ;WIRD DISKFLG AUF 00H GESETZT, SONST AUF FFH MVI A,0FFH ;DEFAULT FUER FLOPPY-C DA STA DISKFLG LXI H,0000H ;SETZE ZAEHLER INIFDC1 DCR H ;ERNIEDRIGE ZAEHLER IN FDC ; CPI 80H ;REQUEST FOR MASTER RZ ;OK CONTROLLER DA IN FDD ;LESE DATEN MOV A,H ;IST ZAEHLER NULL ORA L JRNZ INIFDC1 ;NEIN, NEUER VERSUCH STA DISKFLG ;KEIN FLOPPYCONTROLLER DA, DISKFLG=00H RET ; ; ; RECAL: XRA A ;AKKU=0 STA ALT$TRACK ;VORSICHTSHALBER SPUR AUF NULL MVI B,4 ;VIER VERSUCHE RECAL2: PUSH B ; CALL RECAL1 ; CALL SENSD ; ANI 10H ;TRACK NULL ERREICHT? POP B ; RNZ ;RUECKSPRUNG WENN EREICHT DJNZ RECAL2 ; RET ; ; ; RECAL1: LXI B,0207H CALL MOTO JMP SENS ; ; ; NODISK DB 0DH,0AH,BELL DB ' Drive access not possible$' ; ; ; DISKDA: ;GIBT MELDUNG AUS, WENN DISKZUGRIF OHNE KONTROLLER VERSUCHT WIRD ;UND KEHRT AUF DIE EINGABEEBENE ZURUECK LDA DISKFLG ;LADE FLAG ORA A ;=NULL? RNZ ;ZURUECK ZUM RUFENDEN PROGRAMM LXI H,NODISK;GEBE MELDUNG AUS CALL SOUT JMP CRGETCM ;AUF KOMMANDOEBENE ZURUECK ; ; ; READY$MASK: ;HOLT AUS READY$BYTE DIE WERTE FUER LW ;SCHON AUF READY GETESTET UND LW KANN READY LIEFERN ;ODER NICHT CALL UNIT$MASK ;HOLE MASKE FUER EINGELOGGTES LW LDA READY$BYTE ;UND MASKIERE READY$BYTE ANA B ; RET ; ; ; UNIT$MASK: ;ERZEUGE AUS EINGELOGGTEM LW MASKE FUER OBER UND UNTERE 4 BIT LDA UNIT ANI 00000011B INR A MOV B,A MVI A,88H UNIMASK RLC DJNZ UNIMASK MOV B,A RET ; ; ; SEEK3: CALL UNIT$MASK LDA SEEKNR ANA B ANI 0FH RET ; SEEK: LHLD UNIT ;LADE NEUES LAUFWERK UND NEUER TRACK LBCD ALT$UNIT ;LADE ALTES LAUFWERK UND ALTER TRACK MOV A,B ;VERGLEICHE CMP H ; JRNZ SEEK4 ;SPRUNG WENN UNGLEICH MOV A,C ; CMP L ; RZ ;RETURN WENN KEIN SEEK NOTWENDIG SEEK4: SHLD ALT$UNIT ;ALTES:=NEUES IN P$IN$LS258$B ; ANI MASK$MOT ; MVI A,PAD$MOTOR ;AUFJEDEN FALL MOTOR JETZT EINSCHALTEN OUT P$LS259 ; JRZ SEEK5 ;WENN MOTOR SCHON LIEF, DANN KEIN WARTEN LDA STEP$WAIT ;LADE WARTEZEIT SEEK6 ORA A ;WENN WARTEZEIT NULL, DANN WEITER JRZ SEEK5 ; DCR A ; PUSH PSW ; LXI H,2300 ; SEEK7 DCX H ; MOV A,H ; ORA L ; JRNZ SEEK7 ; POP PSW ; JR SEEK6 ; SEEK5: CALL SEEK3 ; JRZ SEEK1 ; LDA TRACK ; PUSH PSW ; ADD A ; STA TRACK ; SEEK1: ; LXI B,030FH ;SEEK TRACK CALL MOTO ; CALL SEEK3 ; JRZ SEEK2 ; POP PSW ; STA TRACK ; SEEK2: ; ;SEEK FINISHD ? SENS: LXI B,0108H ;SENS DRIVE CALL CMFD ; CALL NEXT ; PUSH PSW ;SAVE RESULT CPI 080H ;INVALID COMMAND ? CNZ NEXT ;NO => NEXT RESULT POP PSW ;FIRST RESULT ANI 020H ;ISOLIERE BIT 5 JZ SENS ; MVI A,PAD$MOTOR OR 80H ;SCHALTE MOTOR AUF JEDEN OUT P$LS259 ;FALL AB RET ; ; ; RESULT: ;FETCH RESULT OF READ WRITE OPERATION ;AND CHECK THEM FOR R/W ERRORS ;Z+A=00 IF NO ERRORS ;NZ,A=? IF ERRORS MVI B,006H ;7RESULTS CALL NEXT ; LXI H,REST ;RESULT TABLE MOV M,A ;STORE RESULT ANI 0C0H ;ERROR ? MOV C,A ;SAVE RESLOP CALL NEXT ; INX H ; MOV M,A ;STORE RESULT DJNZ RESLOP ; ; MVI A,PAD$READY ;SCHALTE READY AUF JEDEN FALL WEG OUT P$LS259 ; MVI A,PAD$MOTOR OR 80H ;SCHALTE MOTOR NACH DELAY AB OUT P$LS259 ; ; MOV A,C ;RESTORE RESULT 0 ORA A ;IN AKKU RET ; ; ; READY$TEST: ;ERMITTELT, OB EIN LAUFWERK DAS READY-SIGNAL LIEFERN ;KANN UND SETZT ENTSPRECHEND DAS READY-BYTE ; CALL SPEED$CONST ;WARTE BIS DREHZAHL KONSTANT JRNZ RTST1 ;SPRUNG WENN DREHZAHL KONSTANT CALL NRDYERR ;GEBE FEHLERMELDUNG AUS UND LESE ZEICHEN JRNZ READY$TEST ;NOCH EIN VERSUCH JMP UMLEIT$GETCM ;SONST ZURUECK RTST1 CALL SENSD ;LIEFERT LW READY? ANI 20H ; PUSH PSW ;RETTE ZERO-FLAG CALL UNIT$MASK ;TRAGE IN READY$BYTE EIN CMA ; MOV B,A ;RETTE MASKE POP PSW ;HOLE ZERO-FLAG MVI A,0FH ;KEIN READY JRZ RTST2 ;SPRUNG WENN KEIN READY MVI A,0 ; RTST2 ORA B ; MOV B,A ;SETZE READY$BYTE LDA READY$BYTE ; ANA B ; STA READY$BYTE ; RET ; ; ; SPEED$CONST: ;WARTE BIS DREHZAHL KONSTANT, DANN RETURN MIT ZERO-FLAG=0 ;WENN DREHZAHL NICHT KONSTANT WIRD DANN ZERO-FLAG=1 ; TOLERANZ EQU 64 ;TOLERANZ FUER DREHZAHL KONSTANT ; LXI B,0204H ;SELEKTIERE LAUFWERK CALL CMFD ; MVI A,PAD$MOTOR ;SCHALTE MOTOR EIN OUT P$LS259 ; LXI D,0 ;BESETZE VOR MVI B,10 ;ZEHN VERSUCHE SPEEDC1 XCHG ;ADDIERE ZU DE TOLERANZ LXI D,TOLERANZ ; DAD D ; XCHG ; CALL CDRIVE$SPEED ;MESSE DREHZAHL JRZ SPEEDC3 ;ZURUECK WENN LAUFWERK STEHT XCHG ;BILDE DIVERENZ ZU VORHER DSBC D ; MOV A,H ; CPI 0 ;IM TOLERANZBEREICH? JRNZ SPEEDC2 ;SPRUNG WENN NEIN MOV A,L ; CPI TOLERANZ*2 ; JRNC SPEEDC2 ;SPRUNG WENN DREHZAHL NOCH NICHT KONSTANT CALL CDRIVE$SPEED ;WARTE NOCH ZWEI UMDREHUNGEN CALL CDRIVE$SPEED ; ; CALL NEXT ;DESELEKTIERE LAUFWERK MVI A,PAD$MOTOR OR 80H OUT P$LS259 ; MVI A,0FFH ;ZURUECK MIT ZERO = 0 ORA A ; RET ; ; SPEEDC2 DJNZ SPEEDC1 ;MAXIMAL 10 VERSUCHE SPEEDC3 CALL NEXT ;DESELEKTIERE LAUFWERK MVI A,PAD$MOTOR OR 80H OUT P$LS259 ; XRA A ;SONST ZURUECK MIT ZERO=1 RET ; ; ; ; CDRIVE$SPEED: ;MESSE GESCHWINDIGKEIT DES LAUFWERKS ;WENN SICH DISKETTE NICHT DREHT IST DAS ZERO-FLAG GESETZT ;SONST ZERO-FLAG=0 UND GESCHWINDIGKEIT IN HL ; IN P$IN$LS258$A ;LESE INDEX-SIGNAL ANI MASK$INDEX ;UND MASKIERE JRZ DSPEED1 ;WENN INDEX DA, ERSTE SCHLEIFE ;UEBERSPRINGEN ; LXI H,0 ;WARTE BIS INDEX KOMMT DSPEED2 INX H ;ERHOEHE HL MOV A,H ;OUT OF TIME? ORA L ; RZ ;DANN RETURN IN P$IN$LS258$A ;LESE INDEX-SIGNAL ANI MASK$INDEX ;UND MASKIERE JRNZ DSPEED2 ;WARTE BIS LOW ; DSPEED1 LXI H,0 ;WARTE BIS INDEX WEGGEHT DSPEED3 INX H ;ERHOEHE HL MOV A,H ;OUT OF TIME? ORA L ; RZ ;DANN RETURN IN P$IN$LS258$A ;LESE INDEX-SIGNAL ANI MASK$INDEX ;UND MASKIERE JRZ DSPEED3 ;WARTE BIS HIGH ; LXI H,0 ;EIGENTLICHER ZAEHLER DSPEED4 INX H ;ERHOEHE HL MOV A,H ;OUT OF TIME? ORA L ; RZ ; IN P$IN$LS258$A ;LESE INDEX UND WARTE ANI MASK$INDEX ;BIS WIEDER LOW JRNZ DSPEED4 ; MVI A,0FFH ;RESET ZERO-FLAG ORA A ; ; RET ;ZURUECK MIT DRIVE-SPEED ; ; ; NOREADY$MOTO: IN P$IN$LS258$B ;LAEUFT MOTOR SCHON ? ANI MASK$MOT ; JRZ NREDY1 ;SPRUNG WENN MOTOR SCHON LAEUFT NREDY2 CALL SPEED$CONST ;WARTE BIS LW AUF TOUREN JRNZ NREDY1 ;SPRUNG WENN DREHZAHL KONSTANT CALL NRDYERR ;GEBE ERROR-TEXT AUS JRNZ NREDY2 ;WIEDERHOLUNG JMP UMLEIT$GETCM ; NREDY1 MVI A,PAD$MOTOR ;NEUER MOTOR TRIGGER OUT P$LS259 ; MVI A,PAD$READY OR 80H ;SETZE READY$LEITUNG OUT P$LS259 ; JMP MOTO1 ; ; ; MOTO: ;WAITS UNTIL DISK READY AND THEN ;TRANSMITS COMMAND TO FDC ; PUSH B ;SAVE COMMAND CALL READY$MASK ;LW SCHON GETESTET? ANI 0F0H ;STEHT IN DEN OBEREN 4 BITS CNZ READY$TEST ;WENN NOCH NICHT, DANN TESTE AUF READY CALL READY$MASK ;KANN READY GELIEFERT WERDEN? ANI 0FH ;STEHT IN DEN UNTEREN 4 BITS JNZ NOREADY$MOTO ;WENN NICHT SPRUNG ;SONST WEITER WIE GEHABT ; MVI A,PAD$MOTOR ;SCHALTE MOTOR EIN OUT P$LS259 ; ; MOTO2 LXI H,00FFFH ;SET TIMER MOTO3 PUSH H ;SAVE TIMER LXI B,0204H ;SENSE DRIVE CALL CMFD CALL NEXT ;FETCH RESULT POP H ;GET TIMER VALUE ANI 20H ;DISK READY ? JRNZ MOTO1 ;OK, READY DCX H ;TIMER=TIMER-1 MOV A,H ;= ZERO? ORA L ; JRNZ MOTO3 ;NO, TRY AGAIN CALL NRDYERR ;DRIVE NOT READY TEXT JRNZ MOTO2 ;NO, AGAIN MVI A,PAD$MOTOR OR 80H OUT P$LS259 ; JMP UMLEIT$GETCM ;ENTWEDER MONITOR ODER WARM-BOOT ; ; NRDYERR: ;GEBE FEHLERMELDUNG FUER DRIVE NOT READY AUS ;UND VERGLEICHE EINGEGEBENES ZEICHEN MIT N ; LXI H,NREADY1 ;PRINT ERROR TEXT CALL SOUT ; CALL PRINT$DRIVE ;GEBE LW BUCHSTABE AUS LXI H,NREADY2 ;GEBE REST TEXT AUS CALL SOUT ; CALL GETCH1 ;AGAIN? MOV C,A ;ECHO CALL ECHO ; CALL CROUT ;LINE FEED MOV A,C ; CPI 'N' ; RET ; ; NREADY1 DB 0DH,0AH,BELL,' Drive $' NREADY2 DB 'not ready, retry (Y/N) ? $' ; ; MOTO1: POP B ; ; CMFD: ;TRANSMIT COMMAND TO FDC ;IN B STEHT ANZAHL DER BYTES ;IN C STEHT BEFEHL ; LXI H,CMDTAB ; CMFD1 MVI A,30 ;WAIT FOR MASTER CMFD2 DCR A ; JRNZ CMFD2 ; IN FDC ;REQUEST FOR MASTER ANI 0C0H ; CPI 080H ; JRNZ CMFD1 ;NO => WAIT MOV A,C ;YES => OUT FDD ;SEND BYTE INX H ;POINT TO NEXT BYTE MOV C,M ; DJNZ CMFD1 ;SEND NEXT BYTE RET ;ALL BYTES TRANSFERRED ; ; ; NEXT: ;READ NEXT RESULT FROM FDC ; MVI A,6 ;WAIT FOR MASTER READY NEXT1 DCR A ; JRNZ NEXT1 ; IN FDC ;REQUEST FOR MASTER ANI 0C0H ;TRANSFER TO MASTER CPI 0C0H ; JNZ NEXT ;NO =>WAIT IN FDD ;YES => FETCH RESULT RET ; ; ; WRITE: MVI A,5 ;WRITE COMMANDO LXI H,TXTWR ;WRITE ERROR TEXT JMP RWCOM ; ; ; READ: MVI A,06H ;READ COMMANDO LXI H,TXTRD ;READ ERROR TEXT JMP RWCOM ; ; ; RWCOM: ;VOR EINTRITT IN DIESE ROUTINE MUESSEN CMDTAB ;SECTCNT UND DMAADR GESETZT SEIN. ;IN A MUSS READ ODER WRITE COMMANDO STEHEN, ;IN HL MUSS DIE ADRESSE DER ERROR MSSG. STEHEN. ;ES WERDEN DIE ANGEGEBENE ANZAHL SECTCNT ;VON/NACH DMAADR UEBERTRAGEN. ;HD BIT WIRD ENTSPRECHEND DEM H BIT GESETZT. ;DAS IN CMDTAB STEHENDE MFM BIT WIRD UEBERNOMMEN. ;ES WIRD DIE PRECOMPENSATION ZEIT AUS WRITE$PRECOM ;UEBERNOMMEN. ; ; STA RWCMD ;LEGE COMMANDO AB SHLD ERMSG ;LEGE ADR FUR ERR.TEXT AB LDA SECTCNT ;WIEVIEL SECTOREN SOLLEN UEBERTRAGEN WERDEN? DCR A ;EINS WENIGER FUER ADDITION CPI 0FFH ; RZ ;RETURN WENN NULL GEWESEN MOV C,A ;RETTE AKKU LDA EOT ;RETTE EOT STA EOTSAVE ; MOV B,A ; LDA SECTOR ;BERRECHNE NEUES EOT ADD C ; STA EOT ; MOV C,A ;SOLL UEBER SPUR ENDE UEBERTRAGEN WERDEN? MOV A,B ; MVI B,0 ; SUB C ; JRNC RW5 ; MVI B,080H ; LDA EOTSAVE ;WENN UEBER SPUR ENDE UEBERTRAGEB WERDEN SOLL STA EOT ;DANN EOT GLEICH ALTES EOT RW5: MOV A,B ;SAVE FLAG STA EOTFLG ;FUER FEHLERMELDUNG MVI A,PAD$RTS OR 1 ;SPERRE TASTATUR INTERRUPT OUT P$LS259 ; DI ; CALL SEEK ;POSITIONIERE CALL SETHEAD ;TRAGE HEAD BIT IN UNIT EIN LDA WRITE$PRECOM ;SETZE PRECOMPENSATION CALL SEND$PRECOM ; LDA RWRETRY ;LADE MOV B,A ;ANZAHL DER VERSUCHE NACH B RW4 PUSH B ;SAVE RETRY MVI B,9 ;9 BYTES ZU UEBERTRAGEN LDA RWCMD ;LADE COMMANDO MOV C,A ;NACH C LDA CMDTAB ;TRAGE MFM BIT EIN ANI 040H ;ISOLIERE MFM BIT ORA C ;COMMAND DAZU MOV C,A ;ZURUECK INC CALL MOTO ;SEND COMMAND TO UPD 765 ;BEREITE REGISTER VOR EXX ;LADE DMA ADRESSE IN ZWEITREGISTER SATZ LHLD DMAADR ; MVI C,FDD ;UEBERTRAGUNGSADRESSE EXX ; LXI H,SYSTEMPAGE ;PAGE DER MASTER ABHNG. SPRUENGE MVI C,FDC ; ; CALL RWPOLL ;UEBERTRAGE VON/ZU DISK ; CALL RESULT ;HOLE ERGEBNIS LDA REST+1 ;BLENDE END OF TRACK BIT AUS ANI 7FH ; STA REST+1 ; MOV C,A ; LDA REST+2 ; ORA C ;SONSTIGES FEHLER BIT GESETZT POP B ;RESTORE RETRY COUNTER JRZ RW7 ;KEINE FEHLER DJNZ RW4 ;NOCH VERSUCHE FREI? RW7: ; LDA EOTFLG ;WURDE WIRKLICH UEBER SPURGRENZE GELESEN? MOV C,A ; LDA REST+1 ; ORA C ; STA REST+1 ; MOV C,A ; LDA REST+2 ; ORA C ;SET ZERO FLAG PUSH PSW ;RETTE FLAGS UND AKKU FUER FEHLERMELDUNG CNZ DISKERR ;DRUCKE FEHLER LDA EOTSAVE ;LADE ORG EOT STA EOT ;ZURUECK EI ; LDA IO$JUMPERBYTE ;MUSS EINGABE FREIGEGEBEN WERDEN? DCR A ; JRNZ RW1 ; MVI A,PAD$RTS ;GEBE EINGABE FREI OUT P$LS259 ; RW1: ; LDA RWCMD ;WAR DISK WRITE ? CPI 06H ; JRZ RW2 ;SPRUNG WENN NEIN LDA TE$TIME ;SONST VERZOEGERUNG ORA A ;WENN NULL DANN ENDE JRZ RW2 ; MOV B,A ; RW3: LXI H,22 ;<10> RW6: DCX H ;<6> MOV A,H ;<4> ORA L ;<4> JRNZ RW6 ;<12/7> DJNZ RW3 ;<13/8> RW2: ; POP PSW ;LADE AKKU FUER FEHLERMELDUNG RET ; ; ; SETHEAD: ;SETZE HEAD BYTE AUF 00H ODER 01H ;SETZE HEAD BIT IN UNIT BYTE ; ;FOLGENDE KOMBINATIONEN SIND MOEGLICH: ;X BEDEUTET UNBESTIMMT, - BEDEUTET KEINE AENDERUNG ZU VORHER ; ; HEAD VORHER=> UNIT NACHHER, HEAD NACHHER ; XXXXXX00 000000-- 00000000 ; XXXXXX01 000001-- 00000001 ; XXXXXX10 000001-- 00000000 ; XXXXXX11 000000-- 00000001 ; LDA HEAD ;LADE HEAD BIT MOV C,A ;RETTE IN C ANI 1 ; STA HEAD ; MOV A,C ; RLC ;EIN BIT NACH LINKS MOV C,A ; RLC ;ZWEI BIT NACH LINKS XRA C ;ERZEUGE UNIT BIT ANI 04H ;BLENDE ANDERE BITS AUS MOV C,A ;SAVE LDA UNIT ;LADE DRIVE NR. ANI 03H ;BLENDE OBERE BITS AUS ORA C ;HEAD DAZU STA UNIT ;ZURUECK RET ; ; ; TEST: ;DIESE ROUTINE ERMITTELT DIE DATEN DER PLATTE, DIE SICH IM VON ;UNIT SPEZIFIZIERTEN LAUFWERK BEFINDET ;GETESTET WIRD DIE SPUR, DIE IN TEST$TRACK STEHT ;ALS ERGEBNIS WERDEN TEST$TYPE UND TEST$MSEK GESETZT ;KANN DER PLATTEN-TYP NICHT ERMITTELT WERDEN IST DER AKKU AUF FFH ;WENN PLATTEN-TYP ERKANNT WURDE IST AKKU=00H ; CALL RECAL ;RECALIBRIERE LDA UNIT ;SEITE 0 WAEHLEN ANI 03H ; STA UNIT ; LDA TEST$TRACK ;POSITIONIERE AUF DIE SPUR STA TRACK ;DEREN FORMAT ERKANNT WERDEN SOLL CALL SEEK ; ; MVI A,00 ;TESTE OB SD,MAXI STA TEST$TYPE ; CALL MAXI$SET ; CALL READID ;VERSUCHE ID-FELD ZU LESEN JZ TEST1 ;SPRUNG WENN SD,MAXI ; MVI A,40H ;TESTE OB DD,MAXI STA TEST$TYPE ; CALL READID ; JZ TEST1 ;SPRUNG WENN DD,MAXI ; MVI A,20H ;TESTE OB SD,MINI STA TEST$TYPE ; CALL MINI$SET ; CALL READID ; JZ TEST1 ;SPRUNG WENN SD,MINI ; MVI A,60H ;TESTE OB DD,MINI STA TEST$TYPE ; CALL READID ; JZ TEST1 ;SPRUNG WENN DD,MINI ; TEST2: MVI A,0FFH ;BLEIBT NICHTS MEHR UEBRIG RET ;RUECKSPRUNG MIT FEHLER ; TEST1: ;OK, MINI ODER MAXI, FM ODER MFM ;ERKANNT ;ZAEHLE JETZT DIE ANZAHL DER SEKTOREN ;AUF DER SPUR CALL READ$ID ;LESE ERSTES ID-FELD JRNZ TEST2 ;SPRUNG WENN NICHT MOEGLICH LDA REST+5 ;LADE SEKTORNUMMER MOV D,A ;NACH D UM EINE UMDREHUNG ABZUWARTEN MOV C,A ;NACH C UM GROESSTEN SEKTOR ZU ERMITTELN MVI B,52 ;MAXIMAL 52 LESEVERSUCHE, DANN FEHLER TEST3: PUSH B ;RETTE REGISTER PUSH D ; CALL READ$ID ;LESE NAECHSTES ID-FELD POP D ;RESTORE REGISTER POP B ; JRNZ TEST2 ;SPRUNG WENN FEHLER LDA REST+5 ;LADE SEKTORNUMMER CMP D ;EINE UMDREHUNG ? JRZ TEST4 ;DANN ENDE (MAX-SEKTOR IN C) CMP C ;NEUE SEKTORNUMMER GROESSER ALS ALLE ANDEREN? JRC TEST5 ;SPRUNG WENN NEIN MOV C,A ;SONST NEUER SEKTOR DER GROESSTE TEST5: DJNZ TEST3 ;LESE NEUEN SEKTOR EIN JR TEST2 ;WENN ZAEHLER ABLAEUFT, DANN FEHLER ; TEST4: MOV A,C ;LEGE GROSSTE SEKTORNUMMER AB STA TEST$MSEK ; ; LDA REST+6 ;PACKE SEKTORGROESSE ZU TEST$TYPE ANI 0FH ; MOV C,A ; LDA TEST$TYPE ; ORA C ; STA TEST$TYPE ; ; LDA UNIT ;SOLL TWO-SIDED-BIT IMMER AUF HIGH SEIN? CMA ;(NAEMLICH DANN, WENN ENTSPRECHENDES ANI 00000011B ;BIT IM OBEREN NIPPLE VON SEEKNR AUF HIGH) MOV B,A ; ORA A ; LDA SEEKNR ; JRZ TEST6 ;KEIN SCHIEBEN NOTWENDIG TEST7: RLC ; DJNZ TEST7 ; TEST6: ANI 80H ;WENN OBERSTES BIT 1, DANN TS-BIT AUCH EINS JRNZ TEST8 ;SONST TS-BIT WIE TS-LEITUNG CALL SENSD ;LESE TWO-SIDED SIGNAL EIN RLC ;VERSCHIEBE IN OBEERSTES BIT RLC ; RLC ; RLC ; ANI 80H ;BLENDE REST AUS TEST8: MOV C,A ;PACKE ZU TEST$TYPE LDA TEST$TYPE ; ORA C ; STA TEST$TYPE ; ;OK, ALLES GEPRUEFT MVI A,0 ;FEHLERFREIE RUECKKEHR RET ; ; ; ; READID: ;LESE NAECHSTES ID FELD ;IN TEST$TYPE BIT 6 SEHT OB FM ODER MFM ;KONNTE KEIN ID-FELD GELESEN WERDEN, DANN IST AKKU<>0 ;UND ZERO-FLAG NICHT GESETZT ; LXI B,020AH ;READ ID KOMMANDO LDA TEST$TYPE ;PACKE MFM BIT DAZU ANI 040H ; ORA C ; MOV C,A ; CALL MOTO ;LESE ID-FELD CALL RESULT ;WAR LESEVERSUCH ERFOLGREICH? ORA A ; RET ; ; ; MAXI$SET: ;SETZT FLOPPY KONTROLER AUF MAXI-LAUFWERKE PUSH PSW MVI A,PAD$MINI OUT P$LS259 POP PSW RET ; ; ; MINI$SET: ;SETZT FLOPPY-KONTROLER AUF MINI-LAUFWERKE PUSH PSW MVI A,PAD$MINI OR 1 OUT P$LS259 POP PSW RET ; ; ; SENSD LXI B,0204H CALL CMFD CALL NEXT RET ; ; ; DISKERR: ;GIBT DISK FEHLERMELDUNG AUS ;BENUTZT DAZU DIE RESULT TABELLE ;UND DIE ERMSG EINTRAGUNG ; LDA DERMSG ;SOLL FEHLERMELDUNG INR A ;UNTERDRUECKT WERDEN ? RZ ;WENN JA, RUECKSPRUNG LHLD ERMSG ;LADE READ BZW WRITE TEXT CALL SOUT ;UND GEBE IHN AUS LDA REST ;LADE LAUFWERK NUMMER ANI 03H ;ISOLIERE LE NR ADI 41H ;WANDLE IN ASCCI MOV C,A ;GEBE LAUFWERK BUCHSTABE AUS CALL ECHO ; ; LXI H,TXT1 ;GEBE TRACK AUS CALL SOUT ; LDA REST+3 ; CALL DEZOUT ; ; LXI H,TXT2 ;GEBE HEAD AUS CALL SOUT ; LDA REST+4 ; ADI 30H ;WANDLE IN ASCII MOV C,A ; CALL ECHO ; ; LXI H,TXT3 ;GEBE SECTOR AUS CALL SOUT ; LDA REST+5 ; CALL DEZOUT ; ; ;GEBE FEHLER IM KLARTEXT AUS ; LXI D,ERROR$TABLE ; LDA REST+1 ;LESE STATUS1 MOV H,A ; LDA REST+2 ;LESE STATUS2 MOV L,A ; ERRLOP: DAD H ;TESTE OB FEHLERBIT GESETZT PUSH H ; LDAX D ; MOV L,A ; INX D ; LDAX D ; MOV H,A ; CC SOUT ;WENN JA GEBE TEXT AUS POP H ; INX D ;ZEIGE AUF NAECHSTE MELDUNG MOV A,H ;KEIN FEHLER MEHR DA? ORA L ; JRNZ ERRLOP ; ; CALL CROUT ; ; RET ;OK, ENDE ; ; ; ;************************************************************************** ;*** *** ;*** ES FOLGT NUN DIE ROUTINE ZUM BOOTEN VON DER HARDDISK *** ;*** *** ;************************************************************************** ; ; ; ; PORTADRESSEN FUER OMTI-CONTROLLER AUF ECB-BUS (MIT ECPC VON CONITEC) ODATA EQU 0E0H OSTATUS EQU 0E1H OCONFIG EQU 0E2H OMASK EQU 0E3H ORESET EQU 0E1H OSELECT EQU 0E2H HDADR EQU 0FC00H ; LADEADRESSE FUER BOOTSTRAP-LOADER HCMD: ; READ FIRST SECTOR CALL WAIT$HD$READY JNZ CRGETCM CALL SELECT LXI H,READ$BOOT$CMD ; POINT TO CMDFIELD CALL SCMD2 LXI H,HDADR ; LOAD DMA ADDRESS READBUFFER: ; READ OMTI DATABUFFER TO (HL) IN OSTATUS ; WAIT FOR DATA READ TRANSFER ANI 00111111B ; CPI 00001111B ; RZ ; NO TRANSFER IN ERROR CASE CPI 00001011B ; JRNZ READBUFFER ; LXI B,ODATA ; CLEAR B AND SET C TO DATAPORT INIR ; READ 256 BYTE INIR ; READ THE NEXT 256 BYTE CALL READSTATUS JNZ CRGETCM ; STA HD$BOOT ; JMP HDADR ; SELECT: ; SELECT OMTI CONTROLLER OUT OSELECT ; SELECT1 IN OSTATUS ; WAIT FOR CONTROLLER SELECTED ANI 00111111B CPI 00001101B ; WAIT UNTIL COMMANDTRANSFER IS READY JRNZ SELECT1 ; RET SCMD2: MVI B,6 ; BYTE COUNTER MVI C,ODATA ; POINTER TO OMTI DATAPORT SCMD1: IN OSTATUS ; READ STATUSBYTE ANI 00111111B CPI 00001101B ; READY FOR WRITE COMMAND BYTE ? JRNZ SCMD1 ; NO, WAIT UNTIL READY OUTI ; WRITE COMMANDBYTE TO OMTI JRNZ SCMD1 ; UNTIL ALL DONE RET READSTATUS: ; READ STATUSBYTE AND SET ZEROFLAG AND ; ERRFLAG IF ANY ERROR IN OSTATUS ; READ CONTOLLER STATUSBYTE ANI 00111111B CPI 00001111B ; READY FOR STATUS READ ? JRNZ READSTATUS ; NO, WAIT UNTIL READY IN ODATA ; OK, READ STATUSBYTE ORA A ; AND SET ZEROFLAG RET ; WAIT$HD$READY: ; WARTE BIS WINCHESTER READY ODER TIMEOUT CALL CHECK$HD$READY ; RZ ; ALLES OK WINCHESTER BEIM ERSTEN MAL READY LXI H,WHRTXT ; GEBE WARTEMELDUNG AUS CALL SOUT ; LXI H,0FFFFH ; LADE TIMEOUT ZAEHLER WHR1: PUSH H ; CALL CHECK$HD$READY ; POP H ; RZ ; DCX H ; MOV A,H ; ORA L ; JRNZ WHR1 ; MVI A,0FFH ; ORA A ; RET ; WHRTXT: DB 0DH,0AH,'waiting for Harddisk ready $' CHECK$HD$READY: ; PRUEFE OB WINCHESTERLAUFWERK READY CALL SELECT ; LXI H,READYCMDFIELD ; CALL SCMD2 ; CALL READSTATUS ; RET ; READYCMDFIELD: DB 0,0,0,0,0,0 ; ; READ$BOOT$CMD: DB 008H,000H,000H,000H,001H,000H ; ; ; ;************************************************************************** ;*** *** ;*** ENDE DER ROUTINEN FUER DEN HARDDISK CONTROLLER *** ;*** *** ;************************************************************************** ; ; ; ;********************************************************** ;*** *** ;*** ROUTINEN ZUM EIN UND AUSLESEN DER UHRZEIT *** ;*** FUER DEN UPD 1990 *** ;*** *** ;********************************************************** ; ; ; SEND$TIME$COM: ; SENDE DIE UNTEREN 3BITS DES AKKU ALS KOMMANDO ; ZUM UPD 1990 ; CALL SEND$PRECOM CALL SEND$STB RET ; ; ; SEND$PRECOM: ;SENDE GEBE DIE UNTEREN 3 BITS DES AKKU ;AUF DEN LEITUNGEN C0-C2 AUS ;DIENT FUER UHREN KOMMANDO, ;DISK PRECOMPENSATION UND JUMPER EINLESEN ; PUSH B ;RETTE BC MVI C,PAD$C0 ;ADRESSE DES BITS MVI B,3 ;ZAEHLER SEND$TIME$COM$1: RRC ;ZYKLISCH VERSCHIEBEN PUSH PSW ;RETTE AKKU ANI 80H ;MASKIERE BIT ORA C ; OUT P$TIME$OUT ; MVI A,16 ;EINE ADRESSE HOEHER ADD C ; MOV C,A ; POP PSW ; DJNZ SEND$TIME$COM$1 ;GEBE ALLE DREI BITS AUS POP B ; RET ; ; ; ; SEND$STB: ;SENDE STROBE ZUM UPD1990 ; MVI A,PAD$STB OR 1 ; OUT P$TIME$OUT ; MVI A,10 ; SSTB: DCR A ; JRNZ SSTB ; MVI A,PAD$STB ; OUT P$TIME$OUT ; RET ; ; ; SEND$CLK: ;SENDE SHIFT TAKT ZUM UPD1990 MVI A,PAD$CLK OR 80H; OUT P$TIME$OUT ; MVI A,10 ; SCKL: DCR A ; JRNZ SCKL ; MVI A,PAD$CLK ; OUT P$TIME$OUT ; RET ; ; ; TIME$ENABLE: RET ; ; ; TIME$DISABLE: ;SETZE CS DES UPD 1990 AUF OFF RET ; ; ; READ$SHIFT: ; DIE 40 BITS DES SHIFTREGISTERS DES UPD 1990 ; WERDEN IN DIE NACHFOLGENDEN 5 BYTES VON (HL) ; ABGELEGT. NACH DIESER AKTION IST DAS SCHIFFTREGISTER ; GELOESCHT MVI A,1 ;READ SCHIF REGISTER CALL SEND$TIME$COM MVI B,5 ;LESE 5 BYTES AUS READ$SHIFT$1: MVI C,8 ;JEDES BYTE ENTHAELT 8 BIT READ$SHIFT$2: IN P$TIME$IN ;LESE EIN BIT AUS CMA ;74LS258 NEGIERT RAL MOV A,D ;SETZE UNTERSTES BIT IN D RAR ;ENTSPRECHEND CARRY MOV D,A CALL SEND$CLK ;SHIFTE NAECHSTES BIT DCR C ;LESE PRO BYTE 8 BIT AUS JRNZ READ$SHIFT$2 ;IST BYTE FERTIG? MOV M,D ;LEGE BYTE NACH (HL) INX H ;ZEIGER AUF NAECHSTES BYTE DJNZ READ$SHIFT$1 ;LESE FUENF BYTES AUS MVI A,0 ;GEHE IN HOLD MODE CALL SEND$TIME$COM RET WRITE$SHIFT: ; SCHREIBT SHIFTREGISTER MIT DEN 5 BYTES, AUF DIE ; (HL) ZEIGT MOV D,M ;LESE ERSTES BYTE EIN MVI A,1 ;GEHE IN SHIFT MODE CALL SEND$TIME$COM MVI B,5 ;SCHREIBE FUENF BYTES EIN WRITE$SHIFT$1: MVI C,8 ;JEDES BYTE ENTHAELT ACHT BIT WRITE$SHIFT$2: MOV A,D ;AUSGABE BYTE IN AKKU RRC ANI 80H ORI PAD$C0 OUT P$TIME$OUT MOV A,D ;SCHIEBE UM EINE POS. NACH RECHTS RAR MOV D,A ;ZURUECK IN D CALL SEND$CLK ;TAKTE BIT EIN DCR C ;SCHON 8 BIT AUSGEGEBEN? JRNZ WRITE$SHIFT$2 INX H ;LESE NAECHSTES BYTE MOV D,M ;NACH D DJNZ WRITE$SHIFT$1 ;SCHREIBE INSGESAMT FUENF BYTES MVI A,0 ;SETZE UPD 1990 AUF HOLD CALL SEND$TIME$COM RET SET$PHYS$TIME: ;SETZE ZEIT IM UPD 1990 MIT DEN FUENF BYTES DIE ;IN PHYS$TIME STEHEN CALL TIME$ENABLE ;AKTIVIERE UPD 1990 LXI H,SHIFT$CONT ;RETTE SHIFTREGISTER INHALT CALL READ$SHIFT LXI H,PHYS$TIME ;SCHREIBE ZEIT IN SHIFTREGISTER CALL WRITE$SHIFT MVI A,2 ;SETZE ZAEHLER CALL SEND$TIME$COM LXI H,SHIFT$CONT ;LADE ALTEN SHIFTREGISTER INHALT CALL WRITE$SHIFT CALL TIME$DISABLE ;DEAKTIVIERE UPD 1990 RET READ$PHYS$TIME: ;LESE ZEIT AUS UPD 1990 IN DIE FUENF BYTES ;VON PHYS$TIME CALL TIME$ENABLE ;AKTIVIERE UPD 1990 LXI H,SHIFT$CONT ;RETTE SHIFTREGISTER INHALT CALL READ$SHIFT MVI A,3 ;SETZE SHIFTREGISTER MIT ZEIT CALL SEND$TIME$COM MVI B,0FFH ;WARTE ETWAS READ$PHYS$TIME$1: DJNZ READ$PHYS$TIME$1 LXI H,PHYS$TIME ;LESE ZEIT AUS CALL READ$SHIFT LXI H,SHIFT$CONT ;LADE SHIFTREGISTER INHALT ZURUECK CALL WRITE$SHIFT CALL TIME$DISABLE ;DEAKTIVIERE UPD 1990 RET SET$SHIFT: ;SETZE SHIFTREGISTER MIT FUENF BYTES ;SHIFT$CONT CALL TIME$ENABLE ;AKTIVIERE UPD 1990 LXI H,SHIFT$CONT ;LADE SHIFT REG. CALL WRITE$SHIFT CALL TIME$DISABLE RET ; ; ; GET$SPEED: ;TESTE OB UHR IN ORDNUNG ;WENN OK, A=FF, WENN NICHT IN ORDNUNG, A=00 ;WENN UHR OK, DANN IN HL TAKTFREQUENZ CALL TIME$ENABLE ;SELECT UPD 1990 MVI A,0 ;IN HOLD MODE CALL SEND$TIME$COM ;WARTE AUF AENDERUNG AM DATENAUSGANG LXI H,0 ; LXI D,0FFFFH ;TIME OUT IN P$TIME$IN ;LESE AUSGANG ANI TIME$DATA$MASK MOV B,A ;NACH B GET$SPEED1: IN P$TIME$IN ;LESE AUSGANG BIS AENDERUNG ODER TIME OUT ANI TIME$DATA$MASK ;MASKIERE CMP B JRNZ GET$SPEED2 ;VERAENDERUNG, WEITER MOV C,A ;RETTE AKKU DCX D ;TIME OUT ZAEHLER EINS RUNTER MOV A,D ORA E ;TIME OUT JRNZ GET$SPEED1 ;UHR NICHT OK? CALL TIME$DISABLE ; XRA A ;FEHLER MELDUNG RET GET$SPEED2: ;TESTE TAKT FREQUENZ MOV B,A ;WIEDER IN B FUER VERAENDERUNG MVI C,TIME$DATA$MASK ;MASKE GET$SPEED3: ;ERMITTLE TAKT, LOOP MUSS 50 ZYKLEN DAUERN IN P$TIME$IN ; 11 ZYKLEN ANA C ;MASKIERE, 4 ZYKLEN CMP B ;GLEICH ?, 4 ZYKLEN JRNZ GET$SPEED4 ;ENDE, 7 ZYKLEN INX H ; 6 ZYKLEN NOP ;DIENT NUR ZUR VERZOEGERUNG, 4 ZYKLEN NOP ; 4 ZYKLEN JMP GET$SPEED3 ; 10 ZYKLEN GET$SPEED4: CALL TIME$DISABLE MVI A,0FFH RET ; ; ; ;*************************************************************; ; ; ;ENDE DES MASCHINEN CODES, ES FOLGEN NUN TABELLEN ; ; ; ;*************************************************************; ; ; ; TXT1 DB ', track #' DB 24H TXT2 DB ', head #' DB 24H TXT3 DB ', sector #' DB 24H ; ERROR$TABLE: DW B15MSG ;FEHLERMELDUNGEN FUER ST1 DW NOBMSG DW B13MSG DW B12MSG DW NOBMSG DW B10MSG DW B9MSG DW B8MSG ; DW NOBMSG ;FEHLERMELDUNGEN FUER ST2 DW B6MSG DW B5MSG DW B4MSG DW NOBMSG DW NOBMSG DW B1MSG DW B0MSG ; NOBMSG DB 24H B15MSG DB 10,13,' end of cylinder',24H B13MSG DB 10,13,' data error',24H B12MSG DB 10,13,' over run',24H B10MSG DB 10,13,' no data',24H B9MSG DB 10,13,' not writable',24H B8MSG DB 10,13,' missing address mark',24H B6MSG DB 10,13,' control mark',24H B5MSG DB 10,13,' data error in data field',24H B4MSG DB 10,13,' wrong cylinder',24H B1MSG DB 10,13,' bad cylinder',24H B0MSG DB 10,13,' missing address mark in data field',24H ; TXTRD: DB BELL,0DH,0AH,' Read error on $' TXTWR: DB BELL,0DH,0AH,' Write error on $' ; ; SOFT$BAUD$TAB: ;BAUDRATEN FAKTOR FUER DIE SOFTSCHNITTSTELLE ;BERRECHNUNG ERFOLGT SO: ;EINTRAG:=((1000000/BAUDRATE)-12,5)*65536/240000 ; ; IF ACHTMHZ ; DW 50 ; 9600 BAUD DW 106 ; 4800 BAUD DW 221 ; 2400 BAUD DW 448 ; 1200 BAUD DW 1814 ; 300 BAUD DW 4054 ; 134.5 BAUD DW 7275 ; 75 BAUD DW 50 ; 9600 BAUD DW 22 ;19200 BAUD DW 69 ; 7200 BAUD DW 145 ; 3600 BAUD DW 297 ; 1800 BAUD DW 903 ; 600 BAUD DW 3634 ; 150 BAUD DW 4958 ; 110 BAUD DW 10916 ; 50 BAUD ; ELSE ; DW 25 ; 9600 BAUD DW 53 ; 4800 BAUD DW 110 ; 2400 BAUD DW 224 ; 1200 BAUD DW 907 ; 300 BAUD DW 2027 ; 134.5 BAUD DW 3637 ; 75 BAUD DW 25 ; 9600 BAUD DW 11 ;19200 BAUD DW 35 ; 7200 BAUD DW 72 ; 3600 BAUD DW 148 ; 1800 BAUD DW 452 ; 600 BAUD DW 1817 ; 150 BAUD DW 2479 ; 110 BAUD DW 5458 ; 50 BAUD ; ENDIF ; ; SGNON: DB 0DH,0AH DB 'Monitor' DB 0DH,0AH DB '$' ; ; ; KENNUNGSTEXT: DB 'PROF-80' ;WIRD VON INIT INS RAM KOPIERT ; ; ; CMDMSG: ;NACH EINGABE EINES ZEICHENS WIRD TEXT AUSGEGEBEN ; DB 'Address for read (write) from (to) drive $' DB 'Boot$' DB 'Check drive $' DB 'Display memory $' DB 'Fill memory $' DB 'Go to $' DB 'Harddisk boot$' DB 'Keyboard mode$' DB 'In port $' DB 'List time$' DB 'Move memory $' DB 'New date and time set$' DB 'Out port $' DB 'Read from drive $' DB 'Substitute memory $' DB 'Test memory $' DB 'User defined disk timing$' DB 'Verify memory $' DB 'Write to drive $' DB 'X Register $' DB 0 ;ENDE DER COMMAND TEXTE ; CADR: DW 0 DW UCMD DW KCMD DW LCMD DW GCMD DW WCMD DW ACMD DW RCMD DW OCMD DW CCMD DW TCMD DW VCMD DW FCMD DW BCMD DW XCMD DW SCMD DW MCMD DW ICMD DW DCMD DW NCMD DW HCMD ; ; ; CTAB: DB 'H' DB 'N' DB 'D' DB 'I' DB 'M' DB 'S' DB 'X' DB 'B' DB 'F' DB 'V' DB 'T' DB 'C' DB 'O' DB 'R' DB 'A' DB 'W' DB 'G' DB 'L' DB 'K' DB 'U' NCMDS EQU $-CTAB ; ; ; RTAB: DB 'A' DB ASAVE AND 0FFH DB 0 DB 'B' DB BSAVE AND 0FFH DB 0 DB 'C' DB CSAVE AND 0FFH DB 0 DB 'D' DB DSAVE AND 0FFH DB 0 DB 'E' DB ESAVE AND 0FFH DB 0 DB 'F' DB FSAVE AND 0FFH DB 0 DB 'H' DB HSAVE AND 0FFH DB 0 DB 'L' DB LSAVE AND 0FFH DB 0 DB 'M' DB HSAVE AND 0FFH DB 1 DB 'P' DB PSAVE+1 AND 0FFH DB 1 DB 'S' DB SSAVE+1 AND 0FFH DB 1 DB 'a' DB AASAVE AND 0FFH DB 0 DB 'b' DB BBSAVE AND 0FFH DB 0 DB 'c' DB CCSAVE AND 0FFH DB 0 DB 'd' DB DDSAVE AND 0FFH DB 0 DB 'e' DB EESAVE AND 0FFH DB 0 DB 'f' DB FFSAVE AND 0FFH DB 0 DB 'h' DB HHSAVE AND 0FFH DB 0 DB 'l' DB LLSAVE AND 0FFH DB 0 DB 'm' DB HHSAVE AND 0FFH DB 1 DB 'X' DB XSAVE+1 AND 0FFH DB 1 DB 'Y' DB YSAVE+1 AND 0FFH DB 1 DB 'I' DB ISAVE AND 0FFH DB 0 DB 'R' DB RSAVE AND 0FFH DB 0 DB 0,0 ;ENDE KENNUNG DER TABELLE ; ; ; DISKPAGE: ; DIE DISKPAGE WIRD DER SYSTEMPAGE UEBERLAGERT ; INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; RET DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; RET DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; RET DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; EXX OUTI EXX INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1 ; RET DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; RET DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; RET DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ; EXX INI EXX INP L PCHL DB -1,-1,-1,-1,-1,-1,-1,-1,-1 ; LASTADD EQU $-1 ;LETZTE BENUTZTE ADRESSE IM EPROM ; ; ; ;************************************* BEGINN DES RAM-BEREICHES ****** ; ; ; ORG SYSTEMPAGE-1024-256 ; BOOTADR EQU $ ;HIERHER WIRD ERSTER SEKTOR GELADEN ; DS 1024 ;PLATZ FUER ERSTEN SEKTOR ; DS 256-26 ;PLATZ FUER STACK ; REGS: EQU $ MSTAK: EQU $ ; ; REGISTER INHALTE ; RSAVE: DS 1 ISAVE: DS 1 LLSAVE DS 1 HHSAVE DS 1 EESAVE DS 1 DDSAVE DS 1 CCSAVE DS 1 BBSAVE DS 1 FFSAVE DS 1 AASAVE DS 1 YSAVE: DS 2 XSAVE: DS 2 ESAVE: DS 1 DSAVE: DS 1 CSAVE: DS 1 BSAVE: DS 1 FSAVE: DS 1 ASAVE: DS 1 LSAVE: DS 1 HSAVE: DS 1 PSAVE: DS 2 SSAVE: DS 2 ; ; DIE NACHFOLGENDEN SPEICHERZELLEN MUESSEN ; MIT DER DISKPAGE GEMISCHT WERDEN KOENNEN ; SYSTEMPAGE: ; RWPOLL: ; NACHDEM DIE SYSTEMPAGE VON DER DISKPAGE ; UEBERLAGERT WURDE, ERLEDIGT EIN CALL VON ; RWPOLL DIE DISK-UEBERTRAGUNG. ; ;*** ERSTE 16 BYTE *** DS 3 ;FREI FUER FLOPPY BEDIENUNG TEMP: DS 1 ;ALLGEMEINER ZWISCHENSPEICHER BAUD$JUMPERBYTE DS 1 ;STELLUNG DES JUMPERS J5: 0=KEIN JUMPER ;1=1-3,2=2-4,3=3-5,4=4-6 CLKFLG DS 1 ;"0": UHR NICHT OK, "FF": UHR OK DISKFLG DS 1 ;"0": UPD 765 NICHT OK, "FF": UPD 765 OK SYSTEMTAKT DS 2 ;SYSTEMFREQUENZ * 100 HZ DISPADR DS 2 ;LETZTER ZAEHLERSTAND DES D-BEFEHLS EOTSAVE DS 1 ;WIRKLICHES ENDE EINER SPUR EOTFLG DS 1 ;FEHLERFLAG FUER DISK R/W UEBER SPUR ENDE RWCMD DS 1 ;COMMANDO FUER RWCOM ERMSG DS 2 ;MEASSAGE FUR RWCOM ; ; ;*** ZWEITE 16 BYTE *** DS 3 ;FREI FUER FLOPPY BEDIENUNG IO$JUMPERBYTE DS 1 ;STELLUNG DES JUMPERS J4: 0=KEIN JUMPER ;1=1-3,2=2-4,3=3-5,4=4-6. DIRIGIERT KONSOLE PHYS$TIME DS 5 ;ZWISCHENSPEICHER FUER UPD 1990 ZAEHLER INHALT SHIFT$CONT DS 5 ;ZWISCHENSPEICHER FUER UPD 1990 SHIFTREGISTER SOFTVERZ DS 2 ;VERZOGERUNGSZEIT FUER DUPLEX-SCHNITTSTELLE ; ; ;*** DRITTE 16 BYTE *** DS 3 ;FREI FUER FLOPPY BEDIENUNG TEST$TYPE DS 1 ;WIRD BEI TEST GESETZT (FORMATERKENNUNG FLOPPY) ;BIT 7: 0=SS, 1=DS ;BIT 6: 0=SD, 1=DD ;BIT 5: 0=MAXI, 1=MINI ;BIT 4: IMMER 0 ;BIT 0-3: SEKTORGROESSE ; TEST$MSEK DS 1 ;ANZAHL DER SEKTOREN/SPUR, DIE TEST ERMITTELTE TEST$TRACK DS 1 ;AUF DIESER SPUR WIRD DAS FLOPPY- ;FORMAT GETESTET (DEFAULT=1) UMLEIT$NMI DS 3 ;EIN NMI GEHT UEBER DIESEN SPRUNG ; BANK$ERR$BYTE DS 1 ;BELEGUNG DER ZWEI RAM BANKS ;0: BANK 0 UND BANK 1 OK ;1: BANK 0 FEHLER ;2: BANK 1 FEHLER ; DMAADR DS 2 ;DMA ADRESSE FUER FLOPPY READ UND WRITE SECTCNT DS 1 ;ANZAHL DER SEKTOREN FUER FLOPPY READ UND WRITE UMLEIT$GETCM DS 3 ;ROUTINEN, DIE VON CP/M BENUTZT WERDEN, MUESSEN ;UEBER DIESEN SPRUNG AUF BEFEHLS-EINGABE-EBENE ;ZURUECKKEHREN. CP/M BIOS SETZT DIESEN SPRUNG ;DANN AUF WBOOT ; ; ;*** VIERTE 16 BYTE DS 3 ;FREI FUER FLOPPY BEDIENUNG ;KOMMANDO-TABELLE FUER FLOPY-CONTROLER CMDTAB DS 1 ; UNIT DS 1 ;WIRD VON C-BEFEHL GESETZT TRACK DS 1 ;WIRD VON A-BEFEHL GESETZT HEAD DS 1 ;WIRD VON A-BEFEHL GESETZT SECTOR DS 1 ;WIRD VON A-BEFEHL GESETZT SECSZ DS 1 ;WIRD VON C-BEFEHL GESETZT EOT DS 1 ;WIRD VON C-BEFEHL GESETZT GAPLL DS 1 ;WIRD VON C-BEFEHL GESETZT DTLL DS 1 ;WIRD VON C-BEFEHL GESETZT UMLEIT$CONST DS 3 ;KONSOLEN STATUS GEHT UEBER DIESEN SPRUNG SEEKNR DS 1 ;EINIGE LAUFWERKE BENOETIGEN ZWEI STEPIMPULSE ;DIE UNTEREN 4 BIT GEBEN FUER JEDES LW ;AN, OB ES EIN ('0') ODER ZWEI ('1') IMPULSE ;PRO SPURWECHSEL BRAUCHT, LAUFWERK 0 IST LSB. ;DIE OBEREN 4 BIT DIESES BYTES GEBEN AN, OB ;TEST DAS TWO-SIDED-BIT IMMER AUF 1 ODER ;ENTSPRECHEND DER TWO-SIDED-LEITUNG SETZTEN ;SOLL. DURCH DIESE ERWEITERUNG SPART MAN SICH ;DEN HARDWARE-ZUSATZ (SIEHE CP/M ANPASSUNS- ;BESCHREIBUNG) FUER GEMISCHTEN BETRIEB MIT ;80 TRACK LAUFWERKEN. ;DEFAULTMAESSIG WIRD SEEKNR MIT XSEEKNR ;INITIALISIERT. SEEKNR KANN ABER AUCH MIT DEM ;U-BEFEHL GESETZT WERDEN. ; ;*** FUENFTE 16 BYTES *** DS 3 ;FREI FUER FLOPPY BEDIENUNG REST DS 7 ;ERGEBNISSTABELLE DES FLOPY-CONTROLERS UMLEIT$CONIN DS 3 ;KONSOLEN EINGABE GEHT UEBER DIESEN SPRUNG UMLEIT$CONOUT DS 3 ;KONSOLEN AUSGABE GEHT UEBER DIESEN SPRUNG ; ; ;*** SECHSTE 16 BYTES *** DS 3 ;FREI FUER FLOPPY BEDIENUNG IN$BUFF$END DS 11 ;FIFO ZEICHEN BUFFER FUER DUPLEX EINGABE ;IM INTERRUPTBETRIEB (J-51-A GESETZT) IN$BUFF$ZEIG DS 2 ;ZEIGER FUER ZEICHEN BUFFER ; ; ;*** SIEBTE 16 BYTES *** DS 3 ;FREI FUER FLOPPY BEDIENUNG DERMSG DS 1 ;"0":AUSGABE VON FLOPPY-FEHLER ;"FF": AUSGABE VON FLOPPY-FEHLER UNTERDRUECKEN RWRETRY DS 1 ;ANZAHL DER LESE/SCHREIB-VERSUCHE MIT FLOPPY WRITE$PRECOM DS 1 ;WRITE PRECOMPENSATION FUER RWCOM ROUTINE KENNUNG DS 7 ;DER MONITOR SCHREIBT HIER PROF-80 KENNUNG EIN MON$VERS DS 1 ;MONITOR VERSIONSNUMMER COMMON$PAGE DS 1 ;PAGEGRENZE FUER COMMON BEREICH (SETZT BIOS) CURRENT$BANK DS 1 ;GEWAEHLTE BANK UNTER COMMON (SETZT BIOS) ; ; ;*** ACHTE 16 BYTES *** DS 3 ;FREI FUER FLOPPY BEDIENUNG SOFTPRNTVERZ DS 2 ;VERZOEGERUNGSZEIT FUER SIMPLEX SCHNITTSTELLE READY$BYTE DS 1 ;DIE UNTEREN 4 BITS GEBEN AN, OB EIN LW ;EIN READY SIGNAL LIEFERN KANN ('0') ODER OB ;ES KEIN READY LIEFERT ('1'). ;DIE OBEREN 4 BITS GEBEN AN, OB BEI DEM ;BETREFFENDEN LW UEBERHAUPT SCHON GETESTET ;WURDE OB ES READY LIEFERT ;'0'= SCHON GETESTET, '1'= NOCH NICHT GETESTET ;LAUFWERK 0 IST LSB EPROMZ DS 1 ;WIEVIEL MAL WURDE EPROM EINGESCHALTET? ;(WIRD VOM BIOS GESETZT) TYPELIST DS 2 ;ZEIGER AUF DISK$TYPE$LIST (WIRD VOM BIOS ;GESETZT) SPECD$WORD DS 2 ;DER INHALT DIESER ZWEI BYTE BESTIMMT DIE ;STEP-RATE, DIE HEAD-LOAD-TIME UND DIE HEAD- ;UNLOAD-TIME. SPECD$WORD WIRD NACH EINEM RESET ;VOREINGESTELLT. NACH JEDEM CHECK DRIVE WERDEN ;DIE DRIVE-ZEITEN NEU GESETZT. ;DIE 16 BIT VON SPECD$WORD SIND FOLGENDERMASSEN ;AUFGEBAUT: ; SSSSUUUU LLLLLLLX ; ; SSSS: STEPRATE 0000=16MS ; 0001=15MS ; ......... ; 1111=1MS ; ; UUUU: HEADUNLOADTIME IN 16 MS SCHRITTEN ; 0000=0MS, 0001=16MS, .. ,1111=240MS ; ; LLLLLLL: HEADLOADTIME IN 2 MS SCHRITTEN ; ; X: IMMER 1 ; ;DEFAULTMAESSIG WIRD SPECD$WORD MIT ;XSPECD$WORD INITIALISIERT, ES KANN ABER ;AUCH MIT DEM U-BEFEHL GESETZT WERDEN. ; TE$TIME DS 1 ;WARTEZEIT NACH DISK-WRITE IN 100US (BEI 6MHZ) SIOABAUD DS 1 ;JUMPERSTELLUNG UNIO J2-A SIOBBAUD DS 1 ;JUMPERSTELLUNG UNIO J2-B STEP$WAIT DS 1 ;WARTEZEIT VOR SEEK WENN MOTOR VORHER AUS WAR ;IST BEI EPSON 3,5 ZOLL LAUFWERKEN NOTWENDIG. ;ZEIT: MAL 10 MS (BEI 6 MHZ) DS 1 ;NOCH FREI ; ; ;*** NEUNTE 16 BYTE *** DS 1 ;FREI FUER FLOPPY BEDIENUNG ALT$UNIT DS 1 ;LAUFWERK UND TRACK BEI LETZTEM ALT$TRACK DS 1 ;SEEK AUFRUF HD$BOOT DS 1 ;FUER CP/M 0FFH => FLOPPY-BOOT, 000H => HARDDISK-BOOT BOOT$FLG DS 1 ;FUER MONITOR 0 => HARDDISK-BOOT, SONST FLOPPY-BOOT DS 11 ;NOCH FREI ; ; DS 7*16 ;FREIHALTEN FUER ERWEITERUNGEN UND ;FLOPPY BEDIENUNG ; END