P8000/firmware/MON8/FLOPPY.S

894 lines
18 KiB
ArmAsm

*P 84
;******************************************************************************
;
; Floppydisk Treiber fuer P8000
;
;******************************************************************************
DMA EQU 1
UDOS EQU 1
U880SM EQU 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENTRY FLOPPY TREIBER
DISK
FLOPPY LD HL,(DSKVSL) ;ist Parametervektor eingetragen ?
LD A,H
OR L
JR NZ,FLOPPY ;Treiber besetzt --> warten !
LD (DSKVSL),IY ;Treiber ist frei --> Parametervektor
;eintragen und damit als "besetzt" setzen
CALL FLP ;CALL-Aufruf des Treibers
WAIT BIT 0,(IY+1) ;zeitgeteilter Verkehr ?
WAIT1 RET NZ
BIT 7,(IY+10) ;Operation fertig ?
JR WAIT1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RETURN FUER WARTEN AUF INTERRUPT
SFLPI POP HL ;IN HL ADR WO PROGRAMM NACH
LD (INTPNT),HL ;INTERRUPT WEITER LAEUFT
EI ;falls Programm als ISR des PIO2 laeuft
;kann neuer INT vom PIO2 erst nach RETI
RET ;erfolgen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Auswertung UDOS-Requestcode
FLP
COND 1-U880SM
; Adressen der Interruptserviceroutinen
LD HL,ISRPB ; Initialisierung der Interruptserviceroutinen
LD (INTABP),HL ; wenn FLOPPY-Teil als externer Treiber arbeitet.
LD HL,ISRCT1
LD (INTAB+2),HL
LD HL,ISRDMA
LD (INTABD),HL
ENDC
;
LD A,(IY+1) ;Request Code
AND 0FEH ;Loeschen der Abarbeitungsart
CP 0AH ;Read Binary Request ?
JR Z,TYPTEST
CP 0EH ;Write Binary Request ?
JR Z,TYPTEST
CP 50H ;Format
JR Z,TYPTEST
LD A,0C1H ;'Invalid Request'
ERRRTN CALL OPFIN
LD H,(IY+9)
LD L,(IY+8)
LD A,H
OR L
JR Z,FEHL1
JP (HL) ;Jump to Error Return Address
FEHL1 BIT 0,(IY+1)
RET Z ;Ruecksprung, wenn einfacher Request
LD H,(IY+7)
LD L,(IY+6)
JP (HL) ;Jump to Completion Return Address
ERRC2 LD A,0C2H
JR ERRRTN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Floppy-Typ testen und FDC einstellen
TYPTEST LD C,(IY+11) ;Drive/Sector
LD A,C
RLA
JR C,ERRC2
LD HL,FDCONF
BIT 6,C ;0 = Drive 0,1
JR Z,TYP1
INC HL
TYP1 LD A,(HL)
BIT 5,C ;0 = Drive 0,2
JR Z,TYP2
RRCA ;Verschiebung fuer Drive 1 und 3
RRCA
RRCA
RRCA
TYP2 AND 0FH
JR Z,ERRC2 ;Ist Laufwerktyp in FDCONF eingetragen?
CP 8 ;Ja, testen.
JR NC,ERRC2
LD HL,FDTYP ;Nein, weiter testen.
CP (HL) ;altes = neues Format ?
JR Z,TYPOK
LD (HL),A ;neuen Typ einstellen
LD HL,TYPTAB ;Treiber auf Typ einstellen
LD DE,11
LD B,A
JR TYP4
TYP3 ADD HL,DE
TYP4 DJNZ TYP3 ;solange <DE> addieren, bis <B>:=0, dann ist die
;richtige Tabelle eingestellt
LD C,2
LD DE,FDCTAB+1
LDIR
INC DE
INC DE ;veraenderliche Werte ueberspringen
LD C,8
LDIR
DI ;besser DI
IN A,(PIO2AD) ;Takt einstellen
SET 4,A ;5" = 4MHz Takt einstellen
BIT 1,(HL)
JR Z,TYP5
RES 4,A ;8" = 8MHz Takt einstellen
TYP5 OUT (PIO2AD),A
LDI ;CMD Byte eintragen
COND 1-DMA
LD HL,FDCTAB+2
SET 0,(HL) ;NON-DMA setzen
ENDC
LD BC,0303H ;Specify; Werte aus Tabelle eintragen
CALL FDCKMD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Drive, Track und Sektor uebernehmen
TYPOK LD HL,0202H ;Setzen der Fehlerzaehler
LD (WSCTR),HL ;WSCTR und WTCTR
LD A,10
LD (CRCCTR),A ;fuer CRC (Data Transfer) Errors (C6)
XOR A
LD (IY+10),A ;Loeschen Completion Code
LD A,(IY+12) ;Ueberpruefen Spurnummer
LD (SPURNR),A ;Spurnummer in Speicherzelle eintragen
LD HL,TRK
CP (HL)
LD A,0C5H
JR NC,ERR
LD A,(IY+11) ;Uebernehmen Sektor/Laufwerk
LD C,A
AND 60H ;Drive Maske
RLCA
RLCA
RLCA
LD B,A
LD A,C
LD C,0 ;Head 0
AND 1FH ;Sektor Maske
LD HL,FDCTAB+6 ;EOT
CP (HL) ;Sektor >= EOT --> Head 1
JR C,HEADOK
SUB (HL) ;Sektornummer einmal subtrahieren, wegen Doppelkopflaufwerk
CP (HL) ;Sektornummer zu gross ?
JR NC,HERRC4
LD HL,CMD
BIT 7,(HL) ;Head (Side) 1 zugelassen ?
JR NZ,HEAD1
HERRC4 LD A,0C4H
ERR JP ERRRTN
HEAD1 SET 2,B ;Head 1 setzen in Drivenummer
INC C
HEADOK INC A ;1. PHYSISCHER SEKTOR = 1
LD (FDCTAB+4),A ;Sektornummer eintragen
LD A,C
LD (FDCTAB+3),A ;Head eintragen
LD A,B
LD (FDCTAB+1),A ;Drive und Head select
AND 03H ;Laufwerk-Nummer in <A>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DRIVE SELEKT UND BEREITSCHAFT PRUEFEN
CALL READY ;in A Drive
JP Z,ERRC2 ;Drive not ready"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Laufwerksanwahl ist ok. --> Pruefen der Kopfposition
LD HL,CURT0 ;Tabelle der Kopfpositionen (nach RESET mit
;0FFH beschrieben)
;in DE noch Laufwerk von READY
ADD HL,DE ;zeigt auf die Kopfposition des angef. LW
LD A,(HL)
INC A ;war Kopf schon mal positioniert ?
LD (HL),D ;beim 8272 muss sich nicht die Kopfposition
;gemerkt werden, nur Unterscheidung ob
;schon mal positioniert
JR NZ,HDMOV ;JA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Kopf des angewaehlten LW auf Spur 00 fahren
TR00 LD BC,0207H ;Recalibrate Command
CALL FDCKMD
CALL SFLPI
;*************** Warten auf Interrupt *******************
LD BC,0207H ;2.Recalibrate falls mehr als 77 Spuren
CALL FDCKMD
CALL SFLPI
;*************** Warten auf Interrupt *******************
;auf Fehlerauswertung wird hier verzichtet
;sie werden spaeter auch noch gemerkt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;In HDMOV wird der Kopf des angewaehlten LW auf die richtige
;Spur gefahren
HDMOV LD A,(SPURNR) ;Track Nummer
LD HL,CMD
BIT 0,(HL) ;Doppelstep ?
JR Z,HDMOV1
ADD A,A ;*2
HDMOV1 LD (FDCTAB+2),A ;Spur in Kommandotabelle
LD HL,(PR1) ;Praekompensation ein/aus
DI
LD C,PIO2BD
IN B,(C)
RES 5,B
RES 6,B
CP L ;1. Praekompensation
JR C,CHKP
SET 5,B
CP H ;2. Praekompensation
JR C,CHKP
SET 6,B
CHKP OUT (C),B
LD BC,030FH ;Kommandotabelle fuer "SEEK"
CALL FDCKMD
CALL SFLPI
;*************** Warten auf Interrupt *******************
;auf Fehlerauswertung wird hier verzichtet
;sie werden spaeter auch noch gemerkt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SEKTOR(EN) LESEN SCHREIBEN
COND 1-DMA
DTRANS LD A,(SPURNR) ;Spur
LD (FDCTAB+2),A
LD H,(IY+5)
LD L,(IY+4) ;Datenlaenge
LD A,H
OR L
JP Z,OPCOMP
PUSH DE
EX DE,HL
LD L,(IY+2) ;Adresse
LD H,(IY+3)
LD A,3 ;Interrupt PIO2 aus, Lesen/Schreiben erfolgt
OUT (PIO2BC),A ;ohne Interrupt, Abfrage von INT
LD B,9
LD A,(CMD)
AND 0F0H
OR 5 ;Write
LD C,A
BIT 2,(IY+1) ;Lesen oder Schreiben ?
JR NZ,WR
BIT 4,(IY+1) ;Format ?
JR NZ,FORMAT
;DATEN EINLESEN
INC C ;Read
CALL FDCKMD ;Ausfuehrung
LREAD IN A,(MSR)
RLCA
JR NC,LREAD ;warten auf Zeichen
RLCA
RLCA
JR NC,RWEND ;1= NON DMA MODE --> 0= Ende Uebertragung
INI ;REG C = DATREG in FDCKMD gesetzt
DEC DE
LD A,D
OR E
JR NZ,LREAD
JR RWEND
;DATEN SCHREIBEN
FORMAT PUSH HL ;Format
LD HL,(FDCTAB+5)
LD (FDCTAB+2),HL
LD HL,(GPL2)
LD H,0E5H
LD (FDCTAB+4),HL
LD A,H
LD (FDTYP),A ;NACH FORMAT IMMER TYP NEU EINSTELLEN
POP HL
LD B,6
SET 3,C ;Format
RES 7,C ;MT nicht bei Format
WR CALL FDCKMD
LWRITE IN A,(MSR)
RLCA
JR NC,LWRITE
RLCA
RLCA
JR NC,RWEND ;FDC bereits fertig
OUTI
DEC DE
LD A,D
OR E
JR NZ,LWRITE
;ENDE LESEN / SCHREIBEN
RWEND IN A,(PIO2AD)
SET 6,A ;TC auf 1;Abbruch R/W
OUT (PIO2AD),A
RES 6,A ;TC wieder auf 0
OUT (PIO2AD),A
POP DE
LD A,83H ;Interrupt PIO2 erlauben
OUT (PIO2BC),A
CALL SFLPI
ENDC
COND DMA
DTRANS LD A,(SPURNR) ;Spur eintragen
LD (FDCTAB+2),A
LD H,(IY+3)
LD L,(IY+2) ;Datenadresse
LD (DMALSW+1),HL ;in DMA-Tabelle
LD H,(IY+5)
LD L,(IY+4) ; Datenlaenge
LD A,H
OR L
JP Z,OPCOMP
DEC HL
LD (DMALSW+3),HL ;Datenlaenge-1 in DMA-Tabelle
LD B,9 ;Kommandokode fuer Schreiben
LD A,(CMD)
AND 0F0H
OR 05H
LD C,A
BIT 2,(IY+1) ;Abfrage Schreiben oder Lesen
JR NZ,AUSDMA
BIT 4,(IY+1) ;FORMAT ?
JR Z,DREAD
LD HL,(FDCTAB+5)
LD (FDCTAB+2),HL
LD HL,(GPL2)
LD H,0E5H
LD (FDCTAB+4),HL
LD A,H
LD (FDTYP),A ;NACH FORMAT IMMER TYP NEU EINSTELLEN
LD B,6
SET 3,C ;Format
RES 7,C
JR AUSDMA
DREAD INC C ;Read
LD A,1 ;Festlegung der Datenrichtung DMA <--- FDC
LD (DMALSW+6),A
LD A,7DH
LD (DMALSW),A
AUSDMA PUSH BC
LD HL,DMALSW
LD BC,0A00H+DMAADR
OTIR
LD A,5 ;Festlegung der Datenrichtung DMA ---> FDC
LD (DMALSW+6),A ;Wert fuer Schreiben wieder eintragen
LD A,79H
LD (DMALSW),A ;Wert fuer Schreiben wieder eintragen
POP BC
CALL FDCKMD
CALL SFLPI
ENDC
;********** Warten auf Interrupt ************
CALL RDRES ;Result einlesen
;in A (RESUL)
AND 0C0H ;IC & SE
JR Z,OPCOMP ;kein Fehler
;Fehler bei der Datenuebertragung
LD A,(RESUL+1) ;Statusregister 1
BIT 1,A ;Schreibschutz ?
JR NZ,WRPROT
AND 30H ;CRC-Fehler im ID-Feld oder Overrun ?
JR NZ,BADCRC
LD A,(RESUL+2)
BIT 5,A ;CRC Fehler im Datenfeld ?
JR NZ,BADCRC
AND 12H
JR NZ,WRNGTR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DISK FEHLER
;Sector Address Errors (C4)
WRNGSEC LD HL,(SECERR)
INC HL
LD (SECERR),HL
LD HL,WSCTR
LD A,0C4H ;Sektor Address Error
JR WRNG1
;CRC-Fehler (C6)
BADCRC LD HL,(CRCERR)
INC HL
LD (CRCERR),HL
LD HL,CRCCTR
LD A,0C6H ;CRC-Fehler
WRNG1 DEC (HL)
JP NZ,DTRANS ;neuer Versuch
JR OPFIN
;Seek-Errors (C5)
WRNGTR LD HL,(TRKERR)
INC HL
LD (TRKERR),HL
LD HL,WTCTR
DEC (HL)
JP NZ,TR00 ;neuer Versuch
LD A,0C5H ;Seek Error
JR OPFIN
;Schreibschutz (C3)
WRPROT LD A,0C3H
JR OPFIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Abschluss-Routine
OPCOMP LD A,80H ;Completion Code = 80H (Transfer ok.)
OPFIN LD (IY+10),A
AND 40H ;Error wenn bit 6 = 1
JR Z,OPFIN1
XOR A
LD (IY+4),A ;0 Bytes uebertragen
LD (IY+5),A
OPFIN1 LD H,A ;A = 0
LD L,A
LD (DSKVSL),HL ;Treiber frei
LD (DMASK),A ;LW Maske loeschen
RET ;ab hier beginnt die Zeit fuer Motor aus
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;KOMMANDOAUSFUEHRUNG DES FDC
;Vor dem Einschreiben von Bytes in den FDC muss im Main Status Register
;RQM=1 und DIO=0 sein.
;Vor dem Auslesen von Bytes aus dem FDC muss im Main Status Register
;RQM=1 und DIO=1 sein.
;Programmierung des FDC
FDCKMD DI
PUSH HL
LD HL,FDCTAB
LD (HL),C ;Kommando eintragen
FDCKM1 LD C,DATREG
RQMDIO IN A,(MSR) ;Lesen des Main Status Register
AND 0C0H ;nur RQM & DIO
CP 080H ;RQM=1 & DIO=0 ?
JR NZ,RQMDIO ;Warten
OUTI ;Ausgabe
PUSH HL ;mindestens 12 Mikrosek. zwischen Zugriff
POP HL ;Daten- und Hauptstatusregister einhalten
PUSH HL
POP HL
JR NZ,FDCKM1
POP HL
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RESULT VOM FDC LESEN
RDRES LD HL,RESUL ;Resultatstabelle
LD C,DATREG
RDRES1 IN A,(MSR) ;Lesen Main Status Register
CPL
AND 0C0H
JR NZ,RDRES1 ;warten auf READ-Bereitschaft des FDC
INI ;FDC --> CPU
LD B,6 ;Zeit von 12 Mikrosek. einhalten
DJNZ $
IN A,(MSR)
BIT 4,A ;FDC noch in einer Kommandodurchfuehrung
JR NZ,RDRES1 ;ja (noch Resultatsbytes zu lesen)
LD A,(RESUL) ;Statusregister 0
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;INTERRUPTSERVICE-ROUTINE FUER PIO2/B-INTERRUPTS
;zeigt den Beginn der "Result Phase" an
ISRPB PUSH HL
PUSH AF
PUSH BC
PUSH IY
LD IY,(DSKVSL)
IN A,(MSR)
BIT 4,A ;FDC besetzt ?
JR NZ,RUECK ;Ja -> Transfer Kommando
;ermitteln, ob Recalibrate oder Seek Int
LD BC,0108H ;FDC-Kommando "Sense Interrupt Status"
CALL FDCKMD ;Ausfuehrung des Kommandos
CALL RDRES ;Lesen des Resultats
;in A (RESUL) = Statusregister 0
AND 0E0H ;IC & SE (Interrupt und Seek End)
CP 0C0H ;Ready Line Changed ?
JR Z,SOFORT ;Ja -> keine Reaktion
RUECK LD HL,RTNPTR
PUSH HL ;Eintragen der Rueckkehradresse
LD HL,(INTPNT)
JP (HL) ;weiter bei eingetragener Adresse
RTNPTR BIT 7,(IY+10) ;Operation fertig
JR NZ,CCOK ;ja
SOFORT POP IY
JR INTEND
CCOK BIT 6,(IY+10)
JR Z,KEINF ;Durchfuehrung fehlerfrei
LD H,(IY+9)
LD L,(IY+8) ;Error Return Address
LD A,H
OR L ;=0 ?
JR NZ,ERRRET
KEINF BIT 0,(IY+1) ;zeitgeteilt ?
JR Z,SOFORT ;nein
LD H,(IY+7)
LD L,(IY+6) ;Completion Return Address
ERRRET POP IY
POP BC
POP AF
EX (SP),HL
JR IRET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ISR CTC fuer Motor aus
ISRCT1 PUSH HL
PUSH AF
PUSH BC
LD C,01H ;Maske fuer LW 0
LD HL,TTAB ;Motorzeitentabelle
CLOOP LD A,(DMASK)
AND C
JR NZ,CLOOPE ;fuer aktuelles LW Motorzeit nicht decrement
IN A,(PIO2AD) ;PIO-Port fuer Motorsteuerung
LD B,A
AND C ;Motor LW n an ?
JR NZ,CLOOPE ;nein
DEC (HL) ;Zeit herunterzaehlen
JR NZ,CLOOPE ;noch nicht Null
LD A,B
OR C ;MOTORBIT = 1 SETZEN
LD B,A
CPL
AND 0FH
JR NZ,CLOOP1
LD A,03H ;kein Motor an, CTC Reset
OUT (CTC0+1),A
RES 5,B ;Kopf ab
CLOOP1 LD A,B
OUT (PIO2AD),A
IN A,(PIO2BD)
OR C
OUT (PIO2BD),A ;Select mit dem Motor abschalten
CLOOPE INC HL ;naechste Motorzeit
SLA C ;Maske auf naechstes LW
BIT 4,C ;alle LW abgearbeitet ?
JR Z,CLOOP
INTEND POP BC
POP AF
POP HL
COND 1-DMA
ISRDMA
ENDC
IRET EI ;EI fuer ISR PIO2
RETI
COND DMA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Interruptserviceroutine fuer den DMA
;enthaelt nur DMA ruecksetzen
;
ISRDMA PUSH AF
LD A,0A3H ;DMA Interrupt ruecksetzen
OUT (DMAADR),A
POP AF
JR IRET
ENDC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;READY
;READY prueft die Bereitschaft des angeforderten LW mit Hilfe des
;FDC-Kommandos "Sense Drive Status" und schaltet gegebenenfalls
;den Motor ein.
;A enthaelt Laufwerksnummer
READY LD E,A
LD D,0
INC A ;LW Maske aus LW Nr. bilden
LD B,7FH
RDY0 RLC B
DEC A
JR NZ,RDY0
LD A,B
CPL
LD (DMASK),A ;LW Maske speichen
COND UDOS
LD HL,DSEL
AND (HL)
JR NZ,RDY1
BIT 7,(HL) ;INITIALISIERUNG ?
RES 7,(HL)
RET Z ;nein
RDY1 XOR (HL) ;Drive in DSEL erst einmal not ready setzen
LD (HL),A
ENDC
PUSH HL
LD HL,TTAB
ADD HL,DE
LD (HL),100 ;2 Sekunden bis Motor aus (ab OPFIN)
DI ;besser DI
IN A,(PIO2BD)
OR 0FH ;Select altes Laufwerk ruecksetzen
AND B
OUT (PIO2BD),A ;Ausgabe des "Drive select" an PIO/B
IN A,(PIO2AD)
AND B ;Motor LW an
SET 5,A ;Kopf an
OUT (PIO2AD),A
LD A,0A5H ;CTCINT fuer Motor aus programmieren
OUT (CTC0+1),A
LD A,255 ;16,3ms
OUT (CTC0+1),A
LD HL,01500H ;Warteschleife
RDY2 LD BC,0204H ;Kommando "Sense Drive Status"
CALL FDCKMD
PUSH HL
CALL RDRES
POP HL
EI
BIT 5,A
JR NZ,RDY3
DEC HL
LD A,H
OR L
JR NZ,RDY2 ;not ready
RDY3 POP HL
COND UDOS
RET Z ;LW nicht bereit
LD A,(DMASK)
OR (HL) ;bereites LW in DSEL eintragen
LD (HL),A
ENDC
RET ;mit NZ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Floppy-Typ und Format Tabellen
COND U880SM
ORG 0B24H
ENDC
TYPTAB
;Standard FM 77 Spuren 26 Sektoren a 128 Byte (Typ 1)
DEFB 6FH ;10ms, 240ms
DEFB 28H ;40ms (8MHz)
DEFB 0
DEFB 26
DEFB 07H
DEFB 128
DEFB -1
DEFB -1
DEFB 1BH
DEFB 77
DEFB 02H ;MT=0, MFM=0, SK=0, 8"=1, DSTEP=0
;Mini MFM 40 Spuren 16 Sektoren a 256 Byte (Typ 2)
DEFB 9FH ;14ms, 480ms
DEFB 14H ;40ms (4MHz)
DEFB 01H
DEFB 16
DEFB 22H
DEFB -1
DEFB 20
DEFB 29
DEFB 32H
DEFB 40
DEFB 40H ;MT=0, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM 40 Spuren auf 80 Spur Drive 16 Sektoren a 256 Byte (Typ 3)
DEFB 0BFH ;10ms (bei NEC nur 3ms erforderlich), 480ms
DEFB 12H ;36ms (fuer NEC Laufwerk)
;fuer K5600.20 nur 12ms (Kopfberuhigungzeit)
;erforderlich (DEFB 06H)
DEFB 01H
DEFB 16
DEFB 22H
DEFB -1
DEFB 35
DEFB 0FFH
DEFB 32H
DEFB 40
DEFB 41H ;MT=0, MFM=1, SK=0, 8"=0, DSTEP=1
;Mini MFM 80 Spuren 16 Sektoren a 256 Byte (Typ 4)
DEFB 0BFH ;SRT=10ms, HUT=480ms
DEFB 12H ;HLT=36ms
DEFB 01H ;N
DEFB 16 ;EOT
DEFB 22H ;GPL
DEFB -1 ;DTL
DEFB 35 ;PR 1
DEFB 0FFH ;PR 2
DEFB 32H
DEFB 80 ;Anzahl der Spuren
DEFB 40H ;MT=0, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*16 Sektoren a 256 Byte (Typ 5)
DEFB 0BFH ;10ms, 480ms
DEFB 12H ;36ms
DEFB 01H
DEFB 16
DEFB 22H
DEFB -1
DEFB 0FFH
DEFB 0FFH
DEFB 32H
DEFB 80
DEFB 0C0H ;MT=1, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*9 Sektoren a 512 Byte (Typ 6)
DEFB 0EFH ;4ms, 480ms
DEFB 08H ;16ms
DEFB 02H
DEFB 9
DEFB 1BH
DEFB -1
DEFB -1
DEFB -1
DEFB 54H
DEFB 80
DEFB 0C0H ;MT=1, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*5 Sektoren a 1024 bYTE (Typ 7)
DEFB 0EFH ;4ms, 480ms
DEFB 08H ;16ms
DEFB 03H
DEFB 5
DEFB 35H
DEFB -1
DEFB -1
DEFB -1
DEFB 74H
DEFB 80
DEFB 0C0H ;MT=1, MFM=1, SK=0, 8"=0, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*15 Sektoren a 512 bYTE (Typ 8)
;DEFB 0DFH ;3ms, 240ms
;DEFB 10H ;16ms (8MHz)
;DEFB 02H
;DEFB 15
;DEFB 1BH
;DEFB -1
;DEFB -1
;DEFB -1
;DEFB 54H
;DEFB 80
;DEFB 0C1H ;MT=1, MFM=1, SK=0, 8"=1, DSTEP=0
;Mini MFM Doppelkopf 80 Spuren 2*8 Sektoren a 1024 Byte (Typ 9)
;DEFB 0DFH ;3ms, 240ms
;DEFB 10H ;16ms (8MHz)
;DEFB 03H
;DEFB 8
;DEFB 35H
;DEFB -1
;DEFB -1
;DEFB -1
;DEFB 74H
;DEFB 80
;DEFB 0C1H ;MT=1, MFM=1, SK=0, 8"=1, DSTEP=0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;VEREINBARUNGEN
;Kommandotabelle fuer den FDC
COND 1-U880SM
FDCTAB DEFB 00H ;Command Codes (MT,MFM,SK & Read/Write)
DEFB 00H ;Bit 2,1,0: HDS,DS1,DS0
DEFB 0 ;Spur
DEFB 00H ;Kopf
DEFB 00H ;Record
DEFB 01H ;256 Byte/Sector
DEFB 16 ;EOT (last sector on track)
DEFB 0EH ;GPL (Length of gap 3)
DEFB 0FFH ;DTL (N=0 --> Data length)
PR1 DEFB 35
PR2 DEFB 45
GPL2 DEFB 32H
TRK DEFB 80
CMD DEFB 40H
;DMA-Tabelle fuer die Uebernahme/Uebergabe der Daten vom/zum FDC
DMALSW DEFB 79H ;Datenlaenge und Datenadresse ist einzutragen
DEFB 0 ;Daten-Adresse Low-Teil
DEFB 0 ;Daten-Adresse High-Teil
DEFB 0 ;Datenlaenge Low-Teil
DEFB 0 ;Datenlaenge High-Teil
DEFB 0CFH ;Laden der Adresse und Laenge
DEFB 5 ;Richtungsumkehr programmieren
DEFB 0CFH ;Laden Richtungsumkehr
DEFB 0ABH ;Interruptfreigabe fuer DMA
DEFB 87H ;DMA aktivieren
;Resultats-Tabelle der FDC-Kommandos
RESUL DEFS 7
;Motorzeittabelle
TTAB DEFB 0 ;Motor 0 aus
DEFB 0 ;Motor 1 aus
DEFB 0 ;Motor 2 aus
DEFB 0 ;Motor 3 aus
;Fehlerzaehler
WSCTR DEFB 0 ;Fehlerzaehler Sektor
WTCTR DEFB 0 ;Fehlerzaehler Spur
CRCCTR DEFB 0 ;CRC-Fehlerzaehler
DSKVSL DEFW 0 ;Disk Semaphor
INTPNT DEFW 0 ;Adresse fuer Programmfortsetzung
DMASK DEFB 0 ;LW Maske fuer Motor aus und ...
FDTYP DEFB 0
CURT0 DEFB -1 ;Tabelle der Kopfpositionen der Laufwerke
DEFB -1
DEFB -1
SPURNR DEFB 0
DEFB -1
FDCONF DEFW 0
SECERR DEFW 0
CRCERR DEFW 0
TRKERR DEFW 0
PIO2AD EQU 1CH
PIO2AC EQU 1DH
PIO2BD EQU 1EH
PIO2BC EQU 1FH
MSR EQU 20H
DATREG EQU 21H
DMAADR EQU 3CH
CTC0 EQU 08
ENDC