4099 lines
86 KiB
ArmAsm
4099 lines
86 KiB
ArmAsm
;----------------------------------------------------------------------
|
|
; *** PROGRAMMIERUNG DER WDC-KARTE ***
|
|
; *** Hard-Disk (Winchester) ***
|
|
;----------------------------------------------------------------------
|
|
; CPU Z80A, CTC, 8K PROM, 6K RAM, Host-Schnittstelle, Disk-Schnittstelle
|
|
; Programmierung fuer die Arbeit mit bis zu drei Laufwerken
|
|
;----------------------------------------------------------------------
|
|
|
|
begin 0
|
|
|
|
jr entry
|
|
string text 'WDC_4.21'
|
|
|
|
sc_len equ 512 ;Laenge des Datenfeldes eines Sektors (Byte)
|
|
|
|
; I/O-Adressen
|
|
CTC equ 70h ;Grundadresse des CTC
|
|
DSKEA equ 08h ;Disk-Endadresse (8282)
|
|
CNTST equ 18h ;Steuer- und Statusport (OUT-Port, 8212)
|
|
BM_T equ 28h ;Port fuer die Ausgabe des Taktbitmuster fuer Marken
|
|
BM_D equ 38h ;Port fuer die Ausgabe des Datenbitmusters fuer Marken
|
|
DSKC1 equ 48h ;Disk-Schnittstellenport 1 (8282)
|
|
DSKC2 equ 58h ;Disk-Schnittstellenport 2 (8212)
|
|
IMPAUS equ 68h ;Port zum Ausschalten der DSS
|
|
IMPATV equ 78h ;Impuls /ATV (Anzeige Takt vorwaerts)
|
|
ST_PRT equ 88h ;Status-Port (IN-Port, DL541)
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; PROM-Adressen
|
|
;-----------------------------------------------------------------------------
|
|
crc_0 equ 1ff8h ;CRC-Wert EPROM 0
|
|
crc_0n equ 1ffah ;CRC-Wert EPROM 0 negiert
|
|
crc_1 equ 1ffch ;CRC-Wert EPROM 1
|
|
crc_1n equ 1ffeh ;CRC-Wert EPROM 1 negiert
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; RAM-Adressen
|
|
;-----------------------------------------------------------------------------
|
|
; Adressen aus dem Lese-Schreibbereich
|
|
ram equ 2000h ;Anfangsadresse RAM
|
|
dt equ 2ff5h ;Anfangsadresse fuer die Datenbereiche
|
|
|
|
; Stackbereich
|
|
stk_br equ 3080h
|
|
|
|
; Startadressentabelle fuer ISR (CTC-Kanaele 0, 1, 2, 3)
|
|
isr_mk equ 30a0h
|
|
isr_dk equ 30a2h
|
|
isr_hs equ 30a4h
|
|
isr_ix equ 30a6h
|
|
|
|
; Kommandoeingabebereich
|
|
cmd_br equ 30bfh
|
|
|
|
; Fehlerausgabe
|
|
err_br equ 30c7h
|
|
|
|
;-------- Parametertabelle (vom Laufwerk) ------------------------------
|
|
p_str equ 30d0h ;8 Byte, Firmware-Version (aus string)
|
|
p_blk equ 30d8h ;13 Byte, Beschreibung Laufwerkstyp
|
|
;1 Byte frei
|
|
;1 Byte frei
|
|
cyls equ 30e7h ;2 Byte, Zylinderanzahl
|
|
hds equ 30e9h ;1 Byte, Kopfanzahl
|
|
secs equ 30eah ;1 Byte, Sektoranzahl
|
|
pre_cy equ 30ebh ;2 Byte, Zylindernummer der Praekompensation
|
|
rp_mod equ 30edh ;1 Byte, Ramp-Mode-Einschaltung
|
|
;6 Byte frei
|
|
ztk_40 equ 30f4h ;1 Byte, Zeitkonstante Formatieren 40 MHz
|
|
ztk_41 equ 30f5h ;1 Byte, Zeitkonstante formatieren 41,4 Mhz
|
|
zmn_40 equ 30f6h ;1 Byte, u. Grenze fuer Zeitm. IX-Impulse 40 MHz
|
|
zmx_40 equ 30f7h ;1 Byte, o. Grenze fuer Zeitm. IX-Impulse 40 MHz
|
|
zmn_41 equ 30f8h ;1 Byte, u. Grenze fuer Zeitm. IX-Impulse 41,4 MHz
|
|
zmx_41 equ 30f9h ;1 Byte, o. Grenze fuer Zeitm. IX-Impulse 41,4 MHz
|
|
;-------- Ende der Parametertabelle ------------------------------------
|
|
|
|
bl_dr0 equ 3115h ;2 Byte, Anzahl der Bloecke auf einem LW (Low)
|
|
bl_dr1 equ 3117h ;2 Byte, Anzahl der Bloecke auf einem LW (High)
|
|
bl_zyl equ 3119h ;2 Byte, Anzahl der Bloecke auf einem Zyl (Low)
|
|
bl_zyh equ 311bh ;2 Byte, Anzahl der Bloecke auf einem Zyl (High)
|
|
;1 Byte frei
|
|
;1 Byte frei
|
|
sav_fb equ 311fh ;1 Byte, Rettungsbyte fuer FB
|
|
l_inc equ 3120h ;1 Byte, Spurinkrementierungen bei Mehrblockzugr.
|
|
c_s_ix equ 3121h ;1 Byte, Zaehler fuer erlaubte falsche Sektor-
|
|
;nummern nach Index
|
|
hst_bl equ 3122h ;1 Byte, Blockzaehler fuer HS-Treiber
|
|
hst_by equ 3123h ;1 Byte, Besetztanzeiger fuer HS-Treiber
|
|
ident equ 3124h ;7 Byte, Kennfeld FE CY CY HD SC CRC CRC
|
|
cnt_st equ 312bh ;1 Byte, Ausgabebyte fuer CNTST
|
|
dsk_c1 equ 312ch ;1 Byte, Ausgabebyte fuer DSKC1
|
|
dsk_c2 equ 312dh ;1 Byte, Ausgabebyte fuer DSKC2
|
|
ch_cyl equ 312eh ;1 Byte, Zylinderwechsel waehrend eines Zugriffs
|
|
err_in equ 312fh ;1 Byte, Fehler waehrend der Initialisierung
|
|
dt_len equ 3130h ;2 Byte, Datenlaenge (Zwischenspeicher)
|
|
rd_mod equ 3132h ;1 Byte, Modus beim Lesen
|
|
k_flg equ 3133h ;1 Byte, Steuerung der Sektorsuche
|
|
sc_akt equ 3134h ;1 Byte, angeforderte Sektornummer (beim Schreiben)
|
|
;2 Byte frei
|
|
s_rdy equ 3137h ;1 Byte, 'Soft'-Ready-Byte (PAR- & BTT-Zustand)
|
|
d_rdy equ 3138h ;1 Byte, Ready-Byte fuer Laufwerke
|
|
ctc_st equ 3139h ;1 Byte, CTC-Programmierwort (Kanal2)
|
|
sc_cnt equ 313ah ;1 Byte, Sektorzaehler
|
|
|
|
; Steuerbytes fuer die Disk-Schnittstelle
|
|
cl_crc equ 317ah ;1 Byte
|
|
st_ina equ 317bh ;1 Byte
|
|
st_akt equ 317ch ;1 Byte
|
|
st_min equ 317dh ;1 Byte
|
|
st_vb equ 317eh ;1 Byte
|
|
st_dak equ 317fh ;1 Byte
|
|
st_wa equ 3180h ;1 Byte
|
|
st_wm equ 3181h ;1 Byte
|
|
st_wc equ 3182h ;1 Byte
|
|
d_akt equ 3183h ;1 Byte
|
|
d_inak equ 3184h ;1 Byte
|
|
men_ia equ 3185h ;1 Byte
|
|
|
|
; Disk-Adresszaehler
|
|
dsk_ad equ 3186h ;2 Byte
|
|
dsk_az equ 3188h ;2 Byte
|
|
|
|
; Durchlaufzaehler fuer Formatieren
|
|
dl_f equ 3192h ;1 Byte
|
|
dl_r equ 3193h ;1 Byte
|
|
|
|
; Tabelle der Zylinderpositionen der Laufwerke
|
|
cy_tab equ 3194h ;6 Byte
|
|
|
|
; Fehlercode und Fehlerzaehlerinitialisierung
|
|
err_cd equ 31a0h ;1 Byte, Fehlercode
|
|
c_zt equ 31a1h ;1 Byte
|
|
c_cd equ 31a2h ;1 Byte
|
|
c_sc equ 31a3h ;1 Byte
|
|
c_ci equ 31a4h ;1 Byte
|
|
c_cj equ 31a5h ;1 Byte
|
|
c_fb equ 31a6h ;1 Byte
|
|
c_ki equ 31a7h ;1 Byte
|
|
|
|
; Fehlerzaehler
|
|
; Keine Marken erkannt (Zeitueberwachung)
|
|
sum_zt equ 31aah
|
|
mx_zt equ 31ach
|
|
max_zt equ 31adh
|
|
ct_zt equ 31aeh
|
|
; CRC-Fehler im Identifier(1)
|
|
sum_ck equ 31afh
|
|
mx_ck equ 31b1h
|
|
max_ck equ 31b2h
|
|
ct_ck equ 31b3h
|
|
; CRC-Fehler im Identifier(2)
|
|
sum_cj equ 31b4h
|
|
mx_cj equ 31b6h
|
|
max_cj equ 31b7h
|
|
ct_cj equ 31b8h
|
|
; Falsche Sektornummern (nach Distanzinterrupt)
|
|
sum_sc equ 31b9h
|
|
mx_sc equ 31bbh
|
|
max_sc equ 31bch
|
|
ct_sc equ 31bdh
|
|
; Kein richtiges Kennfeld
|
|
sum_ki equ 31beh
|
|
mx_ki equ 31c0h
|
|
max_ki equ 31c1h
|
|
ct_ki equ 31c2h
|
|
; Falsches Datenfeldkennzeichen nach richtigem Kennfeld
|
|
sum_fb equ 31c3h
|
|
mx_fb equ 31c5h
|
|
max_fb equ 31c6h
|
|
ct_fb equ 31c7h
|
|
; CRC-Fehler im Datenfeld
|
|
sum_cd equ 31c8h
|
|
mx_cd equ 31cah
|
|
max_cd equ 31cbh
|
|
ct_cd equ 31cch
|
|
; Schreibwiederholungen bei 'Read after Write'
|
|
sum_ra equ 31cdh
|
|
mx_ra equ 31cfh
|
|
max_ra equ 31d0h
|
|
ct_ra equ 31d1h
|
|
; Falsche Sektornummer beim Schreiben
|
|
sum_wi equ 31d2h
|
|
mx_wi equ 31d4h
|
|
max_wi equ 31d5h
|
|
ct_wi equ 31d6h
|
|
; 'Fault Write'-Fehler
|
|
sum_fw equ 31d7h
|
|
mx_fw equ 31d9h
|
|
max_fw equ 31dah
|
|
ct_fw equ 31dbh
|
|
|
|
; Zugriffszaehler
|
|
z_cnt equ 31dch ;10 Byte fuer Zugriffsanzahl,beginnend mit 'lowest'
|
|
|
|
; Fehlerzaehler fuer das Testlesen
|
|
t_cnt equ 31f0h
|
|
t_kf equ 31f1h
|
|
f_0f equ 31f2h
|
|
f_ebit equ 31f3h
|
|
f_ausr equ 31f4h
|
|
f_unkl equ 31f5h
|
|
f_ande equ 31f6h
|
|
f_eb equ 31f7h
|
|
|
|
; Blockverwaltung
|
|
p_kf equ 31f8h ;2 Byte, Zeiger im 'kf-Feld'
|
|
p_dt equ 31fah ;2 Byte, Zeiger im 'dt-Feld'
|
|
kf_br equ 31fch ;2 Byte, aktuelle Anfangsadresse von kf
|
|
dt_br equ 31feh ;2 Byte, aktuelle Anfangsadresse von dt
|
|
|
|
; Defektspurtabellen der Laufwerke
|
|
df_end equ 3200h ;2 Byte, Adresse des aktuellen Werts von dfendx
|
|
df_tab equ 3202h ;2 Byte, Adresse des aktuellen Werts von dftabx
|
|
dfend0 equ 3204h ;2 Byte, Ende-Adresse der BTT fuer LW0
|
|
dftab0 equ 3206h ;120(78h) Byte, BTT des LW0 (40*3 Byte Laenge)
|
|
; 327eh ;3 Byte, Bereich fuer moegliches Endekennzeichen
|
|
dfend1 equ 3281h ;2 Byte, Ende-Adresse der BTT fuer LW0
|
|
dftab1 equ 3283h ;120(78h) Byte, BTT des LW1 (40*3 Byte Laenge)
|
|
; 32fbh ;3 Byte, Bereich fuer moegliches Endekennzeichen
|
|
dfend2 equ 32feh ;2 Byte, Ende-Adresse der BTT fuer LW0
|
|
dftab2 equ 3300h ;120(78h) Byte, BTT des LW2 (40*3 Byte Laenge)
|
|
; 3378h ;3 Byte, Bereich fuer moegliches Endekennzeichen
|
|
|
|
; Hilfsgroessen fuer die Zeitkonstantenbestimmung beim Formatieren
|
|
ztk equ 3380h ;1 Byte, Zeitkonstante
|
|
ztk_f equ 3381h ;8 Byte, Feld fuer Hilfsgroessen
|
|
|
|
; Rettungsbereich
|
|
s_prae equ 3590h ;10h Byte fuer Praeambelbereich (Schreiben)
|
|
s_post equ 35a0h ;10h Byte fuer Postambelbereich (Schreiben)
|
|
sav_20 equ 35b0h ;20h Byte 36b0...36cf
|
|
fs_tab equ 35e0h ;20h Byte (32), Sektorfolge fuer Formatieren
|
|
|
|
; 3600h bis 378fh Bereich fuer Sektorkennfelder
|
|
kf_top equ 3600h
|
|
kf equ 3603h
|
|
|
|
; Bereiche fuer das Umladen von Zugriffszaehler und Fehlerzellen
|
|
s_zcnt equ 37c0h ;10 Byte, Zugriffszaehler
|
|
s_errz equ 37cah ;50 Byte, Fehlerzellen
|
|
eject
|
|
;--------------------------------------------------------
|
|
; Systemanlauf und Initialisierungen
|
|
;--------------------------------------------------------
|
|
entry
|
|
ld sp,stk_br+1
|
|
|
|
; Test der CRC-Werte fuer beide EPROM's
|
|
ld hl,(crc_0) ;CRC-Wert fuer 1.EPROM
|
|
ld de,(crc_0n) ;negierter CRC-Wert
|
|
add hl,de
|
|
inc hl
|
|
ld a,h
|
|
or l
|
|
jp nz,err_pr
|
|
ld hl,(crc_1) ;CRC-Wert fuer 2.EPROM
|
|
ld de,(crc_1n) ;negierter CRC-Wert
|
|
add hl,de
|
|
inc hl
|
|
ld a,h
|
|
or l
|
|
jp nz,err_pr
|
|
ld hl,0 ;Anfangsadresse 1.EPROM
|
|
ld bc,1000h ;4K Byte
|
|
call crc_br ;CRC-Berechnung
|
|
ld hl,(crc_0) ;abgelegter CRC-Wert fuer 1.EPROM
|
|
ld a,d
|
|
ld d,e
|
|
ld e,a
|
|
xor a
|
|
sbc hl,de
|
|
jp nz,err_pr
|
|
ld hl,1000h ;Anfangsadresse 2. EPROM
|
|
ld bc,0ff8h ;4K Byte - 8
|
|
call crc_br ;CRC-Berechnung
|
|
ld hl,(crc_1) ;abgelegter CRC-Wert fuer 2. EPROM
|
|
ld a,d
|
|
ld d,e
|
|
ld e,a
|
|
xor a
|
|
sbc hl,de
|
|
jp z,crc_ok
|
|
err_pr
|
|
ld a,06h ;Status 6
|
|
out (CNTST),a ;Statusausgabe
|
|
halt
|
|
|
|
; Umladen Zugriffszaehler
|
|
crc_ok ld de,s_zcnt
|
|
ld hl,z_cnt
|
|
ld bc,10
|
|
ldir
|
|
|
|
; Umladen Fehlerzellen
|
|
ld hl,ct_fw
|
|
ld bc,sum_zt
|
|
xor a
|
|
sbc hl,bc
|
|
inc hl
|
|
push hl
|
|
pop bc
|
|
ld de,s_errz
|
|
ld hl,sum_zt
|
|
ldir
|
|
|
|
; Loeschen Gesamt-RAM
|
|
ld hl,2000h
|
|
ld de,2001h
|
|
ld (hl),081h
|
|
ld bc,017bfh
|
|
ldir
|
|
|
|
; Interrupt-Initialisierung
|
|
ld hl,isr_mk
|
|
ld a,h
|
|
ld i,a ;High-Teil Interruptvektor
|
|
im 2
|
|
ei
|
|
ld a,3 ;Reset fuer die CTC-Kanaele
|
|
out (CTC),a
|
|
out (CTC+1),a
|
|
out (CTC+2),a
|
|
out (CTC+3),a
|
|
ld a,l ;Low-Teil Interruptvektor
|
|
out (CTC),a
|
|
|
|
; ISR-Tabelle initialisieren
|
|
ld hl,isr_m1
|
|
ld (isr_mk),hl
|
|
ld hl,isr_al
|
|
ld (isr_dk),hl
|
|
ld hl,isr_h0
|
|
ld (isr_hs),hl
|
|
ld hl,isr_al
|
|
ld (isr_ix),hl
|
|
|
|
; Loeschen Zugriffszaehler
|
|
ld b,10
|
|
ld hl,z_cnt
|
|
cl_zc ld (hl),0
|
|
inc hl
|
|
djnz cl_zc
|
|
|
|
; Loeschen Fehlercode und Fehlerzellen
|
|
xor a
|
|
ld (err_in),a
|
|
ld (err_cd),a
|
|
ld (s_rdy),a
|
|
ld hl,ct_fw ;Ende der Fehlerzellen
|
|
ld bc,sum_zt ;Beginn der Fehlerzellen
|
|
sbc hl,bc
|
|
ld b,l
|
|
inc b
|
|
ld hl,sum_zt
|
|
xor a
|
|
cl_sum ld (hl),a
|
|
inc hl
|
|
djnz cl_sum
|
|
|
|
; Loeschen Zeitkonstante und Hilfsfeld (Formatierungshilfsmittel)
|
|
ld b,9
|
|
xor a
|
|
ld hl,ztk
|
|
cl_ztk ld (hl),a
|
|
inc hl
|
|
djnz cl_ztk
|
|
|
|
; Loeschen Besetztzeiger und Blockzaehler des HS-Treibers
|
|
ld (hst_by),a
|
|
ld (hst_bl),a
|
|
|
|
; Initialisieren 'cnt_st' fuer CNTST (nach Reset)
|
|
ld a,0 ;Status '0' nach Reset (8212 hat CLR-Eingang)
|
|
ld (cnt_st),a
|
|
|
|
; Initialisieren 'dsk_c2' fuer DSKC2
|
|
ld a,92h ;FR & Harddisk & Select0 & 'DEN=inaktiv'
|
|
; & 'MEN=inaktiv' & 'CRCEN=inaktiv'
|
|
; & 'WG=inaktiv'
|
|
out (DSKC2),a
|
|
ld a,12h ;FR ruecksetzen
|
|
ld (dsk_c2),a
|
|
out (DSKC2),a
|
|
|
|
; Initialisieren 'dsk_c1' fuer DSKC1
|
|
ld a,0 ;HS0 & 'SD=inaktiv' (nach aussen)
|
|
; & 'STEP=inaktiv' & Motor aus & 'HL=inaktiv'
|
|
ld (dsk_c1),a
|
|
out (DSKC1),a
|
|
|
|
; Loeschen der Positionstabelle
|
|
ld hl,-1
|
|
ld (cy_tab),hl
|
|
ld (cy_tab+2),hl
|
|
ld (cy_tab+4),hl
|
|
|
|
;--------------------------------------------------------
|
|
; Bestimmung der DSKC2-Steuerbytes (DEN, MEN, CRCEN, WG)
|
|
;--------------------------------------------------------
|
|
ld a,(dsk_c2)
|
|
and 0f0h
|
|
ld b,a ;alle Steuerbits = 0
|
|
; Steuerbytes fuer das Lesen ('WG=inaktiv')
|
|
or 7 ;'DEN=aktiv' & 'MEN=inaktiv' & 'CRCEN=aktiv'
|
|
ld (cl_crc),a ;Steuerbits zum CRC-Loeschen auf 'ff'
|
|
ld a,b
|
|
or 2 ;alles inaktiv
|
|
ld (st_ina),a ;Steuerbits zum Abschalten der Schnittstelle
|
|
ld a,b
|
|
or 5 ;alles aktiv
|
|
ld (st_akt),a ;Steuerbits zur Aktivierung der Markenerkennung
|
|
ld a,b
|
|
or 7 ;'MEN=inaktiv' & 'DEN=aktiv' & 'CRCEN=aktiv'
|
|
ld (st_min),a ;Steuerbits fuer den CRC-Test
|
|
ld a,b
|
|
or 3 ;'MEN=inaktiv' & 'DEN=aktiv' & 'CRCEN=inaktiv'
|
|
ld (st_dak),a ;Steuerbits waehrend langer Transfers
|
|
ld a,b
|
|
or 4 ;'DEN=inaktiv' & 'CRCEN=aktiv' & 'MEN=aktiv'
|
|
ld (st_vb),a ;Steuerbits fuer die Vorbereitung der
|
|
;inaktiven Disk-Ansteuerung
|
|
; Steuerbytes fuer das Schreiben ('WG=aktiv')
|
|
set 3,b ;'WG=aktiv'
|
|
ld a,b
|
|
or 0dh
|
|
ld (st_wa),a ;alles aktiv
|
|
ld a,b
|
|
or 0bh ;'DEN=aktiv' & 'MEN=inaktiv' & 'CRCEN=inak'
|
|
ld (st_wm),a
|
|
ld a,b
|
|
or 0fh ;auch 'CRCEN'=aktiv
|
|
ld (st_wc),a
|
|
|
|
; Initialisierung der Parametertabelle mit vorlaeufigen Werten
|
|
ld hl,100
|
|
ld (cyls),hl
|
|
ld (pre_cy),hl
|
|
ld a,2
|
|
ld (hds),a
|
|
ld a,18
|
|
ld (secs),a
|
|
ld a,1
|
|
ld (rp_mod),a
|
|
|
|
; Initialisierung von 'kf_br' und 'dt_br'
|
|
ld hl,kf
|
|
ld (kf_br),hl
|
|
ld hl,dt
|
|
ld (dt_br),hl
|
|
|
|
; Berechnung des Disk-Adresszaehlers fuer das Kennfeld
|
|
ld hl,(kf_br)
|
|
call b_daz
|
|
ld (dsk_ad),hl
|
|
|
|
;-------------------------------------------------
|
|
; Ready-Test der angeschlossenen Laufwerke
|
|
;-------------------------------------------------
|
|
; Loeschen Ready-Byte
|
|
ld a,87h ;INIT-Bit gesetzt
|
|
ld (d_rdy),a
|
|
; Ready-Test Laufwerk 0 (mit Abwarten der Startzeit)
|
|
ld b,30 ;max. Startzeit (in sec.)
|
|
inc b
|
|
inc b
|
|
ld a,12h
|
|
out (DSKC2),a ;Select LW0
|
|
rdy0 in a,(ST_PRT)
|
|
bit 2,a
|
|
jr z,rdy1 ;Sprung, wenn "ready"
|
|
ld de,100 ;100 * 10ms = 1s
|
|
call time2 ;ca 10 ms
|
|
djnz rdy0
|
|
ld hl,d_rdy ;Ready-Byte
|
|
res 0,(hl) ;LW nicht "ready"
|
|
; Ready-Test Laufwerk 1 (mit Abwarten der Restzeit)
|
|
rdy1 ld b,2
|
|
ld a,22h
|
|
out (DSKC2),a ;Select LW1
|
|
rdy11 in a,(ST_PRT)
|
|
bit 2,a
|
|
jr z,rdy2 ;Sprung, wenn "ready"
|
|
ld de,100 ;100 * 10ms = 1s
|
|
call time2 ;ca 10 ms
|
|
djnz rdy11
|
|
ld hl,d_rdy ;Ready-Byte
|
|
res 1,(hl) ;LW nicht "ready"
|
|
; Ready-Test Laufwerk 2 (mit Abwarten der Restzeit)
|
|
rdy2 ld b,2
|
|
ld a,32h
|
|
out (DSKC2),a ;Select LW2
|
|
rdy21 in a,(ST_PRT)
|
|
bit 2,a
|
|
jr z,rdy_ok ;Sprung, wenn "ready"
|
|
ld de,100 ;100 * 10ms = 1s
|
|
call time2 ;ca 10 ms
|
|
djnz rdy21
|
|
ld hl,d_rdy ;Ready-Byte
|
|
res 2,(hl) ;LW nicht "ready"
|
|
rdy_ok ld hl,d_rdy
|
|
ld a,(hl)
|
|
cp 80h ;kein LW "ready" ?
|
|
jr nz,posit0
|
|
set 6,(hl) ;ERR_IN-Bit setzen
|
|
jp begin
|
|
|
|
;-------------------------------------------------------
|
|
; Positionieren der Koepfe der Ready-Laufwerke auf Zyl 0
|
|
;-------------------------------------------------------
|
|
; Richtung der Kopfbewegung
|
|
posit0 ld a,(dsk_c1)
|
|
res 3,a ;SD nach aussen
|
|
ld (dsk_c1),a
|
|
out (DSKC1),a
|
|
; Laufwerk 0
|
|
ld hl,d_rdy
|
|
bit 0,(hl)
|
|
jp z,p_lw1
|
|
ld a,12h
|
|
out (DSKC2),a
|
|
call pos_t0
|
|
jr z,p_lw00
|
|
ld hl,d_rdy
|
|
set 3,(hl) ;Zyl 0 bei LW 0 nicht erreicht
|
|
res 0,(hl) ;READY-Bit fuer LW 0 ruecksetzen
|
|
set 6,(hl) ;Fehler waehrend der Initialisierung
|
|
jr p_lw1
|
|
p_lw00 ld hl,0 ;Kopfposition eintragen
|
|
ld (cy_tab),hl
|
|
; Laufwerk 1
|
|
p_lw1 ld hl,d_rdy
|
|
bit 1,(hl)
|
|
jp z,p_lw2
|
|
ld a,22h
|
|
out (DSKC2),a
|
|
call pos_t0
|
|
jr z,p_lw10
|
|
ld hl,d_rdy
|
|
set 4,(hl) ;Zyl 0 bei LW 1 nicht erreicht
|
|
res 1,(hl) ;READY-Bit fuer LW 1 ruecksetzen
|
|
set 6,(hl) ;Fehler waehrend der Initialisierung
|
|
jr p_lw2
|
|
p_lw10 ld hl,0 ;Kopfposition eintragen
|
|
ld (cy_tab+2),hl
|
|
; Laufwerk 2
|
|
p_lw2 ld hl,d_rdy
|
|
bit 2,(hl)
|
|
jp z,t0_ok
|
|
ld a,32h
|
|
out (DSKC2),a
|
|
call pos_t0
|
|
jr z,p_lw20
|
|
ld hl,d_rdy
|
|
set 5,(hl) ;Zyl 0 bei LW 2 nicht erreicht
|
|
res 2,(hl) ;READY-Bit fuer LW 2 ruecksetzen
|
|
set 6,(hl) ;Fehler waehrend der Initialisierung
|
|
jr t0_ok
|
|
p_lw20 ld hl,0 ;Kopfposition eintragen
|
|
ld (cy_tab+4),hl
|
|
t0_ok
|
|
|
|
;----------------------------------------------------------------
|
|
; Lesen der Sektoren 0/0/1 der Laufwerke
|
|
; Ueberpruefung der Parameter- und der Defektspurtabellen
|
|
;----------------------------------------------------------------
|
|
; Laufwerk 0
|
|
ld hl,d_rdy ;Ready-Byte
|
|
bit 0,(hl)
|
|
jp z,df_1
|
|
ld hl,cl_crc ;Tabelle der Steuerbytes der DSS
|
|
ld b,9
|
|
ld c,10h ;Select LW0
|
|
sdf0 ld a,(hl)
|
|
and 0fh ;Loeschen der Select-Bits
|
|
or c
|
|
ld (hl),a
|
|
inc hl
|
|
djnz sdf0
|
|
ld a,0
|
|
ld (cmd_br-7),a ;LW im Kommandobereich
|
|
call def_ad
|
|
call rd_dfk ;Lesen des Sektors 0/0/1
|
|
jr nz,df_00 ;Sprung, wenn Lesefehler
|
|
call t_par ;Ueberpruefung der Parametertabelle
|
|
jr nz,df_01
|
|
call v_par ;Umladen der Parameter
|
|
ld hl,s_rdy
|
|
set 0,(hl)
|
|
jr df_03
|
|
df_01 ld hl,err_in
|
|
set 3,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl) ;ERR_IN-Bit setzen
|
|
jr df_1
|
|
df_03 call t_btt ;Ueberpruefung der BTT
|
|
jr nz,df_02
|
|
call v_btt ;Umladen der BTT
|
|
ld hl,s_rdy
|
|
set 3,(hl)
|
|
jr df_1
|
|
df_02 ld hl,err_in
|
|
set 3,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl)
|
|
jr df_1
|
|
df_00 ld hl,err_in
|
|
set 0,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl)
|
|
; Laufwerk 1
|
|
df_1 ld hl,d_rdy ;Ready-Byte
|
|
bit 1,(hl)
|
|
jp z,df_2
|
|
ld hl,cl_crc ;Tabelle der Steuerbytes der DSS
|
|
ld b,9
|
|
ld c,20h ;Select LW1
|
|
sdf1 ld a,(hl)
|
|
and 0fh ;Loeschen der Select-Bits
|
|
or c
|
|
ld (hl),a
|
|
inc hl
|
|
djnz sdf1
|
|
ld a,1
|
|
ld (cmd_br-7),a ;LW im Kommandobereich
|
|
call def_ad
|
|
call rd_dfk ;Lesen des Sektors 0/0/1
|
|
jr nz,df_10
|
|
call t_par ;Ueberpruefung der Parameter
|
|
jr nz,df_11 ;Sprung, wenn Fehler
|
|
ld hl,s_rdy
|
|
bit 0,(hl)
|
|
jr z,df_12
|
|
call parram ;Uebereinstimmung PAR mit RAM-Eintrag ?
|
|
jr z,df_13 ;Sprung, wenn PAR ok
|
|
df_11 ld hl,err_in
|
|
set 4,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl)
|
|
ld hl,s_rdy
|
|
bit 0,(hl)
|
|
jr nz,df_14
|
|
jr df_2
|
|
df_12 call v_par ;Umladen der Parameter
|
|
df_13 ld hl,s_rdy
|
|
set 1,(hl)
|
|
df_14 call t_btt ;Ueberpruefung der BTT
|
|
jr nz,df_15
|
|
call v_btt
|
|
ld hl,s_rdy
|
|
set 4,(hl)
|
|
jr df_2
|
|
df_15 ld hl,err_in
|
|
set 4,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl)
|
|
jr df_2
|
|
df_10 ld hl,err_in
|
|
set 1,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl)
|
|
; Laufwerk 2
|
|
df_2 ld hl,d_rdy ;Ready-Byte
|
|
bit 2,(hl)
|
|
jp z,df_3
|
|
ld hl,cl_crc ;Tabelle der Steuerbytes der DSS
|
|
ld b,9
|
|
ld c,30h ;Select LW2
|
|
sdf2 ld a,(hl)
|
|
and 0fh ;Loeschen der Select-Bits
|
|
or c
|
|
ld (hl),a
|
|
inc hl
|
|
djnz sdf2
|
|
ld a,2
|
|
ld (cmd_br-7),a ;LW im Kommandobereich
|
|
call def_ad
|
|
call rd_dfk ;Lesen des Sektors 0/0/1
|
|
jp nz,df_20
|
|
call t_par ;Ueberprufung der Parameter
|
|
jr nz,df_22
|
|
ld hl,s_rdy
|
|
bit 0,(hl)
|
|
jr nz,df_21
|
|
bit 1,(hl)
|
|
jr nz,df_21
|
|
call v_par ;Eintragen der Parameter
|
|
df_23 ld hl,s_rdy
|
|
set 2,(hl)
|
|
jr df_24
|
|
df_21 call parram ;Uebereinstimmung mit eingetr. Par. ?
|
|
jr z,df_23
|
|
df_22 ld hl,err_in
|
|
set 5,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl)
|
|
ld hl,s_rdy
|
|
bit 0,(hl) ;PAR-Bit-LW0
|
|
jr nz,df_24 ;Sprung, wenn PAR-Tab von LW0 ok
|
|
bit 1,(hl) ;PAR-Bit-LW1
|
|
jr z,df_3 ;Sprung, wenn PAR-Tab von LW1 nicht ok
|
|
df_24 call t_btt ;Ueberpruefung der BTT
|
|
jr nz,df_25
|
|
call v_btt ;Umladen der BTT
|
|
ld hl,s_rdy
|
|
set 5,(hl)
|
|
jr df_3
|
|
df_25 ld hl,err_in
|
|
set 5,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl)
|
|
jr df_3
|
|
df_20 ld hl,err_in
|
|
set 2,(hl)
|
|
ld hl,d_rdy
|
|
set 6,(hl)
|
|
df_3
|
|
|
|
;---------------------------------------------------
|
|
; Bestimmung 'Anzahl Bloecke pro Zylinder'
|
|
; und 'Anzahl Bloecke pro Laufwerk'
|
|
;---------------------------------------------------
|
|
ld hl,0
|
|
ld a,(hds) ;Anzahl Koepfe
|
|
ld b,a
|
|
ld d,0
|
|
ld a,(secs) ;Blockanzahl pro Spur
|
|
ld e,a
|
|
ld a,0
|
|
blz0 add hl,de
|
|
jr nc,blz1
|
|
inc a
|
|
blz1 djnz blz0
|
|
ld (bl_zyl),hl
|
|
ld (bl_zyh),a
|
|
ld hl,0
|
|
ld (bl_dr0),hl
|
|
ld (bl_dr1),hl
|
|
ld d,0
|
|
ld a,(secs) ;Blockanzahl pro Spur
|
|
ld e,a
|
|
ld hl,(cyls) ;Zylinderanzahl pro Laufwerk
|
|
dec hl
|
|
blz4 push hl
|
|
ld a,(hds) ;Spuranzahl pro Zylinder
|
|
ld b,a
|
|
blz2 ld hl,(bl_dr0)
|
|
add hl,de
|
|
ld (bl_dr0),hl
|
|
jr nc,blz3
|
|
xor a
|
|
ld hl,(bl_dr1)
|
|
inc hl
|
|
ld (bl_dr1),hl
|
|
blz3 djnz blz2
|
|
pop hl
|
|
dec hl
|
|
ld a,h
|
|
or l
|
|
jp nz,blz4
|
|
ld hl,bl_dr0 ;Lowest
|
|
ld b,4
|
|
d_bl dec (hl)
|
|
ld a,(hl)
|
|
cp 0ffh
|
|
jr nz,d_bn
|
|
inc hl
|
|
djnz d_bl
|
|
d_bn
|
|
jp begin
|
|
|
|
;--- pos_t0 ------------------------------------
|
|
; Schrittweises Zurueckfahren der Koepfe auf Zyl 0
|
|
; Rueckkehr: Z ok.
|
|
; NZ Fehler
|
|
;-------------------------------------------------
|
|
pos_t0 ld hl,3000 ;mehr als Max von Zylindern
|
|
wt_see ld bc,400 ;max. 400 ms warten auf SEEKC
|
|
wt_se1 in a,(ST_PRT) ;Lesen des Statusports
|
|
bit 3,a ;'SEEKC=aktiv' ?
|
|
jr z,rd_stp ;Sprung, wenn 'SEEKC=aktiv'
|
|
ld de,1
|
|
call time1 ;ca. 1 ms
|
|
dec bc
|
|
ld a,b
|
|
or c
|
|
jr nz,wt_se1
|
|
inc a ;Rueckkehr mit Fehler (nz)
|
|
ret ;Rueckkehr mit Fehler
|
|
rd_stp in a,(ST_PRT) ;Lesen des Statusports
|
|
bit 6,a ;'T0=aktiv' ?
|
|
ret z ;Rueckkehr ok.
|
|
ld a,(dsk_c1)
|
|
set 0,a ;'ST=aktiv'
|
|
di
|
|
out (DSKC1),a
|
|
res 0,a ;'ST=inaktiv'
|
|
out (DSKC1),a
|
|
ei
|
|
dec hl
|
|
ld a,h
|
|
or l
|
|
jr nz,wt_see
|
|
inc a
|
|
ret ;Rueckkehr mit Fehler (nz)
|
|
|
|
;--- cy_pos ---------------------------------------------
|
|
; Bestimmung der Position in 'cy_tab'
|
|
; IN : A = Laufwerk
|
|
; OUT: HL= Adresse der Eintragung in der Zylindertabelle
|
|
;----------------------------------------------------------
|
|
cy_pos add a,a
|
|
ld c,a
|
|
ld b,0
|
|
ld hl,cy_tab ;Positionstabelle
|
|
add hl,bc
|
|
ret
|
|
|
|
;--- rd_dfk ----------------------------------------------
|
|
; Lesen des Sektors der Parameter- und der Defektspurtabelle
|
|
;-----------------------------------------------------------
|
|
rd_dfk ld de,ident
|
|
ld hl,id_df
|
|
ld bc,5
|
|
ldir
|
|
ld de,c_zt
|
|
ld hl,fe_n
|
|
ld bc,7
|
|
ldir ;Setzen der Fehlerzaehler
|
|
ld hl,200h
|
|
ld (cmd_br-2),hl ;Laenge festlegen
|
|
ld (dt_len),hl
|
|
ld a,0
|
|
ld (rd_mod),a ;Lesen von Kenn- und Datenfeld
|
|
call rd_id
|
|
ret
|
|
|
|
;--- t_par -----------------------------------------------------
|
|
; Ueberpruefung der Parametertabelle
|
|
; Daten muessen im RAM-Bereich fuer den ersten Sektor stehen
|
|
;---------------------------------------------------------------
|
|
; Test auf 'PARMTR'
|
|
t_par ld hl,(dt_br)
|
|
ld bc,269
|
|
add hl,bc ;erstes Byte der Parametertabelle
|
|
res 4,h
|
|
ld de,txt_pm ;Kenntext der Parametertabelle
|
|
ld b,6
|
|
sl_pm ld a,(de)
|
|
cp (hl)
|
|
jp nz,t_pare
|
|
inc hl
|
|
inc de
|
|
djnz sl_pm
|
|
; Test auf ASCII-Zeichen in der Laufwerksbezeichnung
|
|
ld b,12
|
|
sl_asc ld a,(hl)
|
|
cp 20h ;unterste Grenze
|
|
jp c,t_pare ;Fehler
|
|
cp 7bh ;oberste Grenze + 1
|
|
jp nc,t_pare ;Fehler
|
|
inc hl
|
|
djnz sl_asc
|
|
inc hl
|
|
; Test der Zylindernummer
|
|
inc hl
|
|
inc hl
|
|
ld a,(hl) ;Zylinder Low
|
|
inc hl
|
|
ld h,(hl) ;Zylinder High
|
|
ld l,a
|
|
push hl
|
|
pop de ;Zylinderanzahl
|
|
push hl
|
|
ld bc,100 ;mind. 100 Zylinder
|
|
xor a
|
|
sbc hl,bc
|
|
pop hl ;Zylinder
|
|
jp c,t_pare
|
|
ld bc,3000 ;max. 3000 Zylinder
|
|
xor a
|
|
sbc hl,bc
|
|
jp nc,t_pare
|
|
; Test der Kopfanzahl
|
|
ld hl,(dt_br)
|
|
ld bc,292
|
|
add hl,bc
|
|
res 4,h ;HL zeigt Kopfanzahl
|
|
ld a,(hl)
|
|
cp 2 ;mind. 2 Koepfe
|
|
jp c,t_pare
|
|
cp 17 ;max. 16 Koepfe
|
|
jp nc,t_pare
|
|
; Test der Sektoranzahl
|
|
inc hl
|
|
ld a,(hl) ;Sektoranzahl
|
|
cp 17
|
|
jp c,t_pare
|
|
cp 19
|
|
jp nc,t_pare
|
|
; Test der Praekompensationseinschaltung
|
|
inc hl
|
|
ld a,(hl)
|
|
inc hl
|
|
ld h,(hl)
|
|
ld l,a
|
|
push hl ;Zylindernummer der Praek.
|
|
ld bc,0
|
|
xor a
|
|
sbc hl,bc
|
|
pop hl
|
|
jp c,t_pare
|
|
xor a
|
|
ex de,hl
|
|
sbc hl,de ;HL enthaelt Zylinderanzahl
|
|
jp c,t_pare
|
|
; Test von 'rp_mod'
|
|
ld hl,(dt_br)
|
|
ld bc,296
|
|
add hl,bc
|
|
res 4,h
|
|
ld a,(hl)
|
|
cp 1
|
|
jp c,t_pare
|
|
cp 22
|
|
jp nc,t_pare
|
|
; Test der Zeitkonstanten
|
|
ld hl,(dt_br)
|
|
ld bc,303
|
|
add hl,bc
|
|
res 4,h
|
|
ld a,(hl) ;Zeitkonstante 40 MHz
|
|
cp 0b0h ;untere Grenze
|
|
jp c,t_pare
|
|
inc hl
|
|
cp (hl) ;Zeitkonstante 41,4 MHz
|
|
jp nc,t_pare
|
|
cp 0f1h ;obere Grenze + 1
|
|
jp nc,t_pare
|
|
; Test der Grenzwerte fuer 40MHz/41,4MHz-Umschaltung
|
|
inc hl
|
|
ld b,(hl) ;'zmn_40'
|
|
inc hl
|
|
ld a,(hl) ;'zmx_40'
|
|
cp b
|
|
jp c,t_pare
|
|
inc hl
|
|
ld c,(hl) ;'zmn_41'
|
|
inc hl
|
|
ld a,(hl) ;'zmx_41'
|
|
cp c
|
|
jp c,t_pare
|
|
ld a,c ;'zmn_41'
|
|
sub b ;'zmn_40'
|
|
jp nc,t_pare
|
|
xor a
|
|
ret ;Rueckkehr ok
|
|
t_pare ld a,1
|
|
cp 0
|
|
ret ;Fehlerrueckkehr
|
|
|
|
;--- parram ---------------------------------------------------
|
|
; Vergleich der im RAM (3000) eingetragenen Parameter mit den
|
|
; von 0/0/1 gelesenen Werten
|
|
;--------------------------------------------------------------
|
|
parram ld hl,(dt_br)
|
|
ld bc,275
|
|
add hl,bc
|
|
res 4,h ;Beginn der Inf. im Sektorbereich
|
|
ld de,p_blk ;Beginn der Inf. im RAM-Bereich
|
|
ld b,12
|
|
prr1 ld a,(de)
|
|
cp (hl)
|
|
ret nz
|
|
inc de
|
|
inc hl
|
|
djnz prr1
|
|
inc de
|
|
inc de
|
|
inc de
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
ld b,19
|
|
prr2 ld a,(de)
|
|
cp (hl)
|
|
ret nz
|
|
inc de
|
|
inc hl
|
|
djnz prr2
|
|
xor a
|
|
ret
|
|
|
|
;--- v_par ----------------------------------------------------
|
|
; Umladen der Parametertabelle aus dem Sektorbereich in den
|
|
; PAR-RAM-Bereich
|
|
;--------------------------------------------------------------
|
|
v_par ld hl,(dt_br)
|
|
ld bc,275
|
|
add hl,bc
|
|
res 4,h
|
|
ld bc,12
|
|
ld de,p_blk
|
|
ldir
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
xor a
|
|
inc de
|
|
ld (de),a
|
|
inc de
|
|
ld (de),a
|
|
inc de
|
|
ld (de),a
|
|
ld bc,19
|
|
ldir
|
|
ret
|
|
|
|
;--- par_v ---------------------------------------------------------------
|
|
; Umladen von PAR aus dem 3000-Bereich in den Datenbereich des 1. Sektors
|
|
;-------------------------------------------------------------------------
|
|
par_v ld hl,(dt_br)
|
|
ld bc,275
|
|
add hl,bc
|
|
res 4,h
|
|
ex de,hl
|
|
ld bc,34
|
|
ld hl,p_blk
|
|
ldir
|
|
ret
|
|
|
|
;--- btt_cl ----------------------------------------------------------
|
|
; Loeschen der BTT im 3000-RAM
|
|
;---------------------------------------------------------------------
|
|
btt_cl ld hl,(df_end)
|
|
ld (hl),0
|
|
inc hl
|
|
ld (hl),0
|
|
ld hl,(df_tab)
|
|
ld b,40*3+3
|
|
xor a
|
|
btt_c1 ld (hl),a
|
|
inc hl
|
|
djnz btt_c1
|
|
ld hl,(df_tab)
|
|
ld (hl),0ffh
|
|
inc hl
|
|
ld (hl),0ffh
|
|
inc hl
|
|
ld (hl),0ffh
|
|
ret
|
|
|
|
;--- t_btt --------------------------------------------------------
|
|
; Ueberpruefung der Defektspurtabelle
|
|
; Daten muessen im RAM-Bereich fuer den ersten Sektor stehen
|
|
;------------------------------------------------------------------
|
|
; Test auf 'DEFEKT'
|
|
t_btt ld hl,(dt_br)
|
|
ld bc,13
|
|
add hl,bc ;erstes Datenbyte
|
|
res 4,h
|
|
ld de,txt_df ;Text der BTT
|
|
ld b,6
|
|
sl_df ld a,(de)
|
|
cp (hl)
|
|
jp nz,t_btte
|
|
inc hl
|
|
inc de
|
|
djnz sl_df
|
|
; Test, ob Zaehler Vielfaches von 3
|
|
t_btt1 ld e,(hl)
|
|
inc hl
|
|
ld d,(hl) ;DE: Anzahl der Eintragungen
|
|
df_dek bit 7,d
|
|
jp nz,t_btte
|
|
ld a,d
|
|
or d
|
|
jr nz,df_dk1
|
|
ld a,e
|
|
or e
|
|
jr z,df_ok
|
|
df_dk1 dec de
|
|
dec de
|
|
dec de
|
|
jr df_dek
|
|
; Test auf Maximalwert des Zaehlers
|
|
df_ok inc hl
|
|
push hl ;Beginn der BTT-Eintragungen
|
|
dec hl
|
|
dec hl ;Anzahl der Eintragungen
|
|
ld e,(hl)
|
|
inc hl
|
|
ld d,(hl) ;DE: Anzahl der belegten Plaetze in der BTT
|
|
ld hl,40*3 ;Maximum von Eintragungen
|
|
xor a
|
|
sbc hl,de
|
|
pop hl ;Beginn der Eintragungen
|
|
jp c,t_btte ;Fehler, da Zaehler zu gross
|
|
; Test auf richtige Anordnung der Defektspuren
|
|
push hl
|
|
add hl,de ;HL: zeigt auf Endekennzeichen
|
|
push hl
|
|
push de
|
|
exx
|
|
pop de
|
|
pop hl
|
|
exx
|
|
pop hl ;Beginn der Eintragungen
|
|
ld a,d
|
|
or e
|
|
jr z,er_df5 ;keine Eintragungen
|
|
er_df3 ld d,(hl) ;Zyl high
|
|
inc hl
|
|
ld e,(hl) ;Zyl low
|
|
push de ;Zylinder
|
|
inc hl
|
|
inc hl
|
|
ld b,(hl) ;Zyl high
|
|
inc hl
|
|
ld c,(hl) ;Zyl low
|
|
dec hl
|
|
dec hl
|
|
dec hl ;HL zeigt auf Zyl low
|
|
ex de,hl
|
|
pop hl ;Zylinder
|
|
xor a
|
|
sbc hl,bc ;Zyl - Zyl_nex
|
|
jr c,er_df4 ;Zyl_nex groesser
|
|
jp nz,t_btte ;Fehler: Reihenfolge falsch
|
|
ex de,hl
|
|
inc hl
|
|
ld a,(hl) ;Kopf
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
ld b,(hl) ;Kopf_nex
|
|
sub b ;Kopf - Kopf_nex
|
|
jp nc,t_btte ;Fehler: Zyl gleich, Kopfreihenfolge falsch
|
|
dec hl
|
|
dec hl
|
|
dec hl
|
|
dec hl ;HL zeigt auf Zyl low
|
|
ex de,hl
|
|
; Test auf Maximalwert fuer Zylinder
|
|
er_df4 ex de,hl ;HL zeigt auf Zyl low
|
|
ld e,(hl)
|
|
dec hl
|
|
ld d,(hl)
|
|
ex de,hl ;HL: Zyl, DE: zeigt auf Zyl high
|
|
ld bc,(cyls)
|
|
xor a
|
|
sbc hl,bc
|
|
jp nc,t_btte ;Fehler: Zylinder zu gross
|
|
; Test auf Maximalwert fuer Kopf
|
|
ex de,hl
|
|
inc hl
|
|
inc hl
|
|
ld a,(hds)
|
|
ld b,a
|
|
ld a,(hl) ;Kopf
|
|
sub b
|
|
jp nc,t_btte
|
|
inc hl ;HL zeigt auf Zyl high
|
|
exx
|
|
dec de ;Endetest
|
|
dec de
|
|
dec de
|
|
ld a,d
|
|
or e
|
|
exx
|
|
jp nz,er_df3
|
|
; Test auf Endekennzeichen
|
|
er_df5 exx
|
|
push hl
|
|
exx
|
|
pop hl ;HL: zeigt auf Endekennzeichen
|
|
ld a,(hl)
|
|
cp 0ffh
|
|
jr nz,t_btte ;Fehler, da kein exaktes Endekennzeichen
|
|
inc hl
|
|
cp (hl)
|
|
jr nz,t_btte ;Fehler, da kein exaktes Endekennzeichen
|
|
inc hl
|
|
cp (hl)
|
|
jr nz,t_btte ;Fehler, da kein exaktes Endekennzeichen
|
|
xor a
|
|
ret ;Ruecksprung ok
|
|
t_btte ld a,1
|
|
cp 0
|
|
ret ;Fehler-Ruecksprung
|
|
|
|
;--- v_btt -----------------------------------------------------------
|
|
; Umladen der BTT aus dem Datenbereich des 1. Sektors in den 3000-RAM
|
|
;---------------------------------------------------------------------
|
|
v_btt ld hl,(dt_br)
|
|
ld bc,19
|
|
add hl,bc
|
|
res 4,h
|
|
ld bc,40*3+2+3
|
|
ld de,(df_end)
|
|
ldir
|
|
ret
|
|
|
|
;--- btt_v -----------------------------------------------------------
|
|
; Umladen der BTT aus 3000-RAM in den Datenbereich des 1. Sektors
|
|
;---------------------------------------------------------------------
|
|
btt_v ld hl,(dt_br)
|
|
ld bc,19
|
|
add hl,bc
|
|
res 4,h
|
|
ex de,hl
|
|
ld hl,(df_end)
|
|
ld bc,40*3+2+3
|
|
ldir
|
|
ret
|
|
|
|
;--- def_ad ---------------------------------------------
|
|
; Bestimmung der aktuellen Adressen der Defektspurtabelle
|
|
; cmd_br-7 : Laufwerk
|
|
;--------------------------------------------------------
|
|
def_ad ld a,(cmd_br-7) ;Laufwerk
|
|
ld hl,dfend0
|
|
ld (df_end),hl
|
|
ld hl,dfend1
|
|
ld de,dfend2
|
|
cp 1
|
|
jr c,d_adr
|
|
jr z,d_ad1
|
|
ld (df_end),de
|
|
jr d_adr
|
|
d_ad1 ld (df_end),hl
|
|
d_adr ld hl,(df_end) ;Adresse von 'dfendx'
|
|
inc hl
|
|
inc hl
|
|
ld (df_tab),hl ;Adresse des Beginns der aktuellen BTT
|
|
ret
|
|
|
|
;--- par_s ---------------------------------------------------
|
|
; UP Setzen des PAR-Bits in 's_rdy' fuer das Laufwerk
|
|
;-------------------------------------------------------------
|
|
par_s ld a,(cmd_br-7) ;Laufwerk aus Kommando
|
|
ld b,a
|
|
inc b
|
|
xor a
|
|
scf
|
|
par_s1 rla
|
|
djnz par_s1
|
|
ld hl,s_rdy
|
|
or (hl)
|
|
ld (s_rdy),a
|
|
ret
|
|
|
|
;--- btt_s ---------------------------------------------------
|
|
; UP Setzen des BTT-Bits in 's_rdy' fuer das Laufwerk
|
|
;-------------------------------------------------------------
|
|
btt_s ld a,(cmd_br-7) ;Laufwerk aus Kommando
|
|
ld b,a
|
|
inc b
|
|
xor a
|
|
scf
|
|
rla
|
|
rla
|
|
rla
|
|
btt_s1 rla
|
|
djnz btt_s1
|
|
ld hl,s_rdy
|
|
or (hl)
|
|
ld (s_rdy),a
|
|
ret
|
|
|
|
;--- par_r ---------------------------------------------------
|
|
; UP Ruecksetzen des PAR-Bits in 's_rdy' fuer das Laufwerk
|
|
;-------------------------------------------------------------
|
|
par_r ld a,(cmd_br-7) ;Laufwerk aus Kommando
|
|
ld b,a
|
|
inc b
|
|
xor a
|
|
scf
|
|
par_r1 rla
|
|
djnz par_r1
|
|
cpl
|
|
ld hl,s_rdy
|
|
and (hl)
|
|
ld (s_rdy),a
|
|
ret
|
|
|
|
;--- btt_r ---------------------------------------------------
|
|
; UP Ruecksetzen des BTT-Bits in 's_rdy' fuer das Laufwerk
|
|
;-------------------------------------------------------------
|
|
btt_r ld a,(cmd_br-7) ;Laufwerk aus Kommando
|
|
ld b,a
|
|
inc b
|
|
xor a
|
|
scf
|
|
rla
|
|
rla
|
|
rla
|
|
btt_r1 rla
|
|
djnz btt_r1
|
|
cpl
|
|
ld hl,s_rdy
|
|
and (hl)
|
|
ld (s_rdy),a
|
|
ret
|
|
eject
|
|
begin
|
|
;-----------------------------------------------------------------------
|
|
; Host-Schnittstelle auf die Eingabe eines Kommandos (9 Byte) einstellen
|
|
;-----------------------------------------------------------------------
|
|
ld bc,9 ;Eingabelaenge
|
|
ld hl,cmd_br ;Ende des Kommandobereich
|
|
ld a,1 ;Status '1'
|
|
call p_h_wc ;Programmierung der Host-Schnittstelle
|
|
|
|
;---------------------------------------
|
|
; Auswertung des eingelaufenen Kommandos
|
|
;---------------------------------------
|
|
; Inkrement Zugriffszaehler
|
|
ld b,10
|
|
ld hl,z_cnt
|
|
zc_inc inc (hl)
|
|
jr nz,zc_ok
|
|
inc hl
|
|
djnz zc_inc
|
|
; Fehler in der Initialisierung ?
|
|
zc_ok ld hl,d_rdy
|
|
bit 7,(hl) ;INIT-Bit
|
|
jr z,not_in ;nicht erste Abfrage nach Initialisierung
|
|
res 7,(hl) ;INIT-Bit ruecksetzen
|
|
bit 6,(hl) ;ERR_IN-Bit
|
|
jr z,not_in ;kein Fehler in der Initialisierung
|
|
ld a,(hl)
|
|
and 3fh ;ZY0- und RDY-Bits
|
|
jr nz,nt_27 ;kein LW "ready"
|
|
ld a,27h ;kein LW "ready"
|
|
ld (err_cd),a
|
|
jp error
|
|
nt_27 ld a,(hl)
|
|
and 38h ;ZY0-Bits
|
|
jr z,inerr ;kein ZY0-Fehler
|
|
srl a
|
|
srl a
|
|
srl a ;Laufwerkscodierung
|
|
or 28h ;CYL0-Fehler
|
|
ld (err_cd),a
|
|
jp error
|
|
inerr ld hl,err_in
|
|
ld a,(hl)
|
|
and 7 ;0/0/1 nicht lesbar
|
|
jr z,nt_30
|
|
or 30h
|
|
ld (err_cd),a
|
|
jp error
|
|
nt_30 ld a,(hl)
|
|
and 38h ;PAR&BTT-Fehler
|
|
srl a
|
|
srl a
|
|
srl a
|
|
or 38h
|
|
ld (err_cd),a
|
|
jp error
|
|
|
|
; Loeschen Inkrementierungszaehler
|
|
not_in xor a
|
|
ld (l_inc),a
|
|
; Warten, bis HS-Treiber frei
|
|
wt_hst ld hl,hst_by
|
|
bit 7,(hl)
|
|
jr nz,wt_hst
|
|
; Auswertung des Kommando-Codes
|
|
ld a,(cmd_br-8) ;Kommandocode
|
|
cp 21h ;Block lesen ?
|
|
jr z,t_com
|
|
cp 22h ;Block schreiben ?
|
|
jr z,t_com1
|
|
ld hl,com_tb ;Tabelle aller Kommandos
|
|
com_ts cp (hl)
|
|
jr z,com_ok
|
|
cp 0ffh ;Endekennzeichen
|
|
inc hl
|
|
jr nz,com_ts
|
|
jp err_1 ;Fehler 1 : falscher Kommandocode
|
|
com_ok bit 3,a ;WDC-RAM-Kommandos ?
|
|
jp nz,mv_ok
|
|
bit 1,a ;HD-Schreiben ?
|
|
jp z,t_com
|
|
cp 0c2h ;HD-Schreiben Defektspurtabelle ?
|
|
jr z,t_com
|
|
; Uebernahme der zu schreibenden Daten vom Host
|
|
t_com1 ld hl,dt
|
|
ld bc,13
|
|
add hl,bc
|
|
res 4,h
|
|
ld bc,(cmd_br-2) ;Laenge
|
|
add hl,bc
|
|
dec hl ;Endadresse Daten
|
|
ld a,2 ;Status 2
|
|
call p_h_wc
|
|
; Datenlaenge umspeichern
|
|
t_com ld hl,(cmd_br-2) ;Datenlaenge aus Kommando
|
|
ld (dt_len),hl
|
|
; Bestimmung der aktuellen BTT
|
|
call def_ad
|
|
; Einfuegen der Select-Bits in die Steuerbytes der DSS
|
|
ld a,(cmd_br-7) ;angefordertes Laufwerk
|
|
and 3
|
|
inc a
|
|
rlca
|
|
rlca
|
|
rlca
|
|
rlca
|
|
ld c,a
|
|
ld hl,cl_crc ;Beginn der Steuerbytes
|
|
ld b,9
|
|
einf_d ld a,(hl)
|
|
and 0fh ;Loeschen der Select-Bits
|
|
or c
|
|
ld (hl),a
|
|
inc hl
|
|
djnz einf_d
|
|
; Laufwerkstest
|
|
ld a,(d_rdy) ;Ready-Byte
|
|
ld b,a
|
|
ld a,(cmd_br-7) ;Laufwerk
|
|
cp 3
|
|
jp nc,err_3 ;max. drei LW moeglich
|
|
cp 0
|
|
jp nz,lt_1
|
|
bit 0,b
|
|
jp z,err_3
|
|
jr lt_ok
|
|
lt_1 cp 1
|
|
jr nz,lt_2
|
|
bit 1,b
|
|
jp z,err_3 ;gefordertes LW nicht 'ready'
|
|
jr lt_ok
|
|
lt_2 bit 2,b
|
|
jp z,err_3 ;gefordertes LW nicht 'ready'
|
|
lt_ok
|
|
; weitere Auswertung des Kommandocodes
|
|
ld a,(cmd_br-8) ;Kommandocode
|
|
bit 2,a ;Formatier-Kommandos ?
|
|
jp nz,t_cd3
|
|
bit 0,a ;Lese-Kommandos ?
|
|
jp nz,t_cd
|
|
bit 1,a ;Schreib-Kommandos ?
|
|
jp z,mv_ok
|
|
t_cd bit 5,a ;Blocknummern ?
|
|
jr z,t_cd1
|
|
; Test der Blocknummer
|
|
ld hl,cmd_br-3 ;hoechstwertiges Byte im Kommando
|
|
ld de,bl_dr1+1 ;hoechstwertiges Byte in Blockanzahl
|
|
ld b,4
|
|
t_bn ld a,(de)
|
|
cp (hl)
|
|
jr c,bn_err
|
|
jr nz,bn_ok
|
|
dec hl
|
|
dec de
|
|
djnz t_bn
|
|
|
|
;------------------------------------------------------------
|
|
; Bestimmung der physischen Sektoradresse aus der Blocknummer
|
|
; Blocknummer in cmd_br-6,...,cmd_br-3 (low..high)
|
|
; Sektoradresse in ident+1,...,ident+4
|
|
; Blocknummer 0: Zyl 1, Hd 0, Sc 1
|
|
;------------------------------------------------------------
|
|
bn_ok ld de,(bl_zyl) ;Anzahl der Bloecke pro Zylinder
|
|
; Bloecke auf Zylinder
|
|
ld bc,(cmd_br-6)
|
|
ld hl,(cmd_br-4)
|
|
ld a,17
|
|
or a
|
|
bl2 sbc hl,de
|
|
jr nc,bl4
|
|
add hl,de
|
|
bl4 ccf
|
|
rl c
|
|
rl b
|
|
adc hl,hl
|
|
dec a
|
|
jr nz,bl2
|
|
rr h
|
|
rr l
|
|
inc bc
|
|
ld (ident+1),bc
|
|
; Bestimmung der Kopfnummer
|
|
ex de,hl
|
|
ld hl,ident+3 ;zeigt auf Kopfnummer
|
|
ld a,(secs)
|
|
ld c,a
|
|
ld b,0 ;Sektoranzahl pro Spur
|
|
ld (hl),-1 ;Loeschen der Kopfnummer
|
|
bl5 inc (hl)
|
|
ex de,hl
|
|
xor a
|
|
sbc hl,bc
|
|
ex de,hl
|
|
jr nc,bl5
|
|
ex de,hl
|
|
; Bloecke auf Sektoren
|
|
add hl,bc ;restliche Bloecke
|
|
ld a,l
|
|
inc a
|
|
ld (ident+4),a
|
|
ld a,0feh
|
|
ld (ident),a
|
|
; ENDE der Blocknummernumrechnung ---------------------------------
|
|
call sc_def
|
|
jp hd_mov
|
|
bn_err ld a,5 ;Fehlercode 5: Blocknummer zu gross
|
|
ld (err_cd),a
|
|
jp error
|
|
t_cd1 bit 4,a ;Defektspurberuecksichtigung ?
|
|
jr z,t_cd2
|
|
ld hl,cmd_br-6
|
|
call id_ein
|
|
call sc_def
|
|
jp hd_mov
|
|
t_cd2 bit 6,a ;Defektspurtabelle ?
|
|
jr z,t_cd3
|
|
ld de,ident
|
|
ld hl,id_df
|
|
ld bc,5
|
|
ldir
|
|
jp hd_mov
|
|
t_cd3 ld hl,cmd_br-6
|
|
call id_ein
|
|
jp hd_mov
|
|
eject
|
|
;--------------------------------------------------------------------
|
|
; Routine zur Bewegung der Schreib-Lese-Koepfe (Kamm)
|
|
;--------------------------------------------------------------------
|
|
hd_mov
|
|
; Test der Zylindernummer im Kommando
|
|
ld hl,(ident+1) ;Zylinder
|
|
ld bc,(cyls) ;Anzahl der Zylinder
|
|
xor a
|
|
sbc hl,bc
|
|
jp nc,err_4 ;Zylindernummer im Kommando zu gross
|
|
; Laufwerk selektieren
|
|
ld a,(st_ina)
|
|
out (DSKC2),a
|
|
; Bestimmung der aktuellen Kopfposition
|
|
ld a,(cmd_br-7) ;Laufwerk
|
|
add a,a
|
|
ld c,a
|
|
ld b,0
|
|
ld hl,cy_tab ;Tabelle der Kopfpositionen
|
|
add hl,bc ;Zeiger auf Kopfposition
|
|
ld c,(hl) ;Low-Teil
|
|
inc hl
|
|
ld b,(hl) ;High-Teil
|
|
inc bc ;ffff-Test
|
|
ld a,b
|
|
or c
|
|
jp z,err_6
|
|
dec bc
|
|
ld hl,(ident+1) ;angeforderter Zylinder
|
|
xor a
|
|
sbc hl,bc ;Positionsdifferenz
|
|
jp z,mv3 ;Position ok.
|
|
jp c,st_out ;Kopfbewegung nach aussen
|
|
; Kopfbewegung nach innen
|
|
ld a,(dsk_c1)
|
|
set 3,a ;SD nach innen
|
|
ld (dsk_c1),a
|
|
out (DSKC1),a
|
|
jr mv0
|
|
; Kopfbewegung nach aussen
|
|
st_out
|
|
ld a,(dsk_c1)
|
|
res 3,a ;SD nach aussen
|
|
ld (dsk_c1),a
|
|
out (DSKC1),a
|
|
push hl
|
|
pop bc
|
|
ld hl,0
|
|
xor a
|
|
sbc hl,bc
|
|
; Bestimmung der Art der Schrittbewegung
|
|
mv0 push hl ;Step-Anzahl
|
|
ld a,(rp_mod)
|
|
ld c,a
|
|
ld b,0
|
|
xor a
|
|
sbc hl,bc
|
|
pop hl
|
|
jp z,si_step
|
|
jp nc,ramp
|
|
|
|
; Stepausfuehrung im Single- und Slow-Step-Mode, HL: Schrittanzahl
|
|
si_step ld a,(dsk_c1) ;Ausgabebyte fuer DSKC1
|
|
xor 1 ;Step-Impuls ein
|
|
di
|
|
out (DSKC1),a
|
|
xor 1 ;Step-Impuls aus
|
|
out (DSKC1),a
|
|
ei
|
|
dec hl
|
|
ld a,h
|
|
or l
|
|
jr z,mv1
|
|
ld de,320
|
|
call time
|
|
jr si_step
|
|
; Stepausfuehrung im Ramp-Mode, HL: Schrittanzahl
|
|
ramp ld a,(hst_by) ;Test auf Abschluss von Host-Transfers
|
|
bit 7,a
|
|
jr nz,ramp
|
|
ld de,(dsk_c1) ;Ausgabebyte fuer DSKC1 nach e
|
|
set 0,e ;Step-Impuls an
|
|
rmp ld a,e
|
|
out (DSKC1),a
|
|
xor 1 ;Step-Impuls aus
|
|
out (DSKC1),a
|
|
dec hl
|
|
ld a,h
|
|
or l
|
|
jp nz,rmp
|
|
mv1 in a,(ST_PRT) ;Lesen des Status-Ports
|
|
bit 3,a ;'SEEKC=aktiv' ?
|
|
jr nz,mv1
|
|
ld hl,(ident+1) ;angeforderter Zylinder
|
|
ld a,h
|
|
or l ;Track0 angefordert ?
|
|
jr nz,mv2
|
|
in a,(ST_PRT)
|
|
bit 6,a ;'Track0=aktiv' ?
|
|
jr z,mv2
|
|
ld a,7 ;Fehlercode fuer 'Track0 nicht erreicht'
|
|
ld (err_cd),a
|
|
jp error
|
|
; Eintragen der neuen Kopfposition
|
|
mv2 ld a,(cmd_br-7) ;Laufwerk
|
|
call cy_pos
|
|
ld bc,(ident+1) ;geforderte Position
|
|
ld (hl),c
|
|
inc hl
|
|
ld (hl),b
|
|
;------------
|
|
; Kopfauswahl
|
|
;------------
|
|
mv3 ld a,(hds)
|
|
ld b,a
|
|
ld a,(ident+3) ;Kopfnummer
|
|
cp b
|
|
jp nc,err_2 ;Kopfnummer zu gross
|
|
rrca
|
|
rrca
|
|
rrca
|
|
rrca
|
|
ld b,a
|
|
ld a,(dsk_c1)
|
|
and 0fh ;Loeschen der HS-Bits
|
|
or b ;Einfuegen der neuen HS-Bits
|
|
ld (dsk_c1),a
|
|
out (DSKC1),a
|
|
;-----------------------------
|
|
; Auswertung des Kommandocodes
|
|
;-----------------------------
|
|
mv_ok
|
|
ld a,(cmd_br-8) ;Kommandocode
|
|
cp 21h ;Blocklesen ?
|
|
jp z,read1
|
|
cp 22h ;Blockschreiben ?
|
|
jp z,write
|
|
cp 0a1h ;Block-Kopieren ?
|
|
jp z,read1
|
|
cp 81h ;Testlesen ?
|
|
jp z,read5
|
|
cp 11h ;Lesen mit BTT-Test ?
|
|
jp z,read1
|
|
cp 1 ;Sektorlesen ohne BTT-Test ?
|
|
jp z,read1
|
|
cp 0 ;Ready-Test ?
|
|
jp z,rdy_ts
|
|
bit 1,a ;Schreib-Kommandos ?
|
|
jp nz,write
|
|
bit 2,a ;Formatier-Kommandos ?
|
|
jp nz,format
|
|
bit 3,a ;WDC-RAM-Transfers ?
|
|
jp nz,ram_tr
|
|
jp err_1
|
|
;-------------------------
|
|
; Ready-Test des Laufwerks
|
|
;-------------------------
|
|
rdy_ts
|
|
jp begin
|
|
eject
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
; Lesen eines Sektors, der durch seine Sektoradresse angegeben ist
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
read1
|
|
; Setzen der Fehlerzaehler
|
|
ld de,c_zt
|
|
ld hl,fe_n
|
|
ld bc,7
|
|
ldir
|
|
; Lesen von Hard-Disk
|
|
ld a,0
|
|
ld (rd_mod),a ;Lesen von Kenn- und Datenfeld
|
|
call rd_id
|
|
jp nz,error
|
|
; Test auf Block-Kopieren
|
|
ld a,(cmd_br-8)
|
|
cp 0a1h
|
|
jr nz,read11
|
|
ld a,22h
|
|
ld (cmd_br-8),a ;Block-Schreiben
|
|
ld a,0
|
|
ld (cmd_br-7),a ;Schreiben auf Laufwerk 0
|
|
jp t_com
|
|
; Uebergabe der gelesenen Daten an den Host
|
|
read11 ld hl,dt
|
|
ld bc,13
|
|
add hl,bc ;Anfangsadresse der gelesenen Daten
|
|
res 4,h ;eventuelles Bit 12 ruecksetzen
|
|
ld bc,(cmd_br-2) ;Datenlaenge
|
|
add hl,bc
|
|
dec hl ;Endadresse der gelesenen Daten
|
|
ld a,3 ;Status '3'
|
|
call p_wc_h ;Programmierung der Host-Schnittstelle
|
|
jp begin
|
|
eject
|
|
read5
|
|
;+++++++++++++++++++++++++++++++++++++++++++
|
|
; Testlesen eines Sektors
|
|
;+++++++++++++++++++++++++++++++++++++++++++
|
|
; Datenlaenge fuer einen Sektor einstellen
|
|
ld hl,200h
|
|
ld (dt_len),hl
|
|
; Loeschen der RAM-Zellen fuer Auswertung beim Testlesen
|
|
ld hl,t_cnt
|
|
ld b,8
|
|
clr_fm
|
|
ld (hl),0
|
|
inc hl
|
|
djnz clr_fm
|
|
; Setzen der Fehlerzaehler
|
|
rd5_sl
|
|
ld de,c_zt
|
|
ld hl,fe_t
|
|
ld bc,7
|
|
ldir
|
|
; Lesen von Hard-Disk
|
|
ld a,0
|
|
ld (rd_mod),a ;Lesen von Kenn- und Datenfeld
|
|
call rd_id
|
|
; Auswertung der Leseversuche im Testmodus
|
|
jr nz,t_err
|
|
ld hl,t_kf ;Anzahl der richtigen Leseversuche (Test)
|
|
inc (hl)
|
|
jp t_end
|
|
; Fehlerauswertung im Test-Modus
|
|
t_err
|
|
ld a,(err_cd) ;Fehlercode
|
|
cp 0fh ;CRC-Fehler im Datenfeld ?
|
|
jp z,asw_f
|
|
ld hl,f_ande
|
|
inc (hl)
|
|
jp t_end
|
|
; Auswertung der CRC-Fehler im Datenfeld
|
|
asw_f
|
|
ld hl,f_0f
|
|
inc (hl)
|
|
ld hl,(dt_br) ;Beginn des Datenfeldes
|
|
ld bc,13
|
|
add hl,bc
|
|
res 4,h
|
|
ld bc,200h ;Laenge des Datenfeldes
|
|
sl_t1 ld a,(hl)
|
|
cp 0e5h ;Wert ok. ?
|
|
jr nz,diff1
|
|
inc hl
|
|
dec bc
|
|
ld a,c
|
|
or b
|
|
jr nz,sl_t1
|
|
ld a,(f_eb)
|
|
cp 1
|
|
jp z,t_end
|
|
ld hl,f_unkl
|
|
inc (hl)
|
|
jp t_end
|
|
diff1
|
|
ld d,a ;Wert retten
|
|
inc hl
|
|
dec bc
|
|
ld a,b
|
|
or c
|
|
jr nz,sl_t2
|
|
ld hl,f_eb
|
|
ld (hl),1
|
|
jp t_end
|
|
sl_t2
|
|
ld a,(hl) ;naechster Wert
|
|
cp 0e5h ;Wert ok. ?
|
|
jr nz,ausras
|
|
push hl
|
|
ld hl,f_eb
|
|
ld (hl),1
|
|
pop hl
|
|
jp sl_t1
|
|
ausras
|
|
ld hl,f_ausr
|
|
inc (hl) ;Fehler: ausgerastet
|
|
jp t_end
|
|
; Endebehandlung des Testmodus
|
|
t_end
|
|
ld a,(f_eb)
|
|
cp 1 ;Einzelbit-Fehler ?
|
|
jr nz,k_eb
|
|
ld hl,f_ebit
|
|
inc (hl)
|
|
k_eb ld a,(t_cnt)
|
|
inc a
|
|
ld (t_cnt),a
|
|
cp 0ffh
|
|
jp z,t_ueb
|
|
xor a
|
|
ld (f_eb),a
|
|
jp rd5_sl
|
|
; Uebergabe der Testwerte an den Host
|
|
t_ueb
|
|
ld bc,(cmd_br-2)
|
|
ld hl,t_cnt
|
|
add hl,bc
|
|
dec hl
|
|
ld a,3
|
|
call p_wc_h
|
|
xor a
|
|
ld (err_cd),a
|
|
jp begin
|
|
eject
|
|
;**************************************************************************
|
|
; UP rd_id
|
|
; Lesen eines Kennfeldes (und des Datenfeldes) von Hard-Disk
|
|
; 'ident' : Kennfeld, 'rd_mod' : 0=Lesen des Kennfeldes und des Datenfeldes
|
|
; 1=Lesen des Kennfeldes
|
|
;**************************************************************************
|
|
rd_id
|
|
; Initialisierung von 'dt_br'
|
|
ld hl,dt
|
|
ld (dt_br),hl
|
|
; Test auf Abschluss eventueller Host-Datentransfers
|
|
rd_id1 ld a,(hst_by)
|
|
bit 7,a
|
|
jr nz,rd_id1
|
|
; Loeschen bzw. Umladen der Zaehler
|
|
xor a
|
|
ld (err_cd),a
|
|
ld (k_flg),a
|
|
ld a,(c_zt)
|
|
ld (ct_zt),a ;Zaehler fuer Zeitueberwachung
|
|
ld a,(c_cd)
|
|
ld (ct_cd),a ;Zaehler fuer CRC-Fehler im Datenfeld
|
|
ld a,(c_sc)
|
|
ld (ct_sc),a ;Zaehler fuer 'kein richtiges Kennfeld'
|
|
nx_sc
|
|
ld a,40
|
|
ld (sc_cnt),a ;Sektorzaehler
|
|
nx_sc1
|
|
; Ausschaltimpuls fuer DSS
|
|
ld a,(st_ina)
|
|
out (DSKC2),a
|
|
out (IMPAUS),a
|
|
; Ausgabe der Bitmuster der Marken fuer Takt und Daten
|
|
ld a,0a1h ;Datenbits
|
|
out (BM_D),a
|
|
ld a,0ah ;Taktbits
|
|
out (BM_T),a
|
|
; Berechnung des Disk-Adresszaehlers fuer das Datenfeld
|
|
ld hl,(dt_br)
|
|
ld bc,11
|
|
add hl,bc
|
|
res 4,h
|
|
call b_daz
|
|
ld (dsk_az),hl
|
|
; Vorbereiten der '-Register
|
|
exx
|
|
ld a,(st_ina)
|
|
ld b,a
|
|
ld a,(st_akt)
|
|
ld c,a
|
|
ld a,0f0h ;DEND zur Steuerungsumschaltung
|
|
ld e,a
|
|
exx
|
|
|
|
;--------------------------------
|
|
; Schleife zum Suchen des Sektors
|
|
;--------------------------------
|
|
nx_sec
|
|
; Loeschen eventuellen CRC-Fehler
|
|
in a,(ST_PRT)
|
|
; Richtung des Transfers ausgeben
|
|
ld a,(cnt_st) ;Ausgabebyte
|
|
res 7,a ;DR/W: Disk-->RAM
|
|
set 6,a ;DA12=1
|
|
ld (cnt_st),a
|
|
out (CNTST),a
|
|
; Vorbereiten der Ausgabewerte fuer die ISR
|
|
exx
|
|
ld hl,(dsk_az) ;HL: Adresse des Datenfeld
|
|
exx
|
|
; ISR-Adresse fuer Markenerkennung beim Kennfeld
|
|
ld hl,isr_m9
|
|
ld a,(rd_mod)
|
|
cp 1
|
|
jr z,is_ok
|
|
ld hl,isr_m1
|
|
is_ok ld (isr_mk),hl
|
|
; Laden des Disk-Adresszaehlers
|
|
ld hl,(dsk_ad)
|
|
ld (hl),a
|
|
; Laden der Disk-Endadresse fuer den CRC-Test des Kennfeldes
|
|
; Angabe der Anzahl der zu erkennenden Marken in den unteren drei Bits
|
|
ld hl,(kf_br)
|
|
ld bc,7
|
|
add hl,bc ;HL: Kennfeldadresse fuer CRC-Test & CM
|
|
ld a,l
|
|
out (DSKEA),a
|
|
; Vorbereiten der Register
|
|
ld a,(st_min) ;'MEN=inaktiv'
|
|
ld b,a
|
|
; CTC/0 fuer Markenerkennung programmieren
|
|
ld a,0c7h ;EI & Counter & High-Low-Flanke
|
|
out (CTC),a
|
|
ld a,1
|
|
out (CTC),a
|
|
; Beginn des CRC-Loeschens
|
|
ld a,(cl_crc)
|
|
out (DSKC2),a ;Loeschen des CRC-Gen./Checkers auf 'ff'
|
|
; Einschalten der Zeitueberwachung
|
|
ld a,0a7h ;Timer & VT256
|
|
out (CTC+3),a
|
|
ld a,30h ;(20h) ca. 2,0 ms
|
|
out (CTC+3),a
|
|
; Eintragen der ISR-Adresse fuer die Zeitueberwachung
|
|
ld hl,isr_zt
|
|
ld (isr_ix),hl
|
|
; Aktivieren der Schnittstelle zur Markenerkennung
|
|
ld a,(st_akt)
|
|
out (DSKC2),a ;alles aktiv zur Markenerkennung
|
|
ld a,b ;Vorbereitung fuer ISR
|
|
halt ;Warten auf das Erkennen der Marke A1
|
|
; ------- Warten auf drei Marken A1 vor dem Kennfeld ----------
|
|
|
|
halt ;Warten auf Marke
|
|
; ------- Warten auf Marke A1 vor dem Datenfeld ---------
|
|
|
|
; Loeschen der Zeitueberwachung und der Markenerkennung
|
|
hlt_2 di
|
|
ld a,3
|
|
out (CTC),a
|
|
out (CTC+3),a
|
|
ei
|
|
;-----------------------------------
|
|
; Auswertung der eingelaufenen Daten
|
|
;-----------------------------------
|
|
; Test des Identifiers
|
|
ld b,5
|
|
ld hl,(kf_br)
|
|
inc hl ;Beginn des eingelaufenen Idents
|
|
ld de,ident ;Beginn des geforderten Idents
|
|
tst_id ld a,(de)
|
|
cp (hl)
|
|
jp nz,id_e
|
|
inc hl
|
|
inc de
|
|
djnz tst_id
|
|
; CRC-Test des Identifiers
|
|
in a,(ST_PRT)
|
|
bit 7,a
|
|
jp z,id_e
|
|
; geforderter Sektor ist gefunden
|
|
ld a,(rd_mod) ;Nur Kennfeld ?
|
|
cp 1
|
|
ret z ;Rueckkehr ok.
|
|
|
|
;-----------------------------------------
|
|
; Kennfeld gefunden, Lesen des Datenfeldes
|
|
;-----------------------------------------
|
|
; Test auf Datenfeldkennzeichen
|
|
ld hl,(dt_br)
|
|
ld bc,12
|
|
add hl,bc
|
|
res 4,h
|
|
ld a,0fbh ;HL auf Datenfeldkennzeichen
|
|
cp (hl)
|
|
jp nz,tdc_er
|
|
; Zurueckschreiben des durch FB ueberschriebenen Wertes
|
|
ld a,(sav_fb) ;gerettetes Byte
|
|
ld (hl),a
|
|
; Programmierung der Disk-Schnittstelle fuer exakte Datenfelduebertragung
|
|
ld a,(st_dak)
|
|
out (DSKC2),a ;'DEN=aktiv' & 'MEN=inaktiv' & 'CRCEN=inaktiv'
|
|
ld hl,(dt_br)
|
|
ld bc,90h ;neue DEND-Adresse zur Steuerungsumschaltung
|
|
add hl,bc
|
|
ld a,l
|
|
out (DSKEA),a
|
|
; CTC/1 fuer DEND-Erkennung programmieren
|
|
ld a,0d7h ;EI & Counter & Low-High-Flanke
|
|
out (CTC+1),a
|
|
ld a,2 ;Zaehler
|
|
out (CTC+1),a
|
|
halt ;Warten auf das 2. DEND
|
|
; ------- Warten auf DEND vor dem CRC-Test -------
|
|
|
|
; Berechnung der Adresse fuer den CRC-Test
|
|
ld hl,(dt_br)
|
|
ld bc,526
|
|
add hl,bc
|
|
ld a,l
|
|
out (DSKEA),a
|
|
; Umprogrammierung der Schnittstelle auf CRC-Test
|
|
ld a,(st_min)
|
|
out (DSKC2),a ;'DEN=aktiv' & 'MEN=inaktiv' & 'CRCEN=aktiv'
|
|
; Vorbereitung fuer das Abschalten der Disk-Schnittstelle
|
|
ld a,(st_ina) ;alles inaktiv
|
|
ld c,a
|
|
ld a,0d7h
|
|
out (CTC+1),a
|
|
ld a,1
|
|
out (CTC+1),a
|
|
halt
|
|
; ------- Warten auf das DEND zum CRC-Test -------
|
|
|
|
; Programmierung fuer das Abschalten der Schnittstelle
|
|
ld a,c
|
|
out (DSKC2),a ;alles inaktiv
|
|
out (IMPAUS),a ;Schnittstelle aus
|
|
ld a,3
|
|
out (CTC+1),a ;Loeschen der Interrupts fuer DEND
|
|
out (CTC),a ;Loeschen der Interrupts fuer MAERK
|
|
|
|
;----------------------------------------
|
|
; Auswertung des eingelesenen Datenfeldes
|
|
;----------------------------------------
|
|
; Test auf CRC-Fehler
|
|
in a,(ST_PRT)
|
|
bit 7,a ;CRC-Fehler ?
|
|
jp z,tdc_er
|
|
; Retten des Anfangs des ersten Datenfeldes
|
|
ld hl,k_flg ;Steuerbyte
|
|
bit 7,(hl)
|
|
jr nz,no_sav
|
|
set 7,(hl) ;Anfang ist gerettet
|
|
ld hl,(dt_br)
|
|
ld bc,13
|
|
add hl,bc
|
|
res 4,h
|
|
ld de,sav_20
|
|
ld b,20h
|
|
call ldir23
|
|
no_sav
|
|
; Retten des letzten Datenbytes des Datenfeldes
|
|
ld hl,(dt_br)
|
|
ld bc,524
|
|
add hl,bc
|
|
res 4,h
|
|
ld a,(hl)
|
|
ld (sav_fb),a
|
|
; naechsten Sektor lesen ?
|
|
ld hl,(dt_len) ;aktuelle Datenlaenge
|
|
ld bc,200h
|
|
xor a
|
|
sbc hl,bc
|
|
ld (dt_len),hl
|
|
jr z,um_20
|
|
jp nc,n_sec
|
|
; Zurueckschreiben des Anfangs des ersten Datenfeldes
|
|
um_20 ld hl,dt
|
|
ld bc,13
|
|
add hl,bc
|
|
ex de,hl
|
|
res 4,d
|
|
ld hl,sav_20
|
|
ld b,20h
|
|
call ldir32
|
|
ld hl,k_flg
|
|
res 7,(hl) ;Flag ruecksetzen
|
|
|
|
xor a ;Flags loeschen
|
|
ret ;Rueckkehr, wenn Lesen ok.
|
|
|
|
n_sec
|
|
; Bestimmung des naechsten Bereichs im WDC-RAM
|
|
ld hl,(dt_br)
|
|
ld bc,200h
|
|
add hl,bc
|
|
res 4,h
|
|
ld (dt_br),hl
|
|
; Berechnung des Disk-Adresszaehlers fuer das Datenfeld
|
|
ld hl,(dt_br)
|
|
ld bc,11
|
|
add hl,bc
|
|
res 4,h
|
|
call b_daz
|
|
ld (dsk_az),hl
|
|
; Setzen der Fehlerzaehler fuer den neuen Sektor
|
|
ld a,10
|
|
ld (sc_cnt),a
|
|
ld a,(c_zt)
|
|
ld (ct_zt),a ;Zaehler fuer Zeitueberwachung
|
|
ld a,(c_cd)
|
|
ld (ct_cd),a ;Zaehler fuer Fehler im Datenfeld
|
|
; Bestimmung des naechsten Sektors
|
|
ld a,(secs)
|
|
ld b,a
|
|
inc b
|
|
ld hl,ident+4 ;HL zeigt auf Sektor
|
|
inc (hl)
|
|
ld a,(hl) ;Sektornummer
|
|
cp b ;max. Sektor + 1
|
|
jp c,nx_sec
|
|
ld (hl),1 ;naechste Spur, Beginn mit Sektor 1
|
|
dec hl ;HL zeigt auf Kopf
|
|
ld a,(l_inc) ;Inkrementierungszaehler
|
|
ld b,a
|
|
inc b
|
|
nx_s1 push bc ;Zaehler retten
|
|
ld a,(hds)
|
|
ld b,a
|
|
ld hl,ident+3
|
|
inc (hl) ;Kopfnummer inkr.
|
|
ld a,(hl) ;Kopfnummer
|
|
cp b ;Max. Kopf + 1
|
|
jr nc,nx_cy ;Sprung, wenn Zylinderwechsel noetig
|
|
nx_s2 pop bc
|
|
djnz nx_s1
|
|
ld a,(ident+3)
|
|
call hd_sl ;Kopfselektierung
|
|
jp nx_sc
|
|
; Zylinderwechsel waehrend eines Tranfers
|
|
nx_cy ld (hl),0 ;naechster Zyl, Beginn mit Kopf 0
|
|
dec hl ;Zyl high
|
|
ld d,(hl)
|
|
dec hl ;HL zeigt auf Zyl low
|
|
ld e,(hl)
|
|
inc de ;naechster Zylinder
|
|
push hl
|
|
ld hl,(cyls)
|
|
xor a
|
|
sbc hl,de
|
|
pop hl
|
|
jp p,nxs ;Sprung, wenn Zyl ok
|
|
pop bc
|
|
ld a,04h ;Fehlercode: Zyl zu gross
|
|
ld (err_cd),a
|
|
cp 0
|
|
ret
|
|
nxs ld (hl),e
|
|
inc hl
|
|
ld (hl),d
|
|
call step1
|
|
jr nx_s2
|
|
|
|
;--------------------------------------------------------------------
|
|
; Fehlerbehandlung fuer Fehler waehrend des Lesevorgangs
|
|
;--------------------------------------------------------------------
|
|
; es wird nicht der richtige Sektor gefunden
|
|
id_e ld a,(st_ina) ;alles inaktiv
|
|
out (DSKC2),a
|
|
out (IMPAUS),a ;Ausschaltimpuls
|
|
ld hl,sc_cnt ;Sektorzaehler
|
|
dec (hl)
|
|
jp nz,nx_sec
|
|
ld hl,sum_sc
|
|
ld a,0ah ;Fehlercode 0A
|
|
call d_err
|
|
jp nz,nx_sc ;sofort weitersuchen
|
|
jp err_rt ;Fehlerabbruch
|
|
; keine Marke waehrend der Zeit der Zeitueberwachung
|
|
err_mk ld hl,sum_zt
|
|
ld a,0bh ;Fehlercode 0B
|
|
call d_err
|
|
jp nz,nx_sec ;sofort weitersuchen
|
|
jp err_rt ;Fehlerabbruch
|
|
; Fehler im Datenfeld
|
|
tdc_er ld hl,sum_cd
|
|
ld a,0ch ;Fehlercode 0C
|
|
call d_err
|
|
jp z,err_rt
|
|
call dis_1 ;fast eine Umdrehung abwarten
|
|
ld a,10
|
|
ld (sc_cnt),a
|
|
jp nx_sc
|
|
; Rueckkehr mit Fehler
|
|
err_rt ld (err_cd),a ;Fehlercode
|
|
cp 0 ;Flags setzen
|
|
ret
|
|
|
|
;--- isr_m1 -------------------------------------------------
|
|
; ISR fuer den Interrupt bei der Markenerkennung des Kennfeldes
|
|
; (fuer Kennfeldlesen mit anschliessendem Datenfeldlesen
|
|
; CTC-Kanal 0
|
|
;--------------------------------------------------------------
|
|
isr_m1
|
|
out (DSKC2),a ;'MEN=inaktiv'
|
|
exx
|
|
ld a,b
|
|
out (DSKC2),a ;alles inaktiv
|
|
out (IMPAUS),a ;Abschaltimpuls
|
|
; Vorbereitung fuer das Lesen des Datenfeldes
|
|
ld (hl),a ;Laden Diskadresszaehler
|
|
ld hl,isr_m7 ;ISR-Adresse fuer Int. vor Datenfeld
|
|
ld (isr_mk),hl ;Umladen der ISR-Adresse
|
|
ld a,e
|
|
out (DSKEA),a ;DEND-Adresse fuer Markenanzahl
|
|
ld a,(cnt_st)
|
|
res 6,a ;DA12 = 0
|
|
ld (cnt_st),a
|
|
out (CNTST),a ;Umschaltung des RAM-Bereichs
|
|
ld a,c
|
|
out (DSKC2),a ;alles aktiv zur Markenerkennung
|
|
exx
|
|
|
|
;--- isr_al ------------------------------------------------
|
|
; ISR fuer allgemeine Verwendung
|
|
; alle CTC-Kanaele
|
|
;------------------------------------------------------------
|
|
isr_al ei
|
|
reti
|
|
|
|
;--- isr_m9 ------------------------------------------------
|
|
; ISR fuer Interrupt bei Markenerkennung des Kennfeldes
|
|
; (nur Kennfeldlesen)
|
|
; CTC-Kanal 0
|
|
;-------------------------------------------------------------
|
|
isr_m9
|
|
out (DSKC2),a ;'MEN=inaktiv'
|
|
nop
|
|
ld a,(st_ina)
|
|
out (DSKC2),a ;alles inaktiv
|
|
out (IMPAUS),a ;Abschaltimpuls
|
|
ld a,3
|
|
out (CTC),a ;Reset Markenerkennung
|
|
pop hl ;Verwerfen der Returnadresse
|
|
ld hl,hlt_2 ;neue Returnadresse
|
|
push hl
|
|
ei
|
|
reti
|
|
|
|
;--- isr_m7 -------------------------------------------------
|
|
; ISR fuer Interrupt bei Markenerkennung des Datenfeldes
|
|
; CTC-Kanal 0
|
|
;--------------------------------------------------------------
|
|
isr_m7 ld a,3
|
|
out (CTC),a ;Reset Markenerkennung
|
|
ei
|
|
reti
|
|
|
|
;--- isr_zt --------------------------------
|
|
; ISR fuer das Ansprechen der Zeitueberwachung
|
|
; (CTC-Kanal 3)
|
|
;---------------------------------------------
|
|
isr_zt
|
|
ld a,3
|
|
out (CTC),a
|
|
out (CTC+3),a ;Reset
|
|
pop hl ;Verwerfen der Returnadresse
|
|
ld hl,err_mk
|
|
push hl ;neue Returnadresse
|
|
ei
|
|
reti
|
|
|
|
;--- ct_um ------------------------------------
|
|
; Umladen bzw. Loeschen der Maximalfehlerzellen
|
|
; hl: Adresse des Momentanwerts 'mx_xx'
|
|
; hl+1: Adresse des Maximalwerts 'max_xx'
|
|
;------------------------------------------------
|
|
ct_um ld a,(hl) ;'mx_xx'
|
|
inc hl ;'max_xx'
|
|
cp (hl)
|
|
jr c,ct_um1
|
|
ld (hl),a ;neuen Maxwert eintragen
|
|
ct_um1 xor a
|
|
dec hl
|
|
ld (hl),a ;Loeschen Momentanwert 'mx_xx'
|
|
ret
|
|
|
|
;--- d_err -------------------------------------------------------------
|
|
; Ausschalten der Diskschnittstelle nach Fehler und Behandlung der Zaehler
|
|
; hl: Adresse des Beginns der speziellen Zaehlerzellen
|
|
; a: Fehlercode
|
|
;-------------------------------------------------------------------------
|
|
d_err ld b,a
|
|
ld a,(st_ina) ;alles inaktiv
|
|
out (DSKC2),a ;Steuerbits inaktiv
|
|
out (IMPAUS),a ;Ausschaltimpuls
|
|
inc (hl) ;Low-Teil 'sum_xx'
|
|
push af
|
|
inc hl ;Zeiger auf High-Teil 'sum_xx'
|
|
pop af
|
|
jr nz,sm_ok
|
|
inc (hl) ;Inc High-Teil 'sum_xx'
|
|
sm_ok inc hl ;Zeiger auf 'mx_xx'
|
|
; inc (hl) ;Inc 'mx_xx'
|
|
inc hl ;'max_xx' uebergehen
|
|
inc hl ;Zeiger auf 'ct_xx'
|
|
dec (hl) ;Dec 'ct_xx'
|
|
ret nz ;Return fuer Wiederholung
|
|
xor a
|
|
ld a,b ;Fehlercode
|
|
ret ;Return im Fehlerfall
|
|
|
|
;--- dis_1 -------------------------------------------------
|
|
; Programmierung Zeitinterrupt fuer fast eine Plattenumdrehung
|
|
;-------------------------------------------------------------
|
|
dis_1 push af
|
|
ld a,0a7h
|
|
out (CTC+1),a
|
|
ld a,230
|
|
out (CTC+1),a
|
|
halt
|
|
ld a,3
|
|
out (CTC+1),a
|
|
pop af
|
|
ret
|
|
eject
|
|
;--- id_ein -----------------------
|
|
; Eintragen des Kennfeldes
|
|
; hl: Zeiger auf 'Cy-L, Cy-H, Hd, Sc'
|
|
;------------------------------------
|
|
id_ein ld de,ident
|
|
ld a,0feh
|
|
ld (de),a
|
|
inc de
|
|
ld bc,4
|
|
ldir
|
|
ret
|
|
|
|
;--- step1 --------------------------------------------------------
|
|
; Verschiebung der Koepfe um einen Zylinder nach innen
|
|
;-------------------------------------------------------------------
|
|
step1 ld a,(dsk_c1) ;Ausgabebyte fuer DSKC1
|
|
set 3,a ;SD nach innen
|
|
out (DSKC1),a
|
|
xor 1 ;ST ein
|
|
di
|
|
out (DSKC1),a
|
|
xor 1 ;ST aus
|
|
out (DSKC1),a
|
|
ei
|
|
step11 in a,(ST_PRT)
|
|
bit 3,a
|
|
jr nz,step11
|
|
ld a,(cmd_br-7) ;Laufwerk
|
|
add a,a
|
|
ld c,a
|
|
ld b,0
|
|
ld hl,cy_tab ;Positionstabelle
|
|
add hl,bc
|
|
ld e,(hl) ;Low-Teil
|
|
inc hl
|
|
ld d,(hl) ;High-Teil
|
|
inc de ;Inc Zylinder
|
|
ld (hl),d
|
|
dec hl
|
|
ld (hl),e
|
|
ret ;ok.
|
|
|
|
;--- hd_sl ------------------------------------------------------
|
|
; Kopfselektierung
|
|
; A: Kopfnummer 0...max, Test auf Richtigkeit muss vorher erfolgen
|
|
;------------------------------------------------------------------
|
|
hd_sl rrca
|
|
rrca
|
|
rrca
|
|
rrca
|
|
ld b,a
|
|
ld a,(dsk_c1)
|
|
and 0fh ;Loeschen der HS-Bits
|
|
or b ;neue HS-Bits
|
|
ld (dsk_c1),a
|
|
out (DSKC1),a
|
|
ret
|
|
|
|
;--- sc_def ------------------------------------------------
|
|
; Berechnung der Sektoradresse mit Defektspurberuecksichtigung
|
|
; Sektoradresse vorher und nachher in 'ident'
|
|
;-------------------------------------------------------------
|
|
; l_inc: Anzahl der Spurinkrementierungen, um bei Mehrblock-
|
|
; transfers auf die richtige Spuradresse zu kommen
|
|
;-------------------------------------------------------------
|
|
sc_def xor a
|
|
ld (l_inc),a ;Loeschen Spurinkrementierungen
|
|
ld de,(df_end) ;Adresse
|
|
ld a,(de)
|
|
ld l,a
|
|
inc de
|
|
ld a,(de)
|
|
or l
|
|
ret z ;keine Adressinkr. noetig
|
|
ex af,af'
|
|
xor a ;Loeschen Inkrements
|
|
ex af,af'
|
|
ld de,(df_tab) ;Adresse der Tabelle der Defektspuren
|
|
dec de
|
|
; naechste Spur aus der BTT
|
|
sc2 inc de ;Zeiger auf Zylinder High
|
|
ld a,(de) ;Zyl High
|
|
ld h,a
|
|
inc de
|
|
ld a,(de) ;Zyl Low
|
|
ld l,a
|
|
inc de ;Zeiger auf Kopfnummer
|
|
; Endekennzeichen ?
|
|
push hl
|
|
ld bc,0ffffh ;Endekennzeichen
|
|
xor a
|
|
sbc hl,bc
|
|
pop hl
|
|
jp z,sc4 ;Sprung, wenn Ende der Defektspuren
|
|
; Spur_def <= geforderte Spur ?
|
|
ld bc,(ident+1) ;Zyl-gef
|
|
xor a
|
|
sbc hl,bc
|
|
jp c,sc3
|
|
jp nz,sc4
|
|
; Cyl-gef = Cyl-def, Test der Kopfnummer
|
|
ld a,(de) ;Kopf defekt
|
|
ld b,a
|
|
ld a,(ident+3) ;Kopf
|
|
sub b ;Kopf - Kopf-def
|
|
jp c,sc4
|
|
; Zaehler erhoehen
|
|
sc3 ex af,af'
|
|
inc a
|
|
ex af,af'
|
|
jp sc2
|
|
; Erhoehung der Spuradresse
|
|
sc4 dec de ;Zeiger auf vorhergehenden BTT-Eintrag
|
|
dec de
|
|
dec de
|
|
ex af,af'
|
|
ld b,a
|
|
xor a ;Zaehler loeschen
|
|
ex af,af'
|
|
ld a,b
|
|
cp 0
|
|
jr z,sc7
|
|
ld b,a ;Anzahl der Inkrementierungen
|
|
sc5 ld a,(hds)
|
|
ld c,a
|
|
ld a,(ident+3) ;Kopf
|
|
inc a
|
|
ld (ident+3),a
|
|
cp c
|
|
jr nz,sc6
|
|
xor a
|
|
ld (ident+3),a
|
|
ld hl,(ident+1) ;Zylinder
|
|
inc hl
|
|
ld (ident+1),hl
|
|
sc6 djnz sc5
|
|
jp sc2 ;Test auf weitere BTT-Eintragungen
|
|
; Test, ob naechste Spur defekt ist (fuer Mehrblocktransfer)
|
|
sc7 ld hl,(dt_len)
|
|
ld bc,201h
|
|
xor a
|
|
sbc hl,bc
|
|
ret c ;Return, wenn nur ein Block
|
|
ld hl,(ident+1) ;Zyl_akt
|
|
ld a,(ident+3) ;Hd_akt
|
|
ld b,a
|
|
sc9 inc de ;DE: Zeiger auf Zyl_btt_high
|
|
inc b ;naechster Kopf
|
|
ld a,(hds) ;Kopfanzahl
|
|
ld c,a
|
|
ld a,b
|
|
cp c
|
|
jr c,sc8
|
|
ld b,0 ;naechster Kopf ist 0
|
|
inc hl ;naechster Zyl
|
|
sc8 ld a,(de) ;Zyl_btt_high
|
|
cp h ;Zyl_akt_high
|
|
ret nz ;naechste Spur ist keine BTT-Spur
|
|
inc de
|
|
ld a,(de) ;Zyl_btt_low
|
|
cp l ;Zyl_akt_low
|
|
ret nz ;naechste Spur ist keine BTT-Spur
|
|
inc de
|
|
ld a,(de) ;Hd_btt
|
|
cp b ;Hd_akt
|
|
ret nz ;naechste Spur ist keine BTT-Spur
|
|
ld a,(l_inc) ;Zaehler inkrementieren
|
|
inc a
|
|
ld (l_inc),a
|
|
jr sc9 ;naechste Spur auch BTT-Spur ?
|
|
eject
|
|
;***********************************************************
|
|
; Schreiben auf Hard-Disk
|
|
;***********************************************************
|
|
write
|
|
; Setzen der Fehlerzaehler
|
|
ld de,c_zt
|
|
ld hl,fe_n
|
|
ld bc,7
|
|
ldir
|
|
; Auswertung des Kommandocodes
|
|
ld a,(cmd_br-8) ;Kommandocode
|
|
cp 0c2h ;Schreiben 'PAR&BTT' ?
|
|
jp z,wr_df
|
|
call wr_dt ;Schreiben des Datenfeldes
|
|
jp nz,error
|
|
jp begin
|
|
|
|
;----------------------------------------------------------------------
|
|
; Schreiben 'PAR&BTT' auf den Sektor 0/0/1
|
|
;----------------------------------------------------------------------
|
|
wr_df
|
|
ld hl,200h
|
|
ld (cmd_br-2),hl
|
|
ld (dt_len),hl
|
|
; Eintragen 'DEFEKT'
|
|
ld hl,dt
|
|
ld (dt_br),hl
|
|
ld bc,13
|
|
add hl,bc
|
|
res 4,h
|
|
push hl
|
|
ex de,hl
|
|
ld hl,txt_df
|
|
ld bc,6
|
|
ldir
|
|
; Umladen der Defektspurtabelle
|
|
ld hl,(df_end)
|
|
ld bc,40*3+3+2
|
|
ldir
|
|
; Eintragen 'PARMTR'
|
|
pop hl
|
|
ld bc,256
|
|
add hl,bc
|
|
res 4,h
|
|
ex de,hl
|
|
ld hl,txt_pm
|
|
ld bc,6
|
|
ldir
|
|
; Umladen der Parametertabelle
|
|
call par_v
|
|
; Untersuchung der umgeladenen Tabellen
|
|
call t_par ;Test der Parameter
|
|
jp nz,err_17 ;Fehler, kein Schreiben
|
|
call t_btt ;Test der Defektspurtabelle
|
|
jr nz,wr_df1 ;Sprung, wenn fehlerhafte BTT
|
|
call btt_s ;Setzen des BTT-Bits
|
|
jr wr_df2
|
|
; Loeschen des BTT-Bereichs
|
|
wr_df1 call btt_cl ;Loeschen der BTT im 3000-RAM
|
|
call btt_v ;Umladen in den Datenbereich des 1. Sektors
|
|
call btt_r ;Ruecksetzen des BTT-Bits
|
|
wr_df2 call wr_dt ;Aufruf des Schreibprogramms
|
|
jr nz,wr_df7
|
|
call par_s ;Setzen des PAR-Bits
|
|
jp entry
|
|
wr_df7 call par_r ;Ruecksetzen des PAR-Bits
|
|
call btt_r ;Ruecksetzen des BTT-Bits
|
|
jp error
|
|
|
|
;--- wr_dt -----------------------------------------------------------
|
|
; UP Aufruf des Schreibprogramms
|
|
;---------------------------------------------------------------------
|
|
wr_dt
|
|
ld a,4
|
|
ld (ct_ra),a ;Zaehler fuer Schreibwiederholungen
|
|
wr_dt1 call wrt_dt ;Schreiben des Datenfeldes
|
|
ret nz ;Schreibfehler
|
|
ld a,(cmd_br-8) ;Kommandocode
|
|
bit 7,a ;'Read after Write' ?
|
|
ret z
|
|
; Setzen der Fehlerzaehler fuer das Lesen
|
|
ld de,c_zt
|
|
ld hl,fe_n
|
|
ld bc,7
|
|
ldir
|
|
; Lesen von Hard-Disk
|
|
ld a,0
|
|
ld (rd_mod),a
|
|
call rd_id
|
|
ret ;Ruecksprung bei 'Read after Write'
|
|
; Fehler, Fehlerzaehlerbehandlung
|
|
ld hl,(sum_ra)
|
|
inc hl
|
|
ld (sum_ra),hl
|
|
ld hl,mx_ra
|
|
; inc (hl)
|
|
ld hl,ct_ra
|
|
dec (hl)
|
|
jp nz,wr_dt1
|
|
ld a,11h ;Fehlercode 11h
|
|
ld (err_cd),a
|
|
cp 0
|
|
ret ;Fehlerruecksprung bei 'Read after Write'
|
|
eject
|
|
;***************************************************************************
|
|
; UP wrt_dt
|
|
; Schreiben des Datenfeldes eines Sektors
|
|
;***************************************************************************
|
|
wrt_dt
|
|
; Initialisierung von 'dt_br'
|
|
ld hl,dt
|
|
ld (dt_br),hl
|
|
; Setzen der Fehlerzaehler fuer das Schreiben
|
|
ld a,3
|
|
ld (ct_fw),a ;Zaehler fuer Fault-Write-Fehler
|
|
ld a,3
|
|
ld (ct_wi),a ;Zaehler fuer Identfehler vor dem Schreiben
|
|
; Umspeichern des aktuellen Sektors,
|
|
; da in 'ident' fuer das Lesen geaendert wird
|
|
ld a,(ident+4) ;geforderte Sektornummer
|
|
ld (sc_akt),a ;retten des aktuellen Sektors
|
|
; Bestimmung der vorhergehenden Sektornummer (fuer das Schreiben)
|
|
suche ld a,(sc_akt) ;aktuelle Sektornummer
|
|
ld hl,sc_tab ;Tabelle des Sektorversatz
|
|
vs_sl cp (hl)
|
|
jr z,vs_ok
|
|
inc hl
|
|
jr vs_sl
|
|
vs_ok dec hl ;HL zeigt auf Vorgaenger
|
|
ld a,(hl)
|
|
cp 0ffh ;vor Sektor 1
|
|
jr nz,vs_ok1
|
|
ld a,(secs)
|
|
ld c,a
|
|
ld b,0
|
|
ld hl,sc_tab-1
|
|
add hl,bc
|
|
ld a,(hl) ;letzter Sektor vor Sektor 1
|
|
vs_ok1 ld (ident+4),a ;vorhergehende Sektornummer
|
|
; Test auf Abschluss eventueller Host-Datentransfers
|
|
wr_sl1 ld a,(hst_by)
|
|
bit 7,a
|
|
jr nz,wr_sl1
|
|
; Retten des Praeambelbereichs des Sektors
|
|
ld hl,(dt_br) ;Beginn der Praeambel
|
|
ld de,s_prae ;Rettungsbereich
|
|
ld b,13
|
|
call ldir23 ;Umladen
|
|
; Lesen des vorhergehenden Sektorkennfeldes
|
|
ld a,1 ;Kennfeldlesen
|
|
ld (rd_mod),a
|
|
call rd_id1 ;Kennfeldlesen ohne Bereichsweiterschaltung
|
|
ret nz ;Fehler im Kennfeld
|
|
; Retten des Postambel-Bereichs
|
|
nx_wrt ld hl,(dt_br)
|
|
ld bc,525
|
|
add hl,bc ;Beginn der Postambel
|
|
res 4,h
|
|
ld de,s_post ;Rettungsbereich fuer Postambel
|
|
ld bc,12 ;Laenge der Postambel
|
|
ldir
|
|
; Eintragen der Praeambel und der Postambel
|
|
ld de,(dt_br) ;Beginn der Praeambel
|
|
ld hl,prae ;Praeambel
|
|
ld bc,11 ;Laenge der Praeambel
|
|
ldir
|
|
res 4,d
|
|
ld bc,2
|
|
ldir
|
|
ld hl,(dt_br)
|
|
ld bc,525
|
|
add hl,bc
|
|
res 4,h
|
|
ex de,hl ;Beginn der Postambel
|
|
ld hl,post ;Postambel
|
|
ld bc,12 ;Laenge der Postambel
|
|
ldir
|
|
; Setzen des Sektor-Index-Zaehlers
|
|
ld a,4
|
|
ld (c_s_ix),a
|
|
; Vorbereitung des Schreibens
|
|
nx_wr1 ld a,(cnt_st)
|
|
res 7,a ;DR/W: Disk-->RAM (Lesen)
|
|
set 6,a ;DA12=1
|
|
ld (cnt_st),a
|
|
out (CNTST),a
|
|
ld hl,(kf_br)
|
|
dec hl
|
|
ld a,l
|
|
out (DSKEA),a ;DEND-Adresse bereinigen
|
|
ld a,0a1h
|
|
out (BM_D),a ;Datenbits der Marke
|
|
ld hl,(kf_br)
|
|
call b_daz
|
|
ld (hl),a ;Diskadresszaehler fuer das Kennfeld
|
|
ld hl,isr_m2 ;Eintragen der neuen ISR
|
|
ld (isr_mk),hl
|
|
ld hl,(dt_br) ;Anfangsadresse der Daten
|
|
call b_daz ;Berechnung des Disk-Adresszaehlers
|
|
push hl
|
|
exx
|
|
ex af,af'
|
|
ld hl,(dt_br) ;DEND-Adresse fuer Markeneinblenden
|
|
ld bc,11
|
|
add hl,bc
|
|
ld e,l
|
|
pop hl ;Disk-Adresszaehler
|
|
ld a,(st_wa)
|
|
ld c,a ;'WG=aktiv'
|
|
res 3,a ;'WG=inaktiv'
|
|
ld b,a
|
|
ld a,4 ;PRAEOFF & MFM & eine Marke
|
|
ld d,a
|
|
push hl
|
|
push bc
|
|
ld a,(cmd_br-7) ;akt. Laufwerk
|
|
call cy_pos
|
|
ld b,(hl) ;Low-Teil Zylinderposition
|
|
inc hl
|
|
ld h,(hl) ;High-Teil Zylinderposition
|
|
ld l,b
|
|
ld bc,(pre_cy) ;Praekompensationsbeginn
|
|
xor a
|
|
sbc hl,bc
|
|
pop bc
|
|
pop hl
|
|
jr c,pre_ok
|
|
ld a,0ch ;PRAEON & MFM & eine Marke
|
|
ld d,a
|
|
pre_ok
|
|
ld a,(cnt_st)
|
|
set 7,a ;DR/W: RAM-->Disk
|
|
res 6,a ;DA12=0
|
|
ld (cnt_st),a
|
|
ex af,af'
|
|
exx
|
|
; Programmierung CTC/0 auf MAERK
|
|
ld a,0c7h
|
|
out (CTC),a
|
|
ld a,1
|
|
out (CTC),a
|
|
; Einschalten der DSS zur Erkennung des Kennfeldes des zu schreibenden S.
|
|
ld hl,(kf_br)
|
|
ld bc,5
|
|
add hl,bc ;zeigt auf Sektornummer im Kennfeld
|
|
ld a,(sc_akt) ;aktuelle Sektornummer
|
|
ld b,a
|
|
ld a,(st_min) ;Schnittstelle aktiv mit 'MEN=inaktiv'
|
|
out (DSKC2),a
|
|
ld a,(st_vb) ;'DEN=inaktiv' als Vorbereitung zum Abschalten
|
|
out (DSKC2),a
|
|
ld a,3 ;Vorbereitung fuer CTC-Reset
|
|
halt
|
|
; ------ Warten auf drei A1 des Kennfeldes vor dem Schreiben ------
|
|
; ------ Interruptserviceroutine 'isr_m2' -------------------------
|
|
ld hl,(kf_br)
|
|
ld bc,5
|
|
add hl,bc
|
|
ld a,(sc_akt)
|
|
ld b,a
|
|
ld a,(hl)
|
|
cp b ;Sektornummer richtig ?
|
|
jp nz,wr_err
|
|
ld hl,(dt_br)
|
|
ld bc,93
|
|
add hl,bc
|
|
ld a,l
|
|
out (DSKEA),a ;DEND-Adresse fuer das Umschalten
|
|
ld a,0d5h
|
|
out (CTC+1),a
|
|
ld a,2 ;Interrupt nach zwei DEND
|
|
out (CTC+1),a
|
|
; Rueckschreiben des Praeambelbereichs des Sektors
|
|
ld hl,(dt_br)
|
|
ex de,hl
|
|
ld hl,s_prae
|
|
ld bc,11
|
|
ldir
|
|
res 4,d
|
|
ld bc,2
|
|
ldir
|
|
halt ;Warten auf das 2. DEND
|
|
; ---- Warten auf Zwischeninterrupt -------------------
|
|
|
|
ld hl,(dt_br)
|
|
ld bc,525 ;DEND-Adresse zum CRC-Einblenden
|
|
add hl,bc
|
|
ld a,l
|
|
out (DSKEA),a
|
|
ld a,(st_wc) ;Steuerbits zum CRC-Einblenden
|
|
out (DSKC2),a
|
|
ld a,0d7h
|
|
out (CTC+1),a
|
|
ld a,1
|
|
out (CTC+1),a ;Interrupt beim CRC-Einblenden
|
|
; Vorbereitung der nachfolgenden Operationen
|
|
ld a,(st_ina) ;alles inaktiv
|
|
halt ;Warten auf den CRC-Interrupt
|
|
; --- Warten -------------------
|
|
|
|
out (DSKC2),a
|
|
out (IMPAUS),a ;Disk-Schnittstelle aus
|
|
ld a,3
|
|
out (CTC+1),a ;CTC/1-Reset (DEND)
|
|
in a,(ST_PRT)
|
|
bit 5,a ;'Fault write=aktiv ?'
|
|
jp z,wr_fw
|
|
; naechsten Sektor schreiben ?
|
|
ld hl,(dt_len) ;aktuelle Datenlaenge
|
|
ld bc,200h
|
|
xor a
|
|
sbc hl,bc
|
|
ld (dt_len),hl
|
|
ret z ;Schreiben ok.
|
|
ret c ;Schreiben ok.
|
|
|
|
; Berichtigung des Postambelbereichs
|
|
ld hl,(dt_br)
|
|
ld bc,525
|
|
add hl,bc
|
|
res 4,h
|
|
ex de,hl ;Postambel
|
|
ld hl,s_post ;Rettungsbereich fuer Postambel
|
|
ld bc,12
|
|
ldir
|
|
; Bestimmung der RAM-Adressen fuer den naechsten Sektor
|
|
ld hl,(dt_br)
|
|
ld bc,200h
|
|
add hl,bc
|
|
res 4,h
|
|
ld (dt_br),hl
|
|
; Loeschen des Zylinderwechsel-Flag
|
|
ld hl,ch_cyl
|
|
ld (hl),0
|
|
; Bestimmung des naechsten Sektors
|
|
ld a,(secs)
|
|
ld b,a
|
|
inc b
|
|
ld hl,sc_akt ;aktueller Sektor
|
|
inc (hl)
|
|
ld a,(hl) ;Sektornummer
|
|
cp b ;max. Sektor + 1
|
|
jp c,nx_wrt
|
|
; Kopfwechsel waehrend eines Zugriffs
|
|
ld a,1
|
|
ld (sc_akt),a
|
|
ld hl,ident+4 ;zeigt auf Sektornummer
|
|
ld (hl),a ;naechster Sektor, Beginn mit Sektor 1
|
|
dec hl ;HL zeigt auf Kopf
|
|
ld a,(l_inc) ;Inkrementierungszaehler
|
|
ld b,a
|
|
inc b
|
|
n_cy1 push bc
|
|
ld a,(hds)
|
|
ld c,a
|
|
ld hl,ident+3 ;Kopfnummer
|
|
inc (hl) ;Kopfnummer inkr.
|
|
ld a,(hl) ;Kopfnummer
|
|
cp c ;Max. Kopf + 1
|
|
jr nc,n_cy ;Sprung, wenn Zylinderwechsel
|
|
n_cy2 pop bc
|
|
djnz n_cy1
|
|
ld a,(ident+3)
|
|
call hd_sl ;Kopfselektierung
|
|
ld a,(ch_cyl)
|
|
cp 0
|
|
jp z,nx_wrt ;Schreiben des Sektors
|
|
jp suche ;Orientieren auf der Spur
|
|
; Zylinderwechsel waehrend eines Zugriffs
|
|
n_cy ld (hl),0 ;naechster Zyl, Beginn mit Kopf 0
|
|
dec hl ;Zyl high
|
|
ld d,(hl)
|
|
dec hl ;HL zeigt auf Zyl low
|
|
ld e,(hl)
|
|
inc de ;naechster Zylinder
|
|
push hl
|
|
ld hl,(cyls) ;max. Zylinder + 1
|
|
xor a
|
|
sbc hl,de
|
|
pop hl
|
|
jp p,nxd ;Sprung, wenn Zyl ok.
|
|
pop bc
|
|
ld a,04h ;Fehlercode: Zyl zu gross
|
|
ld (err_cd),a
|
|
cp 0
|
|
ret ;Fehlerrueckkehr
|
|
; Kopfauswahl bzw. Zylinderauswahl
|
|
nxd ld (hl),e
|
|
inc hl
|
|
ld (hl),d
|
|
call step1
|
|
ld hl,ch_cyl
|
|
ld (hl),1
|
|
jr n_cy2
|
|
|
|
; Fehler vor dem Schreiben (falsche Sektornummer)
|
|
wr_err ld hl,c_s_ix ;erlaubte falsche Sektornummern
|
|
dec (hl)
|
|
jp nz,nx_wr1 ;sofort den naechsten Sektor schreiben
|
|
ld hl,sum_wi
|
|
ld a,12h ;Fehlercode 12
|
|
call d_err
|
|
jr nz,wr_er2
|
|
ld (err_cd),a
|
|
cp 0
|
|
ret
|
|
wr_er2 call r_post ;Berichtigung des Postambelbereichs
|
|
ld hl,(dt_br)
|
|
ex de,hl
|
|
ld hl,s_prae
|
|
ld bc,11
|
|
ldir
|
|
res 4,d
|
|
ld bc,2
|
|
ldir
|
|
jp suche ;neu orientieren auf der Spur
|
|
|
|
; Fehler beim Schreiben
|
|
wr_fw ld a,(st_ina)
|
|
set 7,a ;'FR=aktiv'
|
|
out (DSKC2),a
|
|
out (IMPAUS),a ;Schnittstelle aus
|
|
res 7,a ;FR ruecksetzen
|
|
out (DSKC2),a
|
|
ld hl,sum_fw
|
|
ld a,10h ;Fehlercode 10h
|
|
call d_err
|
|
jr nz,wr_fw1
|
|
ld (err_cd),a
|
|
cp 0
|
|
ret
|
|
wr_fw1 call r_post ;Berichtigung des Postambelbereichs
|
|
jp suche
|
|
|
|
;--- isr_m2 ---------------------------------------------------------
|
|
; ISR fuer den Interrupt nach Erkennung von drei A1 vor dem Kennfeld
|
|
; beim Schreiben
|
|
;--------------------------------------------------------------------
|
|
isr_m2
|
|
out (CTC),a ;Reset CTC/0 (MAERK)
|
|
out (IMPAUS),a ;Schnittstelle aus
|
|
ld a,(hl)
|
|
cp b
|
|
jr nz,isr_m3
|
|
exx
|
|
ex af,af'
|
|
out (CNTST),a ;Richtungsumsteuerung der Schnittstelle
|
|
ld (hl),a ;neuer Disk-Adresszaehler
|
|
ld a,e ;DEND-Adresse zum Markeneinblenden holen
|
|
out (DSKEA),a
|
|
ld a,d
|
|
out (BM_D),a ;MFM
|
|
ld a,b
|
|
out (DSKC2),a ;alles aktiv zum Schreiben
|
|
ld a,c ;'WG=aktiv'
|
|
out (DSKC2),a
|
|
ex af,af'
|
|
exx
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
ld a,(st_wm)
|
|
out (DSKC2),a ;'MEN=inaktiv' & 'CRCEN=inaktiv'
|
|
isr_m3
|
|
ei
|
|
reti
|
|
|
|
;-- r_post --------------------------------------------------
|
|
; Rueckschreiben Postambelbereich
|
|
;--------------------------------------------------------------
|
|
r_post ld hl,(dt_br)
|
|
ld bc,525
|
|
add hl,bc
|
|
res 4,h
|
|
ex de,hl ;Postambel
|
|
ld hl,s_post ;Rettungsbereich fuer Postambel
|
|
ld bc,12
|
|
ldir
|
|
ret
|
|
|
|
;--- ldir23 ------------------------------------------------
|
|
; Umladen von RAM-Bereich 2000...2fff nach RAM-Bereich 3000,
|
|
; wobei die Adresse im 2000-Bereich "rund" laeuft
|
|
; HL: Quelle (2000...2fff), DE: Ziel (3000), B: Anzahl
|
|
;-------------------------------------------------------------
|
|
ldir23 ld a,(hl)
|
|
ld (de),a ;Umladen
|
|
inc hl
|
|
res 4,h
|
|
inc de
|
|
djnz ldir23
|
|
ret
|
|
|
|
;--- ldir32 ------------------------------------------------
|
|
; Umladen von RAM-Bereich 3000 nach RAM-Bereich 2000...2fff,
|
|
; wobei die Adresse im 2000-Bereich "rund" laeuft
|
|
; HL: Quelle (3000), DE: Ziel (2000...2fff), B: Anzahl
|
|
;-------------------------------------------------------------
|
|
ldir32 ld a,(hl)
|
|
ld (de),a ;Umladen
|
|
inc hl
|
|
inc de
|
|
res 4,d
|
|
djnz ldir32
|
|
ret
|
|
eject
|
|
;**********************************
|
|
; Formatierprogramme fuer Hard-Disk
|
|
;**********************************
|
|
format
|
|
ld hl,200h
|
|
ld (cmd_br-2),hl ;Laenge setzen
|
|
ld (dt_len),hl
|
|
; Zeitkonstante schon bestimmt ?
|
|
ld a,(ztk)
|
|
and a
|
|
jp nz,ztk_ok
|
|
ld a,(cmd_br-8)
|
|
cp 84h ;Spurloeschen ?
|
|
jp z,ztk_ok
|
|
;-----------------------------------------------------------
|
|
; Bestimmung der Zeitkonstanten fuer das Formatieren
|
|
;-----------------------------------------------------------
|
|
; Laufwerk mit 17 Sektoren ?
|
|
ld a,(ztk_41)
|
|
ld (ztk),a ;Voreinstellen ztk
|
|
ld a,(secs)
|
|
cp 17
|
|
jp z,ztk_ok
|
|
ld hl,isr_al
|
|
ld (isr_ix),hl ;ISR-Adresse
|
|
ld hl,ztk_f ;HL zeigt auf Hilfsfeld
|
|
ld b,8 ;8 Durchlaeufe
|
|
ztk_1 ld a,0d5h ;Counter, EI
|
|
out (CTC+3),a
|
|
ld a,1
|
|
out (CTC+3),a
|
|
halt
|
|
;---- Warten auf den naechsten IX-Impuls ----
|
|
;---- ISR 'isr_al' --------------------------
|
|
ld a,027h ;Timer ohne Interrupt
|
|
out (CTC+1),a
|
|
ld a,0
|
|
out (CTC+1),a
|
|
halt
|
|
;---- Warten auf den naechsten IX-Impuls ----
|
|
;---- ISR 'isr_al' --------------------------
|
|
ld a,3 ;RESET
|
|
out (CTC+3),a
|
|
in a,(CTC+1) ;Lesen Zaehlerstand
|
|
ld (hl),a ;sichern
|
|
ld a,3 ;RESET
|
|
out (CTC+1),a
|
|
inc hl
|
|
djnz ztk_1
|
|
; Summieren des Hilfsfeldes
|
|
ld b,8
|
|
ld hl,0
|
|
ld de,ztk_f
|
|
ztk_2 push bc
|
|
ld b,0
|
|
ld a,(de)
|
|
ld c,a
|
|
add hl,bc
|
|
inc de
|
|
pop bc
|
|
djnz ztk_2
|
|
; Division durch 8
|
|
ld b,3
|
|
ztk_3 srl l
|
|
srl h
|
|
jr nc,ztk_4
|
|
set 7,l
|
|
ztk_4 djnz ztk_3
|
|
ld a,l
|
|
; 'ztk' im 41,4-MHz-Bereich ?
|
|
ld hl,zmn_41 ;Zeiger auf Grenzwerte
|
|
cp (hl)
|
|
jr c,ztk_6 ;Sprung, wenn kleiner
|
|
inc hl ;Zeiger auf 'zmx_41'
|
|
ld b,(hl)
|
|
inc b
|
|
cp b
|
|
jr nc,ztk_5 ;Sprung, wenn groesser
|
|
ld a,(ztk_41) ;Zeitkonstante fuer 41,4 MHz
|
|
ld (ztk),a
|
|
jr ztk_ok
|
|
; 'ztk' im 40,0-MHz-Bereich ?
|
|
ztk_5 dec hl
|
|
dec hl
|
|
dec hl ;Zeiger auf 'zmn_40'
|
|
cp (hl)
|
|
jr c,ztk_6 ;Sprung, wenn kleiner
|
|
inc hl ;Zeiger auf 'zmx_40'
|
|
ld b,(hl)
|
|
cp b
|
|
jr nc,ztk_6 ;Sprung, wenn groesser
|
|
ld a,(ztk_40) ;Zeitkonstante fuer 40,0 MHz
|
|
ld (ztk),a
|
|
jr ztk_ok
|
|
; Fehler waehrend der Zeitkonstantenbestimmung
|
|
ztk_6 xor a
|
|
ld (ztk),a
|
|
jp err_15
|
|
; Ende der Zeitkonstantenbestimmung
|
|
|
|
ztk_ok ld a,(cmd_br-8)
|
|
cp 04h
|
|
jp z,frmt1
|
|
cp 14h
|
|
jp z,frmt2
|
|
cp 24h
|
|
jp z,frmt3
|
|
cp 44h
|
|
jp z,frmt4
|
|
cp 84h
|
|
jr z,frmt1
|
|
jp err_1
|
|
;---------------------------------
|
|
; Einfaches Formatieren einer Spur
|
|
;---------------------------------
|
|
frmt1
|
|
call ft_trk
|
|
jp nz,error
|
|
jp begin
|
|
|
|
;---------------------------------------------
|
|
; Formatieren einer Spur mit Test der Sektoren
|
|
;---------------------------------------------
|
|
frmt2
|
|
; Formatieren der Spur
|
|
call ft_trk
|
|
jp nz,error
|
|
; Ruecklesen der Einzelsektoren
|
|
frmt4
|
|
ld de,c_zt
|
|
ld hl,fe_n
|
|
ld bc,7
|
|
ldir
|
|
ld a,1
|
|
ld (ident+4),a ;Sektor
|
|
ld hl,2400h ;18 Sektoren
|
|
ld a,(secs)
|
|
cp 18
|
|
jr z,frmt41
|
|
ld hl,2200h ;17 Sektoren
|
|
frmt41 ld (dt_len),hl
|
|
ld a,0
|
|
ld (rd_mod),a
|
|
call rd_id
|
|
jp nz,error
|
|
jp begin
|
|
|
|
;-------------------------------------------------------------
|
|
; Formatieren einer Spur mit Defektfeststellung und Eintragung
|
|
; in die Defektspurtabelle
|
|
;-------------------------------------------------------------
|
|
frmt3
|
|
ld de,c_zt
|
|
ld hl,fe_f1
|
|
ld bc,7
|
|
ldir
|
|
ld a,3
|
|
ld (dl_f),a ;Anfangswert
|
|
f301
|
|
ld hl,dl_f
|
|
dec (hl)
|
|
jp z,f_def
|
|
call ft_trk ;Formatieren einer Spur
|
|
jp nz,f301
|
|
; Ruecklesen der Einzelsektoren
|
|
ld a,2
|
|
ld (dl_r),a ;Anfangswert
|
|
f302 ld hl,dl_r
|
|
dec (hl)
|
|
jp z,begin ;Formatierung ok.
|
|
ld a,1
|
|
ld (ident+4),a ;Sektor
|
|
ld hl,2400h ;18 Sektoren
|
|
ld a,(secs)
|
|
cp 18
|
|
jr z,f303
|
|
ld hl,2200h ;17 Sektoren
|
|
f303 ld (dt_len),hl
|
|
ld a,0
|
|
ld (rd_mod),a
|
|
call rd_id
|
|
jp nz,f301
|
|
jp f302
|
|
|
|
; Eintragen der Adresse der Defektspur in die Defektspurtabelle
|
|
; df_tab : Anfangsadresse der Defektspurtabelle
|
|
; df_end : Adresse des Beginns der Eintragung des Endekennzeichens
|
|
f_def
|
|
xor a
|
|
ld (err_cd),a ;Loeschen Fehlercode
|
|
ld hl,(df_end)
|
|
ld c,(hl)
|
|
inc hl
|
|
ld b,(hl) ;BC: Anzahl schon eingetragener Spuren
|
|
ld hl,39*3 ;Maximum = 120 ( -3)
|
|
xor a
|
|
sbc hl,bc
|
|
jp c,err_16 ;Fehler 16: BTT voll
|
|
ld hl,(df_tab) ;Beginn der aktuellen BTT
|
|
f350 ld a,(ident+2) ;High-Teil Zylinder
|
|
ld b,a
|
|
ld a,(hl)
|
|
cp b
|
|
jp c,f351
|
|
jp nz,f358
|
|
inc hl
|
|
ld a,(ident+1) ;Low-Teil Zylinder
|
|
ld b,a
|
|
ld a,(hl)
|
|
cp b
|
|
jp c,f352
|
|
jp nz,f357
|
|
inc hl
|
|
ld a,(ident+3) ;Kopf
|
|
ld b,a
|
|
ld a,(hl)
|
|
cp b
|
|
jp c,f353
|
|
jp z,begin ;Eintragung schon vorhanden
|
|
; Verschieben der Resttabelle nach hinten
|
|
dec hl
|
|
f357 dec hl
|
|
f358 ex de,hl ;DE: unterste Adresse zum Umladen
|
|
push de
|
|
ld hl,(df_end) ;Adresse des Endwertes
|
|
push de
|
|
ld e,(hl)
|
|
inc hl
|
|
ld d,(hl)
|
|
ex de,hl
|
|
pop de
|
|
ld bc,(df_tab)
|
|
add hl,bc
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
push hl ;HL: erster freier Platz nach Endek.
|
|
xor a
|
|
sbc hl,de
|
|
push hl
|
|
pop bc ;BC: Anzahl der umzuladenden Bytes
|
|
pop hl
|
|
dec hl ;Quelle: oberstes Byte
|
|
push hl
|
|
pop de
|
|
inc de
|
|
inc de
|
|
inc de ;Ziel: oberstes Byte
|
|
lddr ;Verschieben der Resttabelle
|
|
pop de
|
|
ex de,hl
|
|
; Eintragen der defekten Spuradresse
|
|
ld a,(ident+2) ;High-Teil Zylinder
|
|
ld (hl),a
|
|
inc hl
|
|
ld a,(ident+1) ;Low-Teil Zylinder
|
|
ld (hl),a
|
|
inc hl
|
|
ld a,(ident+3) ;Kopf
|
|
ld (hl),a
|
|
ld de,(df_end)
|
|
ld a,(de)
|
|
ld l,a
|
|
inc de
|
|
ld a,(de)
|
|
ld h,a
|
|
ld bc,3
|
|
add hl,bc
|
|
dec de
|
|
ld a,l
|
|
ld (de),a
|
|
inc de
|
|
ld a,h
|
|
ld (de),a
|
|
; Ausgabe der Adresse des defekten Sektors an den Host
|
|
ld bc,3
|
|
ld hl,ident+3
|
|
ld a,3 ;Status 3
|
|
call p_wc_h
|
|
jp begin
|
|
; naechste Eintragung
|
|
f351 inc hl
|
|
f352 inc hl
|
|
f353 inc hl
|
|
; Ende-Test
|
|
ld a,(hl)
|
|
cp 0ffh
|
|
jp nz,f350
|
|
jp f358
|
|
eject
|
|
;*************************************************
|
|
; Formatieren der aktuellen Spur
|
|
;*************************************************
|
|
ft_trk
|
|
ld a,(st_ina)
|
|
out (DSKC2),a ;alles inaktiv
|
|
out (IMPAUS),a
|
|
; Loeschen des RAM von 2000 bis 2fff
|
|
ld hl,ram ;Anfangsadresse
|
|
ld bc,0fffh ;Laenge
|
|
ld de,ram+1
|
|
ld (hl),0 ;Loeschbyte
|
|
ldir
|
|
; Programmierung der Transfer-Richtung
|
|
ld a,(cnt_st)
|
|
set 7,a ;RAM-->Disk
|
|
res 6,a ;DA12=0
|
|
ld (cnt_st),a
|
|
out (CNTST),a
|
|
; Laden des Diskadresszaehlers
|
|
ld hl,2000h
|
|
call b_daz
|
|
ld (hl),a
|
|
; Einschalten der Disk-Schnittstelle
|
|
ld a,(st_wm) ;'WG=aktiv' & 'DEN=aktiv'
|
|
ld b,a
|
|
res 3,a
|
|
out (DSKC2),a ;Schnittstelle in Betrieb
|
|
ld a,b
|
|
out (DSKC2),a
|
|
; Warten auf den 2.Index
|
|
ld hl,isr_al
|
|
ld (isr_ix),hl ;Eintragen der ISR-Adresse
|
|
ld a,0d5h ;Counter & L-H-Flanke
|
|
out (CTC+3),a
|
|
ld a,2
|
|
out (CTC+3),a
|
|
halt ;Warten auf Interrupt nach zwei Impulsen
|
|
; --- warten --------------------
|
|
|
|
; Ausschalten der Schnittstelle nach dem Spurloeschen
|
|
ld a,(st_ina)
|
|
out (DSKC2),a ;alles inaktiv
|
|
out (IMPAUS),a ;Disk_Schnittstelle aus
|
|
ld a,3
|
|
out (CTC+3),a ;CTC/3-Reset
|
|
; Ende, wenn "Spurloeschen"
|
|
ld a,(cmd_br-8)
|
|
cp 84h
|
|
ret z
|
|
; Sektoraufbau
|
|
ld hl,kf_top ;Beginn der Praeambel
|
|
ld b,18
|
|
id1 ld (hl),0ffh
|
|
inc hl
|
|
djnz id1
|
|
ld b,3
|
|
id2 ld (hl),0a1h ;Vorbytes
|
|
inc hl
|
|
djnz id2
|
|
ld (hl),0feh ;Identmarke
|
|
inc hl
|
|
ex de,hl
|
|
ld bc,3
|
|
ld hl,ident+1
|
|
ldir ;Cylinder & Head
|
|
ex de,hl
|
|
ld (hl),1 ;Beginn mit Sektornummer 1
|
|
inc hl
|
|
ld b,12
|
|
id3 ld (hl),0ffh ;2 Byte CRC und 10 Byte Luecke
|
|
inc hl
|
|
djnz id3
|
|
|
|
;---------------------------------------------------
|
|
; Vorbereiten der Disk-Schnittstelle zum Formatieren
|
|
;---------------------------------------------------
|
|
; Bestimmung Disk-Adresszaehler
|
|
ld hl,3600h
|
|
call b_daz
|
|
ld (dsk_az),hl
|
|
ld (hl),a ;Laden des Zaehlers
|
|
; Markenaufbau
|
|
ld a,4 ;MFM & PRAEOFF
|
|
ld d,a
|
|
ld a,(cmd_br-7) ;akt. Laufwerk
|
|
call cy_pos
|
|
ld b,(hl) ;Low-Teil Zylinderposition
|
|
inc hl
|
|
ld h,(hl) ;High-Teil Zylinderposition
|
|
ld l,b
|
|
ld bc,(pre_cy) ;Praekompensationsbeginn
|
|
xor a
|
|
sbc hl,bc
|
|
jr c,pr_ok
|
|
ld a,0ch ;MFM & PRAEON
|
|
ld d,a
|
|
pr_ok ld a,d
|
|
out (BM_D),a
|
|
ld a,0ah ;Taktbits der Marken
|
|
out (BM_T),a
|
|
; Einstellen des RAM-Bereichs
|
|
ld a,(cnt_st)
|
|
set 6,a ;RAM12 = 1
|
|
ld (cnt_st),a
|
|
out (CNTST),a
|
|
; Eintragen der ISR-Adressen
|
|
ld hl,isr_al
|
|
ld (isr_ix),hl ;ISR-Adresse
|
|
; DEND-Adresse festlegen
|
|
ld a,0ffh
|
|
out (DSKEA),a
|
|
; Bereitstellung der Sektorreihenfolge in 'fs_tab'
|
|
ld hl,fs_tab ;RAM-Tabelle
|
|
ld a,(ident+3) ;Kopfnummer
|
|
ld b,0
|
|
ld c,a
|
|
add hl,bc ;Beginn der Sektornummern fuer akt. Kopf
|
|
ex de,hl ;DE: Position der Sektornummer 1
|
|
ld b,a ;Kopfnummer
|
|
ld a,(secs) ;Anzahl der Sektoren
|
|
sub b ;Anzahl der umzuladenden Sektoren
|
|
ld b,0
|
|
ld c,a ;BC: Anzahl
|
|
ld hl,sc_tab ;Reihenfolge fuer Kopf 0
|
|
ldir
|
|
ld a,(ident+3) ;Kopfnummer
|
|
cp 0
|
|
jr z,fs_ta1 ;kein weiteres Umladen
|
|
ld c,a
|
|
ld b,0
|
|
ld de,fs_tab ;Beginn der RAM-Tabelle
|
|
ldir ;Umladen des Rests
|
|
; Sektornummer initialisieren
|
|
fs_ta1 ld hl,fs_tab ;Beginn der Sektortabelle
|
|
ld a,(hl)
|
|
ex de,hl
|
|
ld hl,kf_top+19h ;Speicherplatz der Sektornummer
|
|
ld (hl),a
|
|
ld a,(secs)
|
|
ld b,a ;Sektorenzaehler
|
|
|
|
;-----------------------------------------------------------------
|
|
; Formatieren einer Spur (Schreiben der Kennfelder)
|
|
;-----------------------------------------------------------------
|
|
; CTC-Programmierung fuer Indexerkennung vor dem Formatieren
|
|
ld a,0d5h ;Counter
|
|
out (CTC+3),a
|
|
ld a,1
|
|
out (CTC+3),a
|
|
halt ;Warten auf den naechsten Index
|
|
; --- warten --- warten --- warten --- warten --- warten
|
|
|
|
f_nsec
|
|
ld a,3
|
|
out (CTC+3),a ;Reset IX-Interrupt
|
|
ld a,(st_wa) ;alles aktiv
|
|
ld c,a
|
|
res 3,a ;'WG=inaktiv'
|
|
out (DSKC2),a ;Schnittstelle an (ohne WG)
|
|
ld a,c
|
|
out (DSKC2),a ;Schnittstelle an (mit WG=aktiv)
|
|
ld a,12h
|
|
out (DSKEA),a ;DEND zum Markeneinblenden und -anzahl
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
ld a,(st_wc)
|
|
out (DSKC2),a ;CRC-Einblenden
|
|
ld a,1ah
|
|
out (DSKEA),a ;DEND zum CRC-Einblenden
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
ld a,(st_ina)
|
|
out (DSKC2),a ;Schnittstelle aus
|
|
out (IMPAUS),a
|
|
ld hl,(dsk_az)
|
|
ld (hl),a ;Diskadresszaehler neu laden
|
|
ld a,87h ;Timer & VT16
|
|
out (CTC+3),a
|
|
ld a,(ztk) ;berechnete Zeitkonstante
|
|
out (CTC+3),a
|
|
inc de ;Tabelle der Reihenfolge der Sektoren
|
|
ld a,(de) ;Sektornummer
|
|
ld hl,kf_top+19h ;Adresse der Sektornummer
|
|
ld (hl),a
|
|
dec b
|
|
jp z,ft_end
|
|
halt ;Warten auf Zeitinterrupt
|
|
;--- Warten -----
|
|
jp f_nsec
|
|
ft_end
|
|
ld a,3
|
|
out (CTC+3),a ;Reset CTC/3
|
|
xor a
|
|
|
|
;-----------------------------------------------------
|
|
; Initialisieren der Datenfelder
|
|
;-----------------------------------------------------
|
|
ld hl,ram
|
|
ld de,ram+1
|
|
ld bc,0fffh
|
|
ld (hl),0e5h
|
|
ldir
|
|
|
|
;----------------------------------------------------
|
|
; Schreiben der Datenfelder
|
|
;----------------------------------------------------
|
|
; Setzen der Fehlerzaehler fuer das Lesen der Kennfelder
|
|
ld de,c_zt
|
|
ld hl,fe_n
|
|
ld bc,7
|
|
ldir
|
|
; Schreiben der Datenfelder der Sektoren
|
|
ld a,4
|
|
ld (ct_ra),a ;Zaehler fuer Schreibwiederholungen
|
|
ld a,1 ;Beginn mit Sektor 1
|
|
ld (ident+4),a
|
|
ld hl,2400h ;18 Sektoren
|
|
ld a,(secs)
|
|
cp 18
|
|
jr z,wrt_d1
|
|
ld hl,2200h ;17 Sektoren
|
|
wrt_d1 ld (dt_len),hl
|
|
call wrt_dt ;Schreiben der Datenfelder
|
|
ret ;Schreibfehler
|
|
eject
|
|
;***********************************************************************
|
|
; Datentransfer zwischen Host und WDC-RAM
|
|
;***********************************************************************
|
|
ram_tr
|
|
ld hl,cmd_br-7 ;RAM-Anfangsadresse
|
|
ld a,(hl)
|
|
ld e,a
|
|
inc hl
|
|
ld a,(hl)
|
|
ld d,a ;(DE): Anfangsadresse
|
|
ld hl,cmd_br-2 ;Laenge
|
|
ld a,(hl)
|
|
ld c,a
|
|
inc hl
|
|
ld a,(hl)
|
|
ld b,a ;(BC): Laenge
|
|
ex de,hl
|
|
add hl,bc
|
|
dec hl
|
|
ld a,(cmd_br-8) ;Kommandocode
|
|
cp 08h ;Lesen WDC-RAM ?
|
|
jp z,rd_ram
|
|
cp 18h ;Schreiben WDC-RAM ?
|
|
jp z,wt_ram
|
|
cp 28h ;Lesen WDC-Parameterblock ?
|
|
jp z,rd_pb
|
|
cp 78h ;Schreiben WDC-Parameterblock ?
|
|
jp z,wr_pb
|
|
cp 38h ;Lesen WDC-Fehlerstatistik ?
|
|
jp z,rd_fs
|
|
cp 58h ;Lesen WDC-RAM-BTT (auf den Host-RAM) ?
|
|
jp z,rd_def
|
|
cp 68h ;Schreiben WDC-RAM-BTT (aus Host-RAM) ?
|
|
jp z,wr_def
|
|
cp 48h ;Loeschen BTT im WC-RAM ?
|
|
jp nz,err_1
|
|
;-----------------------------------------------------
|
|
; Loeschen Defektspurtabelle
|
|
;-----------------------------------------------------
|
|
call def_ad
|
|
call btt_cl
|
|
jp begin
|
|
;-----------------------------------------------------
|
|
; Lesen der BTT aus dem WDC-RAM in den Host-RAM
|
|
;-----------------------------------------------------
|
|
rd_def
|
|
call def_ad
|
|
ld hl,(df_end)
|
|
push bc
|
|
call t_btt1
|
|
pop bc
|
|
jp nz,err_18
|
|
ld hl,(df_end)
|
|
add hl,bc
|
|
dec hl
|
|
ld a,3
|
|
call p_wc_h
|
|
jp begin
|
|
;-----------------------------------------------------
|
|
; Schreiben der BTT im WDC-RAM aus dem Host-RAM
|
|
;-----------------------------------------------------
|
|
wr_def
|
|
call def_ad
|
|
ld hl,(df_end)
|
|
add hl,bc
|
|
dec hl
|
|
ld a,2
|
|
call p_h_wc
|
|
jp begin
|
|
;-----------------------------------------------------
|
|
; Lesen WDC-RAM
|
|
;-----------------------------------------------------
|
|
rd_ram
|
|
ld a,3
|
|
call p_wc_h
|
|
jp begin
|
|
;-----------------------------------------------------
|
|
; Schreiben WDC-RAM
|
|
;-----------------------------------------------------
|
|
wt_ram
|
|
ld a,2
|
|
call p_h_wc
|
|
jp begin
|
|
;-----------------------------------------------------
|
|
; Schreiben WDC-Parameterblock
|
|
;-----------------------------------------------------
|
|
wr_pb
|
|
ld hl,p_blk
|
|
add hl,bc
|
|
dec hl
|
|
ld a,2
|
|
call p_h_wc
|
|
jp begin
|
|
;-----------------------------------------------------
|
|
; Lesen WDC-Parameterblock
|
|
;-----------------------------------------------------
|
|
rd_pb
|
|
; Eintragen der Parameter
|
|
push bc
|
|
ld hl,string ;Zeichenkette zur Identifizierung
|
|
ld de,p_str
|
|
ld bc,7
|
|
ldir
|
|
; Umladen der Anzahl der Bloecke
|
|
ld hl,bl_dr0
|
|
ld de,zmx_41
|
|
inc de
|
|
ld bc,4
|
|
ldir
|
|
; Umladen 'd_rdy', s_rdy, 'err_in', Anzahl Laufwerke
|
|
ld a,(d_rdy)
|
|
ld (de),a
|
|
inc de
|
|
ld a,(s_rdy)
|
|
ld (de),a
|
|
inc de
|
|
ld a,(err_in)
|
|
ld (de),a
|
|
inc de
|
|
ld a,(d_rdy)
|
|
ld b,3
|
|
ld c,0
|
|
dr_t0 rrc a
|
|
jr nc,dr_t1
|
|
inc c
|
|
dr_t1 djnz dr_t0 ;Anzahl der angeschlossenen Laufwerke
|
|
ld a,c
|
|
ld (de),a
|
|
; Ausgabe der Parameter
|
|
pop bc
|
|
ld hl,p_str
|
|
add hl,bc
|
|
dec hl
|
|
ld a,3
|
|
call p_wc_h
|
|
jp begin
|
|
;-----------------------------------------------------
|
|
; Lesen WDC-Fehlerstatistik
|
|
;-----------------------------------------------------
|
|
rd_fs ld hl,sum_zt
|
|
add hl,bc
|
|
dec hl
|
|
ld a,3
|
|
call p_wc_h
|
|
jp begin
|
|
eject
|
|
;---------------------------------------------------------------
|
|
; PROGRAMMIERUNG DER HOST-SCHNITTSTELLE
|
|
;---------------------------------------------------------------
|
|
; A: Status des WDC
|
|
; BC: Laenge der Ausgabe
|
|
; HL: Endadresse des Ausgabebereichs
|
|
;---------------------------------------------------------------
|
|
p_wc_h ;WDC-RAM --> Host
|
|
; bei 'WDC-->Host' muss ein Byte mehr uebertragen werden
|
|
; (wird vom Host nicht abgeholt, nur zur Ready-Abschaltung PIO)
|
|
push af
|
|
p_sl1 ld a,(hst_by) ;Besetzt-Anzeiger
|
|
bit 7,a
|
|
jr nz,p_sl1 ;Warten in Schleife, wenn Treiber besetzt
|
|
set 7,a ;Treiber besetzt
|
|
ld (hst_by),a
|
|
inc hl
|
|
inc bc
|
|
ld a,(cnt_st)
|
|
set 5,a ;WDC-RAM --> Host
|
|
ld (cnt_st),a
|
|
pop af
|
|
jr p_h_1
|
|
;------------------------------------------------------------
|
|
p_h_wc ;Host --> WDC-RAM
|
|
push af
|
|
p_sl2 ld a,(hst_by) ;Besetzt-Anzeiger
|
|
bit 7,a
|
|
jr nz,p_sl2 ;Warten in Schleife, wenn Treiber besetzt
|
|
set 7,a ;Treiber besetzt
|
|
ld (hst_by),a
|
|
ld a,(cnt_st)
|
|
res 5,a ;WDC-RAM <-- Host
|
|
ld (cnt_st),a
|
|
pop af
|
|
;------------------------------------------------------------
|
|
p_h_1 push hl ;Endadresse retten
|
|
push bc ;Laenge retten
|
|
push af ;Status retten
|
|
; Wert des Adresszaehlers berechnen
|
|
xor a
|
|
sbc hl,bc
|
|
inc hl ;Beginn des E/A-Bereiches
|
|
pop af
|
|
push hl ;Beginn retten
|
|
push af
|
|
res 5,h ;Kennzeichnung RAM ruecksetzen (Bit 13)
|
|
; Ausgabebyte fuer CNTST aktualisieren
|
|
ld a,(cnt_st) ;Programmierbyte
|
|
res 4,a ;HA12 = 0
|
|
bit 4,h ;Adressbit 12 gesetzt ?
|
|
jr z,hrt1
|
|
set 4,a ;HA12 = 1
|
|
hrt1 ld (cnt_st),a
|
|
pop af
|
|
push af
|
|
ld b,a
|
|
ld a,(cnt_st)
|
|
set 3,a ;HEN ein
|
|
or b ;Status einfuegen
|
|
ld (cnt_st),a ;Ausgabebyte
|
|
; Host-Adresszaehler-Kennzeichnung einfuegen
|
|
ld a,h
|
|
and 0ch ;Bit 11,10 der Adresse
|
|
rlca
|
|
rlca
|
|
rlca
|
|
rlca ;Bit 15,14
|
|
ld b,a
|
|
ld a,h
|
|
and 03h ;Bit 9,8 der Adresse
|
|
or b ;Bit 15,14,9,8
|
|
or 038h ;Kennzeichnung einfuegen
|
|
ld h,a ;Host-Adresszaehler fertig
|
|
pop af
|
|
pop de ;Beginn des Bereichs
|
|
pop bc ;Laenge des Bereichs
|
|
; Host-Adresszaehler laden
|
|
ld (hl),a
|
|
; Bestimmung der Schaltflanke fuer den CTC-Kanal
|
|
pop hl ;Endadresse des E/A-Bereiches
|
|
ld a,0c7h ;Uebergang '1...0'
|
|
bit 0,l ;gerade oder ungerade
|
|
jr nz,hrt11
|
|
ld a,0d7h ;Uebergang '0...1'
|
|
hrt11 ld (ctc_st),a
|
|
; Bestimmung der CTC-Clocks
|
|
inc bc
|
|
xor a
|
|
rr b
|
|
rr c ;Laenge/2
|
|
ld hl,100h
|
|
xor a
|
|
sbc hl,bc
|
|
jr c,gr_100
|
|
|
|
; CTC-Clocks kleiner/gleich 100h
|
|
hrt17 ld a,(ctc_st) ;CTC-Steuerwort
|
|
out (CTC+2),a
|
|
ld a,c ;Anzahl der Impulse
|
|
out (CTC+2),a
|
|
ld hl,cnt_st
|
|
ld a,(hl)
|
|
res 3,(hl) ;'HEN=inaktiv'
|
|
out (CNTST),a ;Ansteuerung aktiv
|
|
ld a,(hl)
|
|
out (CNTST),a ;Vorbereitung von 'Schnittstelle inaktiv'
|
|
ret
|
|
|
|
; CTC-Clocks groesser 100h
|
|
gr_100 xor a
|
|
cp c ;C = 0 ?
|
|
jr nz,gr_101
|
|
dec b
|
|
gr_101 ld a,b
|
|
ld (hst_bl),a ;Anzahl der Bloecke auf der HS
|
|
ld hl,isr_h1 ;ISR-Adresse
|
|
ld (isr_hs),hl
|
|
ld a,(ctc_st) ;CTC-Steuerwort
|
|
out (CTC+2),a
|
|
ld a,c
|
|
out (CTC+2),a
|
|
ld a,(ctc_st) ;CTC-Steuerwort
|
|
res 1,a ;kein Reset
|
|
out (CTC+2),a
|
|
ld a,0
|
|
out (CTC+2),a ;256 Impulse
|
|
ld a,(cnt_st)
|
|
out (CNTST),a
|
|
ret
|
|
|
|
;---------------------------------------------------------------
|
|
; Interruptroutinen fuer den Host-Adresszaehler
|
|
;---------------------------------------------------------------
|
|
; ISR fuer Zwischeninterrupts bei langen Uebertragungen
|
|
isr_h1 push af
|
|
push hl
|
|
ld hl,hst_bl ;Zaehler fuer HS-Bloecke
|
|
dec (hl)
|
|
jr nz,isr_h2 ;Sprung, wenn Zaehler nicht abgelaufen
|
|
ld hl,isr_h0 ;ISR fuer letzen Interrupt
|
|
ld (isr_hs),hl
|
|
ld a,(cnt_st)
|
|
res 3,a ;'HEN=inaktiv'
|
|
ld (cnt_st),a
|
|
out (CNTST),a
|
|
isr_h2 pop hl
|
|
pop af
|
|
ei
|
|
reti
|
|
; ISR fuer letzten Interrupt waehrend eines Transfers
|
|
isr_h0 push af
|
|
ld a,(cnt_st)
|
|
and 0d0h ;'TR=inaktiv' & 'HEN=inaktiv' & Status=0
|
|
ld (cnt_st),a
|
|
out (CNTST),a
|
|
ld a,3
|
|
out (CTC+2),a
|
|
ld a,(hst_by)
|
|
res 7,a ;Treiber frei
|
|
ld (hst_by),a
|
|
pop af
|
|
ei
|
|
reti
|
|
eject
|
|
;---------------------------------------------------------------------
|
|
; Fehlerauswertung und Uebergabe an den Host
|
|
;---------------------------------------------------------------------
|
|
err_1 ld a,1
|
|
jr error1
|
|
err_2 ld a,2
|
|
jr error1
|
|
err_3 ld a,3
|
|
jr error1
|
|
err_4 ld a,4
|
|
jr error1
|
|
err_5 ld a,5
|
|
jr error1
|
|
err_6 ld a,6
|
|
jr error1
|
|
err_7 ld a,7
|
|
jr error1
|
|
err_15 ld a,15h
|
|
jr error1
|
|
err_16 ld a,16h
|
|
jr error1
|
|
err_17 ld a,17h
|
|
jr error1
|
|
err_18 ld a,18h
|
|
jr error1
|
|
|
|
error1 ld (err_cd),a
|
|
; Programmierung der Host-Schnittstelle
|
|
error ld a,(err_cd)
|
|
ld (err_br),a
|
|
ld bc,1 ;Ausgabelaenge
|
|
ld hl,err_br ;auszugebendes Byte
|
|
ld a,7 ;Status '7'
|
|
call p_wc_h ;Programmierung der Host-Schnittstelle
|
|
xor a
|
|
ld (err_cd),a ;Loeschen des Fehlercodes
|
|
jp begin
|
|
|
|
;--- b_daz ---------------------------------------------
|
|
; Berechnung des Disk-Adresszaehlers
|
|
; in : HL Adresse
|
|
; out: HL Disk-Adresszaehler
|
|
;---------------------------------------------------------
|
|
b_daz res 5,h ;Kennzeichnung RAM ruecksetzen
|
|
ld a,h
|
|
and 0ch ;Bit 11,10 der Adresse
|
|
rlca
|
|
rlca
|
|
rlca
|
|
rlca
|
|
ld b,a
|
|
ld a,h
|
|
and 03h ;Bit 9,8 der Adresse
|
|
or b ;Bit 15,14,9,8 des Disk-Adresszaehlers
|
|
or 03ch ;Kennzeichnung einfuegen
|
|
ld h,a ;Adresszaehler fertig
|
|
ret
|
|
|
|
;--- time --------------------------------------
|
|
; ca. 0,01 ms pro Durchlauf, 4MHz-CPU, Wait-Zyklen
|
|
; DE: Zaehlwert
|
|
;-------------------------------------------------
|
|
time ld a,1
|
|
ld a,1
|
|
dec de
|
|
bit 7,d
|
|
jr z,time
|
|
ret
|
|
|
|
;--- time1 ----------------------------------
|
|
; ca. 1 ms pro Durchlauf, 4MHz-CPU, Wait-Zyklen
|
|
; DE: Zaehlwert
|
|
;----------------------------------------------
|
|
time1 push de
|
|
ld de,130
|
|
time10 dec de
|
|
bit 7,d
|
|
jr z,time10
|
|
pop de
|
|
dec de
|
|
ld a,d
|
|
or e
|
|
jr nz,time1
|
|
ret
|
|
|
|
;--- time2 -----------------------------------
|
|
; ca. 10 ms pro Durchlauf, 4MHz-CPU, Wait-Zyklen
|
|
; DE: Zaehlwert
|
|
;-----------------------------------------------
|
|
time2 push de
|
|
ld de,1288
|
|
time20 dec de
|
|
bit 7,d
|
|
jr z,time20
|
|
pop de
|
|
dec de
|
|
ld a,d
|
|
or e
|
|
jr nz,time2
|
|
ret
|
|
|
|
;--- crc_br -----------------------------------
|
|
; CRC-Berechnung
|
|
;------------------------------------------------
|
|
crc_br ld de,-1
|
|
crc1 ld a,(hl)
|
|
xor d
|
|
ld d,a
|
|
rrca
|
|
rrca
|
|
rrca
|
|
rrca
|
|
and 0fh
|
|
xor d
|
|
ld d,a
|
|
rrca
|
|
rrca
|
|
rrca
|
|
push af
|
|
and 1fh
|
|
xor e
|
|
ld e,a
|
|
pop af
|
|
push af
|
|
rrca
|
|
and 0f0h
|
|
xor e
|
|
ld e,a
|
|
pop af
|
|
and 0e0h
|
|
xor d
|
|
ld d,e
|
|
ld e,a
|
|
inc hl
|
|
dec bc
|
|
ld a,b
|
|
or c
|
|
jr nz,crc1
|
|
ret
|
|
|
|
;---------------- PROGRAMMTEXT-ENDE ---------------------------------------
|
|
|
|
begin 1
|
|
; Tabelle der Kommandocodes
|
|
com_tb db 021h ;HD-Lesen von einer Blocknummer
|
|
db 022h ;HD-Schreiben auf eine Blocknummer
|
|
db 001h ;HD-Lesen von einer Sektoradresse
|
|
db 081h ;HD-Testlesen von einer Sektoradresse
|
|
db 011h ;HD-Lesen von einer Sektoradresse mit BTT-Berueck.
|
|
db 002h ;HD-Schreiben auf eine Sektoradresse
|
|
db 082h ;HD-Schreiben auf eine Sektoradresse mit Ruecklesen
|
|
db 012h ;HD-Schreiben auf eine Sektoradresse mit BTT-Berue.
|
|
db 092h ;HD-Schreiben auf eine Sektoradresse mit BTT-
|
|
;Beruecksichtigung und Ruecklesen
|
|
db 0a1h ;HD-Kopieren von einer Blocknummer des LW 1 auf LW 0
|
|
db 0a2h ;HD-Schreiben auf eine Blocknummer mit Ruecklesen
|
|
db 0c2h ;HD-Schreiben von PAR und BTT auf das Laufwerk
|
|
db 004h ;HD-Formatieren einer Spur
|
|
db 014h ;HD-Formatieren einer Spur mit Ruecklesen
|
|
db 024h ;HD-Formatieren einer Spur mit Defektspurfeststellung
|
|
db 044h ;HD-Ruecklesen einer Spur (Verify)
|
|
db 084h ;HD-Loeschen einer Spur
|
|
db 008h ;Lesen WDC-RAM
|
|
db 018h ;Schreiben WDC-RAM
|
|
db 028h ;Lesen des WDC-Parameterblocks
|
|
db 038h ;Lesen der WDC-Fehlerstatistik
|
|
db 048h ;Loeschen der BTT im WDC-RAM
|
|
db 058h ;Lesen der BTT aus dem WDC-RAM in den Host-RAM
|
|
db 068h ;Schreiben der BTT aus dem Host-RAM in den WDC-RAM
|
|
db 078h ;Schriben des WDC-Parameterblocks
|
|
db 0ffh ;Endekennzeichen
|
|
; Praeambel beim Schreiben eines Datenfeldes (13 Byte)
|
|
prae db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0a1h
|
|
db 0fbh
|
|
; Postambel beim Schreiben eines Datenfeldes (12 Byte)
|
|
post db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
db 0ffh
|
|
; Kennfeld der Defektspurtabelle
|
|
id_df db 0feh
|
|
db 00h
|
|
db 00h
|
|
db 00h
|
|
db 01h
|
|
; Kennung der Parametertabelle
|
|
txt_pm text 'PARMTR'
|
|
; Kennung der Defektspurtabelle
|
|
txt_df text 'DEFEKT'
|
|
; Fehlerzaehler fuer normales Lesen
|
|
fe_n db 4
|
|
db 8
|
|
db 4
|
|
db 4
|
|
db 4
|
|
db 4
|
|
db 4
|
|
; Fehlerzaehler fuer das Formatieren
|
|
fe_f1 db 2
|
|
db 2
|
|
db 2
|
|
db 2
|
|
db 2
|
|
db 2
|
|
db 2
|
|
; Fehlerzaehler fuer das Testlesen
|
|
fe_t db 1
|
|
db 1
|
|
db 1
|
|
db 1
|
|
db 1
|
|
db 1
|
|
db 1
|
|
; Tabelle des Sektorversatz
|
|
db 0ffh
|
|
sc_tab db 1
|
|
db 10
|
|
db 2
|
|
db 11
|
|
db 3
|
|
db 12
|
|
db 4
|
|
db 13
|
|
db 5
|
|
db 14
|
|
db 6
|
|
db 15
|
|
db 7
|
|
db 16
|
|
db 8
|
|
db 17
|
|
db 9
|
|
db 18
|
|
db 0ffh
|
|
|
|
end
|
|
|