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