-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathHARD.280
363 lines (309 loc) · 9.94 KB
/
HARD.280
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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
title 'Harddisk Driver Module of CP/M-3 BIOS'
.z280
.xlist
maclib Z280EQU
maclib CPU280
maclib OPTIONS
.list
; 950214 Tilmann Reh
; 10-July-2017 Tony Nicholson
; Comments translated from German to English (using Google
; Translate with some appropriate language adjustments resulting
; from an examination of the instruction sequences). Also
; corrected the syntax to be compatible with Hector Peraza's
; ZSM4 Z80/Z180/Z280 assembler
; Drive parameters for hard disk here. Pseudo-native CP-3044
Cyls equ 526
Heads equ 4
Secs equ 40
; Partitioning: Defaults. Partitioning only possible using whole cylinders.
; Translation: log. Tracks = cylinder, log. Sectors = Sectors * Heads.
; Calculations follow at the end of the module (check!). Signon messages and
; DPB's at the end of this Module may also need to be adjusted.
; The number of partitions must be specified globally in SYSTEM/LOADER.LIB
; (Also needed in KERNEL)
PartH equ 150 ; Cylinder first Partition (12 MB)
PartI equ 113 ; Cylinder second Partition (9 MB)
PartJ equ 150 ; Cylinder third Partition (12 MB)
PartK equ 113 ; Cylinder fourth Partition (9 MB)
PartL equ 0 ; Partitions 5..9 not used
PartM equ 0
PartN equ 0
PartO equ 0
PartP equ 0
SpGH equ 8 ; 512 Bytes per Sector Group (4k)
SpGI equ 8 ; 512 Bytes per Sector Group (4k)
SpGJ equ 8 ; 512 Bytes per Sector Group (4k)
SpGK equ 8 ; 512 Bytes per Sector Group (4k)
SpGL equ 1 ; Dummy for non-existent Partitions
SpGM equ 1
SpGN equ 1
SpGO equ 1
SpGP equ 1
dseg ; Complete driver in Bank 0 (except for DPB's)
;***********************************************************************
;** IDE - Driver (REH IDE-Interface) **
;***********************************************************************
if ide
; Task File Register Definitions:
IDEBase equ 80h ; Base address IDE-Interface
IdeDOR equ IDEBase+6 ; Digital Output Register
IdeDat equ IDEBase+8 ; Data Register
IdeErr equ IDEBase+9 ; Error Register
IdeSCnt equ IDEBase+0Ah ; Sector Count
IdeSNum equ IDEBase+0Bh ; Sector Number
IdeCLo equ IDEBase+0Ch ; Cylinder Low
IdeCHi equ IDEBase+0Dh ; Cylinder High
IdeSDH equ IDEBase+0Eh ; Drive and Head
IdeCmd equ IDEBase+0Fh ; Command / Status
; IDE Hard Disk commands:
CmdHome equ 10h ; Recalibrate
CmdRd equ 20h ; Read Sector
CmdWr equ 30h ; Write Sector
CmdInit equ 91h ; Initialize Drive Params
; Macros: wait until disk ready (Non-Busy) or DRQ active.
; Prerequisite: Bus-Page already active.
WaitRdy macro
local wait
wait: in a,(IdeCmd)
rla
jr c,wait
endm
WaitDrq macro
local wait
wait: in a,(IdeCmd)
bit 3,a
jr z,wait
endm
; Initialisation of IDE Hard Disks (e.g. enable Translation Mode).
; Called once at System Boot. If the hard disk does not respond
; then remove the DPH's for H: to K: in the Drive Table.
HDInit: iopage BusP
ld a,6
out (IdeDOR),a ; IDE Hard Drive: Software Reset
ld b,0
djnz $ ; (wait at least 3 us)
ld a,2
out (IdeDOR),a ; Software Reset
ld hl,Cnt10
ldw (hl),1000 ; Delay up to 10 seconds (10 * 100ms)
inc hl ; Point to high byte of counter (Sign)
HDI_1: bit 7,(hl) ; Counter expired?
jr nz,HDI_Ex ; yes: zero out HDD DPH's
in a,(IdeCmd)
bit 7,a
jr nz,HDI_1 ; otherwise wait for Non-Busy
and 11111001b
cp 01010000b ; Status: Ready & NoError ?
jr nz,HDI_1 ; Error --> keep waiting
ld a,Secs
out (idescnt),a ; Sector Count: number of sectors per track
ld a,low cyls
out (ideclo),a
ld a,high cyls
out (idechi),a ; Specify number of cylinders
ld a,0A0h or (heads-1)
out (idesdh),a ; SDH: Number of Heads -1
ld a,cmdinit ; Command : Initialise
out (idecmd),a ; (wait for Non-Busy at the next command)
if loader
ret
else
ld hl,SignOK ; Signon-Text: all ok
jp PMsg
endif
; Unsuccessful Initialisation:
; Zero relevant DPH's for Hard Drives in Drive Table
HDI_Ex: ld de,DTbl+14 ; Point to Hard Drives in DPHH
ld b,2*Parts ; for each partition in the DPH's
xor a
HDI_E1: ld (de),a
inc de
djnz HDI_E1 ; replace the DPH's with 0
if loader
ret
else
ld hl,SignBad ; Output message about Hard Drive
jp PMsg
endif
; Read data from Hard Disk:
RdIDE: call HdPrep ; set Task File Register, DMA-Adr. count
ld (RdDest+2),a
ld (RdDest),hl ; set Read destination DMA address
ld a,CmdRd
out (IdeCmd),a ; Command to Hard Disk: Read sector
WaitDrq
in a,(IdeDat) ; ECB-IDE-Interface: set LH Flipflop
ld hl,RdDmaPB
RdIDE1: call DmaSet ; start DMA: Submit/ pick up data
iopage BusP
WaitRdy
in a,(IdeCmd)
and 10001001b ; Busy, DRQ, or Error?
ret z ; no: all ok
ld a,1
ret ; Error: End with A=1
; Write data to Hard Disk:
if not loader
WrIDE: call HdPrep ; set Task File Register, DMA-Adr. count
ld (WrSrc+2),a
ld (WrSrc),hl ; set Write source address for DMA
ld a,CmdWr
out (IdeCmd),a ; Command to Hard Disk: Write sector
WaitRdy
WaitDrq
ld hl,WrDmaPB
jr RdIDE1 ; continue to check status
endif
; Prepare for Read or Write operation (set Register).
; Return with phys. DMA address in AHL.
HdPrep: iopage BusP
WaitRdy ; wait for Ready
ld a,1
out (IdeSCnt),a ; Sector number always 1
ld hl,(Sector) ; log. Sector (from 0)
divu hl,Secs ; Runs in Head (Quotient) and Sector (Rest)
or 0A0h ; (Head in A) Drive 0
out (IdeSDH),a ; SDH Register output
ld a,l ; phys. Sector (from 0)
inc a
out (IdeSNum),a ; Sector nummer (from 1)
ld hl,(CurDPH) ; Current XDPH
dec hl
dec hl
ldw de,(hl) ; get Offset Cylinder (start of partition)
ld hl,(Track)
add hl,de ; add logical track --> phys. Cylinder
ld a,l
out (IdeCLo),a
ld a,h
out (IdeCHi),a ; Output Cylinder
if loader
ld a,81h
ld hl,(DMA) ; DMA-Buffer in System-Bank
ret
else
in a,(IdeCmd) ; (because of Z280 chip fault)
jp ClcDma ; Calculate DMA address of sector buffer
endif ; back with address in AHL
; DMA Parameter blocks for IDE-I/O:
RdDmaPb:defb dal3 ; DMA 3
RdDest: defs 3 ; Destination
defb IdeDat,0,BusP ; Source IDE Data register
defw 512 ; Count: 512 Bytes
defw 1110000100000000b ; I/O --> MEM cont.
if not loader
WrDmaPb:defb dal3 ; DMA 3
defb IdeDat,0,Busp ; Destination: IDE Data register
WrSrc: defs 3 ; Source
defw 512 ; Count: 512 Bytes
defw 1000000100001100b ; MEM --> I/O cont.
endif
endif ; (if ide)
;***********************************************************************
;** Common features of all Hard Disk Drivers **
;***********************************************************************
if hard
; Text: Signon and error messages.
if not loader
if deutsch
SignOK: defz 'H:-K: Festplatte 42 MB',cr,lf
SignBad:defz 'Fehler: Festplatte nicht installiert',cr,lf
endif
if english
SignOK: defz 'H:-K: Harddisk 42 MB',cr,lf
SignBad:defz 'Error: Harddisk not installed',cr,lf
endif
endif
; Partitioning: Calculations. More data in DPB's!
OffsetH equ 0 ; Offset first Partition always 0
OffsetI equ PartH ; Offset second Partition
OffsetJ equ OffsetI+PartI ; Offset third Partition
OffsetK equ OffsetJ+PartJ ; Offset fourth Partition
OffsetL equ OffsetK+PartK ; Offset fifth Partition
OffsetM equ OffsetL+PartL ; Offset sixth Partition
OffsetN equ OffsetM+PartM ; Offset seventh Partition
OffsetO equ OffsetN+PartN ; Offset eighth Partition
OffsetP equ OffsetO+PartO ; Offset nineth Partition
; Calculate with loop macro for all nine partitions:
; - Number of Groups (Blocks) in the Partition,
; - Extended Disk Parameter Header,
; - Allocation Vectors,
; - DPB-Parameter Block Shift, Block Mask, and Extent Mask.
;
; Init entry in XDPH only for H: assigned, Login entry never used.
; Attention: There may be arithmetic overflow in the block number for
; large partitions (> 32 MB)!!! For these partitions insert another
; line with a specific block number set directly below the
; "Blocks&i aset ..." line - e.g. "BlocksK aset 4000".
irpc i,<HIJKLMNOP>
if Part&i>0
Blocks&i aset Part&i*Heads*Secs/SpG&i ; Number of Groups in each Partition
defw Offset&i ; Offset Tracks
DPH&i:: defw 0,0,0,0,0,0
defw DPB&i,0
if loader
defw 0,BCB,BCB,-1 ; Buffer in Loader, Hash disable, no ALV
else
defw ALV&i,-2,-2,-2 ; ALV; GENCPM: DirBCB, DtaBCB, Hash
endif
defb 0 ; Hash-Bank
if '&i' = 'H'
defw HDInit ; Init routine entry point
else
defw 0 ; none for other Partitions
endif
if loader
defw 0,RdIDE,0 ; Driver entry points
else
defw 0,RdIDE,WrIDE ; Driver entry points
endif
if not loader
ALV&i: defs (Blocks&i+7)/4 ; Allocation Vectors (2 bits per Block)
endif
j aset SpG&i/2 ; Calculate the Block-Shift:
BSH&i aset 3
rept 8
j aset j/2
if j = 0
exitm
endif
BSH&i aset BSH&i+1
endm
BLM&i equ SpG&i*4-1 ; Block-Mask
EXM&i aset SpG&i/2-1 ; Extent Mask
if Blocks&i > 255
if EXM&i = 0
.printx *** Illegal Blocksize Drive &i: ***
.dephase ; --> Error Return (MAKE Abort)
exitm
endif
EXM&i aset EXM&i / 2
endif
endif ; (if Part&i > 0)
endm ; (IRPC for all partitions)
; DPB's for the Partitions. Several identical partitions can be chared.
; Use DPB so no automatic generation by macros!
; Here we have two common DPB's for this setup.
; In DPB's directly enter (by Hand) Directory-Size (& Alloc.!).
cseg
DPBH:
DPBJ: defw 4*Heads*Secs ; 128 byte sec/trk
defb BSHH,BLMH,EXMH ; block shift, mask; extent mask
defw BlocksH-1 ; max block number
defw 2047 ; dir entries
defb 0FFh,0FFh ; dir blocks alloc vec
defw 8000h ; checksum size
defw 0 ; tracks offset
defb 2,3 ; phys sec shift
DPBI:
DPBK: defw 4*Heads*Secs ; 128 byte sec/trk
defb BSHI,BLMI,EXMI ; block shift, mask; extent mask
defw BlocksI-1 ; max block number
defw 2047 ; dir entries
defb 0FFh,0FFh ; dir blocks alloc vec
defw 8000h ; checksum size
defw 0 ; tracks offset
defb 2,3 ; phys sec shift
endif ; (if hard)
end