]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blame - cbios/bioskrnl.180
Minor bugfixes: clear multi sector count on drive change, ?pmsg
[z180-stamp-cpm3.git] / cbios / bioskrnl.180
CommitLineData
ea5293bb
L
1 title 'Root module of relocatable BIOS for CP/M 3.0'\r
2\r
3 ; version 1.0 15 Sept 82\r
4\r
5 include config.inc\r
6 include z180reg.inc\r
7\r
8\r
9; Copyright (C), 1982\r
10; Digital Research, Inc\r
11; P.O. Box 579\r
12; Pacific Grove, CA 93950\r
13\r
14\r
15; This is the invariant portion of the modular BIOS and is\r
16; distributed as source for informational purposes only.\r
17; All desired modifications should be performed by\r
18; adding or changing externally defined modules.\r
19; This allows producing "standard" I/O modules that\r
20; can be combined to support a particular system\r
21; configuration.\r
22\r
ea5293bb
L
23ctlQ equ 'Q'-'@'\r
24ctlS equ 'S'-'@'\r
25\r
b27f7b99
L
26ccp equ 0100h ; Console Command Processor gets loaded\r
27 ; into the TPA\r
ea5293bb 28\r
b27f7b99 29 cseg ; GENCPM puts CSEG stuff in common memory\r
ea5293bb
L
30\r
31\r
32 ; variables in system data page\r
33\r
34 extrn @covec,@civec,@aovec,@aivec,@lovec ; I/O redirection vectors\r
35 extrn @mxtpa ; addr of system entry point\r
36 extrn @bnkbf ; 128 byte scratch buffer\r
37\r
38 ; initialization\r
39\r
b27f7b99 40 extrn hwinit,?init ; general initialization and signon\r
ea5293bb
L
41 extrn ?ldccp,?rlccp ; load & reload CCP for BOOT & WBOOT\r
42\r
43 ; user defined character I/O routines\r
44\r
45 extrn ?ci,?co,?cist,?cost ; each take device in <B>\r
46 extrn ?cinit ; (re)initialize device in <C>\r
47 extrn @ctbl ; physical character device table\r
48\r
49 ; disk communication data items\r
50\r
51 extrn @dtbl ; table of pointers to XDPHs\r
52 public @adrv,@rdrv,@trk,@sect ; parameters for disk I/O\r
53 public @dma,@dbnk,@cnt ; '' '' '' ''\r
d628fed8 54 public @xdph\r
ea5293bb
L
55\r
56 ; memory control\r
57\r
d12d8b38
L
58 public @cbnk ; current bank\r
59 extrn ?xmove,?move ; select move bank, and block move\r
60 extrn ?bank ; select CPU bank\r
ea5293bb
L
61\r
62 ; clock support\r
63\r
d12d8b38 64 extrn ?time ; signal time operation\r
ea5293bb 65\r
d12d8b38 66 include modebaud.inc ; define mode bits\r
ea5293bb
L
67\r
68\r
69 ; External names for BIOS entry points\r
70\r
1e1c17d3 71 public ?boot,?wboot,boot,?const,?conin,?cono,?list,?auxo,?auxi\r
ea5293bb
L
72 public ?home,?sldsk,?sttrk,?stsec,?stdma,?read,?write\r
73 public ?lists,?sctrn\r
74 public ?conos,?auxis,?auxos,?dvtbl,?devin,?drtbl\r
75 public ?mltio,?flush,?mov,?tim,?bnksl,?stbnk,?xmov\r
76\r
77 public bs$stack\r
78\r
79\r
80 ; BIOS Jump vector.\r
81\r
b27f7b99
L
82 ; All BIOS routines are invoked by calling these\r
83 ; entry points.\r
84\r
85?boot: jp boot ; initial entry on cold start\r
86?wboot: jp wboot ; reentry on program exit, warm start\r
87\r
88?const: jp const ; return console input status\r
89?conin: jp conin ; return console input character\r
90?cono: jp conout ; send console output character\r
91?list: jp list ; send list output character\r
92?auxo: jp auxout ; send auxiliary output character\r
93?auxi: jp auxin ; return auxiliary input character\r
94\r
95?home: jp home ; set disks to logical home\r
96?sldsk: jp seldsk ; select disk drive, return disk parameter info\r
97?sttrk: jp settrk ; set disk track\r
98?stsec: jp setsec ; set disk sector\r
99?stdma: jp setdma ; set disk I/O memory address\r
100?read: jp read ; read physical block(s)\r
101?write: jp write ; write physical block(s)\r
102\r
103?lists: jp listst ; return list device status\r
104?sctrn: jp sectrn ; translate logical to physical sector\r
105\r
106?conos: jp conost ; return console output status\r
107?auxis: jp auxist ; return aux input status\r
108?auxos: jp auxost ; return aux output status\r
109?dvtbl: jp devtbl ; return address of device def table\r
110?devin: jp ?cinit ; change baud rate of device\r
111\r
112?drtbl: jp getdrv ; return address of disk drive table\r
113?mltio: jp multio ; set multiple record count for disk I/O\r
114?flush: jp flush ; flush BIOS maintained disk caching\r
115\r
116?mov: jp ?move ; block move memory to memory\r
117?tim: jp ?time ; Signal Time and Date operation\r
118?bnksl: jp bnksel ; select bank for code execution and default DMA\r
119?stbnk: jp setbnk ; select different bank for disk I/O DMA operations\r
120?xmov: jp ?xmove ; set source and destination banks for one operation\r
ea5293bb
L
121\r
122 jp 0 ; reserved for future expansion\r
123 jp 0 ; reserved for future expansion\r
124 jp 0 ; reserved for future expansion\r
125\r
126\r
127 ; BOOT\r
128 ; Initial entry point for system startup.\r
129\r
b27f7b99 130 dseg ; this part can be banked\r
ea5293bb
L
131\r
132boot:\r
1e1c17d3
L
133 ld a,SYS$CBR\r
134 out0 (cbr),a\r
135 ld a,USR$CBAR\r
136 out0 (cbar),a\r
ea5293bb
L
137 ld sp,bs$stack\r
138\r
b27f7b99 139 call hwinit ; first time hardware initialisation\r
ea5293bb 140\r
d12d8b38 141 ld bc,16*256 + 0 ; initialize all 16 character devices\r
ea5293bb
L
142c$init$loop:\r
143 push bc\r
144 call ?cinit\r
145 pop bc\r
d12d8b38
L
146 inc c\r
147 djnz c$init$loop\r
ea5293bb 148\r
b27f7b99
L
149 call ?init ; perform any additional system initialization\r
150 ; and print signon message\r
ea5293bb
L
151\r
152 ld bc,16*256+0\r
b27f7b99 153 ld hl,@dtbl ; init all 16 logical disk drives\r
ea5293bb 154d$init$loop:\r
b27f7b99 155 push bc ; save remaining count and abs drive\r
ea5293bb
L
156 ld e,(hl)\r
157 inc hl\r
158 ld d,(hl)\r
b27f7b99 159 inc hl ; grab @drv entry\r
ea5293bb
L
160 ld a,e\r
161 or d\r
b27f7b99
L
162 jr z,d$init$next ; if null, no drive\r
163 push hl ; save @drv pointer\r
ea5293bb 164 push de\r
40df51ae 165 pop ix ; XDPH address in <DE>\r
ea5293bb 166 ld b,(ix-2)\r
b27f7b99 167 ld (@ADRV),bc ; save absolute and relative drive code\r
ea5293bb 168 ld l,(ix-4)\r
b27f7b99
L
169 ld h,(ix-3) ; get init pointer\r
170 call ipchl ; call init routine\r
b27f7b99 171 pop hl ; recover @drv pointer\r
ea5293bb 172d$init$next:\r
b27f7b99 173 pop bc ; recover counter and drive #\r
ea5293bb 174 inc c\r
b27f7b99 175 djnz d$init$loop ; and loop for each drive\r
ea5293bb
L
176 jp boot$1\r
177\r
178 cseg ; following in resident memory\r
179\r
180boot$1:\r
181 call set$jumps\r
b27f7b99 182 call ?ldccp ; fetch CCP for first time\r
ea5293bb
L
183 jp ccp\r
184\r
185\r
186 ; WBOOT\r
187 ; Entry for system restarts.\r
188\r
189wboot:\r
190 ld sp,bs$stack\r
b27f7b99
L
191 call set$jumps ; initialize page zero\r
192 call ?rlccp ; reload CCP\r
193 jp ccp ; then reset jmp vectors and exit to ccp\r
ea5293bb
L
194\r
195\r
196set$jumps:\r
197\r
198 if banked\r
199 ld a,1\r
200 call ?bnksl\r
201 endif\r
202\r
203 ld a,0C3h ; jp opcode\r
204 ld (0),a\r
205 ld (5),a ; set up jumps in page zero\r
206 ld hl,?wboot\r
207 ld (1),hl ; BIOS warm start entry\r
208 ld hl,(@MXTPA)\r
209 ld (6),hl ; BDOS system call entry\r
210 ret\r
211\r
212\r
b43b4662 213 ds bs$stack$size\r
ea5293bb
L
214bs$stack equ $\r
215\r
216\r
217 ; DEVTBL\r
218 ; Return address of character device table\r
219\r
220devtbl:\r
221 ld hl,@ctbl\r
222 ret\r
223\r
224\r
225 ; GETDRV\r
226 ; Return address of drive table\r
227\r
228getdrv:\r
229 ld hl,@dtbl\r
230 ret\r
231\r
232\r
233\r
2a413c0d
L
234 ; LIST\r
235 ; List Output. Send character in <C>\r
236 ; to all selected devices.\r
ea5293bb 237\r
2a413c0d
L
238list:\r
239 ld hl,(@lovec) ; fetch list output bit vector\r
ea5293bb
L
240 jr out$scan\r
241\r
242\r
243 ; AUXOUT\r
244 ; Auxiliary Output. Send character in <C>\r
245 ; to all selected devices\r
246\r
247auxout:\r
248 ld hl,(@aovec) ; fetch aux output bit vector\r
249 jr out$scan\r
250\r
251\r
2a413c0d
L
252 ; CONOUT\r
253 ; Console Output. Send character in <C>\r
254 ; to all selected devices\r
ea5293bb 255\r
2a413c0d
L
256conout:\r
257\r
258 ld hl,(@covec) ; fetch console output bit vector\r
ea5293bb
L
259\r
260out$scan:\r
261 ld b,0 ; start with device 0\r
262co$next:\r
263 add hl,hl ; shift out next bit\r
264 jr nc,not$out$device\r
265 push hl ; save the vector\r
7055170f 266 push bc ; save device num and the character\r
b27f7b99 267 call ?co ; if device selected, print it\r
ea5293bb
L
268 pop bc ; recover count and character\r
269 pop hl ; recover the rest of the vector\r
270not$out$device:\r
271 inc b ; next device number\r
272 ld a,h\r
b27f7b99 273 or l ; see if any devices left\r
ea5293bb
L
274 jr nz,co$next ; and go find them...\r
275 ret\r
276\r
277\r
2a413c0d
L
278 ; LISTST\r
279 ; List Output Status. Return true if\r
280 ; all selected list output devices\r
ea5293bb
L
281 ; are ready.\r
282\r
2a413c0d
L
283listst:\r
284 ld hl,(@lovec) ; get list output bit vector\r
ea5293bb
L
285 jr ost$scan\r
286\r
287\r
288 ; AUXOST\r
289 ; Auxiliary Output Status. Return true if\r
290 ; all selected auxiliary output devices\r
291 ; are ready.\r
292\r
293auxost:\r
294 ld hl,(@aovec) ; get aux output bit vector\r
295 jr ost$scan\r
296\r
297\r
2a413c0d
L
298 ; CONOST\r
299 ; Console Output Status. Return true if\r
300 ; all selected console output devices\r
ea5293bb
L
301 ; are ready.\r
302\r
2a413c0d
L
303conost:\r
304 ld hl,(@covec) ; get console output bit vector\r
ea5293bb
L
305\r
306ost$scan:\r
307 ld b,0 ; start with device 0\r
308cos$next:\r
309 add hl,hl ; check next bit\r
310 push hl ; save the vector\r
311 push bc ; save the count\r
b27f7b99 312 ld a,0FFh ; assume device ready\r
7055170f 313 call c,?cost ; check status for this device\r
ea5293bb
L
314 pop bc ; recover count\r
315 pop hl ; recover bit vector\r
316 or a ; see if device ready\r
317 ret z ; if any not ready, return false\r
318 inc b ; drop device number\r
319 ld a,h\r
b27f7b99 320 or l ; see if any more selected devices\r
ea5293bb 321 jr nz,cos$next\r
b27f7b99 322 or 0FFh ; all selected were ready, return true\r
ea5293bb
L
323 ret\r
324\r
ea5293bb 325\r
b27f7b99 326cist1: ; get input status with <BC> and <HL> saved\r
ea5293bb
L
327 push bc\r
328 push hl\r
329 call ?cist\r
330 pop hl\r
331 pop bc\r
332 or a\r
333 ret\r
334\r
ea5293bb 335\r
ea5293bb
L
336 ; AUXIST\r
337 ; Auxiliary Input Status. Return true if\r
338 ; any selected auxiliary input device\r
339 ; has an available character.\r
340\r
341auxist:\r
342 ld hl,(@aivec) ; get aux input bit vector\r
2a413c0d
L
343 jr ist$scan\r
344\r
345\r
346 ; CONST\r
347 ; Console Input Status. Return true if\r
348 ; any selected console input device\r
349 ; has an available character.\r
350\r
351const:\r
352 ld hl,(@civec) ; get console input bit vector\r
ea5293bb
L
353\r
354ist$scan:\r
355 ld b,0 ; start with device 0\r
356cis$next:\r
7055170f
L
357 xor a ; assume next device not ready\r
358 add hl,hl ; check next bit (lets z flag unaffected)\r
359 call c,cist1 ; check status for this device\r
ea5293bb
L
360 ret nz ; if any ready, return true\r
361 inc b ; next device number\r
362 ld a,h\r
b27f7b99 363 or l ; see if any more selected devices\r
7055170f
L
364 ret z ; all selected were not ready, return false\r
365 jr cis$next\r
ea5293bb
L
366\r
367\r
ea5293bb
L
368 ; AUXIN\r
369 ; Auxiliary Input. Return character from first\r
370 ; ready auxiliary input device.\r
371\r
372auxin:\r
373 ld hl,(@aivec)\r
2a413c0d
L
374 jr in$scan\r
375\r
376\r
377 ; CONIN\r
378 ; Console Input. Return character from first\r
379 ; ready console input device.\r
380\r
381conin:\r
382 ld hl,(@civec)\r
ea5293bb
L
383\r
384in$scan:\r
385 push hl ; save bit vector\r
386 ld b,0\r
387ci$next:\r
7055170f 388 xor a ; assume next device not ready\r
ea5293bb 389 add hl,hl ; shift out next bit\r
ea5293bb 390 call c,cist1 ; see if the device has a character\r
ea5293bb
L
391 jr nz,ci$rdy ; this device has a character\r
392 inc b ; else, next device\r
393 ld a,h\r
394 or l ; see if any more devices\r
395 jr nz,ci$next ; go look at them\r
396 pop hl ; recover bit vector\r
397 jr in$scan ; loop til we find a character\r
398\r
399ci$rdy:\r
400 pop hl ; discard extra stack\r
401 jp ?ci\r
402\r
403\r
5f701f3a
L
404;-------------------------------------------------------------------------------\r
405; Utility Subroutines\r
ea5293bb
L
406\r
407\r
408ipchl: ; vectored CALL point\r
409 jp (hl)\r
410\r
411\r
ea5293bb
L
412\r
413 ; BNKSEL\r
414 ; Bank Select. Select CPU bank for further execution.\r
415\r
416bnksel:\r
b27f7b99
L
417 ld (@cbnk),a ; remember current bank\r
418 jp ?bank ; and go exit through users\r
419 ; physical bank select routine\r
ea5293bb 420\r
ea5293bb
L
421 dseg ; following resides in banked memory\r
422\r
ea5293bb
L
423; Disk I/O interface routines\r
424\r
425\r
426 ; SELDSK\r
427 ; Select Disk Drive. Drive code in <C>.\r
428 ; Invoke login procedure for drive\r
429 ; if this is first select. Return\r
430 ; address of disk parameter header\r
431 ; in <HL>\r
432\r
433seldsk:\r
b27f7b99 434 ld a,c ; save drive select code\r
ea5293bb 435 ld (@adrv),a\r
d628fed8
L
436 xor a\r
437 ld (@cnt),a\r
438 ld b,a ; create index from drive code\r
ea5293bb 439 ld hl,@dtbl\r
b27f7b99 440 add hl,bc ; get pointer to dispatch table\r
ea5293bb
L
441 add hl,bc\r
442 ld a,(hl)\r
443 inc hl\r
444 ld h,(hl)\r
b27f7b99
L
445 ld l,a ; point at disk descriptor\r
446 ld (@xdph),hl ; save descriptor pointer\r
ea5293bb 447 or h\r
b27f7b99 448 ret z ; if no entry in table, no disk\r
ea5293bb 449\r
5c4f36fa
L
450 bit 0,e ; login bit to zero flag\r
451 ex de,hl\r
452 ld hl,-2 ; get relative drive\r
453 add hl,de\r
454 ld a,(hl)\r
455 ld (@RDRV),a\r
456 jr nz,notfirst ; examine login bit\r
457 ld hl,-6\r
458 add hl,de\r
459 ld a,(hl)\r
460 inc hl\r
461 ld h,(hl)\r
462 ld l,a\r
b27f7b99 463 call ipchl ; call LOGIN\r
5c4f36fa 464notfirst:\r
b27f7b99 465 ld hl,(@xdph) ; recover DPH pointer\r
ea5293bb
L
466 ret\r
467\r
468\r
469 ; HOME\r
470 ; Home selected drive. Treated as SETTRK(0).\r
471\r
472home:\r
473 ld bc,0 ; same as set track zero\r
474\r
475\r
476 ; SETTRK\r
477 ; Set Track. Saves track address from <BC>\r
478 ; in @TRK for further operations.\r
479\r
480settrk:\r
481 ld (@trk),bc\r
482 ret\r
483\r
484\r
485 ; SETSEC\r
486 ; Set Sector. Saves sector number from <BC>\r
487 ; in @sect for further operations.\r
488\r
489setsec:\r
490 ld (@sect),bc\r
491 ret\r
492\r
493\r
494 ; SETDMA\r
495 ; Set Disk Memory Address. Saves DMA address\r
496 ; from <BC> in @DMA and sets @DBNK to @CBNK\r
497 ; so that further disk operations take place\r
498 ; in current bank.\r
499\r
500setdma:\r
501 ld (@dma),bc\r
502\r
503 ld a,(@cbnk) ; default DMA bank is current bank\r
504 ; fall through to set DMA bank\r
505\r
506 ; SETBNK\r
507 ; Set Disk Memory Bank. Saves bank number\r
508 ; in @DBNK for future disk data\r
509 ; transfers.\r
510\r
511setbnk:\r
512 ld (@dbnk),a\r
513 ret\r
514\r
515\r
516 ; SECTRN\r
517 ; Sector Translate. Indexes skew table in <DE>\r
518 ; with sector in <BC>. Returns physical sector\r
519 ; in <HL>. If no skew table (<DE>=0) then\r
520 ; returns physical=logical.\r
521\r
522sectrn:\r
523 ld l,c\r
524 ld h,b\r
525 ld a,d\r
526 or e\r
527 ret z\r
528 ex de,hl\r
529 add hl,bc\r
530 ld l,(hl)\r
531 ld h,0\r
532 ret\r
533\r
534\r
535 ; READ\r
536 ; Read physical record from currently selected drive.\r
537 ; Finds address of proper read routine from\r
538 ; extended disk parameter header (XDPH).\r
539\r
540read:\r
b27f7b99
L
541 ld ix,(@xdph) ; get drive descriptor pointer\r
542 ld l,(ix-8) ; get read routine entry\r
ea5293bb
L
543 ld h,(ix-7)\r
544 jp (hl)\r
545\r
546\r
547 ; WRITE\r
548 ; Write physical sector from currently selected drive.\r
549 ; Finds address of proper write routine from\r
550 ; extended disk parameter header (XDPH).\r
551\r
552write:\r
b27f7b99
L
553 ld ix,(@xdph) ; get drive descriptor pointer\r
554 ld l,(ix-10) ; get write routine entry\r
ea5293bb
L
555 ld h,(ix- 9)\r
556 jp (hl)\r
557\r
558\r
559\r
560 ; MULTIO\r
561 ; Set multiple sector count. Saves passed count in\r
562 ; @CNT\r
563\r
564multio:\r
565 ld (@cnt),a\r
566 ret\r
567\r
568\r
569 ; FLUSH\r
570 ; BIOS deblocking buffer flush. Not implemented.\r
571\r
572flush:\r
573 xor a\r
b27f7b99 574 ret ; return with no error\r
ea5293bb
L
575\r
576\r
ea5293bb
L
577; disk communication data items\r
578; do not change order. sd driver depends on this\r
579\r
580@xdph: ds 2 ; pointer to currently selected drives dph\r
581@adrv: ds 1 ; currently selected disk drive\r
582@rdrv: ds 1 ; controller relative disk drive\r
ea5293bb
L
583@trk: ds 2 ; current track number\r
584@sect: ds 2 ; current sector number\r
585@dma: ds 2 ; current DMA address\r
586@dbnk: db 0 ; bank for DMA operations\r
1d26b866 587@cnt: db 0 ; record count for multisector transfer\r
ea5293bb
L
588\r
589\r
590 cseg ; common memory\r
591\r
592@cbnk: db 0 ; bank for processor operations\r
593\r
594\r
595 end\r