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