summaryrefslogtreecommitdiff
path: root/z180/bioscio.180
diff options
context:
space:
mode:
authorLeo C2014-10-28 10:29:13 +0100
committerLeo C2014-10-28 10:29:13 +0100
commit30d1329e8e5c029a87f657baace698d1d7031f9e (patch)
tree8968e54145c1212cbaad6938e3da86cb42bf3707 /z180/bioscio.180
parent8a7deceacd30529e5c32082b2c719eb055841d0d (diff)
downloadz180-stamp-30d1329e8e5c029a87f657baace698d1d7031f9e.zip
CP/M 3 compatible character i/o handling
Diffstat (limited to 'z180/bioscio.180')
-rw-r--r--z180/bioscio.180325
1 files changed, 325 insertions, 0 deletions
diff --git a/z180/bioscio.180 b/z180/bioscio.180
new file mode 100644
index 0000000..a3a179f
--- /dev/null
+++ b/z180/bioscio.180
@@ -0,0 +1,325 @@
+
+ .z80
+
+; Copyright (C), 1982
+; Digital Research, Inc
+; P.O. Box 579
+; Pacific Grove, CA 93950
+
+; This is the invariant portion of the modular BIOS and is
+; distributed as source for informational purposes only.
+; All desired modifications should be performed by
+; adding or changing externally defined modules.
+; This allows producing "standard" I/O modules that
+; can be combined to support a particular system
+; configuration.
+;
+; Modified for faster character I/O by Udo Munk
+
+cr equ 13
+lf equ 10
+bell equ 7
+ctlQ equ 'Q'-'@'
+ctlS equ 'S'-'@'
+
+ cseg ; GENCPM puts CSEG stuff in common memory
+
+ ; variables in system data page
+
+;; extrn @covec,@civec,@aovec,@aivec,@lovec ; I/O redirection vectors
+
+ ; user defined character I/O routines
+
+ extrn ?ci,?co,?cist,?cost ; each take device in <B>
+ extrn ?cinit ; (re)initialize device in <C>
+ extrn @ctbl ; physical character device table
+
+
+ include modebaud.inc ; define mode bits
+
+
+ public @covec,@civec,@aovec,@aivec,@lovec ; I/O redirection vectors
+ public ?const,?conin,?cono,?list,?auxo,?auxi
+ public ?lists,?conos,?auxis,?auxos,?dvtbl,charini
+
+
+@CIVEC: dw 0 ; Console Input Redirection
+ ; Vector (word, r/w)
+@COVEC: dw 0 ; Console Output Redirection
+ ; Vector (word, r/w)
+@AIVEC: dw 0 ; Auxiliary Input Redirection
+ ; Vector (word, r/w)
+@AOVEC: dw 0 ; Auxiliary Output Redirection
+ ; Vector (word, r/w)
+@LOVEC: dw 0 ; List Output Redirection
+ ; Vector (word, r/w)
+
+
+charini:
+
+ ld c,15 ; initialize all 16 character devices
+c$init$loop:
+ push bc
+ call ?cinit
+ pop bc
+ dec c
+ jp p,c$init$loop
+
+ ld hl,1100000000000000b ; assign console to HOST and ASCI1
+ ld (@civec),hl
+ ld (@covec),hl
+ ld hl,0000000000000000b ; assign auxiliary to nothing
+ ld (@aivec),hl
+ ld (@aovec),hl
+ ld hl,0000000000000000b ; assign printer to nothing
+ ld (@lovec),hl
+ ret
+
+
+ ; DEVTBL
+ ; Return address of character device table
+
+?dvtbl:
+devtbl:
+ ld hl,@ctbl
+ ret
+
+
+ ; CONOUT
+ ; Console Output. Send character in <C>
+ ; to all selected devices
+
+?cono:
+conout:
+ ld hl,(@covec) ; fetch console output bit vector
+ jr out$scan
+
+
+ ; AUXOUT
+ ; Auxiliary Output. Send character in <C>
+ ; to all selected devices
+
+?auxo:
+auxout:
+ ld hl,(@aovec) ; fetch aux output bit vector
+ jr out$scan
+
+
+ ; LIST
+ ; List Output. Send character in <C>
+ ; to all selected devices.
+
+?list:
+list:
+ ld hl,(@lovec) ; fetch list output bit vector
+
+out$scan:
+ ld b,0 ; start with device 0
+co$next:
+ add hl,hl ; shift out next bit
+ jr nc,not$out$device
+ push hl ; save the vector
+ push bc ; save the count and character
+ call ?co ; if device selected, print it
+ pop bc ; recover count and character
+ pop hl ; recover the rest of the vector
+not$out$device:
+ inc b ; next device number
+ ld a,h
+ or l ; see if any devices left
+ jr nz,co$next ; and go find them...
+ ret
+
+
+ ; CONOST
+ ; Console Output Status. Return true if
+ ; all selected console output devices
+ ; are ready.
+
+?conos:
+conost:
+ ld hl,(@covec) ; get console output bit vector
+ jr ost$scan
+
+
+ ; AUXOST
+ ; Auxiliary Output Status. Return true if
+ ; all selected auxiliary output devices
+ ; are ready.
+
+?auxos:
+auxost:
+ ld hl,(@aovec) ; get aux output bit vector
+ jr ost$scan
+
+
+ ; LISTST
+ ; List Output Status. Return true if
+ ; all selected list output devices
+ ; are ready.
+
+?lists:
+listst:
+ ld hl,(@lovec) ; get list output bit vector
+
+ost$scan:
+ ld b,0 ; start with device 0
+cos$next:
+ add hl,hl ; check next bit
+ push hl ; save the vector
+ push bc ; save the count
+ ld a,0FFh ; assume device ready
+ call c,coster ; check status for this device
+ pop bc ; recover count
+ pop hl ; recover bit vector
+ or a ; see if device ready
+ ret z ; if any not ready, return false
+ inc b ; drop device number
+ ld a,h
+ or l ; see if any more selected devices
+ jr nz,cos$next
+ or 0FFh ; all selected were ready, return true
+ ret
+
+coster: ; check for output device ready, including optional
+ ; xon/xoff support
+ ;
+ ;TODO: interrupt driven devices should xon/xoff handle
+ ; in isv
+
+ ld l,b
+ ld h,0 ; make device code 16 bits
+ push hl ; save it in stack
+ add hl,hl
+ add hl,hl
+ add hl,hl ; create offset into device characteristics tbl
+ ld de,@ctbl+6
+ add hl,de ; make address of mode byte
+ ld a,(hl)
+ and mb$xon$xoff
+ pop hl ; recover console number in <HL>
+ jp z,?cost ; not a xon device, go get output status direct
+ ld de,xofflist
+ add hl,de ; make pointer to proper xon/xoff flag
+ call cist1 ; see if this keyboard has character
+ ld a,(hl)
+ call nz,ci1 ; get flag or read key if any
+ cp ctlq
+ jr nz,not$q ; if its a ctl-Q,
+ ld a,0FFh ; set the flag ready
+not$q:
+ cp ctls
+ jr nz,not$s ; if its a ctl-S,
+ ld a,00h ; clear the flag
+not$s:
+ ld (hl),a ; save the flag
+ call cost1 ; get the actual output status,
+ and (hl) ; and mask with ctl-Q/ctl-S flag
+ ret ; return this as the status
+
+cist1: ; get input status with <BC> and <HL> saved
+ push bc
+ push hl
+ call ?cist
+ pop hl
+ pop bc
+ or a
+ ret
+
+cost1: ; get output status, saving <BC> & <HL>
+ push bc
+ push hl
+ call ?cost
+ pop hl
+ pop bc
+ or a
+ ret
+
+ci1: ; get input, saving <BC> & <HL>
+ push bc
+ push hl
+ call ?ci
+ pop hl
+ pop bc
+ ret
+
+
+ ; AUXIST
+ ; Auxiliary Input Status. Return true if
+ ; any selected auxiliary input device
+ ; has an available character.
+?auxis:
+auxist:
+ ld hl,(@aivec) ; get aux input bit vector
+ jr ist$scan
+
+
+ ; CONST
+ ; Console Input Status. Return true if
+ ; any selected console input device
+ ; has an available character.
+?const:
+const:
+ ld hl,(@civec) ; get console input bit vector
+
+
+ist$scan:
+ ld b,0 ; start with device 0
+cis$next:
+ add hl,hl ; check next bit
+ ld a,0 ; assume device not ready
+ call c,cist1 ; check status for this device
+ or a
+ ret nz ; if any ready, return true
+ inc b ; next device number
+ ld a,h
+ or l ; see if any more selected devices
+ jr nz,cis$next
+ xor a ; all selected were not ready, return false
+ ret
+
+
+ ; AUXIN
+ ; Auxiliary Input. Return character from first
+ ; ready auxiliary input device.
+?auxi:
+auxin:
+ ld hl,(@aivec)
+ jr in$scan
+
+
+ ; CONIN
+ ; Console Input. Return character from first
+ ; ready console input device.
+?conin:
+conin:
+ ld hl,(@civec)
+
+in$scan:
+ push hl ; save bit vector
+ ld b,0
+ci$next:
+ add hl,hl ; shift out next bit
+ ld a,0 ; insure zero a (nonexistant device not ready).
+ call c,cist1 ; see if the device has a character
+ or a
+ jr nz,ci$rdy ; this device has a character
+ inc b ; else, next device
+ ld a,h
+ or l ; see if any more devices
+ jr nz,ci$next ; go look at them
+ pop hl ; recover bit vector
+ jr in$scan ; loop til we find a character
+ci$rdy:
+ pop hl ; discard extra stack
+ jp ?ci
+
+
+
+xofflist:
+ db -1,-1,-1,-1,-1,-1,-1,-1 ; ctl-s clears to zero
+ db -1,-1,-1,-1,-1,-1,-1,-1
+
+
+ end
+