mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
475 lines
23 KiB
475 lines
23 KiB
.pl 51
|
|
.nf
|
|
.bp 1
|
|
.ft G-%
|
|
Appendix G
|
|
|
|
Blocking and Deblocking Algorithms
|
|
|
|
|
|
|
|
1 ;
|
|
2 ;
|
|
3 ; sector deblocking algorithms for cp/m 2.0
|
|
4 ;
|
|
5 ;
|
|
6 ;
|
|
7 ; utility macro to compute sector mask
|
|
8 smask macro hblk
|
|
9 ;; compute log2(hblk), return @x as result
|
|
10 ;; (2 ** @x = hblk on return)
|
|
11 @y set hblk
|
|
12 @x set 0
|
|
13 ;; count right shifts of @y until = 1
|
|
14 rept 8
|
|
15 if @y = 1
|
|
16 exitm
|
|
17 endif
|
|
18 ;; @y is not 1, shift right one position
|
|
19 @y set @y shr 1
|
|
20 @x set @x + 1
|
|
21 endm
|
|
22 endm
|
|
23 ;
|
|
24 ;
|
|
25 ;
|
|
26 ; cp/m to host disk constants
|
|
27 ;
|
|
28 ;
|
|
29 0800 = blksiz equ 2048 ;cp/m allocation size
|
|
30 0200 = hstsiz equ 512 ;host disk sector size
|
|
31 0014 = hstspt equ 20 ;host disk sectors/trk
|
|
32 0004 = hstblk equ hstsiz/128 ;cp/m sects/host buff
|
|
33 0050 = cpmspt equ hstblk * hstspt ;cp/m sectors/track
|
|
34 0003 = secmsk equ hstblk-1 ;sector mask
|
|
35 smask hstblk ;compute sector mask
|
|
36 0002 = secshf equ @x ;log2(hstblk)
|
|
37 ;
|
|
38 ;
|
|
39 ;
|
|
40 ; bdos constants on entry to write
|
|
41 ;
|
|
42 ;
|
|
43 0000 = wrall equ 0 ;write to allocated
|
|
44 0001 = wrdir equ 1 ;write to directory
|
|
45 0002 = wrual equ 2 ;write to unallocated
|
|
46 ;
|
|
47 ;
|
|
48 ;
|
|
49 ; the bdos entry points given below show the
|
|
50 ; code which is relevant to deblocking only.
|
|
51 ;
|
|
52 ;
|
|
53 ;
|
|
54 ; diskdef macro, or hand coded tables go here
|
|
55 0000 = dpbase equ $ ;disk param block base
|
|
56 ;
|
|
57 boot:
|
|
58 wboot:
|
|
59 ;enter here on system boot to initialize
|
|
60 0000 af xra a ;0 to accumulator
|
|
61 0001 326a01 sta hstact ;host buffer inactive
|
|
62 0004 326c01 sta unacnt ;clear unalloc count
|
|
63 0007 c9 ret
|
|
64 ;
|
|
65 home:
|
|
66 ;home the selected disk
|
|
67 home:
|
|
68 0008 3a6b01 lda hstwrt ;check for pending write
|
|
69 000b b7 ora a
|
|
70 000c c21200 jnz homed
|
|
71 000f 326a01 sta hstact ;clear host active flag
|
|
72 homed:
|
|
73 0012 c9 ret
|
|
74 ;
|
|
75 seldsk:
|
|
76 ;select disk
|
|
77 0013 79 mov a,c ;selected disk number
|
|
78 0014 326101 sta sekdsk ;seek disk number
|
|
79 0017 6f mov l,a ;disk number to hl
|
|
80 0018 2600 mvi h,0
|
|
81 rept 4 ;multiply by 16
|
|
82 dad h
|
|
83 endm
|
|
84 001a+29 dad h
|
|
85 001b+29 dad h
|
|
86 001c+29 dad h
|
|
87 001d+29 dad h
|
|
88 001e 110000 lxi d,dpbase ;base of parm block
|
|
89 0021 19 dad d ;hl=.dpb(curdsk)
|
|
90 0022 c9 ret
|
|
91 ;
|
|
92 settrk:
|
|
93 ;set track given by registers bc
|
|
94 0023 60 mov h,b
|
|
95 0024 69 mov l,c
|
|
96 0025 226201 shld sektrk ;track to seek
|
|
97 0028 c9 ret
|
|
98 ;
|
|
99 setsec:
|
|
100 ;set sector given by register c
|
|
101 0029 79 mov a,c
|
|
102 002a 326401 sta seksec ;sector to seek
|
|
103 002d c9 ret
|
|
104 ;
|
|
105 setdma:
|
|
106 ;set dma address given by bc
|
|
107 002e 60 mov h,b
|
|
108 002f 69 mov l,c
|
|
109 0030 227501 shld dmaadr
|
|
110 0033 c9 ret
|
|
111 ;
|
|
112 sectran:
|
|
113 ;translate sector number bc
|
|
114 0034 60 mov h,b
|
|
115 0035 69 mov l,c
|
|
116 0036 c9 ret
|
|
117 ;
|
|
118 ;
|
|
119 ;
|
|
120 ; the read entry point takes the place of
|
|
121 ; the previous bios definition for read.
|
|
122 ;
|
|
123 ;
|
|
124 read:
|
|
125 ;read the selected cp/m sector
|
|
126 0037 af xra a
|
|
127 0038 326c01 sta unacnt
|
|
128 003b 3e01 mvi a,1
|
|
129 003d 327301 sta readop ;read operation
|
|
130 0040 327201 sta rsflag ;must read data
|
|
131 0043 3e02 mvi a,wrual
|
|
132 0045 327401 sta wrtype ;treat as unalloc
|
|
133 0048 c3b600 jmp rwoper ;to perform the read
|
|
134 ;
|
|
135 ;
|
|
136 ;
|
|
137 ; the write entry point takes the place of
|
|
138 ; the previous bios definition for write.
|
|
139 ;
|
|
140 ;
|
|
141 write:
|
|
142 ;write the selected cp/m sector
|
|
143 004b af xra a ;0 to accumulator
|
|
144 004c 327301 sta readop ;not a read operation
|
|
145 004f 79 mov a,c ;write type in c
|
|
146 0050 327401 sta wrtype
|
|
147 0053 fe02 cpi wrual ;write unallocated?
|
|
148 0050 c26f00 jnz chkuna ;check for unalloc
|
|
149 ;
|
|
150 ; write to unallocated, set parameters
|
|
151 0058 3e10 mvi a,blksiz/128 ;next unalloc recs
|
|
152 005a 326c01 sta unacnt
|
|
153 005d 3a6101 lda sekdsk ;disk to seek
|
|
154 0060 326d01 sta unadsk ;unadsk = sekdsk
|
|
155 0063 2a6201 lhld settrk
|
|
156 0066 226e01 shld unatrk ;unatrk = sectrk
|
|
157 0069 3a6401 lda seksec
|
|
158 006c 327001 sta unasec ;unasec = seksec
|
|
159 ;
|
|
160 chkuna:
|
|
161 ;check for write to unallocated sector
|
|
162 006f 3a6c01 lda unacnt ;any unalloc remain?
|
|
163 0072 b7 ora a
|
|
164 0073 caae00 jz alloc ;skip if not
|
|
165 ;
|
|
166 ; more unallocated records remain
|
|
167 0076 3d dcr a ;unacnt = unacnt-1
|
|
168 0077 326c01 sta unacnt
|
|
169 007a 3a6101 lda sekdsk ;same disk?
|
|
170 007d 216d01 lxi h,unadsk
|
|
171 0080 be cmp m ;sekdsk = unadsk?
|
|
172 0081 c2ae00 jnz alloc ;skip if not
|
|
173 ;
|
|
174 ; disks are the same
|
|
175 0084 216e01 lxi h,unatrk
|
|
176 0087 cd5301 call sektrkcmp ;saektrk = unatrk?
|
|
177 008a c2ae00 jnz alloc ;skip if not
|
|
178 ;
|
|
179 ; tracks are the same
|
|
180 008d 3a6401 lda seksec ;same sector?
|
|
181 0090 217001 lxi h,unasec
|
|
182 0093 be cmp m ;seksec = unasec?
|
|
183 0094 c2ae00 jnz alloc ;skip if not
|
|
184 ;
|
|
185 ; match, move to next sector for future ref
|
|
186 0097 34 inr m ;unasec = unasec+1
|
|
187 0098 7e mov a,m ;end of track?
|
|
188 0099 fe50 cpi cpmspt ;count cp/m sectors
|
|
189 009b daa700 jc noovf ;skip if no overflow
|
|
190 ;
|
|
191 ; overflow to next track
|
|
192 009e 3600 mvi m,o ;unasec = 0
|
|
193 00a0 2a6e01 lhld unatrk
|
|
194 00a3 23 inx h
|
|
195 00a4 226e01 shld unatrk ;unatrk = unatrk+1
|
|
196 ;
|
|
197 noovf:
|
|
198 ;match found, mark as unnecessary read
|
|
199 00a7 af xra a ;0 to accumulator
|
|
200 00ab 327201 sta rsflag ;rsflag = 0
|
|
201 00ab c3b600 jmp rwoper ;to perform the write
|
|
202 ;
|
|
203 alloc:
|
|
204 ;not an unallocated record, requires pre-read
|
|
205 00ae af xra a ;0 to accum
|
|
206 00af 326c01 sta unacnt ;unacnt = 0
|
|
207 00b2 3c inr a ;1 to accum
|
|
208 00b3 327201 sta rsflag = 1 ;rsflag = 1
|
|
209 ;
|
|
210 ;
|
|
211 ;
|
|
212 ; common code for read and write follows
|
|
213 ;
|
|
214 ;
|
|
215 rwoper:
|
|
216 ;enter here to perform the read-write
|
|
217 00b6 af xra a ;zero to accum
|
|
218 00b7 327101 sta erflag ;no errors (yet)
|
|
219 00ba 3a6401 lda seksec ;compute host sector
|
|
220 rept secshf
|
|
221 ora a ;carry = 0
|
|
222 rar ;shift right
|
|
223 endm
|
|
224 00bd+b7 ora a ;carry = 0
|
|
225 00be+1f rar ;shift right
|
|
226 00bf+b7 ora a ;carry = 0
|
|
227 00c0+1f rar ;shift right
|
|
228 00c1 326901 sta sekhst ;host sector to seek
|
|
229 ;
|
|
230 ; active host sector?
|
|
231 00c4 216a01 lxi h,hstact ;host active flag
|
|
232 00c7 7e mov a,m
|
|
233 00c8 3601 mvi m,1 ;always becomes 1
|
|
234 00ca b7 ora a ;was it already?
|
|
235 00cb caf200 jz filhst ;fill host if not
|
|
236 ;
|
|
237 ; host buffer active, same as seek buffer?
|
|
238 00ce 3a6101 lda sekdsk
|
|
239 00d1 216501 lxi h,hstdsk ;same disk?
|
|
240 00d4 be cmp m ;sekdsk = hstdsk?
|
|
241 00d5 c2eb00 jnz nomatch
|
|
242 ;
|
|
243 ; same disk, same track?
|
|
244 00d8 216601 lxi h,hsttrk
|
|
245 00db cd5301 call sektrkcmp ;sektrk = hsttrk?
|
|
246 00de c2eb00 jnz nomatch
|
|
247 ;
|
|
248 ; same disk, same track, same buffer?
|
|
249 00e1 3a6901 lda sekhst
|
|
250 00e4 216801 lxi h,hstsec ;sekhst = hstsec?
|
|
251 00e7 be cmp m
|
|
252 00e8 ca0f01 jz match ;skip if match
|
|
253 ;
|
|
254 nomatch:
|
|
255 ;proper disk, but not correct sector
|
|
256 00eb 3a6b01 lda hstwrt ;host written?
|
|
257 00ee b7 ora a
|
|
258 00ef c45f01 cnz writehst ;clear host buff
|
|
259 ;
|
|
260 filhst:
|
|
261 ;may have to fill the host buffer
|
|
262 00f2 3a6101 lda sekdsk
|
|
263 00f5 326501 sta hstdsk
|
|
264 00f8 2a6201 lhld sektrk
|
|
265 00fb 226601 shld hsttrk
|
|
266 00fe 3a6901 lda sekhst
|
|
267 0101 326801 sta hstsec
|
|
268 0104 3a7201 lda rsflag ;need to read?
|
|
269 0107 b7 ora a
|
|
270 0108 c46001 cnz readhst ;yes, if 1
|
|
271 010b af xra a ;0 to accum
|
|
272 010c 326b01 sta hstwrt ;no pending write
|
|
273 ;
|
|
274 match:
|
|
275 ;copy data to or from buffer
|
|
276 010f 3a6401 lda seksec ;mask buffer number
|
|
277 0112 e603 ani secmsk ;least signif bits
|
|
278 0114 6f mov l,a ;ready to shift
|
|
279 0115 2600 mvi h,0 ;double count
|
|
280 rept 7 ;shift left 7
|
|
281 dad h
|
|
282 endm
|
|
283 0117+29 dad h
|
|
284 0118+29 dad h
|
|
285 0119+29 dad h
|
|
286 011a+29 dad h
|
|
287 011b+29 dad h
|
|
288 011c+29 dad h
|
|
289 011d+29 dad h
|
|
290 ; hl has relative host buffer address
|
|
291 011e 117701 lxi d,hstbuf
|
|
292 0121 19 dad d ;hl = host address
|
|
293 0122 eb xchg ;now in de
|
|
294 0123 2a7501 lhld dmaadr ;get/put cp/m data
|
|
295 0126 0e80 mvi c,128 ;length of move
|
|
296 0128 3a7301 lda readop ;which way?
|
|
297 012b b7 ora a
|
|
298 012c c23501 jnz rwmove ;skip if read
|
|
299 ;
|
|
300 ; write operation, mark and switch direction
|
|
301 012f 3e01 mvi a,1
|
|
302 0131 326b01 sta hstwrt ;hstwrt = 1
|
|
303 0134 eb xchg ;source/dest swap
|
|
304 ;
|
|
305 rwmove:
|
|
306 ;c initially 128, de is source, hl is dest
|
|
307 0135 1a ldax d ;source character
|
|
308 0136 13 inx d
|
|
309 0137 77 mov m,a ;to dest
|
|
310 0138 23 inx h
|
|
311 0139 od dcr c ;loop 128 times
|
|
312 013a c23501 jnz rwmove
|
|
313 ;
|
|
314 ; data has been moved to/from host buffer
|
|
315 013d 3a7401 lda wrtype ;write type
|
|
316 0140 fe01 cpi wrdir ;to directory?
|
|
317 0142 3a7101 lda erflag ;in case of errors
|
|
318 0145 c0 rnz ;no further processing
|
|
319 ;
|
|
320 ; clear host buffer for directory write
|
|
321 0146 b7 ora a ;errors?
|
|
322 0147 c0 rnz ;skip if so
|
|
323 0148 af xra a ;0 to accum
|
|
324 0149 326b01 sta hstwrt ;buffer written
|
|
325 014c cd5f01 call writehst
|
|
326 014f 3a7101 lda erflag
|
|
327 0152 c9
|
|
328 ;
|
|
329 ;
|
|
330 ;
|
|
331 ; utility subroutine for 16-bit compare
|
|
332 ;
|
|
333 ;
|
|
334 sektrkcmp:
|
|
335 ;hl = .unatrk or .hsttrk, compare with sektrk
|
|
336 0153 eb xchg
|
|
337 0154 216201 lxi h,sektrk
|
|
338 0157 1a ldax d ;low byte compare
|
|
339 0158 be cmp m ;same?
|
|
340 0159 c0 rnz ;return if not
|
|
341 ; low bytes equal, test high 1s
|
|
342 015a 13 inx d
|
|
343 015b 23 inx h
|
|
344 015c 1a ldax d
|
|
345 015d be cmp m ;sets flags
|
|
346 015e c9 ret
|
|
347 ;
|
|
348 ;
|
|
349 ;
|
|
350 ; writehst performs the physical write to
|
|
351 ; the host disk, readhst reads the physical
|
|
352 ; disk.
|
|
353 ;
|
|
354 ;
|
|
355 writehst:
|
|
356 ;hstdsk = host disk #, hsttrk = host track #,
|
|
357 ;hstsec = host sect #. write "hstsiz" bytes
|
|
358 ;from hstbuf and return error flag in erflag.
|
|
359 ;return erflag non-zero if error
|
|
360 015f c9 ret
|
|
361 ;
|
|
362 readhst:
|
|
363 ;hstdsk = host disk #, hsttrk = host track #,
|
|
364 ;hstsec = host sect #. read "hstsiz" bytes
|
|
365 ;into hstbuf and return error flag in erflag.
|
|
366 0160 c9 ret
|
|
367 ;
|
|
368 ;
|
|
369 ;
|
|
370 ; uninitialized ram data areas
|
|
371 ;
|
|
372 ;
|
|
373 ;
|
|
374 0161 sekdsk: ds 1 ;seek disk number
|
|
375 0162 sektrk: ds 2 ;seek track number
|
|
376 0164 seksec: ds 1 ;seek sector number
|
|
377 ;
|
|
378 0165 hstdsk: ds 1 ;host disk number
|
|
379 0166 hsttrk: ds 2 ;host track number
|
|
380 0168 hstsec: ds 1 ;host sector number
|
|
381 ;
|
|
382 0169 sekhst: ds 1 ;seek shr secshf
|
|
383 016a hstact: ds 1 ;host active flag
|
|
384 016b hstwrt: ds 1 ;host written flag
|
|
385 ;
|
|
386 016c unacnt: ds 1 ;unalloc rec cnt
|
|
387 016d unadsk: ds 1 ;last unalloc disk
|
|
388 016e unatrk: ds 2 ;last unalloc track
|
|
389 0170 unasec: ds 1 ;last unalloc sector
|
|
390 ;
|
|
391 0171 erflag: ds 1 ;error reporting
|
|
392 0172 rsflag: ds 1 ;read sector flag
|
|
393 0173 readop: ds 1 ;1 if read operation
|
|
394 0174 wrtype: ds 1 ;write operation type
|
|
395 0175 dmaadr: ds 2 ;last dma address
|
|
396 0177 hstbuf: ds hstsiz ;host buffer
|
|
397 ;
|
|
398 ;
|
|
399 ;
|
|
400 ; the endef macro invocation goes here
|
|
401 ;
|
|
402 ;
|
|
403 0377 end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
alloc 00ae 164 172 177 183 203#
|
|
blksiz 0800 29# 151
|
|
boot 0000 57#
|
|
chkuna 006f 148 160#
|
|
cpmspt 0050 33# 188
|
|
dmaadr 0175 109 294 395#
|
|
dpbase 0000 55# 88
|
|
erflag 0171 218 317 326 391#
|
|
filhst 00f2 235 260#
|
|
home 0008 65# 67#
|
|
homed 0012 70 72#
|
|
hstact 016a 61 71 231 383#
|
|
hstblk 0004 32# 33 34 35
|
|
hstbuf 0177 291 396#
|
|
hstdsk 0165 239 263 378#
|
|
hstsec 0168 250 267 380#
|
|
hstsiz 0200 30# 32 396
|
|
hstspt 0014 31# 33
|
|
hsttrk 0166 244 265 379#
|
|
hstwrt 016b 68 256 272 302 324 384#
|
|
match 010fl 252 274#
|
|
nomatch 00eb 241 246 254#
|
|
noovf 00a7 189 197#
|
|
read 0037 124#
|
|
readhst 0160 270 362#
|
|
readop 0173 129 144 296 393#
|
|
rsflag 0172 130 200 208 268 392#
|
|
rwmove 0135 298 305# 312
|
|
rwoper 00b6 133 201 215#
|
|
secmsk 0003 34# 277
|
|
secshf 0002 36# 220
|
|
sectran 0034 112#
|
|
sekdsk 0161 78 153 169 238 262 374#
|
|
sekhst 0169 228 249 266 382#
|
|
seksec 0164 102 157 180 219 276 376#
|
|
sektrk 0162 96 155 264 337 375#
|
|
sektrkcmp 0153 176 245 334#
|
|
seldsk 0013 75#
|
|
setdma 002e 105#
|
|
setsec 0029 99#
|
|
settrk 0023 92#
|
|
unacnt 016c 62 127 152 162 168 206 386#
|
|
unadsk 016d 154 170 387#
|
|
unasec 0170 158 181 389#
|
|
unatrk 016e 156 175 193 195 388#
|
|
wboot 0000 58#
|
|
wrall 0000 43#
|
|
wrdir 0001 44# 316
|
|
write 004b 141#
|
|
writehst 015f 258 325 355#
|
|
wrtype 0174 132 146 315 394#
|
|
wrual 0002 45# 131 147
|
|
|