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