]>
Commit | Line | Data |
---|---|---|
1 | ; CP/M BIOS for avrcpm | |
2 | ; Copyright (C) 2010 Sprite_tm | |
3 | ; | |
4 | ; This program is free software: you can redistribute it and/or modify | |
5 | ; it under the terms of the GNU General Public License as published by | |
6 | ; the Free Software Foundation, either version 3 of the License, or | |
7 | ; (at your option) any later version. | |
8 | ; | |
9 | ; This program is distributed in the hope that it will be useful, | |
10 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | ; GNU General Public License for more details. | |
13 | ; | |
14 | ; You should have received a copy of the GNU General Public License | |
15 | ; along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | msize: equ 62 ;size of available RAM in k | |
18 | ||
19 | bias: equ (msize-20) * 1024 | |
20 | ccp: equ $3400+bias ;base of cpm ccp | |
21 | bdos: equ ccp+$806 ;base of bdos | |
22 | bios: equ ccp+$1600 ;base of bios | |
23 | cdisk: equ $0004 ;current disk number (0 ... 15) | |
24 | iobyte: equ $0003 ;intel iobyte | |
25 | buff: equ $0080 ;default buffer address | |
26 | retry: equ 3 ;max retries on disk i/o before error | |
27 | ||
28 | cr: equ 13 | |
29 | lf: equ 10 | |
30 | ||
31 | READ_FUNC: equ 7 | |
32 | WRITE_FUNC: equ 6 | |
33 | BOOT_FUNC: equ 5 | |
34 | HOME_FUNC: equ 4 | |
35 | ||
36 | org bios | |
37 | nsects: equ ($-ccp)/128 ;warm start sector count | |
38 | ||
39 | jp boot | |
40 | wboote: | |
41 | jp wboot | |
42 | jp const | |
43 | jp conin | |
44 | jp conout | |
45 | jp list | |
46 | jp punch | |
47 | jp reader | |
48 | jp home | |
49 | jp seldsk | |
50 | jp settrk | |
51 | jp setsec | |
52 | jp setdma | |
53 | jp read | |
54 | jp write | |
55 | jp listst | |
56 | jp sectran | |
57 | ||
58 | signon: | |
59 | db cr,lf | |
60 | db msize/10+'0' | |
61 | db msize - (msize/10)*10 + '0' ;modulo doesn't work? | |
62 | db "k cp/m vers 2.2" | |
63 | msgnl: db cr,lf,0 | |
64 | ||
65 | const: | |
66 | in a,(0) | |
67 | ret | |
68 | ||
69 | conin: | |
70 | in a,(0) | |
71 | cp $ff | |
72 | jp nz,conin | |
73 | ||
74 | in a,(1) | |
75 | ret | |
76 | ||
77 | conout: | |
78 | ld a,c | |
79 | out (2),a | |
80 | ret | |
81 | ||
82 | list: | |
83 | ret | |
84 | ||
85 | listst: | |
86 | ld a,0 | |
87 | ret | |
88 | ||
89 | punch: | |
90 | ret | |
91 | ||
92 | reader: | |
93 | ld a,$1F | |
94 | ret | |
95 | ||
96 | prmsg: | |
97 | ld a,(hl) | |
98 | or a | |
99 | ret z | |
100 | push hl | |
101 | ld c,a | |
102 | call conout | |
103 | pop hl | |
104 | inc hl | |
105 | jp prmsg | |
106 | ||
107 | prhex: | |
108 | ld a,c | |
109 | push af | |
110 | rra | |
111 | rra | |
112 | rra | |
113 | rra | |
114 | call prhexdigit | |
115 | pop af | |
116 | ; fall thru | |
117 | ||
118 | prhexdigit: | |
119 | and $0f | |
120 | cp 10 | |
121 | jp c,prd1 | |
122 | add 7 | |
123 | prd1: | |
124 | add '0' | |
125 | ld c,a | |
126 | jp conout | |
127 | ||
128 | ||
129 | boot: | |
130 | ld sp,buff | |
131 | ld hl,signon | |
132 | call prmsg | |
133 | ||
134 | xor a | |
135 | ld (bootdsk),a | |
136 | ld a,(dpb) | |
137 | ld (bootspt),a | |
138 | ||
139 | ld c,'I'-'A' | |
140 | call seldsk | |
141 | ld a,h | |
142 | or l | |
143 | jp z,boot1 | |
144 | ||
145 | ld de,10 | |
146 | add hl,de | |
147 | ld e,(hl) | |
148 | inc hl | |
149 | ld d,(hl) ;de = dpb of first ram disk | |
150 | ||
151 | ld hl,7 | |
152 | add hl,de | |
153 | ld a,(hl) ;get drm | |
154 | inc a | |
155 | and $0fc | |
156 | rrca ;4 dir entries per sector | |
157 | rrca ;Number of sectors to init | |
158 | push af | |
159 | ||
160 | ld bc,6 | |
161 | add hl,bc | |
162 | ld c,(hl) ;Start track | |
163 | push bc ;Save track | |
164 | ||
165 | ; Check, if we have reserved tracks. | |
166 | ld a,c | |
167 | or a | |
168 | jp z,boot0 ;Skip if not. | |
169 | ||
170 | ; Save CPM to ram disk. | |
171 | ||
172 | ld a,(de) ;sectors per track | |
173 | ld (bootspt),a | |
174 | ld a,'I'-'A' | |
175 | ld (bootdsk),a | |
176 | call home | |
177 | ld b,nsects | |
178 | ld c,0 ;track | |
179 | ld d,1 ;sektor (0 based) | |
180 | ld hl,ccp | |
181 | store1: | |
182 | push bc | |
183 | push de | |
184 | push hl | |
185 | ld c,d | |
186 | ld b,0 | |
187 | call setsec | |
188 | pop bc | |
189 | push bc | |
190 | call setdma | |
191 | ld c,0 | |
192 | call write | |
193 | ||
194 | pop hl | |
195 | ld de,128 | |
196 | add hl,de | |
197 | pop de | |
198 | pop bc | |
199 | dec b | |
200 | jp z,boot0 | |
201 | ||
202 | inc d | |
203 | ld a,(bootspt) | |
204 | dec a | |
205 | cp d ;if sector >= spt then change tracks | |
206 | jp nc,store1 | |
207 | ||
208 | ld d,0 | |
209 | inc c | |
210 | push bc | |
211 | push de | |
212 | push hl | |
213 | ld b,0 | |
214 | call settrk | |
215 | pop hl | |
216 | pop de | |
217 | pop bc | |
218 | jp store1 | |
219 | ||
220 | ; Clear directory area of ram disk. | |
221 | ||
222 | boot0: | |
223 | pop bc | |
224 | call settrk | |
225 | pop af | |
226 | ld d,a ;d = # of sectors | |
227 | ld e,0 ;e = sector | |
228 | push de | |
229 | ld hl,dirbuf ;Clear dirbuf | |
230 | ld c,128 | |
231 | ld a,$E5 | |
232 | boot_cl: | |
233 | ld (hl),a | |
234 | inc hl | |
235 | dec c | |
236 | jp nz,boot_cl | |
237 | ||
238 | ld bc,dirbuf | |
239 | call setdma | |
240 | pop de | |
241 | boot_cl2: | |
242 | push de | |
243 | ld c,e | |
244 | ld b,0 | |
245 | call setsec | |
246 | ld c,0 | |
247 | call write | |
248 | pop de | |
249 | inc e | |
250 | dec d | |
251 | jp nz,boot_cl2 | |
252 | ||
253 | boot1: | |
254 | xor a | |
255 | ld (iobyte),a | |
256 | ld (cdisk),a | |
257 | jp gocpm | |
258 | ||
259 | wboot: ;re-load CP/M | |
260 | ld sp,buff | |
261 | ld a,1<<BOOT_FUNC ;init (de)blocking | |
262 | out (22),a | |
263 | ld a,(bootdsk) | |
264 | ld c,a | |
265 | call seldsk | |
266 | call home | |
267 | ld b,nsects | |
268 | ld c,0 ;track | |
269 | ld d,1 ;sektor (0 based) | |
270 | ld hl,ccp | |
271 | load1: | |
272 | push bc | |
273 | push de | |
274 | push hl | |
275 | ld c,d | |
276 | ld b,0 | |
277 | call setsec | |
278 | pop bc | |
279 | push bc | |
280 | call setdma | |
281 | call read | |
282 | cp 0 ;read error? | |
283 | jp nz,wboot | |
284 | ||
285 | pop hl | |
286 | ld de,128 | |
287 | add hl,de | |
288 | pop de | |
289 | pop bc | |
290 | dec b | |
291 | jp z,gocpm | |
292 | ||
293 | inc d | |
294 | ld a,(bootspt) | |
295 | dec a | |
296 | cp d ;if sector >= spt then change tracks | |
297 | jp nc,load1 | |
298 | ||
299 | ld d,0 | |
300 | inc c | |
301 | push bc | |
302 | push de | |
303 | push hl | |
304 | ld b,0 | |
305 | call settrk | |
306 | pop hl | |
307 | pop de | |
308 | pop bc | |
309 | jp load1 | |
310 | ||
311 | gocpm: | |
312 | ld a,0c3h | |
313 | ld (0),a | |
314 | ld hl,wboote | |
315 | ld (1),hl | |
316 | ld (5),a | |
317 | ld hl,bdos | |
318 | ld (6),hl | |
319 | ||
320 | ld bc,buff | |
321 | call setdma | |
322 | ld a,(cdisk) | |
323 | ld c,a | |
324 | jp ccp | |
325 | ||
326 | seldsk: | |
327 | ld hl,dphtab | |
328 | ld b,0 | |
329 | add hl,bc | |
330 | add hl,bc | |
331 | ld a,(hl) ;get table entry for selected disk | |
332 | inc hl | |
333 | ld h,(hl) | |
334 | ld l,a | |
335 | or h ;no entry, no disk | |
336 | ret z ; | |
337 | ||
338 | ld a,c | |
339 | out (15),a | |
340 | in a,(15) ;querry, if disk exists | |
341 | or a ;0 = disk is ok | |
342 | ret z | |
343 | ld hl,0 ;error return code | |
344 | ret | |
345 | ||
346 | home: | |
347 | ld a,1<<HOME_FUNC | |
348 | out (22),a | |
349 | ||
350 | ld bc,0 ; same as seek to track 0 | |
351 | settrk: | |
352 | ld a,c | |
353 | out (16),a | |
354 | ld a,b | |
355 | out (17),a | |
356 | ret | |
357 | ||
358 | setsec: | |
359 | ld a,c | |
360 | out (18),a | |
361 | ret | |
362 | ||
363 | setdma: | |
364 | ld a,c | |
365 | out (20),a | |
366 | ld a,b | |
367 | out (21),a | |
368 | ret | |
369 | ||
370 | read: | |
371 | ld a,1<<READ_FUNC | |
372 | out (22),a | |
373 | in a,(22) | |
374 | and 1 | |
375 | ret | |
376 | ||
377 | write: | |
378 | ld a,c | |
379 | and 3 ;mask write type | |
380 | or 1<<WRITE_FUNC | |
381 | out (22),a | |
382 | in a,(22) | |
383 | and 1 | |
384 | ret | |
385 | ||
386 | sectran: | |
387 | ;translate sector bc using table at de, res into hl | |
388 | ld h,b | |
389 | ld l,c | |
390 | ld a,d | |
391 | or e | |
392 | ret z | |
393 | ex de,hl | |
394 | add hl,bc | |
395 | ld l,(hl) | |
396 | ld h,0 | |
397 | ret | |
398 | ||
399 | dphtab: | |
400 | dw dpe0 | |
401 | dw dpe1 | |
402 | dw dpe2 | |
403 | dw dpe3 | |
404 | dw 0 | |
405 | dw 0 | |
406 | dw 0 | |
407 | dw 0 | |
408 | dw dperd0 | |
409 | dw 0 | |
410 | dw 0 | |
411 | dw 0 | |
412 | dw 0 | |
413 | dw 0 | |
414 | dw 0 | |
415 | dw 0 | |
416 | ||
417 | ||
418 | ||
419 | ;Disk Parameter Header | |
420 | dpbase: | |
421 | dpe0: dw 0 ;XLT: No sector translation table | |
422 | dw 0 ;000: Scratchpad | |
423 | dw 0 ;000: Scratchpad | |
424 | dw 0 ;000: Scratchpad | |
425 | dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad | |
426 | dw dpb ;DPB: Address of a disk parameter block | |
427 | dw chk0 ;CSV: Address of scratchpad area for changed disks | |
428 | dw all0 ;ALV: Address of an allocation info sratchpad | |
429 | dpe1: dw 0 ;XLT: No sector translation table | |
430 | dw 0 ;000: Scratchpad | |
431 | dw 0 ;000: Scratchpad | |
432 | dw 0 ;000: Scratchpad | |
433 | dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad | |
434 | dw dpb ;DPB: Address of a disk parameter block | |
435 | dw chk1 ;CSV: Address of scratchpad area for changed disks | |
436 | dw all1 ;ALV: Address of an allocation info sratchpad | |
437 | dpe2: dw 0 ;XLT: No sector translation table | |
438 | dw 0 ;000: Scratchpad | |
439 | dw 0 ;000: Scratchpad | |
440 | dw 0 ;000: Scratchpad | |
441 | dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad | |
442 | dw dpb ;DPB: Address of a disk parameter block | |
443 | dw chk2 ;CSV: Address of scratchpad area for changed disks | |
444 | dw all2 ;ALV: Address of an allocation info sratchpad | |
445 | dpe3: dw 0 ;XLT: No sector translation table | |
446 | dw 0 ;000: Scratchpad | |
447 | dw 0 ;000: Scratchpad | |
448 | dw 0 ;000: Scratchpad | |
449 | dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad | |
450 | dw dpb ;DPB: Address of a disk parameter block | |
451 | dw chk3 ;CSV: Address of scratchpad area for changed disks | |
452 | dw all3 ;ALV: Address of an allocation info sratchpad | |
453 | ||
454 | dperd0: dw 0 ;XLT: No sector translation table | |
455 | dw 0 ;000: Scratchpad | |
456 | dw 0 ;000: Scratchpad | |
457 | dw 0 ;000: Scratchpad | |
458 | dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad | |
459 | dw dpbrd ;DPB: Address of a disk parameter block | |
460 | dw chkrd0 ;CSV: Address of scratchpad area for changed disks | |
461 | dw allrd0 ;ALV: Address of an allocation info sratchpad | |
462 | ||
463 | ||
464 | dpb: dw 26 ;SPT: sectors per track | |
465 | db 3 ;BSH: data allocation block shift factor | |
466 | db 7 ;BLM: Data Allocation Mask | |
467 | db 0 ;Extent mask | |
468 | dw 242 ;DSM: Disk storage capacity | |
469 | dw 63 ;DRM, no of directory entries | |
470 | db 192 ;AL0 | |
471 | db 0 ;AL1 | |
472 | dw 16 ;CKS, size of dir check vector | |
473 | dw 2 ;OFF, no of reserved tracks | |
474 | ||
475 | dpbrd: dw 32 ;SPT: sectors per track | |
476 | db 3 ;BSH: data allocation block shift factor | |
477 | db 7 ;BLM: Data Allocation Mask | |
478 | db 0 ;Extent mask | |
479 | dw 55 ;DSM: Disk storage capacity | |
480 | dw 15 ;DRM, no of directory entries | |
481 | db 128 ;AL0 | |
482 | db 0 ;AL1 | |
483 | dw 0 ;CKS, size of dir check vector | |
484 | dw 2 ;OFF, no of reserved tracks | |
485 | ||
486 | bootdsk:ds 1 | |
487 | bootspt:ds 1 | |
488 | ||
489 | dirbuf: | |
490 | ds 128 | |
491 | ||
492 | chk0: ds 16 | |
493 | all0: ds 31 | |
494 | chk1: ds 16 | |
495 | all1: ds 31 | |
496 | chk2: ds 16 | |
497 | all2: ds 31 | |
498 | chk3: ds 16 | |
499 | all3: ds 31 | |
500 | chkrd0: ds 0 | |
501 | allrd0: ds 7 | |
502 | ||
503 | end | |
504 |