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