.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 extrn ?cinit ; (re)initialize device in 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,1000000000000000b ; assign console to HOST ld hl,0010000000000000b ; assign console to 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 ; to all selected devices ?cono: conout: ld hl,(@covec) ; fetch console output bit vector jr out$scan ; AUXOUT ; Auxiliary Output. Send character in ; to all selected devices ?auxo: auxout: ld hl,(@aovec) ; fetch aux output bit vector jr out$scan ; LIST ; List Output. Send character in ; 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 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 and saved push bc push hl call ?cist pop hl pop bc or a ret cost1: ; get output status, saving & push bc push hl call ?cost pop hl pop bc or a ret ci1: ; get input, saving & 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