-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path802hhard.mac
246 lines (204 loc) · 5.25 KB
/
802hhard.mac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
.Z80
; '802HHARD' IS THE I/O DRIVER FOR CPM 2.2 USING A TANDON
; TM-603S HARD DISK DRIVE.
;
; **************************************
; ** HARD DISK I/O & SUPPORT ROUTINES **
; **************************************
; READ A BLOCK
HREAD:
LD A,WREAD ; SET A = READ COMMAND
JR WRWOP ; GO TO READ/WRITE ROUTINE
HWRITE:
LD A,WWRITE ; SET A = WRITE COMMAND
WRWOP:
LD (RCM),A ; SAVE R/W COMMAND FOR LATER USED
LD A,RETRYCNT ; SET ERROR RETRY COUNT
LD (ERRCNT),A
WRWOP1:
CALL SLCT ; SET UP FOR I/O
LD A,(RCM)
OUT (WCMD),A ; PERFORM R/W OP.
LD E,A
CALL GETIO
LD A,E
CP WREAD ; TEST WE ARE IN READ MODE
JR NZ,WRWOP2 ; * IF NOT THEN DO MEMORY TO I/O TRANSFER
INIR ; * ELSE DO I/O TO MEMORY TRANSFER
JR WRWOP3
WRWOP2:
OTIR
WRWOP3:
CALL ERRORS ; THEN CHECK ERROR STATUS
LD A,0
RET Z ; EXIT IF NO ERROR
LD A,WREST
OUT (WCMD),A ; DO RESTORE COMMAND
WRWOP4:
IN A,(WSTAT)
AND WBUSY
JR NZ,WRWOP4 ; WAIT UNTIL NOT BUSY
LD A,(ERRCNT) ; CHECK ERROR RETRY COUNT = 0
DEC A
LD (ERRCNT),A
JR NZ,WRWOP1 ; IF NOT ZERO THEN DO R/W AGAIN
LD A,1 ; ELSE SET ERROR FLAG
LD (ERFLAG),A
RET
; SET UP FOR READ/WRITE COMMANDS
GETIO: IN A,(WSTAT) ; WAIT FOR DRQ
AND WDRQ
JR Z,GETIO
LD HL,HSTBUF ; POINT TO SECTOR BUFFER
LD BC,WDATA ; B = 0, C = DATA PORT
RET
; SELECT DRIVE, HEAD, CYLINDER, AND SECTOR
SLCT: LD HL,FLAGS
BIT F$INIT,(HL) ; CONTROLLER INITIALIZED?
JR NZ,SL0 ; YES, GO ON
CALL INITD ; NO, INITIALIZE IT NOW
SL0: LD HL,(HSTTRK) ; REQUESTED TRACK
LD A,MAXHED ; NUMBER OF HEADS
CALL DIVIDE ; HL/A ==> A = REMAINDER; HL = QUOTIENT
LD (RHD),A ; SAVE REAL HEAD #
LD (RTK),HL ; SAVE AS REAL TRACK#
LD B,A
XOR A ; REAL DISK =0
OR B ; B = HEAD SLCT INFO
OUT (WSDH),A ; SELECT HEAD 0...5, DRIVE
LD A,H ; SEND TO CONTROLLER
OUT (WHICYL),A
LD A,L
OUT (WLOCYL),A
LD A,(HSTSEC) ; SEND SECTOR NUMBER
OUT (WSECT),A
LD A,1 ; SECTOR COUNT = 1
OUT (WCOUNT),A
RET
; DRIVE READY TEST
RDY: IN A,(WSTAT) ; DRIVE STATUS
AND WREADY ; DRIVE READY BIT
XOR WREADY ; INVERT IT
RET ; IF A = 0, DRIVE RDY
PAGE
;
; INITIALIZE FLAGS & VARIABLES
;
INIT: LD HL,FLAGS
LD B,FLGSIZ
XOR A
ZZI1A: LD (HL),A ; CLEAR FLAGS & VARIABLES
INC HL
DJNZ ZZI1A
LD HL,0
INIT1: CALL RDY
RET Z ; IF DRIVE READY THEN RETURN
DEC HL
LD A,H
OR L
JR NZ,INIT1 ; LOOP UNTIL READY OR TIME OUT
RET
; ERROR STATUS ROUTINE
ERRORS: CALL GETERR ; GET PRIMARY ERROR STATUS
; CHECK NUMBER OF RETRY TO SKIP PRINTING ERRORS UNTIL 4TH
; RETRY. AT 5TH RETRY IF NECESSARY, PRINT ERRORS IN DETAIL.
LD A,(ERRCNT) ; GET CURRENT RETRY COUNT
CP 1 ; 5TH RETRY?
JP NZ,EEX ; IF NOT, SKIP ERROR REPORT
EE1: IN A,(WERRS) ; GET ERROR STATUS
LD (ESTAT),A
IN A,(WCOUNT) ; GET RESIDUAL COUNT
LD (RCT),A
LD A,(STAT)
AND WREADY ; DRIVE NOT READY?
JR NZ,EE2
LD HL,MSGNR
CALL PRNT ; PRINT ERROR MESSAGE
EE2: LD A,(STAT)
AND WREADY+WFAULT+WERROR ; ANY ERRORS?
XOR WREADY
JR Z,EEX
; REPORT BIOS ERROR WITH STATUS/ERROR CONDITION CODE TO OPERATOR
LD HL,MSG3 ; MESSAGE HEADER
CALL PRNT
LD A,(RCM) ; GET CURRENT COMMAND
CP WREAD ; READ COMMAND?
JR Z,EE3
CP WWRITE ; WRITE COMMAND?
JR Z,EE4
CP WREST ; RESTORE COMMAND?
JR Z,EE5
LD HL,MSGUC ; UNKNOWN COMMAND
JR EE6
EE3: LD HL,MSGRC ; READ COMMAND
JR EE6
EE4: LD HL,MSGWC ; WRITE COMMAND
JR EE6
EE5: LD HL,MSGSC ; RESTORE COMMAND
EE6: CALL PRNT ; CURRENT COMMAND MESSAGE
CALL ERRHST ; GET DETAILED ERROR AND PRINT
LD A,(STAT) ; GET STATUS REGISTER CODE
LD HL,HSCODE ; GET ADDRESS TO RECORD
CALL FTAB ; CONVERT HEX TO ASCII
LD A,(ESTAT) ; GET ERROR REGISTER CODE
LD HL,HECODE
CALL FTAB
LD HL,MSG4
CALL PRNT
EEX: LD A,(STAT)
AND WFAULT+WERROR ; ANY ERRORS?
RET
; GET ERROR STATUS
GETERR: IN A,(WSTAT) ; WAIT FOR CONTROLLER NOT BUSY
AND WBUSY
JR NZ,GETERR
IN A,(WSTAT) ; GET PRIMARY STATUS
LD (STAT),A
RET
; FILL LOGICAL DRIVE, SECTOR, TRACK NUMBER
; IN ERROR TABLE AND REPORT TO OPERATOR
ERRHST: LD A,(HSTDSK) ; CURRENT HOST DISK
ADD A,41H ; MAKE IT ASCII CHARACTER
LD HL,VDRV ; GET DRIVE TABLE ADDRESS
LD (HL),A ; STORE IT IN TABLE
LD DE,(HSTTRK) ; GET TRACK NUMBER
LD HL,VTRK ; GET TRACK TABLE ADDRESS
CALL CVD4 ; CONVERT IT AS DECIMAL
LD A,(HSTSEC) ; CURRENT SECTOR
LD E,A
LD D,0 ; DE = SECTOR NUMBER
LD HL,VSEC ; GET SECTOR TABLE ADDRESS
CALL CVD2
LD HL,VTAB ; VARIABLE TABLE RECORDED
CALL PRNT
RET
; DISK INITIALIZATION
INITD: LD HL,FLAGS
SET F$INIT,(HL) ; SET FLAG TO SAY INTIALIZED
CALL SL0 ; SELECT PROPER DRIVE
LD A,PCMPCYL/4 ; SET PRECOMP CYLINDER
OUT (WPCYL),A
XOR A ; SELECT TRACK 0, HEAD 0
LD (RHD),A
LD HL,0
LD (RTK),HL
LD A,(RCM) ; LAST COMMAND
LD (SAVRCM),A ; SAVE IT
LD A,WREST ; RESTORE COMMAND
LD (RCM),A
OUT (WCMD),A
CALL GETERR ; WAIT TILL DONE
CALL EE1
LD A,(SAVRCM) ; SAVED COMMAND
LD (RCM),A ; PUT IT BACK
RET Z ; RETURN IF NO ERRORS
LD HL,MSG2 ; YES, TELL OPERATOR
CALL PRNT
CALL CONIN ; WAIT FOR REPLY
CP CTLC ; CTL-C?
RET Z ; YES, IGNORE THIS DRIVE
CALL CRLF ; NO, NEW LINE, THEN RETRY
JR INITD
CODEND EQU $ ; DEFINES END OF CODE
; END OF 802HHARD.MAC