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