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