P8000/UDOS/WEGA/K.BLK.S

485 lines
8.9 KiB
ArmAsm

;*************************************************************
;
; P8000 KOPPELSOFTWARE
; MODUL: BLOCK-FLOPPY E/A
; VERSION: 3.0
;
;*************************************************************
GLOBAL BLKRD BLKWT BLKFO
GLOBAL RBLOCK WBLOCK
GLOBAL BLKINIT
EXTERNAL SNDNET SNDACK LODNET
EXTERNAL SNDDAT LODDAT
EXTERNAL WAIT UEB16
EXTERNAL BUF
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Initialisierung der Floppy-Formate 2 und 4
BLKINIT:
ld de,TYP2 ;Typ 2 wird 48ds16
ld hl,TYP5
ld bc,11
ldir
ld de,TYP4 ;Typ 4 wird 48ds5
ld hl,TYP7
ld bc,11
ldir
ld l,40 ;Anzahl der Spuren
ld h,0c1h ;MT=1, MFM=1, SK=0, 8"=0, DSTEP=1
ld (TYP2+9),hl
ld (TYP4+9),hl
ld hl,(TYP5) ;Typ 3 fuer MF 1.6 optimieren
ld (TYP3),hl ;LW-Zeiten
ld hl,-1 ;PR1/PR2
ld (TYP3+6),hl
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ZEITGETEILTER FLOPPY ZUGRIFF
DISK: LD IY,RQVEC
CALL FLOPPY
DLOOP: CALL UEB16
LD A,(IY+10)
BIT 7,A ;FERTIG ?
JR Z,DLOOP
BIT 6,A
DEND: RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;mehrere Bloecke lesen / schreiben mit Spurwechsel
DISKRQ: ld hl,(RESID)
ld a,h
or l
ret z ;Fertig
call BCOUNT
ex de,hl ;DE Laenge bis Ende der Spur
ld hl,(RESID)
or a
sbc hl,de
jr nc,DB1
ld hl,(RESID) ;RESID < BCOUNT
ld (RQLEN),hl
ld hl,0
DB1: ld (RESID),hl
call DISK
ret nz ;Fehler
ld hl,RQDA ;naechste Spur
ld a,(hl)
and 0e0h ;Sektor auf 0
ld (hl),a
inc hl
inc (hl) ;Track increment
ld hl,(RQADR)
ld de,(RQLEN)
add hl,de
ld (RQADR),hl
jr DISKRQ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;BLOCK LESEN:
RBLOCK: LD A,0BH ;READ BINARY
JP KOPF ;KOPFINFORMATIONEN UEBERNEHMEN
BLKRD: RES 0,(HL) ;RESET READ BIT IM STATUS
CALL DISKRQ
JR NZ,ERROR
CALL SNDACK
LD DE,(LEN) ;DATEN UEBERMITTELN
LD HL,BUF
BLKRLP: LD A,(HL)
CALL SNDDAT
INC HL
DEC DE
LD A,D
OR E
JR NZ,BLKRLP
WATACK: CALL LODDAT
JR Z,WATACK ;WARTEN AUF ACK
JR BRWEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;BLOCK SCHREIBEN:
WBLOCK: LD A,0FH ;WRITE BINARY
CALL KOPF ;KOPFINFORMATIONEN UEBERNEHMEN
LD DE,(LEN) ;DATEN EINLESEN
LD HL,BUF
BLKWLP: CALL LODDAT
JR Z,BLKWLP
LD (HL),A
INC HL
DEC DE
LD A,D
OR E
JR NZ,BLKWLP
RET
BLKWT: RES 1,(HL) ;RESET WRITE-BIT IM STATUS
CALL DISKRQ
JR NZ,ERROR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; BLOCK READ/WRITE Ende
FEND: LD A,ACK
ERROR: CALL SNDNET
BRWEND LD HL,(SAVEFD) ;ALTE WERTE RUECKSCHREIBEN
LD (FDCONF),HL
LD HL,0C050H ;ALTE WERTE FUER TABELLE NR.6
LD (TYP6+9),HL ;WIEDER EINTRAGEN (STANDARD-NR.6)
JP WAIT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;UEBERNAHME KOPFINFORMATIONEN
KOPF: LD (RQCOD),A ;REQUEST-CODE
WAFI: CALL LODDAT
JR Z,WAFI ;1.BYTE ENTHAELT IM OBEREN NIBBLE FLOPPY-TYP
;UND IM UNTEREN NIBBLE DRIVE-NR.
ld hl,(FDCONF) ;Retten FDCONF
ld (SAVEFD),hl
CALL TYP
WABN1: CALL LODDAT
JR Z,WABN1
LD D,A ;BLOCK-NR. HIGH-BYTE
WABN2: CALL LODDAT
JR Z,WABN2
LD E,A ;BLOCK-NR. LOW-BYTE
CALL BLOCK ;KONVERTIERUNG IN SPUR/SEKTOR
WAL1: CALL LODDAT
JR Z,WAL1
LD H,A ;LENGTH HIGH-BYTE
WAL2: CALL LODDAT
JR Z,WAL2
LD L,A ;LENGTH LOW-BYTE
LD (LEN),HL
LD (RESID),HL
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TYP: ;Setzen FDCONF und Drive
ld hl,BUF
ld (RQADR),hl ;Pufferadr setzen
push af
and 0f0h ;Typ
ld e,a
pop af
rrca
rrca
rrca
push af
and 0e0h
ld (RQDA),a ;DRIVE-NR.
pop af
rrca
and 0fh ;Typ
ld b,a
or e
ld e,a
ld d,a
ld hl,OLDTYP ;hat sich Typ geaendert ?
cp (hl)
jr z,T0 ;nein
ld (hl),a
ld hl,PFDTYP ;Floppy-Treiber muss neuen
ld (hl),0 ;Typ initialisieren
T0: cp 88h ;Standardtypen
jr c,T1
ld de,6666H ;andere Typen auf Tabelle 6 abbilden
ld b,6
jr z,FD48DS ;Typ 8
cp 99h
jr z,FD48SS ;Typ 9
cp 0aah
jr z,FD96SS ;Typ10
;alle restlichen werden auf 6 gesetzt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ADRESSE DER TABELLE DER FDTYP-DEFINITIONEN ERMITTELN
T1: ld (FDCONF),de
push ix
ld ix,TYPTAB-11
ld de,11 ;LAENGE EINES TYPTAB-EINTRAGS
T2: add ix,de
djnz T2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Diskparameter ermitteln
ld a,(ix+3) ;Anzahl Sektoren pro Spur und Seite
ld (NSECT1),a
ld l,0
bit 7,(ix+10) ;SS / DS
jr z,T3
add a,a ;DS
inc l
T3: ld (NSECT),a ;Anzahl der Sektoren
ld a,l
ld (DOUBLE),a ;0=SS 1=DS
ld a,(ix+2) ;Sektorlaenge
ld (SECLEN),a
ld a,(ix+9) ;Anzahl der Spuren
ld (NTRACK),a
pop ix
ret
FD96SS: LD HL,4050H ;AUSFUEHREN DER ENTSPR. AENDERUNGEN
LD (TYP6+9),HL ;IN DER FLOPPY-TYP TABELLE NR.6
JR T1
FD48DS: LD HL,0C128H
LD (TYP6+9),HL
JR T1
FD48SS: LD HL,4128H
LD (TYP6+9),HL
JR T1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;UMWANDLUNG BLOCK-NR. IN SPUR- UND SEKTOR-NR. UND SETZEN IM REQUEST-VEKTOR
;DIVIDEND IN AE, DIVISOR IN C
BLOCK: ex de,hl ;de Blocknummer
ld a,(SECLEN)
or a
jr z,BLOCK1 ;1 Block = 4 Sektoren
dec a
jr z,BLOCK2 ;1 Block = 2 Sektoren
dec a
jr z,BLOCK3 ;1 Block = 1 Sektor
dec a
jr nz,BLOCK3 ;unzulaessige Laenge
srl h ;/2 1 Block = 1/2 Sektor
rr l
jr BLOCK3
BLOCK1: add hl,hl
BLOCK2: add hl,hl
BLOCK3: ld a,(NSECT) ;Anzahl der Sektoren
ld c,a
ld a,h ;hl (n. Sektor) -> ae
ld e,l
call DV168 ;QUOTIENT IN E (SPUR-NR.)
;Rest in A = Sektornummer
ld hl,RQDA
or (hl) ;+ DRIVE
ld (hl),a
inc hl
ld (hl),e ;SPUR-NR.
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Integer Division
;Divident in AE, Divisor in C, Quotient in E, Rest in A
DV168: CP C
CCF
RET C
LD B,8
JR DV163
DV161: SUB C
DV162: SCF
DEC B
JR Z,DV165
DV163: RL E
RLA
JR C,DV161
SUB C
JR NC,DV162
ADD A,C
AND A
DJNZ DV163
DV165: RL E
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;BLOCK FORMAT / VERIFY / COPY DISK
BLKFO: ld a,(hl)
ld (BLKREQ),a
ld (hl),0
ld hl,(FDCONF) ;Retten FDCONF
ld (SAVEFD),hl
bit 4,a ;COPY DISK ?
jr z,BLKF1
BLKF0: call LODNET
jr z,BLKF0
ld (STYP),a ;SOURCE-Typ
BLKF1: CALL LODNET
JR Z,BLKF1 ;STATUS-BYTE (FD-TYP + DRIVE)
ld (DTYP),a ;SOURCE-Typ
CALL TYP ;SETZEN FDCONF UND DRIVE-NR.
LD HL,-1 ;POSITIONIERUNG AUF SPUR 0
LD (CURT0),HL
LD (CURT0+2),HL
XOR A
LD (RQDA+1),A ;TRACK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Diskette formatieren
FORMAT: ld a,(BLKREQ)
bit 3,a
jr nz,VERIFY ;nur Verify
LD A,51H ;Requestcode fuer Format
LD (RQCOD),A
LD E,0 ;Seite 1
CALL FBUILD
CALL DISK ;1 SPUR FORMATIEREN
JP NZ,ERROR
LD A,(DOUBLE)
OR A
JR Z,COPYDISK ;SS
LD E,1 ;Seite 2
CALL FBUILD
LD HL,RQDA
LD A,(HL)
OR C ;& SEKTOR NR FUER 2.SEITE
LD (HL),A ;AB SEKTOR 0 2. SEITE
CALL DISK ;1 SPUR FORMATIEREN
JP NZ,ERROR
LD HL,RQDA ;Sektor wieder auf 0
LD A,(HL)
AND 0E0H ;Sektor auf 0
LD (HL),A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;COPY DISK
COPYDISK:
ld a,(BLKREQ)
bit 4,a
jr z,VERIFY ;kein COPY DISK
ld a,(STYP) ;Quelldiskette Lesen
call TYP
ld a,0bh
ld (RQCOD),a ;Requstcode
call BCOUNT
call DISK
set 5,a ;in Fehlercode Source markieren
jp nz,ERROR
ld a,(DTYP) ;Zieldiskette Schreiben
call TYP
ld a,0fh
ld (RQCOD),a ;Requstcode
call DISK
jp nz,ERROR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DISKETTE VERIFY
VERIFY: LD A,0BH
LD (RQCOD),A ;Requstcode
CALL BCOUNT
CALL DISK
JP NZ,ERROR
LD HL,RQDA+1 ;TRACK
INC (HL) ;NAECHSTE SPUR
LD A,(NTRACK)
CP (HL)
JP NZ,FORMAT
JP FEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Format Daten aufbauen
FBUILD: LD HL,(NSECT1) ;ANZAHL DER SEKTOREN 1 SEITE
LD B,L
LD C,L
LD H,0
ADD HL,HL ;*2
ADD HL,HL ;*4 (4 BYTE JE SEKTOR AN FDC)
LD (RQLEN),HL
LD HL,BUF ;FORMAT DATEN AUFBAUEN
LD D,1 ;1. SEKTOR
FLOOP1: LD A,(RQDA+1) ;TRACK
LD (HL),A ;SPUR
INC HL
LD (HL),E ;KOPF
INC HL
LD (HL),D ;SEKTOR
INC D
INC HL
LD A,(SECLEN)
LD (HL),A ;BYTE/SEKTOR
INC HL
DJNZ FLOOP1
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Berechnung der Bytes von Sektornummer bis Ende der Spur
BCOUNT: LD A,(RQDA)
AND 1FH
LD B,A ;START Sektor
LD HL,128
LD A,(SECLEN) ;SEKTORLAENGE (0 = 128 BYTE)
OR A
JR Z,BC2
BC1: ADD HL,HL ;*2
DEC A
JR NZ,BC1
BC2: LD A,(NSECT) ;ANZAHL DER SEKTOREN
SUB B
LD B,A
EX DE,HL
LD HL,0
BC3: ADD HL,DE
DJNZ BC3
LD (RQLEN),HL ;IN HL: LAENGE EINER SPUR
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RQVEC DEFB 0
RQCOD DEFS 1
RQADR DEFW BUF ;DATEN ADR.
RQLEN DEFS 2 ;LAENGE
DEFW DEND
DEFW DEND
DEFS 1
RQDA DEFS 2 ;DISK ADRESSE
LEN DEFS 2
RESID DEFS 2
SAVEFD DEFS 2
OLDTYP defb 0
STYP defs 1
DTYP defs 1
NSECT1 defs 1
NSECT defs 1
NTRACK defs 1
DOUBLE defs 1
SECLEN defs 1
BLKREQ defs 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FLOPPY EQU 0BFDH
PFDTYP EQU 0E88H
FDCONF EQU 0EEBH
TYPTAB EQU 0B24H
TYP2 EQU TYPTAB+1*11
TYP3 EQU TYPTAB+2*11
TYP4 EQU TYPTAB+3*11
TYP5 EQU TYPTAB+4*11
TYP6 EQU TYPTAB+5*11
TYP7 EQU TYPTAB+6*11
CURT0 EQU 0FCEH
POAD EQU 0CH
POBD EQU 0EH
P16A EQU 10H
P16B EQU 14H
ACK EQU 06H
NAK EQU 15H