forked from MirrorRepos/RomWBW
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.
3009 lines
125 KiB
3009 lines
125 KiB
N
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Appendix A
|
|
|
|
The Microcomputer Development System Basic Input/Output System (BIOS)
|
|
|
|
|
|
|
|
1 ; mds-800 i/o drivers for cp/m 2.2
|
|
2 ; (four drive single density version)
|
|
3 ;
|
|
4 ; version 2.2 february, 1980
|
|
5 ;
|
|
6 0016 = vers equ 22 ;version 2.2
|
|
7 ;
|
|
8 ; copyright (c) 1980
|
|
9 ; digital research
|
|
10 ; box 579, pacific grove
|
|
11 ; california, 93950
|
|
12 ;
|
|
13 ;
|
|
14 ffff = true equ 0fffh ;value of "true"
|
|
15 0000 = false equ not true ;"false"
|
|
16 0000 = test equ false ;true if test bios
|
|
17 ;
|
|
18 if test
|
|
19 bias equ 03400h ;base of ccp in test system
|
|
20 endif
|
|
21 if not test
|
|
22 0000 = bias equ 0000h ;generate relocatable cp/m system
|
|
23 endif
|
|
24 ;
|
|
25 1600 = patch equ 1600h
|
|
26 ;
|
|
27 1600 org patch
|
|
28 0000 = cpmb equ $-patch ;base of cpm console processor
|
|
29 0806 = bdos equ 806h+cpmb ;basic dos (resident portion)
|
|
30 1600 = cpml equ $-cpmb ;length (in bytes) of cpm system
|
|
31 002c = nsects equ cpml/128 ;number of sectors to load
|
|
32 0002 = offset equ 2 ;number of disk tracks used by cp/m
|
|
33 0004 = cdisk equ 0004h ;address of last logged disk on warm start
|
|
34 0080 = buff equ 0080h ;default buffer address
|
|
|
|
A-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 000a = retry equ 10 ;max retries on disk i/o before error
|
|
36 ;
|
|
37 ; perform following functions
|
|
38 ; boot cold start
|
|
39 ; wboot warm start (save i/o byte)
|
|
40 ; (boot and wboot are the same for mds)
|
|
41 ; const console status
|
|
42 ; reg-a = 00 if no character ready
|
|
43 ; reg-a = ff if character ready
|
|
44 ; conin console character in (result in reg-a)
|
|
45 ; conout console character out (char in reg-c)
|
|
46 ; list list out (char in reg-c)
|
|
47 ; punch punch out (char in reg-c)
|
|
48 ; reader paper tape reader in (result to reg-a)
|
|
49 ; home move to track 00
|
|
50 ;
|
|
51 ; (the following calls set-up the io parameter block for the
|
|
52 ; mds, which is used to perform subsequent reads and writes)
|
|
53 ; seldsk select disk given by reg-c (0, 1, 2...)
|
|
54 ; settrk set track address (0,...76) for subsequent read-write
|
|
55 ; setsec set sector address (1,...,26) for subsequent read-write
|
|
56 ; setdma set subsequent dma address (initially 80h)
|
|
57 ;
|
|
58 ; (read and write assume previous calls to set up the io parameters)
|
|
59 ; read read track/sector to preset dma address
|
|
60 ; write track/sector from preset dma address
|
|
61 ;
|
|
62 ; jump vector for individual routines
|
|
63 1600 c3b316 jmp boot
|
|
64 1603 c3c316 wboote: jmp wboot
|
|
65 1606 c36117 jmp const
|
|
66 1609 c36417 jmp conin
|
|
67 160c c36a17 jmp conout
|
|
68 160f c36d17 jmp list
|
|
69 1612 c37217 jmp punch
|
|
70 1615 c37517 jmp reader
|
|
71 1618 c37817 jmp home
|
|
72 161b c37d17 jmp seldsk
|
|
73 161e c3a717 jmp settrk
|
|
74 1621 c3ac17 jmp setsec
|
|
|
|
A-2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 1624 c3bb17 jmp setdma
|
|
76 1627 c3c117 jmp read
|
|
77 162a c3ca17 jmp write
|
|
78 162d c37017 jmp listst ;list status
|
|
79 1630 c3b117 jmp sectran
|
|
80 ;
|
|
81 maclib diskdef ;load the disk definition library
|
|
82 disks 4 ;four disks
|
|
83 1633+= dpbase equ $ ;base of disk parameter blocks
|
|
84 1633+82160000 dpe0: dw xlt0, 0000h ;translate table
|
|
85 1637+00000000 dw 0000h, 0000h ;scratch area
|
|
86 163b+6e187316 dw dirbuf, dpb0 ;dir buff, parm block
|
|
87 163f+0d19ee18 dw csv0, alv0 ;check, alloc vectors
|
|
88 1643+82160000 dpe1: dw xlt1, 0000h ;translate table
|
|
89 1647+00000000 dw 0000h, 0000h ;scratch area
|
|
90 164b+6e187316 dw dirbuf, dpb1 ;dir buff, parm block
|
|
91 164f+3c191d19 dw csv1, alv1 ;check, alloc vectors
|
|
92 1653+82160000 dpe2: dw xlt2, 0000h ;translate table
|
|
93 1657+00000000 dw 0000h, 0000h ;scratch area
|
|
94 165b+6e187316 dw dirbuf, dpb2 ;dir buff, parm block
|
|
95 165f+6b194c19 dw csv2, alv2 ;check, alloc vectors
|
|
96 1663+82160000 dpe3: dw xlt3, 0000h ;translate table
|
|
97 1667+00000000 dw 0000h, 0000h ;scratch area
|
|
98 166b+6e187316 dw dirbuf, dpb3 ;check, alloc block
|
|
99 166f+9a197b19 dw csv3, alv3 ;dir buff, parm vectors
|
|
100 diskdef 0, 1, 26, 6, 1024, 243, 64, 64, offset
|
|
101 1673+= dpb0 equ $ ;disk parm block
|
|
102 1673+1a00 dw 26 ;sec per track
|
|
103 1675+03 db 3 ;block shift
|
|
104 1676+07 db 7 ;block mask
|
|
105 1677+00 db 0 ;extnt mask
|
|
106 1678+f200 dw 242 ;disk size-1
|
|
107 167a+3f00 dw 63 ;directory max
|
|
108 167c+c0 db 192 ;alloc0
|
|
109 167d+00 db 0 ;alloc1
|
|
110 167e+1000 dw 16 ;check size
|
|
111 1680+0200 dw 2 ;offset
|
|
112 1682+= xlt0 equ $ ;translate table
|
|
113 1682+01 db 1
|
|
114 1683+07 db 7
|
|
|
|
A-3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 1684+0d db 13
|
|
116 1685+13 db 19
|
|
117 1686+19 db 25
|
|
118 1687+05 db 5
|
|
119 1688+0b db 11
|
|
120 1689+11 db 17
|
|
121 168a+17 db 23
|
|
122 168b+03 db 3
|
|
123 168c+09 db 9
|
|
124 168d+0f db 15
|
|
125 168e+15 db 21
|
|
126 168f+02 db 2
|
|
127 1690+08 db 8
|
|
128 1691+0e db 14
|
|
129 1692+14 db 20
|
|
130 1693+1a db 26
|
|
131 1694+06 db 6
|
|
132 1695+0c db 12
|
|
133 1696+12 db 18
|
|
134 1697+18 db 24
|
|
135 1698+04 db 4
|
|
136 1699+0a db 10
|
|
137 169a+10 db 16
|
|
138 169b+16 db 22
|
|
139 diskdef 1,0
|
|
140 1673+ = dpb1 equ dpb0 ;equivalent parameters
|
|
141 001f+ = als1 equ als0 ;same allocation vector size
|
|
142 0010+ = css1 equ css0 ;same checksum vector size
|
|
143 1682+ = xlt1 equ xlt0 ;same translate table
|
|
144 diskdef 2, 0
|
|
145 1673+ = dpb2 equ dpb0 ;equivalent parameters
|
|
146 001f+ = als2 equ als0 ;same allocation vector size
|
|
147 0010+ = css2 equ css0 ;same checksum vector size
|
|
148 1682+ = xlt2 equ xlt0 ;same translate table
|
|
149 diskdef 3, 0
|
|
150 1673+ = dpb3 equ dpb0 ;equivalent parameters
|
|
151 001f+ = als3 equ als0 ;same allocation vector size
|
|
152 0010+ = css3 equ css0 ;same checksum vector size
|
|
153 1682+ = xlt3 equ xlt0 ;same translate table
|
|
154 ; endef occurs at end of assembly
|
|
|
|
A-4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 ;
|
|
156 ; end of controller--independent code, the remaining subroutines
|
|
157 ; are tailored to the particular operating environment, and must
|
|
158 ; be altered for any system which differs from the intel mds.
|
|
159 ;
|
|
160 ; the following code assumes the mds monitor exists at 0f800h
|
|
161 ; and uses the i/o subroutines within the monitor
|
|
162 ;
|
|
163 ; we also assume the mds system has four disk drives
|
|
164 00fd = revrt equ 0fdh ;interrupt revert port
|
|
165 00fc = intc equ 0fch ;interrupt mask port
|
|
166 00f3 = icon equ 0f3h ;interrupt control port
|
|
167 007E = inte equ 0111$1110b ;enable rst 0 (warm boot), rst 7 (monitor)
|
|
168 ;
|
|
169 ; mds monitor equates
|
|
170 f800 = mon80 equ 0f800h ;mds monitor
|
|
171 ff0f = rmon80 equ 0ff0fh ;restart mon80 (boot error)
|
|
172 f803 = ci equ 0f803h ;console character to reg-a
|
|
173 f806 = ri equ 0f806h ;reader in to reg-a
|
|
174 f809 = co equ 0f809h ;console char from c to console out
|
|
175 f80c = po equ 0f80ch ;punch char from c to punch device
|
|
176 f80f = lo equ 0f80fh ;list from c to list device
|
|
177 f812 = csts equ 0f812h ;console status 00/ff to register a
|
|
178 ;
|
|
179 ; disk ports and commands
|
|
180 0078 = base equ 78h ;base of disk command io ports
|
|
181 0078 = dstat equ base ;disk status (input)
|
|
182 0079 = rtype equ base+1 ;result type (input)
|
|
183 007b = rbyte equ base+3 ;result byte (input)
|
|
184 ;
|
|
185 0079 = ilow equ base+1 ;iopb low address (output)
|
|
186 007a = ihigh equ base+2 ;iopb high address (output)
|
|
187 ;
|
|
188 0004 = readf equ 4h ;read function
|
|
189 0006 = writf equ 6h ;write function
|
|
190 0003 = recal equ 3h ;recalibrate drive
|
|
191 0004 = iordy equ 4h ;i/o finished mask
|
|
192 000d = cr equ 0dh ;carriage return
|
|
193 000a = lf equ 0ah ;line-feed
|
|
194 ;
|
|
|
|
A-5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 signon: ;signon message: xxk cp/m vers y.y
|
|
196 169c 0d0a0a db cr, lf, lf
|
|
197 if test
|
|
198 db '32' ;32k example bios
|
|
199 endif
|
|
200 if not test
|
|
201 169f 3030 db '00' ;memory size filled by relocator
|
|
202 endif
|
|
203 16a1 6b2043502f db 'k cp/m vers '
|
|
204 16ad 322e32 db ver/10+'0', ',' vers mod 10+'0'
|
|
205 16b0 0d0a00 db cr, lf, 0
|
|
206 ;
|
|
207 boot: ;print signon message and go to ccp
|
|
208 ; (note: mds boot initialized iobyte at 0003h)
|
|
209 16b3 310001 lxi sp, buff+80h
|
|
210 16b6 219c16 lxi h, signon
|
|
211 16b9 cdd317 call prmsg ;print message
|
|
212 16bc af xra a ;clear accumulator
|
|
213 16bd 320400 sta cdisk ;set initially to disk a
|
|
214 16c0 c30f17 jmp gocpm ;go to cp/m
|
|
215 ;
|
|
216 ;
|
|
217 wboot:; loader on track 0, sector 1, which will be skipped for warm
|
|
218 ; read cp/m from disk--assuming there is a 128 byte cold start
|
|
219 ; start
|
|
220 ;
|
|
221 16c3 318000 lxi sp, buff ;using dma--thus 80 thru ff available for stack
|
|
222 ;
|
|
223 16c6 0e0a mvi c, retry ;max retries
|
|
224 16c8 c5 push b
|
|
225 wboot0: ;enter here on error retries
|
|
226 16c9 010000 lxi b, cpmb ;set dma address to start of disk system
|
|
227 16cc cdbb17 call setdma
|
|
228 16cf 0e00 mvi c, 0 ;boot from drive 0
|
|
229 16d1 cd7d17 call seldsk
|
|
230 16d4 0e00 mvi c, 0
|
|
231 16d6 cda717 call settrk ;start with track 0
|
|
232 16d9 0e02 mvi c, 2 ;start reading sector 2
|
|
233 16db cdac17 call setsec
|
|
234 ;
|
|
|
|
A-6
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 ; read sectors, count nsects to zero
|
|
236 16de c1 pop b ;10-error count
|
|
237 16df 062c mvi b, nsects
|
|
238 rdsec: ;read next sector
|
|
239 16e1 c5 push b ;save sector count
|
|
240 16e2 cdc117 call read
|
|
241 16e5 c24917 jnz booterr ;retry if errors occur
|
|
242 16e8 2a6c18 lhld iod ;increment dma address
|
|
243 16eb 118000 lxi d, 128 ;sector size
|
|
244 16ee 19 dad d ;incremented dma address in hl
|
|
245 16ef 44 mov b, h
|
|
246 16f0 4d mov c, l ;ready for call to set dma
|
|
247 16f1 cdbb17 call setdma
|
|
248 16f4 3a6b18 lda ios ;sector number just read
|
|
249 16f7 fe1a cpi 26 ;read last sector?
|
|
250 16f9 da0517 jc rd1
|
|
251 ; must be sector 26, zero and go to next track
|
|
252 16fc 3a6a18 lda iot ;get track to register a
|
|
253 16ff 3c inr a
|
|
254 1700 4f mov c, a ;read for call
|
|
255 1701 cda717 call settrk
|
|
256 1704 af xra a ;clear sector number
|
|
257 1705 3c rd1: inr a ;to next sector
|
|
258 1706 4f mov c, a ;ready for call
|
|
259 1707 cdac17 call setsec
|
|
260 170a c1 pop b ;recall sector count
|
|
261 170b 05 dcr b ;done?
|
|
262 170c c2e116 jnz rdsec
|
|
263 ;
|
|
264 ; done with the load, reset default buffer address
|
|
265 gocpm: ;(enter here from cold start boot)
|
|
266 ; enable rst0 and rst7
|
|
267 170f f3 di
|
|
268 1710 3e12 mvi a, 12h ;initialize command
|
|
269 1712 d3fd out revrt
|
|
270 1714 af xra a
|
|
271 1715 d3fc out intc ;cleared
|
|
272 1717 3e7e mvi a, inte ;rst0 and rst7 bits on
|
|
273 1719 d3fc out intc
|
|
274 171b af xra a
|
|
|
|
A-7
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 171c d3f3 out icon ;interrupt control
|
|
276 ;
|
|
277 ; set default buffer address to 80h
|
|
278 171e 018000 lxi b, buff
|
|
279 1721 cdbb17 call setdma
|
|
280 ;
|
|
281 ; reset monitor entry points
|
|
282 1724 3ec3 mvi a, jmp
|
|
283 1726 320000 sta 0
|
|
284 1729 210316 lxi h, wboote
|
|
285 172c 220100 shld 1 ;jump wboot at location 00
|
|
286 172f 320500 sta 5
|
|
287 1732 210608 lxi h, bdos
|
|
288 1735 220600 shld 6 ;jmp bdos at location 5
|
|
289 if not test
|
|
290 1738 323800 sta 7*8 ;jmp to mon80 (may have changed by ddt)
|
|
291 173b 2100f8 lxi h, mon80
|
|
292 173e 223900 shld 7*8+1
|
|
293 endif
|
|
294 ; leave iobyte set
|
|
295 ; previously selected disk was b, send parameter to cpm
|
|
296 1741 3a0400 lda cdisk ;last logged disk number
|
|
297 1744 4f mov c, a ;send to ccp to log it in
|
|
298 1745 fb ei
|
|
299 1746 c30000 jmp cpmb
|
|
300 ;
|
|
301 ; error condition occurred, print message and retry
|
|
302 booterr:
|
|
303 1749 c1 pop b ;recall counts
|
|
304 174a 0d dcr c
|
|
305 174b ca5217 jz booter0
|
|
306 ; try again
|
|
307 174e c5 push b
|
|
308 174f c3c916 jmp wboot0
|
|
309 ;
|
|
310 booter0:
|
|
311 ; otherwise too many retries
|
|
312 1752 215b17 lxi h, bootmsg
|
|
313 1755 cdd317 call prmsg
|
|
314 1758 c30fff jmp rmon80 ;mds hardware monitor
|
|
|
|
A-8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 ;
|
|
316 bootmsg:
|
|
317 175b 3f626f6f74 db '?boot', 0
|
|
318 ;
|
|
319 ;
|
|
320 const: console status to reg-a
|
|
321 ; (exactly the same as mds call)
|
|
322 1761 c312f8 jmp csts
|
|
323 ;
|
|
324 conin: ;console character to reg-a
|
|
325 1764 cd03f8 call ci
|
|
326 1767 e67f ani 7fh ;remove parity bit
|
|
327 1769 c9 ret
|
|
328 ;
|
|
329 conout: ;console character from c to console out
|
|
330 176a c309f8 jmp co
|
|
331 ;
|
|
332 list: ;list device out
|
|
333 ; (exactly the same as mds call)
|
|
334 176d c30ff8 jmp lo
|
|
335 ;
|
|
336 listst:
|
|
337 ;return list status
|
|
338 1770 af xra a
|
|
339 1771 c9 ret ;always not ready
|
|
340 ;
|
|
341 punch: ;punch device out
|
|
342 ; (exactly the same as mds call)
|
|
343 1772 c30cf8 jmp po
|
|
344 ;
|
|
345 reader: ;reader character in to reg-a
|
|
346 ; (exactly the same as mds call)
|
|
347 1775 c306f8 jmp ri
|
|
348 ;
|
|
349 home: ;move to home position
|
|
350 ; treat as track 00 seek
|
|
351 1778 0e00 mvi c, 0
|
|
352 177a c3a717 jmp settrk
|
|
353 ;
|
|
354 seldsk: ;select disk given by register c
|
|
|
|
A-9
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
355 177d 210000 lxi h, 0000h ;return 0000 if error
|
|
356 1780 79 mov a, c
|
|
357 1781 fe04 cpi ndisks ;too large?
|
|
358 1783 d0 rnc ;leave hl = 0000
|
|
359 ;
|
|
360 1784 e602 ani 10b ;00 00 for drive 0, 1 and 10 10 for drive 2, 3
|
|
361 1786 326618 sta dbank ;to select drive bank
|
|
362 1789 79 mov a, c ;00, 01, 10, 11
|
|
363 178a e601 ani 1b ;mds has 0, 1 at 78, 2, 3 at 88
|
|
364 178c b7 ora a ;result 00?
|
|
365 178d ca9217 jz setdrive
|
|
366 1790 3e30 mvi a, 00110000b ;selects drive 1 in bank
|
|
367 setdrive:
|
|
368 1792 47 mov b, a ;save the function
|
|
369 1793 216818 lxi h, iof ;io function
|
|
370 1796 7e mov a, m
|
|
371 1797 e6cf ani 11001111b ;mask out disk number
|
|
372 1799 b0 ora b ;mask in new disk number
|
|
373 179a 77 mov m, a ;save it in iopb
|
|
374 179b 69 mov l, c
|
|
375 179c 2600 mvi h, 0 ;hl=disk number
|
|
376 179e 29 dad h ;*2
|
|
377 179f 29 dad h ;*4
|
|
378 17a0 29 dad h ;*8
|
|
379 17a1 29 dad h ;*16
|
|
380 17a2 113316 lxi d, dpbase
|
|
381 17a5 19 dad d ;hl=disk header table address
|
|
382 17a6 c9 ret
|
|
383 ;
|
|
384 ;
|
|
385 settrk: ;set track address given by c
|
|
386 17a7 216a18 lxi h, iot
|
|
387 17aa 71 mov m, c
|
|
388 17ab c9 ret
|
|
389 ;
|
|
390 setsec: ;set sector number given by c
|
|
391 17ac 216b18 lxi h, ios
|
|
392 17af 71 mov m, c
|
|
393 17b0 c9 ret
|
|
394 sectran:
|
|
|
|
A-10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
395 ;translate sector bc using table at de
|
|
396 17b1 0600 mvi b, 0 ;double-precision sector number in bc
|
|
397 17b3 eb xchg ;translate table address to hl
|
|
398 17b4 09 dad b ;translate (sector) address
|
|
399 17b5 7e mov a, m ;translated sector number to a
|
|
400 17b6 326b18 sta ios
|
|
401 17b9 6f mov l, a ;return sector number in l
|
|
402 17ba c9 ret
|
|
403 ;
|
|
404 setdma: ;set dma address given by regs b, c
|
|
405 17bb 69 mov l, c
|
|
406 17bc 60 mov h, b
|
|
407 17bd 226c18 shld iod
|
|
408 17c0 c9 ret
|
|
409 ;
|
|
410 read: ;read next disk record (assuming disk/trk/sec/dma set)
|
|
411 17c1 0e04 mvi c, readf ;set to read function
|
|
412 17c3 cde017 call setfunc
|
|
413 17c6 cdf017 call waitio ;perform read function
|
|
414 17c9 c9 ret ;may have error set in reg-a
|
|
415 ;
|
|
416 ;
|
|
417 write: ;disk write function
|
|
418 17ca 0e06 mvi c, writf
|
|
419 17cc cde017 call setfunc ;set to write function
|
|
420 17cf cdf017 call waitio
|
|
421 17d2 c9 ret ;may have error set
|
|
422 ;
|
|
423 ;
|
|
424 ; utility subroutines
|
|
425 prmsg: ;print message at h, l to 0
|
|
426 17d3 7e mov a, m
|
|
427 17d4 b7 ora a zero?
|
|
428 17d5 c8 rz
|
|
429 ; more to print
|
|
430 17d6 e5 push h
|
|
431 17d7 4f mov c,a
|
|
432 17d8 cd6a17 call conout
|
|
433 17db e1 pop h
|
|
434 17dc 23 inx h
|
|
|
|
A-11
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
435 17dd c3d317 jmp prmsg
|
|
436 ;
|
|
437 setfunc:
|
|
438 ; set function for next i/o (command in reg-c)
|
|
439 17e0 216818 lxi h, iof ;io function address
|
|
440 17e3 7e mov a, m ;get it to accumulator for masking
|
|
441 17e4 e6f8 ani 11111000b ;remove previous command
|
|
442 17e6 b1 ora c ;set to new command
|
|
443 17e7 77 mov m, a ;replaced in iopb
|
|
444 ; the mds-800 controller requires disk bank bit in sector byte
|
|
445 ; mask the bit from the current i/o function
|
|
446 17e8 e620 ani 00100000b ;mask the disk select bit
|
|
447 17ea 216b18 lxi h, ios ;address the sector select byte
|
|
448 17ed b6 ora m ;select proper disk bank
|
|
449 17ee 77 mov m, a ;set disk select bit on/off
|
|
450 17ef c9 ret
|
|
451 ;
|
|
452 waitio:
|
|
453 17f0 0e0a mvi c, retry ;max retries before perm error
|
|
454 rewait:
|
|
455 ; start the i/o function and wait for completion
|
|
456 17f2 cd3f18 call intype ;in rtype
|
|
457 17f5 cd4c18 call inbyte ;clears the controller
|
|
458 ;
|
|
459 17f8 3a6618 lda dbank ;set bank flags
|
|
460 17fb b7 ora a ;zero if drive 0, 1 and nz if 2, 3
|
|
461 17fc 3e67 mvi a, iopb and offh ;low address for iopb
|
|
462 17fe 0618 mvi b, iopb shr 8 ;high address for iopb
|
|
463 1800 c20b18 jnz iodr1 ;drive bank 1?
|
|
464 1803 d379 out ilow ;low address to controller
|
|
465 1805 78 mov a, b
|
|
466 1806 d37a out ihigh ;high address
|
|
467 1808 c31018 jmp waito ;to wait for complete
|
|
468 ;
|
|
469 iodr1: ;drive bank 1
|
|
470 180b d389 out ilow+10h ;88 for drive bank 10
|
|
471 180d 78 mov a, b
|
|
472 180e d38a out ihigh+10h
|
|
473 ;
|
|
474 1810 cd5918 waito: call instat ;wait for completion
|
|
|
|
A-12
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
475 1813 e604 ani iordy ;ready?
|
|
476 1815 ca1018 jz waito
|
|
477 ;
|
|
478 ; check io completion ok
|
|
479 1818 cd3f18 call intype ;must be io complete (00) unlinked
|
|
480 ; 00 unlinked i/o complete, 01 linked i/o complete (not used)
|
|
481 ; io disk status changed 11 (not used)
|
|
482 181b fe02 cpi 10b ;ready status change?
|
|
483 181d ca3218 jz wready
|
|
484 ;
|
|
485 ; must be 00 in the accumulator
|
|
486 1820 b7 ora a
|
|
487 1821 c23818 jnz werror ;some other condition, retry
|
|
488 ;
|
|
489 ; check i/o error bits
|
|
490 1824 cd4c18 call inbyte
|
|
491 1827 17 ral
|
|
492 1828 da3218 jc wready ;unit not ready
|
|
493 182b 1f rar
|
|
494 182c e6fe ani 11111110b ;any other errors? (deleted data ok)
|
|
495 182e c23818 jnz werror
|
|
496 ;
|
|
497 ; read or write is ok, accumulator contains zero
|
|
498 1831 c9 ret
|
|
499 ;
|
|
500 wready: ;not ready, treat as error for now
|
|
501 1832 cd4c18 call inbyte ;clear result byte
|
|
502 1835 c33818 jmp trycount
|
|
503 ;
|
|
504 werror: ;return hardware malfunction (crc, track, seek, etc.)
|
|
505 ; the mds controller has returned a bit in each position
|
|
506 ; of the accumulator, corresponding to the conditions:
|
|
507 ; 0 -deleted data (accepted as ok above)
|
|
508 ; 1 -crc error
|
|
509 ; 2 -seek error
|
|
510 ; 3 -address error (hardware malfunction)
|
|
511 ; 4 -data over/under flow (hardware malfunction)
|
|
512 ; 5 -write protect (treated as not ready)
|
|
513 ; 6 -write error (hardware malfunction)
|
|
514 ; j -not ready
|
|
|
|
A-13
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
515 ; (accumulator bits are numbered 7 6 5 4 3 2 1 0)
|
|
516 ;
|
|
517 ; it may be useful to filter out the various conditions,
|
|
518 ; but we will get a permanent error message if it is not
|
|
519 ; recoverable. in any case, the not ready condition is
|
|
520 ; treated as a separated condition for later improvement
|
|
521 trycount:
|
|
522 ; register c contains retry count, decrement 'til zero
|
|
523 1838 0d dcr c
|
|
524 1839 c2f217 jnz rewait ;for another try
|
|
525 ;
|
|
526 ; cannot recover from error
|
|
527 183c 3e01 mvi a, 1 ;error code
|
|
528 183e c9 ret
|
|
529 ;
|
|
530 ; intype, inbyte, instat read drive bank 00 or 10
|
|
531 183f 3a6618 intype: lda dbank
|
|
532 1842 b7 ora a
|
|
533 1843 c24918 jnz intyp1 ;skip to bank 10
|
|
534 1846 db79 in rtype
|
|
535 1848 c9 ret
|
|
536 1849 db89 intyp1: in rtype+10h ;78 for 0, 1 88 for 2, 3
|
|
537 184b c9 ret
|
|
538 ;
|
|
539 184c 3a6618 inbyte: lda dbank
|
|
540 184f b7 ora a
|
|
541 1850 c25618 jnz inbyt1
|
|
542 1853 db7b in rbyte
|
|
543 1855 c9 ret
|
|
544 1856 db8b inbyt1: in rbyte+10h
|
|
545 1858 c9 ret
|
|
546 ;
|
|
547 1859 3a6618 instat: lda dbank
|
|
548 185c b7 ora a
|
|
549 185d c26318 jnz insta1
|
|
550 1860 db78 in dstat
|
|
551 1862 c9 ret
|
|
552 1863 db88 insta1: in dstat+10h
|
|
553 1865 c9 ret
|
|
554 ;
|
|
|
|
A-14
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
555 ;
|
|
556 ;
|
|
557 ; data areas (must be in ram)
|
|
558 1866 00 dbank: db 0 ;disk bank 00 if drive 0, 1
|
|
559 ; 10 if drive 2, 3
|
|
560 iopb: ;io parameter block
|
|
561 1867 80 db 80h ;normal i/o operation
|
|
562 1868 04 iof: db readf ;io function, initial read
|
|
563 1869 01 ion: db 1 ;number of sectors to read
|
|
564 186a 02 iot: db offset ;track number
|
|
565 186b 01 ios: db 1 ;sector number
|
|
566 186c 8000 iod: dw buff ;io address
|
|
567 ;
|
|
568 ;
|
|
569 ; define ram areas for bdos operation
|
|
570 endef
|
|
571 186e+= begdat equ $
|
|
572 186e+ dirbuf: ds 128 ;directory access buffer
|
|
573 18ee+ alv0: ds 31
|
|
574 190d+ csv0: ds 16
|
|
575 191d+ alv1: ds 31
|
|
576 193c+ csv1: ds 16
|
|
577 194c+ alv2: ds 31
|
|
578 196b+ csv2: ds 16
|
|
579 197b+ alv3: ds 31
|
|
580 199a+ csv3: ds 16
|
|
581 19aa+= enddat equ $
|
|
582 013c+= datsiz equ $-begdat
|
|
583 19aa end
|
|
|
|
|
|
als1 001f 141#
|
|
als2 001f 146#
|
|
als3 001f 151#
|
|
alv0 18ee 87 573#
|
|
alv1 191d 91 575#
|
|
alv2 194c 95 577#
|
|
alv3 197b 99 579#
|
|
base 0078 180# 181 182 183 185 186
|
|
bdos 0806 29# 287
|
|
|
|
A-15
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
begdat 186e 571# 582
|
|
bias 0000 19# 22#
|
|
boot 16b3 63 207#
|
|
booter0 1752 305 310#
|
|
booterr 1749 241 302#
|
|
bootmsg 175b 312 316#
|
|
buff 0080 34# 209 221 278 566
|
|
cdisk 0004 33# 213 296
|
|
ci f803 172# 325
|
|
co f809 174# 330
|
|
conin 1764 66 324#
|
|
conout 176a 67 329# 432
|
|
const 1761 65 320#
|
|
cpmb 0000 28# 29 30 226 299
|
|
cpml 1600 30# 31
|
|
cr 000d 192# 196 205
|
|
css1 0010 142#
|
|
css2 0010 147#
|
|
css3 0010 152#
|
|
csts f812 177# 322
|
|
csv0 190d 87 574#
|
|
csv1 193c 91 576#
|
|
csv2 196b 95 578#
|
|
csv3 199a 99 580#
|
|
datsiz 013c 582#
|
|
dbank 1866 361 459 531 539 539 547 558#
|
|
dirbuf 186e 86 90 94 98 572#
|
|
dpb0 1673 86 101# 140 145 150
|
|
dpb1 1673 90 140#
|
|
dpb2 1673 94 145#
|
|
dpb3 1673 98 150#
|
|
dpbase 1633 83# 380
|
|
dpe0 1633 84#
|
|
dpe1 1643 88#
|
|
dpe2 1653 92#
|
|
dpe3 1663 96#
|
|
dstat 0078 181# 550 552
|
|
enddat 19aa 581#
|
|
false 0000 15# 16
|
|
gocpm 170f 214 265#
|
|
|
|
A-16
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
home 1778 71 349#
|
|
icon 00fe 166# 275
|
|
ihigh 007a 186# 466 472
|
|
ilow 0079 185# 464 470
|
|
inbyt1 1856 541 544#
|
|
inbyte 184c 457 490 501 539#
|
|
insta1 1863 549 552#
|
|
instat 1859 474 547#
|
|
intc 00fc 165# 271 273
|
|
inte 007e 167# 272
|
|
intyp1 1849 533 536#
|
|
intype 183f 456 479 531#
|
|
iod 186c 242 407 566#
|
|
iodr1 180b 463 469#
|
|
iof 1868 369 439 562#
|
|
ion 1869 563#
|
|
iopb 1867 461 462 560#
|
|
iordy 0004 191# 475
|
|
ios 186b 248 391 400 447 565#
|
|
iot 186a 252 386 564#
|
|
lf 000a 193# 196 196 205
|
|
list 176d 68 332#
|
|
listst 1770 78 336#
|
|
lo f80f 176# 334
|
|
mon80 f800 170# 291
|
|
nsects 002c 31# 237
|
|
offset 0002 32# 100 564
|
|
patch 1600 25# 27 28
|
|
po f80c 175# 343
|
|
prmsg 17d3 211 313 425# 435
|
|
punch 1772 69 341#
|
|
rbyte 007b 183# 542 544
|
|
rd1 1705 250 257#
|
|
rdsec 16e1 238# 262
|
|
read 17c1 76 240 410#
|
|
reader 1775 70 345#
|
|
readf 0004 188# 411 562
|
|
recal 0003 190#
|
|
retry 000a 35# 223 453
|
|
revrt 00fd 164# 269
|
|
|
|
A-17
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rewait 17f2 454# 524
|
|
ri f806 173# 347
|
|
rmon80 ff0f 171# 314
|
|
rtype 0079 182# 534 536
|
|
sectran 17b1 79 394#
|
|
seldsk 177d 72 229 354#
|
|
setdma 17bb 75 227 247 279 404#
|
|
setdrive 1792 365 367#
|
|
setfunc 17e0 412 419 437#
|
|
setsec 17ac 74 233 259 390#
|
|
settrk 17a7 73 231 255 352 385#
|
|
signon 169c 195# 210
|
|
test 0000 16# 18 21 197 200 289
|
|
true ffff 14# 15
|
|
trycount 1838 502 521#
|
|
vers 0016 6# 204 204
|
|
waito 1810 467 474# 476
|
|
waitio 17f0 413 420 452#
|
|
wboot 16c3 64 217#
|
|
wboot0 16c9 225# 308
|
|
wboote 1603 64# 284
|
|
werror 1838 487 495 504#
|
|
wready 1832 483 492 500#
|
|
write 17ca 77 417#
|
|
writf 0006 189# 418
|
|
xlt0 1682 84 112# 143 148 153
|
|
xlt1 1682 88 143#
|
|
xlt2 1682 92 148#
|
|
xlt3 1682 96 153#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A-18
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Appendix B
|
|
|
|
A Skeletal CBIOS
|
|
|
|
|
|
|
|
|
|
1 ; skeletal cbios for first level of cp/m 2.0 alteration
|
|
2 ;
|
|
3 0014 = msize equ 20 ;cp/m version memory size in kilobytes
|
|
4 ;
|
|
5 ; "bias" is address offset from 3400h for memory systems
|
|
6 ; than 16k (referred to as "b" throughout the text)
|
|
7 ;
|
|
8 0000 = bias equ (msize-20)*1024
|
|
9 3400 = ccp equ 3400h+bias ;base of ccp
|
|
10 3c06 = bdos equ ccp+806h ;base of bdos
|
|
11 4a00 = bios equ ccp+1600h ;base of bios
|
|
12 0004 = cdisk equ 0004h ;current disk number 0=a,..., 15=p
|
|
13 0003 = iobyte equ 0003h ;intel i/o byte
|
|
14 ;
|
|
15 4a00 org bios ;origin of this program
|
|
16 002c = nsects equ ($-ccp)/128 ;warm start sector count
|
|
17 ;
|
|
18 ; jump vector for individual subroutines
|
|
19 4a00 c39c4a jmp boot ;cold start
|
|
20 4a03 c3a64a wboote: jmp wboot ;warm start
|
|
21 4a06 c3114b jmp const ;console status
|
|
22 4a09 c3244b jmp conin ;console character in
|
|
23 4a0c c3374b jmp conout ;console character out
|
|
24 4a0f c3494b jmp list ;list character out
|
|
25 4a12 c34d4b jmp punch ;punch character out
|
|
26 4a15 c34f4b jmp reader ;reader character out
|
|
27 4a18 c3544b jmp home ;move head to home position
|
|
28 4a1b c35a4b jmp seldsk ;select disk
|
|
29 4a1e c37d4b jmp settrk ;set track number
|
|
30 4a21 c3924b jmp setsec ;set sector number
|
|
31 4a24 c3ad4b jmp setdma ;set dma address
|
|
32 4a27 c3c34b jmp read ;read disk
|
|
33 4a2a c3d64b jmp write ;write disk
|
|
|
|
B-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 4a2d c34b4b jmp listst ;return list status
|
|
35 4a30 c3a74b jmp sectran ;sector translate
|
|
36 ;
|
|
37 ; fixed data tables for four-drive standard
|
|
38 ; ibm-compatible 8" disks
|
|
39 ; disk parameter header for disk 00
|
|
40 4a33 734a0000 dpbase: dw trans, 0000h
|
|
41 4a37 00000000 dw 0000h, 0000h
|
|
42 4a3b f04c8d4a dw dirbf, dpblk
|
|
43 4a3f ec4d704d dw chk00, all00
|
|
44 ; disk parameter header for disk 01
|
|
45 4a43 734a0000 dw trans, 0000h
|
|
46 4a47 00000000 dw 0000h, 0000h
|
|
47 4a4b f04c8d4a dw dirbf, dpblk
|
|
48 4a4f fc4d8f4d dw chk01, all01
|
|
49 ; disk parameter header for disk 02
|
|
50 4a53 734a0000 dw trans, 0000h
|
|
51 4a57 00000000 dw 0000h, 0000h
|
|
52 4a5b f04c8d4a dw dirbf, dpblk
|
|
53 4a5f 0c4eae4d dw chk02, all02
|
|
54 ; disk parameter header for disk 03
|
|
55 4a63 734a0000 dw trans, 0000h
|
|
56 4a67 00000000 dw 0000h, 0000h
|
|
57 4a6b f04c8d4a dw dirbf, dpblk
|
|
58 4a6f 1c4ecd4d dw chk03, all03
|
|
59 ;
|
|
60 ; sector translate vector
|
|
61 4a73 01070d13 trans: db 1, 7, 13, 19 ;sectors 1, 2, 3, 4
|
|
62 4a77 19050b11 db 25, 5, 11, 17 ;sectors 5, 6, 7, 8
|
|
63 4a7b 1703090f db 23, 3, 9, 15 ;sectors 9, 10, 11, 12
|
|
64 4a7f 1502080e db 21, 2, 8, 14 ;sectors 13, 14, 15, 16
|
|
65 4a83 141a060c db 20, 26, 6, 12 ;sectors 17, 18, 19, 20
|
|
66 4a87 1218040a db 18, 24, 4, 10 ;sectors 21, 22, 23, 24
|
|
67 4a8b 1016 db 16, 22 ;sectors 25, 26
|
|
68 ;
|
|
69 dpblk: ;disk parameter block, common to all disks
|
|
70 4a8d 1a00 dw 26 ;sectors per track
|
|
71 4a8f 03 db 3 ;block shift factor
|
|
72 4a90 07 db 7 ;block mask
|
|
73 4a91 00 db 0 ;null mask
|
|
|
|
B-2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 4a92 f200 dw 242 ;disk size-1
|
|
75 4a94 3f00 dw 63 ;directory max
|
|
76 4a96 c0 db 192 ;alloc 0
|
|
77 4a97 00 db 0 ;alloc 1
|
|
78 4a98 1000 dw 16 ;check size
|
|
79 4a9a 0200 dw 2 ;track offset
|
|
80 ;
|
|
81 ; end of fixed tables
|
|
82 ;
|
|
83 ; individual subroutines to perform each function
|
|
84 boot: ;simplest case is to just perform parameter initialization
|
|
85 4a9c af xra a ;zero in the accum
|
|
86 4a9d 320300 sta iobyte ;clear the iobyte
|
|
87 4aa0 320400 sta cdisk ;select disk zero
|
|
88 4aa3 c3ef4a jmp gocpm ;initialize and go to cp/m
|
|
89 ;
|
|
90 wboot: ;simplest case is to read the disk until all sectors loaded
|
|
91 4aa6 318000 lxi sp, 80h ;use space below buffer for stack
|
|
92 4aa9 0e00 mvi c, 0 ;select disk 0
|
|
93 4aab cd5a4b call seldsk
|
|
94 4aae cd544b call home ;go to track 00
|
|
95 ;
|
|
96 4ab1 062c mvi b, nsects ;b counts # of sectors to load
|
|
97 4ab3 0e00 mvi c, 0 ;c has the current track number
|
|
98 4ab5 1602 mvi d, 2 ;d has the next sector to read
|
|
99 ; note that we begin by reading track 0, sector 2 since sector 1
|
|
100 ; contains the cold start loader, which is skipped in a warm start
|
|
101 4ab7 210034 lxi h, ccp ;base of cp/m (initial load point)
|
|
102 load1: ;load one more sector
|
|
103 4aba c5 push b ;save sector count, current track
|
|
104 4abb d5 push d ;save next sector to read
|
|
105 4abc e5 push h ;save dma address
|
|
106 4abd 4a mov c, d ;get sector address to register c
|
|
107 4abe cd924b call setsec ;set sector address from register c
|
|
108 4ac1 c1 pop b ;recall dma address to b, c
|
|
109 4ac2 c5 push b ;replace on stack for later recall
|
|
110 4ac3 cdad4b call setdma ;set dma address from b, c
|
|
111 ;
|
|
112 ; drive set to 0, track set, sector set, dma address set
|
|
113 4ac6 cdc34b call read
|
|
|
|
B-3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 4ac9 fe00 cpi 00h ;any errors?
|
|
115 4acb c2a64a jnz wboot ;retry the entire boot if an error occurs
|
|
116 ;
|
|
117 ; no error, move to next sector
|
|
118 4ace e1 pop h ;recall dma address
|
|
119 4acf 118000 lxi d, 128 ;dma=dma+128
|
|
120 4ad2 19 dad d ;new dma address is in h, l
|
|
121 4ad3 d1 pop d ;recall sector address
|
|
122 4ad4 c1 pop b ;recall number of sectors remaining, and current trk
|
|
123 4ad5 05 dcr b ;sectors=sectors-1
|
|
124 4ad6 caef4a jz gocpm ;transfer to cp/m if all have been loaded
|
|
125 ;
|
|
126 ; more sectors remain to load, check for track change
|
|
127 4ad9 14 inr d
|
|
128 4ada 7a mov a,d ;sector=27?, if so, change tracks
|
|
129 4adb fe1b cpi 27
|
|
130 4add daba4a jc load1 ;carry generated if sector<27
|
|
131 ;
|
|
132 ; end of current track, go to next track
|
|
133 4ae0 1601 mvi d, 1 ;begin with first sector of next track
|
|
134 4ae2 0c inr c ;track=track+1
|
|
135 ;
|
|
136 ; save register state, and change tracks
|
|
137 4ae3 c5 push b
|
|
138 4ae4 d5 push d
|
|
139 4ae5 e5 push h
|
|
140 4ae6 cd7d4b call settrk ;track address set from register c
|
|
141 4ae9 e1 pop h
|
|
142 4aea d1 pop d
|
|
143 4aeb c1 pop b
|
|
144 4aec c3ba4a jmp load1 ;for another sector
|
|
145 ;
|
|
146 ; end of load operation, set parameters and go to cp/m
|
|
147 gocpm:
|
|
148 4aef 3ec3 mvi a, 0c3h ;c3 is a jmp instruction
|
|
149 4af1 320000 sta 0 ;for jmp to wboot
|
|
150 4af4 21034a lxi h, wboote ;wboot entry point
|
|
151 4af7 220100 shld 1 ;set address field for jmp at 0
|
|
152 ;
|
|
153 4afa 320500 sta 5 ;for jmp to bdos
|
|
|
|
B-4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 4afd 21063c lxi h, bdos ;bdos entry point
|
|
155 4b00 220600 shld 6 ;address field of jump at 5 to bdos
|
|
156 ;
|
|
157 4b03 018000 lxi b, 80h ;default dma address is 80h
|
|
158 4b06 cdad4b call setdma
|
|
159 ;
|
|
160 4b09 fb ei ;enable the interrupt system
|
|
161 4b0a 3a0400 lda cdisk ;get current disk number
|
|
162 4b0d 4f mov c, a ;send to the ccp
|
|
163 4b0e c30034 jmp ccp ;go to cp/m for further processing
|
|
164 ;
|
|
165 ;
|
|
166 ; simple i/o handlers (must be filled in by user)
|
|
167 ; in each case, the entry point is provided, with space reserved
|
|
168 ; to insert your own code
|
|
169 ;
|
|
170 const: ;console status, return 0ffh if character ready, 00h if not
|
|
171 4b11 ds 10h ;space for status subroutine
|
|
172 4b21 3e00 mvi a, 00h
|
|
173 4b23 c9 ret
|
|
174 ;
|
|
175 conin: ;console character into register a
|
|
176 4b24 ds 10h ;space for input routine
|
|
177 4b34 e67f ani 7fh ;strip parity bit
|
|
178 4b36 c9 ret
|
|
179 ;
|
|
180 conout: ;console character output from register c
|
|
181 4b37 79 mov a, c ;get to accumulator
|
|
182 4b38 ds 10h ;space for output routine
|
|
183 4b48 c9 ret
|
|
184 ;
|
|
185 list: ;list character from register c
|
|
186 4b49 79 mov a, c ;character to register a
|
|
187 4b4a c9 ret ;null subroutine
|
|
188 ;
|
|
189 listst: ;return list status (0 if not ready, 1 if ready)
|
|
190 4b4b af xra a ;0 is always ok to return
|
|
191 4b4c c9 ret
|
|
192 ;
|
|
193 punch: ;punch character from register c
|
|
|
|
B-5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 4b4d 79 mov a, c ;character to register a
|
|
195 4b4e c9 ret ;null subroutine
|
|
196 ;
|
|
197 ;
|
|
198 reader: ;reader character into register a from reader device
|
|
199 4b4f 3e1a mvi a, 1ah ;enter end of file for now (replace later)
|
|
200 4b51 e67f ani 7fh ;remember to strip parity bit
|
|
201 4b53 c9 ret
|
|
202 ;
|
|
203 ;
|
|
204 ; i/o drivers for the disk follow
|
|
205 ; for now, we will simply store the parameters away for use
|
|
206 ; in the read and write subroutines
|
|
207 ;
|
|
208 home: ;move to the track 00 position of current drive
|
|
209 ; translate this call into a settrk call with parameter 00
|
|
210 4b54 0e00 mvi c, 0 ;select track 0
|
|
211 4b56 cd7d4b call settrk
|
|
212 4b59 c9 ret ;we will move to 00 on first read/write
|
|
213 ;
|
|
214 seldsk: ;select disk given by register c
|
|
215 4b51 210000 lxi h, 0000h ;error return code
|
|
216 4b5d 79 mov a, c
|
|
217 4b5e 32ef4c sta diskno
|
|
218 4b61 fe04 cpi 4 ;must be between 0 and 3
|
|
219 4b63 d0 rnc ;no carry if 4, 5,...
|
|
220 ; disk number is in the proper range
|
|
221 4b64 ds 10 ;space for disk select
|
|
222 ; compute proper disk parameter header address
|
|
223 4b6e 3aef4c lda diskno
|
|
224 4b71 6f mov l, a ;l=disk number 0, 1, 2, 3
|
|
225 4b72 2600 mvi h, 0 ;high order zero
|
|
226 4b74 29 dad h ;*2
|
|
227 4b75 29 dad h ;*4
|
|
228 4b76 29 dad h ;*8
|
|
229 4b77 29 dad h ;*16 (size of each header)
|
|
230 4b78 11334a lxi d, dpbase
|
|
231 4b7b 19 dad 0 ;hl=.dpbase (diskno*16)
|
|
232 4b7c c9 ret
|
|
233 ;
|
|
|
|
B-6
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 settrk: ;set track given by register c
|
|
235 4b7d 79 mov a, c
|
|
236 4b7e 32e94c sta track
|
|
237 4b81 ds 10h ;space for track select
|
|
238 4b91 c9 ret
|
|
239 ;
|
|
240 setsec: ;set sector given by register c
|
|
241 4b92 79 mov a, c
|
|
242 4b93 32eb4c sta sector
|
|
243 4b96 ds 10h ;space for sector select
|
|
244 4ba6 c9 ret
|
|
245 ;
|
|
246 sectran:
|
|
247 ;translate the sector given by bc using the
|
|
248 ;translate table given by de
|
|
249 4ba7 eb xchg ;hl=.trans
|
|
250 4ba8 09 dad b ;hl=.trans (sector)
|
|
251 4ba9 6e mov l, m ;l=trans (sector)
|
|
252 4baa 2600 mvi h, 0 ;hl=trans (sector)
|
|
253 4bac c9 ret ;with value in hl
|
|
254 ;
|
|
255 setdma: ;set dma address given by registers b and c
|
|
256 4bad 69 mov l, c ;low order address
|
|
257 4bae 60 mov h, b ;high order address
|
|
258 4baf 22ed4c shld dmaad ;save the address
|
|
259 4bb2 ds 10h ;space for setting the dma address
|
|
260 4bc2 c9 ret
|
|
261 ;
|
|
262 read: ;perform read operation (usually this is similar to write
|
|
263 ; so we will allow space to set up read command, then use
|
|
264 ; common code in write)
|
|
265 4bc3 ds 10h ;set up read command
|
|
266 4bd3 c3e64b jmp waitio ;to perform the actual i/o
|
|
267 ;
|
|
268 write: ;perform a write operation
|
|
269 4bd6 ds 10h ;set up write command
|
|
270 ;
|
|
271 waitio: ;enter here from read and write to perform the actual i/o
|
|
272 ; operation. return a 00h in register a if the operation completes
|
|
273 ; properly, and 01h if an error occurs during the read or write
|
|
|
|
B-7
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 ;
|
|
275 ; in this case, we have saved the disk number in 'diskno' (0, 1)
|
|
276 ; the track number in 'track' (0-76)
|
|
277 ; the sector number in 'sector' (1-26)
|
|
278 ; the dma address in 'dmaad' (0-65535)
|
|
279 4be6 ds 256 ;space reserved for i/o drivers
|
|
280 4ce6 3e01 mvi a, 1 ;error condition
|
|
281 4ce8 c9 ret ;replaced when filled-in
|
|
282 ;
|
|
283 ; the remainder of the cbios is reserved uninitialized
|
|
284 ; data area, and does not need to be a part of the
|
|
285 ; system memory image (the space must be available,
|
|
286 ; however, between "begdat" and "enddat").
|
|
287 ;
|
|
288 4ce9 track: ds 2 ;two bytes for expansion
|
|
289 4ceb sector: ds 2 ;two bytes for expansion
|
|
290 4ced dmaad: ds 2 ;direct memory address
|
|
291 4cef diskno: ds 1 ;disk number 0-15
|
|
292 ;
|
|
293 ; scratch ram area for bdos use
|
|
294 4cf0= begdat equ $ ;beginning of data area
|
|
295 4cf0 dirfb: ds 128 ;scratch directory area
|
|
296 4d70 all00: ds 31 ;allocation vector 0
|
|
297 4d8f all01: ds 31 ;allocation vector 1
|
|
298 4dae all02: ds 31 ;allocation vector 2
|
|
299 4dcd all03: ds 31 ;allocation vector 3
|
|
300 4dec chk00: ds 16 ;check vector 0
|
|
301 4dfc chk01: ds 16 ;check vector 1
|
|
302 4e0c chk02: ds 16 ;check vector 2
|
|
303 4e1c chk03: ds 16 ;check vector 3
|
|
304 ;
|
|
305 4e2c enddat equ $ ;end of data area
|
|
306 013c= datsiz equ $-begdat; ;size of data area
|
|
307 4e2c end
|
|
|
|
all00 4d70 43 296#
|
|
all01 4d8f 48 297#
|
|
all02 4dae 53 298#
|
|
all03 4dcd 58 299#
|
|
bdos 3c06 10# 154
|
|
|
|
B-8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
begdat 4cf0 294# 306
|
|
bias 0000 8# 9
|
|
bios 4a00 11# 15
|
|
boot 4a9c 19 84#
|
|
ccp 3400 9# 10 11 16 101 163
|
|
cdisk 0004 12# 87 161
|
|
chk00 4dec 43 300#
|
|
chk01 4dfc 48 301#
|
|
chk02 4e0c 53 302#
|
|
chk03 4e1c 58 303#
|
|
conin 4b24 22 175#
|
|
conout 4b37 23 180#
|
|
const 4b11 21 170#
|
|
datsiz 013c 306#
|
|
dirbf 4cf0 42 47 52 57 295#
|
|
diskno 4cef 217 223 291#
|
|
dmaad 4ced 258 290#
|
|
dpbase 4a33 40# 230
|
|
dpblk 4a8d 42 47 52 57 69#
|
|
enddat 4e2c 305#
|
|
gocpm 4aef 88 124 147#
|
|
home 4b54 27 94 208#
|
|
iobyte 0003 13# 86
|
|
list 4b49 24 185#
|
|
listst 4b4b 34 189#
|
|
load1 4aba 102# 130 144
|
|
msize 0014 3# 8
|
|
nsects 002c 16# 96
|
|
punch 4b4d 25 193#
|
|
read 4bc3 32 113 262#
|
|
reader 4b4f 26 198#
|
|
sector 4ceb 242 289#
|
|
sectran 4ba7 35 246#
|
|
seldsk 4b5a 28 93 214#
|
|
setdma 4bad 31 110 158 255#
|
|
setsec 4b92 30 107 240#
|
|
settrk 4b7d 29 140 211 234#
|
|
track 4ce9 236 288#
|
|
trans 4a73 40 45 50 55 61#
|
|
waitio 4be6 266 271#
|
|
|
|
B-9
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wboot 4aa6 20 90# 115
|
|
wboote 4a03 20# 150
|
|
write 4bd6 33 268#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
B-10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Appendix C
|
|
|
|
A Skeletal GETSYS/PUTSYS Program
|
|
|
|
|
|
|
|
; combined getsys and putsys programs from
|
|
; Sec 6.4
|
|
; Start the programs at the base of the TPA
|
|
|
|
0100 org 0100h
|
|
|
|
0014 = msize equ 20 ;size of cp/m in Kbytes
|
|
|
|
;"bias" is the amount to add to addresses for > 20k
|
|
; (referred to as "b" throughout the text)
|
|
|
|
0000 = bias equ (msize-20)*1024
|
|
3400 = ccp equ 3400h+bias
|
|
3c00 = bdos equ ccp+0800h
|
|
4a00 = bios equ ccp+1600h
|
|
|
|
; getsys programs tracks 0 and 1 to memory at
|
|
; 3880h + bias
|
|
|
|
; register usage
|
|
; a (scratch register)
|
|
; b track count (0...76)
|
|
; c sector count (1...26)
|
|
; d,e (scratch register pair)
|
|
; h,l load address
|
|
; sp set to track address
|
|
|
|
gstart: ;start of getsys
|
|
0100 318033 lxi sp,ccp-0080h ;convenient place
|
|
0103 218033 lxi h,ccp-0080h ;set initial load
|
|
0106 0600 mvi b 0 ;start with track
|
|
rd$trk: ;read next track
|
|
0108 0e01 mvi c,1 ;each track start
|
|
rd$sec:
|
|
|
|
C-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
010a cd0003 call read$sec ;get the next sector
|
|
010d 118000 lxi d,128 ;offset by one sector
|
|
0110 19 dad d ; (hl=hl+128)
|
|
0111 0c inr c ;next sector
|
|
0112 79 mov a,c ;fetch sector number
|
|
0113 felb cpi 27 ;and see if last
|
|
0115 da0a01 jc rdsec ;<, do one more
|
|
|
|
;arrive here at end of track, move to next track
|
|
|
|
0118 04 inr b ;track = track+1
|
|
0119 78 mov a,b ;check for last
|
|
011a fe02 cpi 2 ;track = 2 ?
|
|
011c da0801 jc rd$trk ;<, do another
|
|
|
|
;arrive here at end of load, halt for lack of anything
|
|
;better
|
|
|
|
011f fb ei
|
|
0120 76 hlt
|
|
; putsys program, places memory image
|
|
; starting at
|
|
; 3880h + bias back to tracks 0 and 1
|
|
; start this program at the next page boundary
|
|
0200 org ($+0100h) and 0ff00h
|
|
|
|
put$sys:
|
|
0200 318033 lxi sp,ccp-0080h ;convenient place
|
|
0203 218033 lxi h,ccp-0080h ;start of dump
|
|
0206 0600 mvi b,0 ;start with track
|
|
wr$trk:
|
|
0208 0e01 mvi b,1 ;start with sector
|
|
wr$sec:
|
|
020a cd0004 call write$sec ;write one sector
|
|
020d 118000 lxi d,128 ;length of each
|
|
0210 19 dad d ;<hl>=<hl> + 128
|
|
0211 0c inr c ; <c>=<c> + 1
|
|
0212 79 mov a,c ;see if
|
|
0213 felb cpi 27 ;past end of track
|
|
0215 da0a02 jc wr$sec ;no, do another
|
|
|
|
C-2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;arrive here at end of track, move to next track
|
|
|
|
0218 04 inr b ;track = track+1
|
|
0219 78 mov a,b ;see if
|
|
021a fe02 cpi 2 ;last track
|
|
021c da0802 jc wr$trk ;no, do another
|
|
|
|
; done with putsys, halt for lack of anything
|
|
; better
|
|
|
|
02lf fb ei
|
|
0220 76 hit
|
|
|
|
;user supplied subroutines for sector read and write
|
|
|
|
; move to next page boundary
|
|
|
|
0300 org ($+0100h) and 0ff00h
|
|
|
|
read$sec:
|
|
;read the next sector
|
|
;track in <b>,
|
|
;sector in <c>
|
|
;dmaaddr in <hl>
|
|
|
|
0300 c5 push b
|
|
0301 e5 push h
|
|
|
|
;user defined read operation goes here
|
|
0302 ds 64
|
|
|
|
0342 el pop h
|
|
0343 cl pop b
|
|
0344 c9 ret
|
|
|
|
0400 org ($+0100h) and 0ff00h ;another page
|
|
;boundary
|
|
|
|
write$sec:
|
|
|
|
C-3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;same parameters as read$sec
|
|
|
|
0400 c5 push b
|
|
0401 e5 push h
|
|
|
|
;user defined write operation goes here
|
|
0402 ds 64
|
|
|
|
0442 el pop h
|
|
0443 cl pop b
|
|
0444 c9 ret
|
|
|
|
;end of getsys/putsys program
|
|
|
|
0445 end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C-4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Appendix D
|
|
|
|
The Microcomputer Development System-800 Cold Start Loader for CP/M 2
|
|
|
|
|
|
|
|
1 title mds cold start loader at 3000h'
|
|
2 ;
|
|
3 ; mds-800 cold start loader for cp/m 2.0
|
|
4 ;
|
|
5 ; version 2.0 august, 1979
|
|
6 ;
|
|
7 0000 = false equ 0
|
|
8 ffff true equ not false
|
|
9 0000 = testing equ false if true, then go to mon80 on errors
|
|
10 ;
|
|
11 if testing
|
|
12 bias equ 03400h
|
|
13 endif
|
|
14 if not testing
|
|
15 0000 = bias equ 0000h
|
|
16 endif
|
|
17 0000 = cpmb equ bias ;base of dos load
|
|
18 0806 = bdos equ 806h+bias ;entry to dos for calls
|
|
19 1880 = bdose equ 1880h+bias ;end of dos load
|
|
20 1600 = boot equ 1600h+bias ;cold start entry point
|
|
21 1603 = rboot equ boot+3 ;warm start entry point
|
|
22 ;
|
|
23 3000 org 03000h ;loaded down from hardware boot at 3000H
|
|
24 ;
|
|
25 1880 = bdosl equ bdose-cpmb
|
|
26 0002 = ntrks equ 2 ;number of tracks to read
|
|
27 0031 = bdoss equ bdosl/128 ;number of sectors in dos
|
|
28 0019 = bdoso equ 25 ;number of bdos sectors on track 0
|
|
29 0018 = bdos1 equ bdoss-bdoso ;number of sectors on track 1
|
|
30 ;
|
|
31 f800 = mon80 equ 0f800h ;intel monitor base
|
|
32 ff0f = rmon80 equ 0ff0fh ;restart location for mon80
|
|
33 0078 = base equ 078h ;'base' used by controller
|
|
34 0079 = rtype equ base+1 ;result type
|
|
|
|
D-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 007b = rbyte equ base+3 ;result byte
|
|
36 007f = reset equ base+7 ;reset controller
|
|
37 ;
|
|
38 0078 = dstat equ base ;disk status port
|
|
39 0079 = ilow equ base+1 ;low iopb address
|
|
40 007a = ihigh equ base+2 ;high iopb address
|
|
41 00ff = bsw equ 0ffh ;boot switch
|
|
42 0003 = recal equ 3h ;recalibrate selected drive
|
|
43 0004 = readf equ 4h ;disk read function
|
|
44 0100 = stack equ 100h ;use end of boot for stack
|
|
45 ;
|
|
46 rstart:
|
|
47 3000 310001 lxi sp,stack; ;in case of call to mon80
|
|
48 ; clear disk status
|
|
49 3003 db79 in rtype
|
|
50 3005 db7b in rbyte
|
|
51 ; check if boot switch if off
|
|
52 coldstart:
|
|
53 3007 dbff in bsw
|
|
54 3009 e602 ani 02h ;switch on?
|
|
55 300b c20730 jnz coldstart
|
|
56 ; clear the controller
|
|
57 300e d37f out reset ;logic cleared
|
|
58 ;
|
|
59 ;
|
|
60 3010 0602 mvi b,ntrks ;number of tracks to read
|
|
61 3012 214230 lxi h,iopbo
|
|
62 ;
|
|
63 start:
|
|
64 ;
|
|
65 ; read first/next track into cpmb
|
|
66 3015 7d mov a,l
|
|
67 3016 d379 out ilow
|
|
68 3018 7c mov a,h
|
|
69 3019 d37a out ihigh
|
|
70 301b db78 waito: in dstat
|
|
71 301d e604 ani 4
|
|
72 301f ca1b30 jz waito
|
|
73 ;
|
|
74 ; check disk status
|
|
|
|
D-2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 3022 db79 in rtype
|
|
76 3024 e603 ani 11b
|
|
77 3026 fe02 cpi 2
|
|
78 ;
|
|
79 if testing
|
|
80 cnc rmon80 ;go to monitor if 11 or 10
|
|
81 endif
|
|
82 if not testing
|
|
83 3028 d20030 jnc rstart ;retry the load
|
|
84 endif
|
|
85 ;
|
|
86 302b db7b in rbyte ;i/o complete, check status
|
|
87 ; if not ready, then go to mon80
|
|
88 302d 17 ral
|
|
89 302e dc0fff cc rmon80 ;not ready bit set
|
|
90 3031 1f rar ;restore
|
|
91 3032 e61e ani 11110b ;overrun/addr err/seek/crc/xxxx
|
|
92 ;
|
|
93 if testing
|
|
94 cnz rmon80 ;go to monitor
|
|
95 endif
|
|
96 if not testing
|
|
97 3034 c20030 jnz rstart ;retry the load
|
|
98 endif
|
|
99 ;
|
|
100 ;
|
|
101 3037 110700 lxi d,iopbl ;length of iopb
|
|
102 303a 19 dad d ;addressing next iopb
|
|
103 303b 05 dcr b ;count down tracks
|
|
104 303c c21530 jnz start
|
|
105 ;
|
|
106 ;
|
|
107 ; jmp to boot to print initial message, and set up jmps
|
|
108 303f c30016 jmp boot
|
|
109 ;
|
|
110 ; parameter blocks
|
|
111 3042 80 iopbo: db 80h ;iocw, no update
|
|
112 3043 04 db readf ;read function
|
|
113 3044 19 db bdoso ;#sectors to read on track 0
|
|
114 3045 00 db 0 ;track 0
|
|
|
|
D-3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 3046 02 db 2 ;start with sector 2 on track 0
|
|
116 3047 0000 dw cpmb ;start at base of bdos
|
|
117 0007 = iopbl equ $-iopbo
|
|
118 ;
|
|
119 3049 80 iopb1: db 80h
|
|
120 304a 04 db readf
|
|
121 304b 18 db bdos1 ;sectors to read on track 1
|
|
122 304c 01 db 1 ;track 1
|
|
123 304d 01 db 1 ;sector 1
|
|
124 304e 800c dw cmpb+bdos0*128;base of second read
|
|
125 ;
|
|
126 3050 end
|
|
|
|
|
|
base 0078 33# 34 35 36 38 39 40
|
|
bdos 0806 18#
|
|
bdoso 0019 28# 29 113 124
|
|
bdos1 0018 29# 121
|
|
bdose 1880 19# 25
|
|
bdosl 1880 25# 27
|
|
bdoss 0031 27# 29
|
|
bias 0000 12# 15# 17 18 19 20
|
|
boot 1600 20# 21 108
|
|
bsw 00ff 41# 53
|
|
coldstart 3007 52# 55
|
|
cpmb 0000 17# 25 116 124
|
|
dstat 0078 38# 70
|
|
false 0000 7# 8 9
|
|
ihigh 007a 40# 69
|
|
ilow 0079 39# 67
|
|
iopbo 3042 61 111# 117
|
|
iopb1 3049 119#
|
|
iopbl 0007 101 117#
|
|
mon80 f800 31#
|
|
ntrks 0002 26# 60
|
|
rboot 1603 21#
|
|
rbyte 007b 35# 50 86
|
|
readf 0004 43# 112 120
|
|
recal 0003 42#
|
|
reset 007f 36# 57
|
|
|
|
D-4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rmon80 ff0f 32# 80 89 94
|
|
rstart 3000 46# 83 97
|
|
rtype 0079 34# 49 75
|
|
stack 0100 44# 47
|
|
start 3015 63# 104
|
|
testing 0000 9# 11 14 79 82 93 96
|
|
true ffff 8#
|
|
waito 301b 70# 72
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
D-5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Appendix E
|
|
|
|
A Skeletal Cold Start Loader
|
|
|
|
|
|
|
|
;this is a sample cold start loader, which, when
|
|
;modified
|
|
;resides on track 00, sector 01 (the first sector on the
|
|
;diskette). we assume that the controller has loaded
|
|
;this sector into memory upon system start-up (this
|
|
;program can be keyed-in, or can exist in read-only
|
|
;memory
|
|
;beyond the address space of the cp/m version you are
|
|
;running). the cold start loader brings the cp/m system
|
|
;into memory at "loadp" (3400h + "bias"). in a 20k
|
|
;memory system, the value of "bias" is 000h, with
|
|
;large
|
|
;values for increased memory sizes (see section 2).
|
|
;after
|
|
;loading the cp/m system, the cold start loader
|
|
;branches
|
|
;to the "boot" entry point of the bios, which beings at
|
|
;"bios" + "bias". the cold start loader is not used un-
|
|
;til the system is powered up again, as long as the bios
|
|
;is not overwritten. the origin is assumed at 0000h, and
|
|
;must be changed if the controller brings the cold start
|
|
;loader into another area, or if a read-only memory
|
|
;area
|
|
;is used.
|
|
|
|
0000 org 0 ;base of ram in
|
|
;cp/m
|
|
|
|
0014 = msize equ 20 ;min mem size in
|
|
;kbytes
|
|
0000 = bias equ (msize-20)*1024 ;offset from 20k
|
|
;system
|
|
3400 = ccp equ 3400h+bias ;base of the ccp
|
|
4a00 = bios equ ccp+1600h ;base of the bios
|
|
|
|
E-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0300 = biosl equ 0300h ;length of the bios
|
|
4a00 = boot equ bios
|
|
1900 = size equ bios+biosl-ccp ;size of cp/m
|
|
;system
|
|
0032 = sects equ size/128 ;# of sectors to load
|
|
|
|
; begin the load operation
|
|
|
|
cold:
|
|
0000 010200 lxi b,2 ;b=0, c=sector 2
|
|
0003 1632 mvi d,sects ;d=# sectors to
|
|
;load
|
|
0005 210034 lxi h,ccp ;base transfer
|
|
;address
|
|
lsect: ;load the next sector
|
|
|
|
; insert inline code at this point to
|
|
; read one 128 byte sector from the
|
|
; track given in register b, sector
|
|
; given in register c,
|
|
; into the address given by <hl>
|
|
;branch to location "cold" if a read error occurs
|
|
;
|
|
;
|
|
; user supplied read operation goes
|
|
; here...
|
|
;
|
|
;
|
|
|
|
0008 c36b00 jmp past$patch ;remove this
|
|
;when patched
|
|
000b ds 60h
|
|
|
|
past$patch:
|
|
;go to next sector if load is incomplete
|
|
006b 15 dcr d ;sects=sects-1
|
|
006c ca004a jz boot ;head for the bios
|
|
|
|
; more sectors to load
|
|
;
|
|
|
|
E-2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;we aren't using a stack, so use <sp> as scratch
|
|
;register
|
|
; to hold the load address increment
|
|
|
|
006f 318000 lxi sp,128 ;128 bytes per
|
|
;sector
|
|
0072 39 dad sp ;<hl> = <hl> +
|
|
128
|
|
0073 0c inr c ;sector=sector + 1
|
|
0074 79 mov a,c
|
|
0075 felb cpi 27 ;last sector of
|
|
;track?
|
|
0077 da0800 jc lsect ;no, go read
|
|
;another
|
|
|
|
;end of track, increment to next track
|
|
|
|
007a 0e01 mvi c,l ;sector = 1
|
|
007c 04 inr b ;track = track + 1
|
|
007d c30800 jmp lsect ;for another group
|
|
0080 end ;of boot loader
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
E-3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Appendix F
|
|
|
|
CP/M Disk Definition Library
|
|
|
|
|
|
1:; CP/M 2.0 disk re-definition library
|
|
2:;
|
|
3:; Copyright (c) 1979
|
|
4:; Digital Research
|
|
5:; Box 579
|
|
6:; Pacific Grove, CA
|
|
7:; 93950
|
|
8:;
|
|
9:; CP/M logical disk drives are defined using the
|
|
10:; macros given below, where the sequence of calls
|
|
11:; is:
|
|
12:;
|
|
13:; disks n
|
|
14:; diskdef parameter-list-0
|
|
15:; diskdef parameter-list-1
|
|
16:; ...
|
|
17:; diskdef parameter-list-n
|
|
18:; endef
|
|
19:;
|
|
20:; where n is the number of logical disk drives attached
|
|
21:; to the CP/M system, and parameter-list-i defines the
|
|
22:; characteristics of the ith drive (i=0,1,...,n-1)
|
|
23:;
|
|
24:; each parameter-list-i takes the form
|
|
25:; dn,fsc,lsc,[skf],bls,dks,dir,cks,ofs,[0]
|
|
26:; where
|
|
27:; dn is the disk number 0,1,...,n-1
|
|
28:; fsc is the first sector number (usually 0 or 1)
|
|
29:; lsc is the last sector number on a track
|
|
30:; skf is optional "skew factor" for sector translate
|
|
31:; bls is the data block size (1024,2048,...,16384)
|
|
32:; dks is the disk size in bls increments (word)
|
|
33:; dir is the number of directory elements (word)
|
|
34:; cks is the number of dir elements to checksum
|
|
35:; ofs is the number of tracks to skip (word)
|
|
|
|
F-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36:; [0] is an optional 0 which forces 16K/directory end
|
|
37:;
|
|
38:; for convenience, the form
|
|
39:; dn,dm
|
|
40:; defines disk dn as having the same characteristics as
|
|
41:; a previously defined disk dm.
|
|
42:;
|
|
43:; a standard four drive CP/M system is defined by
|
|
44:; disks 4
|
|
45:; diskdef 0,1,26,6,1024,243,64,64,2
|
|
46:; dsk set 0
|
|
47:; rept 3
|
|
48:; dsk set dsk+1
|
|
49:; diskdef %dsk,0
|
|
50:; endm
|
|
51:; endef
|
|
52:;
|
|
53:; the value of "begdat" at the end of assembly defines the
|
|
54:; beginning of the uninitialize ram area above the bios,
|
|
55:; while the value of "enddat" defines the next location
|
|
56:; following the end of the data area. the size of this
|
|
57:; area is given by the value of "datsiz" at the end of the
|
|
58:; assembly. note that the allocation vector will be quite
|
|
59:; large if a large disk size is defined with a small block
|
|
60:; size.
|
|
61:;
|
|
62:dskhdr macro dn
|
|
63:;; define a single disk header list
|
|
64:dpe&dn: dw xlt&dn,0000h ;translate table
|
|
65: dw 0000h,0000h ;scratch area
|
|
66: dw dirbuf,dpb&dn ;dir buff,parm block
|
|
67: dw csv&dn,alv&dn ;check, alloc vectors
|
|
68: endm
|
|
69:;
|
|
70:disks macro nd
|
|
71:;; define nd disks
|
|
72:ndisks set nd ;;for later reference
|
|
73:dpbase equ $ ;base of disk parameter blocks
|
|
74:;; generate the nd elements
|
|
75:disknxt set 0
|
|
|
|
F-2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76: rept nd
|
|
77: dskhdr %dsknxt
|
|
78:dsknxt set dsknxc+1
|
|
79: endm
|
|
80: endm
|
|
81:;
|
|
82:dpbhdr macro dn
|
|
83:dpb&dn equ $ ;disk parm block
|
|
84: endm
|
|
85:;
|
|
86:ddb macro data,comment
|
|
87:;; define a db statement
|
|
88: db data comment
|
|
89: endm
|
|
90:;
|
|
91:ddw macro data,comment
|
|
92:;; define a dw statement
|
|
93: dw data comment
|
|
94: endm
|
|
95:;
|
|
96:gcd macro m,n
|
|
97:;; greatest common divisor of m,n
|
|
98:;; produces value gcdn as result
|
|
99:;; (used in sector translate table generation)
|
|
100:gcdm set m ;;variable for m
|
|
101:gcdn set n ;;variable for n
|
|
102:gcdr set 0 ;;variable for r
|
|
103: rept 65535
|
|
104:gcdx set gcdm/gcdn
|
|
105:gcdr set gcdm-gcdx*gcdn
|
|
106: if gcdr = 0
|
|
107: exitm
|
|
108: endif
|
|
109:gcdm set gcdn
|
|
110:gcdn set gcdr
|
|
111: endm
|
|
112: endm
|
|
113:;
|
|
114:diskdef macro dn,fsc,lsc,skf,bls,dks,dir,cks,ofs,k16
|
|
115:;; generate the set statements for later tables
|
|
|
|
F-3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116: if nul lsc
|
|
117:;; current disk dn same as previous fsc
|
|
118:dpb&dn equ dpb&fsc ;equivalent parameters
|
|
119:als&dn equ als&fsc ;same allocation vector size
|
|
120:css&dn equ css&fsc ;same checksum vector size
|
|
121:xlt&dn equ xlt&fsc ;same translate table
|
|
122: else
|
|
123:secmax set lsc-(fsc) ;;sectors 0...secmax
|
|
124:sectors set secmax+1 ;;number of sectors
|
|
125:als&dn set (dks)/8 ;;size of allocation vector
|
|
126: if ((dks)mod8) ne 0
|
|
127:als&dn set als&dn+1
|
|
128: endif
|
|
129:css&dn set (cks)/4 ;;number of checksum elements
|
|
130:;; generate the block shift value
|
|
131:blkval set bls/128 ;;number of sectors/block
|
|
132:blkshf set 0 ;;counts right 0's in blkval
|
|
133:blkmsk set 0 ;;fills with l's from right
|
|
134: rept 16 ;;once for each bit position
|
|
135: if blkval=1
|
|
136: exitm
|
|
137: endif
|
|
138:;; otherwise, high order 1 not found yet
|
|
139:blkshf set blkshf+1
|
|
140:blkmsk set (blkmsk shl l) or l
|
|
141:blkval set blkval/2
|
|
142: endm
|
|
143:;; generate the extent mask byte
|
|
144:blkval set bls/1024 ;;number of kilobytes/block
|
|
145:extmsk set 0 ;;fill from right with l's
|
|
146: rept 16
|
|
147: if blkval=1
|
|
148: exitm
|
|
149: endif
|
|
150:;; otherwise more to shift
|
|
151:extmsk set (extmsk shl l) or l
|
|
152:blkval set blkval/2
|
|
153: endm
|
|
154:;; may be double byte allocation
|
|
155: if (dks)>256
|
|
|
|
F-4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156:extmsk set (extmsk shr l)
|
|
157: endif
|
|
158:;; may be optional [0] in last position
|
|
159: if not nul k16
|
|
160:extmsk set k16
|
|
161: endif
|
|
162:;; now generate directory reservation bit vector
|
|
163:dirrem set dir ;;#remaining to process
|
|
164:dirbks set bls/32 ;;number of entries per block
|
|
165:dirblk set 0 ;;fill with l's on each loop
|
|
166: rept 16
|
|
167: if dirrem=0
|
|
168: exitm
|
|
169: endif
|
|
170:;; not complete, iterate once again
|
|
171:;; shift right and add 1 high order bit
|
|
172:dirblk set (dirblk shr l) or 8000h
|
|
173: if dirrem>dirbks
|
|
174:dirrem set dirrem-dirbks
|
|
175: else
|
|
176:direem set 0
|
|
177: endif
|
|
178: endm
|
|
179: dpbhdr dn ;;generate equ $
|
|
180: ddw %sectors,<;sec per track>
|
|
181: ddb %blkshf,<;block shift>
|
|
182: ddb %blkmsk,<;block mask>
|
|
183: ddb %extmsk,<;extnt mask>
|
|
184: ddw %(dks)-1,<;disk size-1>
|
|
185: ddw %(dir)-1,<directory max>
|
|
186: ddb %dirblk shr 8,<;alloc0>
|
|
187: ddb %dirblk and 0ffh,<;allocl>
|
|
188: ddw %(cks)/4,<;check size>
|
|
189: ddw %ofs,<;offset>
|
|
190:;; generate the translate table, if requested
|
|
191: if nul skf
|
|
192:xlt&dn equ 0 ;no xlate table
|
|
193: else
|
|
194: if skf = 0
|
|
195:xlt&dn equ 0 ;no xlate table
|
|
|
|
F-5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196: else
|
|
197:;; generate the translate table
|
|
198:nxtsec set 0 ;;next sector to fill
|
|
199:nxtbas set 0 ;;moves by one on overflow
|
|
200: gcd %sectors,skf
|
|
201:;; gcdn = gcd(sectors,skew)
|
|
202:neltst set sectors/gcdn
|
|
203:;; neltst is number of elements to generate
|
|
204:;; before we overlap previous elements
|
|
205:nelts set neltst ;;counter
|
|
206:xlt&dn equ $ ;;translate table
|
|
207: rept sectors ;;once for each sector
|
|
208: if sectors<256
|
|
209: ddb %nxtsec+(fsc)
|
|
210: else
|
|
211: ddw %nxtsec+(fsc)
|
|
212: endif
|
|
213:nxtsec set nxtsec+(skf)
|
|
214: if nxtsec>=sectors
|
|
215:nxtsec set nxtsec-sectors
|
|
216: endif
|
|
217:nelts set nelts-1
|
|
218: if nelts = 0
|
|
219:nxtbas set nxtbas+1
|
|
220:nxtsec set nxtbas
|
|
221:nelts set neltst
|
|
222: endif
|
|
223: endm
|
|
224: endif ;;end of nul fac test
|
|
225: endif ;;end of nul bls test
|
|
226: endm
|
|
227:;
|
|
228:defds macro lab,space
|
|
229:lab: ds space
|
|
230: endm
|
|
231:;
|
|
232:lds macro lb,dn,val
|
|
233: defds lb&dn,%val&dn
|
|
234: endm
|
|
235:;
|
|
|
|
F-6
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236:endef macro
|
|
237:;; generate the necessary ram data areas
|
|
238:begdat equ $
|
|
239:dirbuf: ds 128 ;directory access buffer
|
|
240:dsknxt set 0
|
|
241: rept ndisks ;;once for each disk
|
|
242: lds alv,%dsknxt,als
|
|
243: lds csv,%dsknxt,ccs
|
|
244:dsknxt set dsknxt+1
|
|
245: endm
|
|
246:enddat equ $
|
|
247:datsiz equ $-begdat
|
|
248:;; db 0 at this point forces hex record
|
|
249: endm
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
F-7
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
G-1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 ;
|
|
|
|
G-2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
G-3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
G-4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
G-5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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?
|
|
|
|
G-6
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
G-7
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
G-8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 ;
|
|
|
|
G-9
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
G-10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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#
|
|
|
|
G-11
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
G-12
|
|
|
|
|
|
|