From 98cab31fc3659e33aef260efca55bf9f1753164c Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 11 Feb 2019 11:49:19 +0100 Subject: Add source files from Michael --- system/shard-z80-ruc-64180/1.5/src/SCSI.MAC | 1478 +++++++++++++++++++++++++++ 1 file changed, 1478 insertions(+) create mode 100644 system/shard-z80-ruc-64180/1.5/src/SCSI.MAC (limited to 'system/shard-z80-ruc-64180/1.5/src/SCSI.MAC') diff --git a/system/shard-z80-ruc-64180/1.5/src/SCSI.MAC b/system/shard-z80-ruc-64180/1.5/src/SCSI.MAC new file mode 100644 index 0000000..d77778c --- /dev/null +++ b/system/shard-z80-ruc-64180/1.5/src/SCSI.MAC @@ -0,0 +1,1478 @@ + + TITLE SCSI Interface fuer RUC 180 Karte + + INCLUDE HD64180.LIB + + .LIST + +;**************************************************************** +; +; S C S I +; +; Elementare Ein- und Ausgaben auf dem SCSI Interface +; +; Version 0.7, R. Ellerbrake +; Version 0.8 vom 31.12.86, M.Staubermann +; +; Copyright (C) 1985 by R. Ellerbrake +; +; Vers. 0.2: Kommando Transfer per DMA wieder eingebaut +; Vers. 0.3: Reset Signal implementiert +; Vers. 0.4: automatische Erkennung 40/80 Spuren Archiv +; +;**************************************************************** + +; Conditional Switches + +FALSE EQU 0 +TRUE EQU NOT FALSE + +DMA EQU TRUE ;-1 = Daten nur per DMA ausgeben +EUMEL EQU TRUE ;EUMEL Version +SEC8 EQU FALSE ;-1 = 8 Sektor Floppy +TRK40 EQU FALSE ;-1 = Voreinst. 2x40 Spuren +DEBUG EQU FALSE ; Retries bei DMA/Hardwarefehler + +;---------------------------------------------------------------- + +; Globale Adressen + + GLOBAL SCSIIO, PHYSADR, INITS + GLOBAL HDIO, FDIO, INIFLP, INITS1, PARKHD +; +;---------------------------------------------------------------- + +; Externe Adressen + + IF EUMEL + + EXTERNAL WARTE + + ENDIF + +;---------------------------------------------------------------- + +; Port-Adressen + +CIOAD EQU 52H ;Z8536 (CIO) Kanal A Daten +CIOCD EQU 50H ;Z8536 (CIO) Kanal C Daten +CIOCTL EQU 53H ;Z8536 (CIO) Control Register + +SCSIP EQU 80H ;SCSI I/O Port + +;................................................................ + +; Masken und Bits fuer CIO + +MBUSY EQU 08H ;BUSY-Signal von SCSI Schnittstelle +MMSG EQU 10H ;Message-Signal von SCSI Schnittstelle +MDC EQU 20H ;Data(0)/Command(1) Sig. von SCSI +MREQ EQU 80H ;REQ-Signal vom SCSI-Controller +MIO EQU 04H ;I/O Signal von SCSI (0=Tr. Host -> SCSI) +MSELS EQU 02H ;Select Signal zum SCSI Interface + +BSELS EQU 1 ;Bitnummern +BIO EQU 2 +BBUSY EQU 3 +BMSG EQU 4 +BDC EQU 5 +BREQ EQU 7 + +BRESS EQU 3 ;Reset-Signal fuer SCSI Controller +MRESS EQU 78H ;Maske zum Bit setzen (Bit 3) + +PCOMA EQU 8 ;Port A Command and Status + +;................................................................ + +; SCSI-Kommandos + +TST_RDY EQU 0 ;Drive Ready pruefen +RECALIBR EQU 1 ;Drive recalibrieren +REQ_STAT EQU 3 ;Fehlerstatus holen +FORMAT EQU 4 ;Diskette oder Harddisk formatieren +CHK_FORM EQU 5 ;Harddisk Format kontrollieren +FRM_TRKS EQU 6 ;Spuren formatieren +SREAD EQU 8 ;Sektoren lesen (1 od. mehrere) +SVREAD EQU 9 ;Read Verify +SWRITE EQU 10 ;Sektoren schreiben (") +SEEK EQU 11 ;Auf Block positionieren +WBUFFER EQU 15 ;Write Controller Buffer +INITDRV EQU 17 ;Disk Parameter setzen +RINIT EQU 18 ;Disk Parameter lesen +FD48TPI EQU 6*32+4 ;Floppy im Doppelstepmodus betreiben +FD96TPI EQU 6*32+3 ;Floppy im Singlestepmodus betreiben + +FDDRIV EQU 0 ;Floppy Laufwerk Nr. + +;................................................................ + +; Werte fuer SCSIIO-Aufruf + +DMATRA EQU 4000H ;Datentransfer per DMA +;DMATRA EQU 0 ;** TEST ** +RDDAT EQU 8000H ;Lesen vom Controller + +;................................................................ + +; DMA-Controller Werte + +ENABDMA EQU 90H ;Enable Kanal 1 DMA (keine Interrupts) +DISDMA EQU 10H ;Disable Kanal 1 DMA (-> DSTAT) +DE1 EQU 7 ;Bitnummer in DSTAT + +CH1MSK EQU 0F4H ;Nicht fuer Kanal 1 wichtige Bits maskieren +CHGDIR EQU 2 ;Aenderung der Transferrichtung (-> DCNTL) + +;................................................................ + +; Fehlernummern + +WPROTE EQU 13H ; Diskette Schreibgeschuetzt +TSNF EQU 14H ; Target Sector not found + +HARD EQU 0F0H ;Kennung Hardware bzw. Kommandofehler + +NOCONT EQU 0 ;SCSI-Controller nicht angeschlossen +TIMOUT EQU 1 ;Timeout Fehler bei SCSI I/O +ENDERR EQU 2 ;Falsches Kommandoende +ILLD EQU 3 ;Falsche Datenrichtung +EARLYE EQU 4 ;vorzeitiges Kommandoende +ILLCOM EQU 5 ;Fehler bei Kommandoausgabe +STRERR EQU 6 ;Fehler beim Status lesen +DMAERR EQU 7 ;Fehler beim DMA Transfer +UNKNOWN EQU 8 ;undefinierte Fehlerfaelle +MULCNT EQU 10 ; Reset nach 10 hardwarefehlern + +;---------------------------------------------------------------- + +; Lokale Daten + + DSEG + +SCSIST: DEFS 4 ;4 Byte Stati +CODALN: DEFW 0 ;Datenlaenge +SEMA: DEFB 0 ;Zugriffs-Semaphor +TOFLG: DEFB 0 ;Timeoutflag + + IF DEBUG +RETRCN: DEFB 4 ;Retry Flag +HERCNT: DEFB 10 ;Hardwarefehlerzaehler + ENDIF + + CSEG + +;**************************************************************** +; +; SCSIIO +; +; Elementare Ausgabe auf SCSI-Interface +; +; Entry: HL = Zeiger auf Datenbereich (falls vorhanden) +; DE = Zeiger auf Kommandobereich (immer 6 Byte) +; BC = Groesse des Datenbereichs (0=nicht vorhanden) +; B Bit 7: 1 = Lesen vom SCSI-Controller +; 0 = Schreiben auf SCSI-Controller +; B Bit 6: 1 = Datentransfer per DMA +; 0 = Datentransfer per Programm +; +; Exit: A = Status (0 = ok, <>0 = Fehlercode) +; alle anderen Register (ausser AF) unveraendert +; +SCSIIO: + IF DEBUG + LD A,3 ;Retries bei Unknown Error + ENDIF + +NRETSC: + IF DEBUG + LD (RETRCN),A + ENDIF + + PUSH HL + PUSH BC + PUSH DE + + CALL SCSI2 ;Kommando ausfuehren + LD L,A + AND 9FH ;Drive Code ausmaskieren + JR Z,EOCOM ;Kein Fehler -> + + CP 2 ;SCSI-Fehler ? + LD A,L + JR NZ,EOCOM ;Nein -> fertig + + POP HL ;Kommandotab.-Adr. + PUSH HL + LD A,(HL) ;altes Kommando retten + PUSH AF + LD A,HARD+STRERR ;Fehler beim Status lesen annehmen + LD (SCSIST),A + LD (HL),REQ_STAT ;Kommando 3: Request Status + EX DE,HL + LD BC,4+RDDAT ;4 Byte Status Informationen + LD HL,SCSIST ;Statusbereich + CALL SCSI2 + POP AF + POP HL + LD (HL),A ;altes Kommando zurueckschreiben + PUSH HL + LD A,(SCSIST) + RES 7,A + AND A ;Meldung: kein Fehler ? + JR NZ,EOCOM + +; kein Fehler: falsche Meldung da vorher einer aufgetreten war !! + + LD A,HARD+UNKNOWN ;unbekannnter Fehler melden + +EOCOM: + POP DE + POP BC + POP HL + + IF DEBUG + CP HARD+ENDERR + JR C,RETSCSI + + LD A,(RETRCN) + DEC A + JR NZ,NRETSC ;Retries bei "Unknown Error" + + LD A,HARD+UNKNOWN +RETSCSI: + PUSH HL + LD HL,HERCNT ;Hardware Fehler Zaehler + CP HARD ;Hardware Fehler ? + JR C,NOHER ;Nein -> + + DEC (HL) + JR NZ,EOHER ;nicht mehrere Hardwarefehler hintereinander + + LD (HL),MULCNT + PUSH AF + PUSH DE + PUSH BC + CALL INITS1 ;Schnittstelle neu initialisieren + POP BC + POP DE + POP AF + JR EOHER + +NOHER: + LD (HL),MULCNT + +EOHER: + POP HL + ENDIF + + AND A + RET + +;................................................................ +; +; SCSI2 +; +; Kommandoausgabe auf dem SCSI-Interface +; +; Entry-Parameter wie SCSIIO +; +; Exit: A = 0: alles ok +; A = 2: Fehler ist aufgetreten +; A >= F0H: Hardware oder Bedienungsfehler +; +SCSI2: + PUSH BC ;Laenge retten + +; Pruefen ob letzter DMA beendet wurde + + IN0 A,(DSTAT) ;DMA beendet ? + BIT DE1,A + JR Z,DMAOK ;Ja -> + + LD A,DISDMA ;Reset Kanal 1 DMA + OUT0 (DSTAT),A + +DMAOK: + LD BC,CIOAD ;B=0 ! + JR TENDLP + +; "Bus free", Controller selektieren + +BUSYOK: + IN A,(C) + SET BSELS,A ;Select Leitung aktivieren + OUT (C),A + RES BSELS,A ;und wieder zuruecknehmen + OUT (C),A + +; "Command Phase" + + XOR A + +WAIREQ: + PUSH AF ;Auf Kommandoanforderung warten + IN A,(C) + AND MDC+MREQ+MIO+MMSG + CP MDC+MREQ + JR Z,RDYCOM ;Ok -> + + POP AF + DEC A + JR NZ,WAIREQ + +; keine Reaktion der Schnittstelle: Versuchen Restbytes einzulesen falls +; dies nicht der 2. Timeout ist. + + LD A,(TOFLG) ;Timeoutflag gesetzt ? + AND A + LD A,HARD+TIMOUT ;Timeout Fehler + JP NZ,POPRET ;bereits gesetzt -> + + LD (TOFLG),A ;Timeoutflag setzen + +; ggf. letztes Kommando abschliessen + +TENDLP: + IN0 A,(CIOAD) ;"Bus free" ? + BIT BBUSY,A + JR Z,BUSYOK ;Ja -> neu selektieren + + CALL CHKREQ + BIT BIO,A + JR NZ,INPU + + XOR A + OUT0 (SCSIP),A + JR TENDLP + +INPU: + IN0 A,(SCSIP) + JR TENDLP + +ILLMOD: + LD A,HARD+ILLCOM ;Fehler bei Kommandoausgabe + JP POPRET + +; Kommando Ausgabe + +RDYCOM: + POP AF ;Clear Stack + LD BC,SCSIP+6*256 ;6 Bytes ausgeben + EX DE,HL + +CMNON: + CALL CHKREQ + CP MDC + JR NZ,ILLMOD ;keine Kommandoausgabe -> Fehler + + DI + OTIM ;Kommando ausgeben + EI + JR NZ,CMNON ;Nicht fertig -> + +; "Data Phase" + + POP HL ;B=0! + PUSH HL + LD A,H ;Datenlaenge = 0 ? + AND 3FH ;Bit 6 und 7 ausblenden + OR L + JP Z,NODAT ;Ja -> keine Datenphase + + IF NOT DMA + + BIT 6,H ;Datentransfer per DMA ? + JR Z,DTAPROG ;Nein -> per Programm + + ENDIF + +; CIO Pattern Match Logik aktivieren + + DI + LD C,CIOCTL ;CIO Control Register + LD A,PCOMA ;Port A Command Register + OUT (C),A + LD A,20H ;Clear IP & IUS + OUT (C),A + EI + +;* IF DMA AND EUMEL + +;* BIT 7,H ;schreiben ? +;* JR Z,POLWRIT + +;* ENDIF + +; DMA-Kanal 1 initialisieren (I/O Adresse wird in SCINIT gesetzt) + + CALL DMASTUP ;DMA-Adressen eintragen + +;* IF NOT EUMEL + + BIT 7,H ;lesen ? + JR Z,ISWRITE ;Nein -> + +;* ENDIF + + OR CHGDIR ;Richtung aendern (I/O -> Memory) + +ISWRITE: + OUT0 (DCNTL),A + LD A,ENABDMA ;DMA aktivieren + OUT0 (DSTAT),A + +; Auf Kommandoende warten +; Die CIO ist so initialisiert dass der SCSI-Status "Status lesen" +; einen Pattern Match Zustand erzeugt + +WEND2: + LD C,CIOCTL ;auf Pattern Match warten + +WAIEND: + + IN0 L,(DSTAT) ;DMA Status pruefen + DI + LD A,PCOMA ;Port A Command Register + OUT (C),A + IN A,(C) ;CIO Status lesen (Port A Statusregister) + BIT 5,A ;Interrupt pending ? + JR NZ,DATRDY ;Ja -> Datentransfer beendet + + EI + IN0 A,(CIOAD) + BIT BBUSY,A ;steht Busy noch an ? + JR Z,ILLEND + + BIT DE1,L ;DMA beendet ? + JR Z,DMAEND + +NOEND: + IF EUMEL + CALL WARTE ;andere Tasks zulassen + ENDIF + + JR WAIEND + +; Pruefen ob ein DMA-Fehler aufgetreten ist + +DMAEND: + IN0 A,(CIOAD) + + BIT BREQ,A ;Anforderung ? + JR Z,NOEND ;Nein -> warten + + AND MDC+MIO+MMSG + CP MDC+MIO ;Statusanforderung ? + JR Z,CMNST ;Ja -> alles in Ordnung + +; Fehler beim DMA-Transfer + + LD L,HARD+DMAERR + JR WENDLP + +DATRDY: + IN A,(C) ;Pattern match testen + EI + BIT 1,A + JR Z,ENDKL ;Nein -> DMA hat Status geklaut + +CMNST: + + IN0 L,(SCSIP) ;Status holen + +; Letztes Statusbyte holen (Kommandoende) + + CALL CHKREQ + IN0 H,(SCSIP) ;letzten Status einlesen (Dummy Read) + CP MDC+MIO+MMSG ;wirklich letzter Status ? + JR Z,ENDOK ;Ja -> + +ILLEND: + LD L,HARD+ENDERR + +ENDOK: + LD A,L ;Status in A + +POPRET: + POP BC + +; Interrupt Daisy Chain der CIO freigeben + + DI + LD L,PCOMA ;Port A Command + OUT0 (CIOCTL),L + LD L,20H ;Clear IP & IUS + OUT0 (CIOCTL),L + EI + RET + +ENDKL: + +; DMA anhalten falls dieser nicht beendet wurde + + LD L,DISDMA ;Reset Kanal 1 DMA + OUT0 (DSTAT),L + LD L,2 ;Error Status + +WENDLP: + IN0 A,(CIOAD) ;"Bus free" ? + BIT BBUSY,A + JR Z,ENDOK ;Ja -> fertig + + CALL CHKREQ + BIT BIO,A + JR NZ,INPU2 + + XOR A + OUT0 (SCSIP),A + JR WENDLP + +INPU2: + IN0 A,(SCSIP) ;Dummy Read + JR WENDLP + + IF NOT DMA + +; Datentransfer bei Schreiben per Programm + +POLWRIT: + CALL CHKREQ + JR NZ,NODAT ;Kein Datentransfer -> Fehler + + BIT BIO,A ;Lesen von SCSI ? + JR NZ,DIRERR ;Ja -> falsche Richtung + + LD A,(DE) ;Daten holen + OUT0 (SCSIP),A ;und ausgeben + + INC DE ;Datenadresse inkrementieren + DEC HL ;Datenlaenge dekrementieren + LD A,H ;Fertig ? + AND 3FH + OR L + JR NZ,POLWRIT ;Nein -> naechstes Byte holen + + JP WEND2 + +; Falsche Datenrichtung (falsches Kommando) + +DIRERR: + LD A,HARD+ILLD + JR POPRET + +; Datentransfer per Programm + +DTAPROG: + CALL CHKREQ + JR NZ,NODAT ;Kein Datentransfer -> Fehler + + BIT BIO,A ;Lesen von SCSI ? + JR NZ,RDSCSI ;Ja -> + + BIT 7,H ;Schreiben definiert ? + JR NZ,DIRERR ;Nein -> falsche Richtung !! + + LD A,(DE) ;Daten holen + OUT0 (SCSIP),A ;und ausgeben + + JR CMDIO + +RDSCSI: + BIT 7,H ;Lesen definiert ? + JR NZ,RDSOK ;Ja -> + +; Falsche Datenrichtung (falsches Kommando) + +DIRERR: + LD A,HARD+ILLD + JR POPRET + +RDSOK: + IN0 A,(SCSIP) ;Daten holen + LD (DE),A + +CMDIO: + INC DE ;Datenadresse inkrementieren + DEC HL ;Datenlaenge dekrementieren + LD A,H ;Fertig ? + AND 3FH + OR L + JR NZ,DTAPROG ;Nein -> naechstes Byte holen + + ENDIF + +; Status lesen + +NODAT: + CALL CHKREQ + CP MDC+MIO ;Status Anforderung ? + JR NZ,ILLEND ;Nein -> Fehler + JR CMNST + +;................................................................ +; +; Pruefen ob Busy und Request anstehen +; +; Exit: A = CIO Port A SCSI-Status Leitungen (ohne BUSY und REQ) +; F = Z: Datentransfer +; +CHKREQ: + IN0 A,(CIOAD) + BIT BBUSY,A ;Busy aktiv ? + JR Z,INCOMPL ;Nein -> vorzeitiges Kommandoende + + BIT BREQ,A ;Anforderung ? + JR Z,CHKREQ ;Nein -> warten + + AND MDC+MIO+MMSG + BIT BDC,A + RET + +INCOMPL: + POP HL ;Skip Return Adresse + LD A,HARD+EARLYE ;vorzeitiges Ende + JR POPRET + +;................................................................ +; +; DMASTUP +; +; Adressen des DMA-Kanals 1 eintragen +; +; Entry: DE = log. Adresse +; DE = 0: auf 6502 Bereich FC00 schalten +; +; Exit: A = (DCNTL) Kanal 1 +; +DMASTUP: + DI + LD A,D + OR E + JR NZ,DOCHG + + LD A,6 + LD D,0FDH ; 6FD00..6FEFF ist SCSI-Puffer + JR NOCHG + +DOCHG: + CALL PHYSADR ;Physikalische Adresse bestimmen (in ADE) + +NOCHG: + LD C,MAR1L ;Adressen eintragen + OUT (C),E ;Speicheradresse eintragen (LSB) + INC C + OUT (C),D ;mittleres Byte + INC C + OUT (C),A ;upper Byte + LD C,BCR1L + OUT (C),L ;Byte Zaehler (LSB) + INC C + LD A,H + AND 3FH + OUT (C),A ;MSB + + IN0 A,(DCNTL) ;DMA-Richtung setzen + AND CH1MSK ;nur DMA-Kanal 1 Bits veraendern ! + EI + RET + +;................................................................ +; +; P H Y S A D R +; +; Umrechnung der logischen in eine physikalische Adresse +; +; Entry: DE = logische Adresse im 64K Adressraum +; +; Exit: DE = niederwertiger Teil der phys. Adr. im 512K Adr.-raum +; A = hoechstwertiges Nibble der phys. Adr. +; alle anderen Register bleiben unveraendert +; +PHYSADR: + INC D ;Fuer Vergleiche + IN0 A,(CBAR) ;Common Bank Area Register + PUSH AF + AND 0F0H ;Common Area Teil ausmaskieren + CP D ;D >= Common Area 1 Anfang ? + JR C,COMA1 ;Ja -> (Stack!!) + + POP AF + AND 0FH ;Bank Area Teil ausmaskieren + RLCA + RLCA + RLCA + RLCA ;und ins MSN schieben + CP D ;D >= Bank Area Anfang ? + JR C,BAR ;Ja -> + +; Common Area 0 (unveraenderte Adresse) + + DEC D ;D wieder korrigieren + XOR A + RET + +; Bank Area + +BAR: + DEC D + IN0 A,(BBR) ;Bank Base Register + +CMND: + PUSH BC + LD B,0 + SLA A + RL B + SLA A + RL B + SLA A + RL B + SLA A + RL B ;B = MSN Phys. Adr., A = mittleres MSB + + ADD A,D ;+ Offset zum Area Anfang + LD D,A ;wieder in D (mittleres MSB der phys. Adr.) + LD A,B ;A = MSN + ADC A,0 ;ggf. 64K-Uebertrag beruecksichtigen + POP BC + RET + +; Common Area 1 + +COMA1: + DEC D ;D wieder korrigieren + POP AF ;Clear Stack + IN0 A,(CBR) + JR CMND + + IF EUMEL + +;................................................................ +; +; C H K A C C +; +; Auf Freiwerden des SCSI-Controllers warten +; +CHKACC: + LD A,(SEMA) ;SCSI-Zugriffssemaphor + AND A ;0=frei + JR Z,ISFREE ;Ja -> + CALL WARTE + JR CHKACC + +ISFREE: + DEC A + LD (SEMA),A ;Semaphor sperren + RET + + ENDIF + +;................................................................ +; +; I N I T S +; +; Initialisierung der SCSI-Schnittstelle +; +; CIO und DMA Kanal 1 werden initialisiert +; Floppy Parameter werden gesetzt +; +; Exit: AF', BC, DE und HL werden veraendert +; AF = Status des Floppy Parameters setzens +; +INITS1: + IF NOT EUMEL + CALL INICIO + ENDIF + +INITS: + IF EUMEL + XOR A + LD (SEMA),A ;Semaphor initialisieren + ENDIF + + LD C,DISDMA + OUT0 (DSTAT),C ;Kanal 1 stoppen, beide Kanaele keine + ; Interrupts zulassen + +; DMA - Kanal 0 intialisieren (Memory <--> Memory Transfer) + + LD C,2 ; Memory <--> Memory im Burst Mode + OUT0 (DMODE),C + +; DMA - Kanal 1 initialisieren (Memory <--> SCSI I/O - Transfer) + + LD BC,SCSIP ;DMA-Kanal 1 I/O Adresse auf SCSI setzen + OUT0 (IAR1L),C + OUT0 (IAR1H),B + +; Warten bis Harddisk hochgelaufen ist + + IF NOT EUMEL +WRTHRD: + LD DE,TESTRD + LD BC,0 + CALL SCSIIO + AND A ;Drive not Ready ? + JR NZ,WRTHRD ;Ja -> warten + + ENDIF + +; Teil der bei Controller RESET neu initialisert werden muss + +SCINIT: + +; Floppy Parameter setzen + + LD DE,FLPINI ;Initialize Kommando + LD HL,FLPDAT ;Parameter + LD BC,PARALNG ;Anzahl der Parameter Bytes + CALL SCSIIO + + LD L,A + LD A,(FLPTRKS) + CP 40 ;40 Tracks ? + LD A,L + LD BC,0 + LD DE,SGLSTEP ; Floppy im Doppelstep Modus + JR NZ,NODBLS ;Nein -> kein Double Step + LD DE,DBLSTEP +NODBLS: + JP SCSIIO + +;................................................................ +; +; I N I C I O +; + IF NOT EUMEL +INICIO: + DI + +; CIO initialisieren + + IN0 C,(CIOCTL) ;Dummy Read + LD B,INILNG + LD HL,INITAB ;CIO Initialisierungstabelle + +INILOP: + LD C,(HL) ;Wert holen + OUT0 (CIOCTL),C ;und ausgeben + INC HL + DJNZ INILOP + RET + ENDIF + +;................................................................ +; +; P A R K H D +; +; Harddisk in Parkposition fahren +; +PARKHD: + + LD BC,0 + LD DE,PARSEK ; seek (0) + CALL SCSIIO + LD DE,RECAL ; Recalibrate + JP SCSIIO + + IF 0 + LD HL,INIHDT + LD DE,RDINI + LD BC,RDDAT+PARALNG + + CALL SCSIIO ;Harddisk Konfiguration lesen + + LD HL,(INIHDT) ;Spuranzahl (H=LSB!) + PUSH HL + INC H ;um 1 erhoehen + JR NZ,INCOK + + INC L +INCOK: + LD (INIHDT),HL + LD HL,RDINI + LD DE,INIHDT + LD (HL),INITDRV ;Init-Schreibkommando eintragen + EX DE,HL + LD BC,PARALNG + + CALL SCSIIO ;neue, groessere, Konfiguration setzen + + POP HL + + LD D,L + LD L,H + LD H,D ;Spuranzahl richtig + LD A,(INIHDT+2) ;Kopfanzahl + LD E,L + +HDLOP: + DEC A + JR Z,HDAOK + + ADD HL,DE + JR HDLOP + +HDAOK: + XOR A + ADC HL,HL + RLCA + ADC HL,HL ;*4 + RLCA + ADC HL,HL ;*8 + RLCA + ADC HL,HL ;*16 + RLCA + ADC HL,HL ;*32 + RLCA + +; max. Blocknr. in AHL + + DEC HL ;-1: 1.Block hinter formatiertem Bereich + + LD (BKNR),A + LD A,L + LD L,H + LD H,A + + LD (BKNR+1),HL ;Blocknr. eintragen + LD BC,0 ;keine Daten + LD DE,PARSEK + + JP SCSIIO ;Drive parken + + ENDIF + +;................................................................ +; +; H D I O +; +; Lesen / Schreiben eines Blocks (512 Byte) auf der Harddisk +; +; Entry: A = Kommandocode (0 = Lesen, 1 = Schreiben) +; HL = Hauptspeicheradresse +; BC = Pointer auf Drive und Offset (256 Byte Bloecke) +; DE = (512 Byte-) Blocknummer (ohne Offset) +; +; BC + 2 -> Low (Block Offset) +; BC + 1 -> Middle (Block Offset) +; BC + 0 -> High (BLock Offset) + Drive * 32 +; +; Exit: A = Status (0=ok, sonst SCSIIO-Fehlercode) +; BC, DE, HL, AF' = veraendert +; +FDIO: +HDIO: + PUSH AF + XOR A + LD (TOFLG),A ;Timeoutflag ruecksetzen + + IF EUMEL + + CALL CHKACC ;Pruefen ob SCSI-Controller bereits belegt ist + + ENDIF + + LD A,(BC) + BIT 6,A ;Floppy Drive ? + JP NZ,FDIO1 ;Ja -> + + POP AF + + CP 2 + JR C,COMOK1 + + LD A,20H ;illegal Command Code + RET + +COMOK1: + PUSH HL + PUSH BC + CALL CMSCOM ;Kommandonr. umrechnen + LD (HDIOTB),A ;Kommando eintragen + POP BC + LD HL,(CODALN) ;Datenlaenge + PUSH HL + LD HL,HDIOTB+3 ;Harddisk Read Command + + SLA E ;Blocknummer * 2 (256 Byte Bloecke) + RL D + +CMFDIO: + INC BC + INC BC + LD A,(BC) ;Low Offset + ADD A,E ;+ Low Block No. + LD (HL),A ;eintragen + DEC HL + DEC BC + LD A,(BC) ;Middle Offset + ADC A,D ;+ Block No. + LD (HL),A + DEC HL + DEC BC + LD A,(BC) + LD (HL),A ;Drive + High Blocknr. + DEC HL + EX DE,HL ;DE = Read Command Adresse + POP BC ;Datenlaenge + POP HL ;Hauptspeicheradresse + CALL SCSIIO + + IF EUMEL + + PUSH AF + XOR A + LD (SEMA),A ;Semaphor freigeben + POP AF + + ENDIF + + RET + +;................................................................ +; +; I N I F L P +; +; Blockanzahl der Floppy ermitteln (nur BC, A und HL veraendern !!) +; +; Eingang:A = Anzahl Spuren, Voreinstellung (40 oder 80) +; Exit: BC = Blockanzahl der Floppy (in 512 Byte Bloecken) +; A = 0 = ok, <> 0 = SCSI-Fehlercode +; +INIFLP: + PUSH AF ; Anzahl Spuren Voreinstellung (40, 80) + + IF EUMEL + CALL CHKACC ;keine Doppelzugriffe !! + ENDIF + + XOR A + LD (TOFLG),A ;Timeoutflag ruecksetzen + POP AF + + PUSH HL + PUSH DE + + LD (FLPTRKS),A ;Spuren eintragen + CALL SCINIT ;Floppy Parameter setzen + + LD A,2 ;Retry-Anzahl +RETR1: + PUSH AF + + LD DE,SEK18 ; Auf Block 18 (Track 2) + LD BC,RDDAT+512 + LD HL,0 + LD A,1 + CALL NRETSC ;Read ohne Retries + + AND 7FH + LD C,A + JR Z,OKA ; Format ok + + CP TSNF ; Target Sector not found ? + CALL Z,TOB ; anderes Format (B) versuchen + + POP AF ; Anderer Floppy Fehler, Retries + DEC A + JR NZ,RETR1 + + XOR A + LD (SEMA),A + + LD A,C ; permanenter Fehler + + LD BC,0 + POP DE + POP HL + RET + +; auf B Spuren umschalten + +TOB: + LD A,(FLPTRKS) + XOR 01111000B ; aus 40 wird 80, aus 80 wird 40 + LD (FLPTRKS),A + CALL SCINIT ;Floppy Parameter setzen + LD C,TSNF + RET + +OKA: + POP AF + POP DE + POP HL + + LD BC,(FLPTRKS) + + IF SEC8 + LD B,8 + ELSE + LD B,9 + ENDIF + + MLT BC + SLA C ;*2: 2 Seiten + RL B + XOR A + + IF EUMEL + LD (SEMA),A ;Sempahor wieder freigeben + ENDIF + + RET + +;................................................................ +; +; F D I O +; +; Lesen oder Schreiben eines Blocks (512 Byte) auf der Floppy Disk +; +; Entry: A = Kommandocode (0=Lesen, 1=Schreiben, 2=Formatieren) +; HL = Hauptspeicheradresse +; BC = Pointer auf Drive und Offset (512 Byte Bloecke) +; DE = (512 Byte-) Blocknummer (ohne Offset) +; +; BC + 2 -> Low (Block Offset) +; BC + 1 -> Middle (Block Offset) +; BC + 0 -> High (BLock Offset) + Drive * 32 +; +; Exit: A = Status (0=ok, sonst SCSIIO-Fehlercode) +; BC, DE, HL, AF' = veraendert +; +FDIO1: + POP AF + CP 3 + JR C,COMOK + + LD A,20H ;illegal Command Code + RET + +COMOK: + PUSH HL + PUSH BC + CP 2 + + CALL Z,SW80 ;Beim Formatieren immer 2x80 Spuren + + CALL CMSCOM ;Kommando und Datenlaenge best. + LD (FDIOTB),A ;Kommandocode eintragen + + LD A,C + LD (FDIOTB+4),A ;Block Count / Skew Faktor eintragen + +; DE enthaelt Blocknummer x aus EUMEL-Sicht. +; Block x meint die 512 Bytes ab 512*x auf Floppy. +; +; Aus Blocknummer: Spur, Sector, Seite berechnen +; +; EUMEL behandelt, im Gegensatz zum SCSI-Controller, +; zunaechst die Oberseite der Floppy und erst dann die Unterseite. + + LD H,D + LD L,E + XOR A + + IF SEC8 + LD DE,8 + ELSE + LD DE,9 ;Anzahl der Sektoren pro Spur + ENDIF + +DIVLOP: + AND A + SBC HL,DE + JR C,DIVDON + INC A + JR DIVLOP + +DIVDON: + ADD HL,DE + +; A = Spurnummer; HL = sector/seite + + LD BC,(FLPTRKS) ;Spuren pro Seite (B undefiniert !) + CP C ;Rueckseite ? + JR C,NOBACK ;Nein -> alles ok + +; Rueckseite: Spurnummer := Spurnummer - Spuranzahl +; Sektornummer := Sektornummer + Sektoranzahl (9) + + SUB C ;tatsaechliche Spurnummer + ADD HL,DE ;HL = sector (cylinder) + +; SCSI Blocknummer aus Spur und Sektor ausrechnen + +NOBACK: + LD D,A + + IF SEC8 + LD E,16 + ELSE + LD E,18 + ENDIF + + MLT DE ;DE = Spur * 18 + ADD HL,DE ;HL = Spur * 18 + Sektor (cylinder) + EX DE,HL + +; SCSI Blocknummer in DE + + POP BC ;Offsetadresse wiederherstellen + + LD HL,(CODALN) + PUSH HL + LD HL,FDIOTB+3 ;Floppy Read Command + JP CMFDIO + +SW80: + PUSH AF + PUSH BC + PUSH DE + PUSH HL + + LD A,80 ; 80 Tracks + LD (FLPTRKS),A + CALL SCINIT + + POP HL + POP DE + POP BC + POP AF + RET + +;................................................................ +; +; C M S C O M +; +; Entry: A = Funktionsnr. +; +; Exit: A = SCSI-Kommandonr. +; C = Block Count / Skew Faktor +; HL = veraendert +; B = veraendert +; (CODALN) = Datenlaenge +; +CMSCOM: + LD BC,LGTAB ;Datenlaenge ermitteln + LD L,A + LD H,0 + ADD HL,HL ;16 Bit Werte + ADD HL,BC + LD C,(HL) + INC HL + LD B,(HL) + LD (CODALN),BC + + LD HL,COMTB ;Kommandonr. umrechnen + ADD A,L + LD L,A + LD A,H + ADC A,0 + LD H,A + LD A,(HL) ;SCSI-Kommando holen + + LD BC,BCSKTB-COMTB + ADD HL,BC + LD C,(HL) ;Block Count ./. Skew Faktor holen + + RET + +;**************************************************************** +; +; SCSI-Kommandotabellen +; +; Achtung: Die Schreib- und Lesetabellen werden vom Programm +; geaendert (muessen im RAM stehen) +; +COMTB: + DEFB SREAD ;Lesekommando + DEFB SWRITE ;Schreibkommando + DEFB FORMAT ;Formatierkommando + +LGTAB: + DEFW 512+DMATRA+RDDAT ;Datenlaenge Lesen + DEFW 512+DMATRA ;Datenlaenge schreiben + DEFW 0 ;Datenlaenge formatieren + +BCSKTB: + DEFB 1 ;1 Block lesen (nur Floppy) + DEFB 1 ;1 Block schreiben (") + DEFB 4 ;Skew 4 (nur Floppy) + +;................................................................ +; + IF NOT EUMEL +TESTRD: + DEFB 0,0,0,0,0,0 ;Test Ready (Harddisk) + ENDIF + + +FDIOTB: ;Lesen / Schreiben auf Floppy Disk + DEFB SREAD ;Lesekommando (wird ueberschrieben) + DEFB FDDRIV*32+40H ;Floppy Drive (wird ueberschrieben) + DEFB 0, 0 ;Block Middle und Low (") + DEFB 1 ;Block Count / Interleave (Format) + DEFB 80H ;keine Retries + + +HDIOTB: ;Lesen / Schreiben auf Harddisk + DEFB SREAD ;Lesekommando (wird ueberschrieben) + DEFB 0 ;Harddisk Drive (wird ueberschrieben) + DEFB 0, 0 ;Block Middle und Low (") + DEFB 2 ;Block Count + DEFB 0H ;Retries + + IF 0 +RDINI: + DEFB RINIT ;Harddisk Konfiguration lesen + DEFB 0 ;Harddisk Drive + DEFB 0,0,0,0 +INIHDT: + DEFB 0,0,0,0,0 + DEFB 0,0,0,0,0 + ENDIF + + +RECAL: + DEFB RECALIBR ;Drive recalibrieren + DEFB 0 ; Harddisk + DEFB 0,0,0,80H ; keine Retries + + +PARSEK: + DEFB SEEK + DEFB 0 ;Harddisk + DEFB 0,0,0 + DEFB 80H ;keine Retries + + +FLPINI: ;Setze Floppy Parameter + DEFB INITDRV ;Initialize Kommando + DEFB FDDRIV*32+40H ;Floppy Drive + DEFB 0, 0, 0, 0 ;nicht benutzt +FLPDAT: ;Floppy Disk Parameter zu INIFLP + DEFB 0 +FLPTRKS: + IF TRK40 + DEFB 40 ;Spuranzahl + ELSE + DEFB 80 + ENDIF + + DEFB 2 ;2 Koepfe (doppelseitig) + DEFB 1*16+3 ;4 ms Steprate, MFM + DEFB 3 ;512 Byte/Sektor + DEFB 15 ;Head Unload Time (240ms) + DEFB 10 ;Motor Start Time (0.1 s) + DEFB 23 ;Head Load Time (46 ms) + DEFB 3 ;Motor off time (3 s) + IF SEC8 + DEFB 0 ;8 Sektoren/Spur + ELSE + DEFB 1 ;9 Sektoren/Spur + ENDIF + +PARALNG EQU $-FLPDAT + + +DBLSTEP: + DEFB FD48TPI ;Doppel Step aktivieren + DEFB FDDRIV*32+40H ;Floppy Drive + DEFB 0, 0, 0, 0 ;nicht benutzt + + +SGLSTEP: + DEFB FD96TPI ;auf Single Step zurueckschalten + DEFB FDDRIV*32+40H + DEFB 0, 0, 0, 0 ;nicht benutzt + + +SEK18: + DEFB SREAD ;auf Block positionieren + DEFB FDDRIV*32+40H ;Floppy Drive + DEFB 0,18,1,80H ;Track 2, ein Block, keine Retries + + +;........................................................................... +; +; CIO Initialisierungs Tabelle +; + + IF NOT EUMEL + +INITAB: +;* DEFB 0,1 ;Set Reset Bit + DEFB 0,0 ;Reset Reset Bit + DEFB 1,0 ;Master configuration control + +; SCSI-Interface-Leitungen + + DEFB 20H,00000010B ;Port A Mode Reg. + DEFB 22H,01000010B ;Port A Data Path Polarity Reg. + DEFB 23H,10111101B ;Port A Data Direction Reg. + DEFB 24H,0 ;Port A Special I/O Control + DEFB 25H,10101100B ;Port A Pattern Polarity + DEFB 26H,0 ;Port A Pattern Transition + DEFB 27H,10101100B ;Port A Pattern Mask + DEFB 0DH,0 ;Port A Data + DEFB 02H,18H ;Port A Interrupt Vector (** TEST **) + DEFB PCOMA,11100000B ;Port A Command: Clear IE + DEFB PCOMA,00100000B ;Port A Command: Clear IUS & IP + +; General Purpose Port (Centronics, SCSI, 6502-IRQ-Maske) + + DEFB 06H,00000001B ;Port C Data Direction Reg. + DEFB 05H,00001000B ;Port C Data Path Polarity Reg. + DEFB 07H,0 ;Port C Special I/O Control + DEFB 0FH,4 ;Port C Data Register + +; Centronics Interface + + DEFB 28H,10010000B ;Port B Mode + DEFB 29H,01000000B ;Port B Handshake: Strobed + DEFB 09H,00100000B ;Port B Command: Clear IUS & IP + DEFB 2AH,0 ;Port B Data Path Polarity + DEFB 2CH,0 ;Port B Special I/O Control + DEFB 03H,30H ;Port B Interrupt Vektor + +; Deskew Timer + + IF 0 + DEFB 1EH,00000010B ;Counter 3 Mode Specification + DEFB 0CH,00100000B ;Counter 3 Command and Status + DEFB 1AH,0 ;Counter 3 Time Constant MSB + DEFB 1BH,7 ;Counter 3 Time Constant LSB (2,268 us) + DEFB 0CH,11100100B ;Counter 3 Gate Enable + ENDIF + +; Timer + + DEFB 1CH,10000000B ;Counter/Timer 1 Mode Spec. Reg. + DEFB 1DH,10000000B ;Counter/Timer 2 Mode Spec. Reg. + DEFB 0AH,00100000B ;Counter/Timer 1 Command: Clear IP & IUS + DEFB 0BH,00100000B ;Counter/Timer 2 Command: Clear IP & IUS + DEFB 16H,HIGH 38400 ;Time Constant 1 MSB + DEFB 17H,LOW 38400 ;Time Constant 1 LSB + DEFB 18H,0 ;Time Constant 2 MSB, mit Timer 1 zus. 50ms + DEFB 19H,4 ;Time Constant 2 LSB + DEFB 04H,18H ;Interrupt Vector Counters + +; CIO-Interrupts freigeben + + DEFB 01H,11110111B ;Master Config. Register + DEFB 00H,10000010B ;Master Interrupt Enable + + DEFB 09H,11000000B ;Port B Command: Set IE + + DEFB 0BH,11000110B ;Counter/Timer 2 Command: Set IE + DEFB 0AH,11100110B ;Counter/Timer 1 Command: Clear IE + +INILNG EQU $-INITAB + ENDIF + + +;**************************************************************** + + END + \ No newline at end of file -- cgit v1.2.3