        page    ,132                    ;
        title   CPMIO2 - device IO for MSDOS

;
; Old style CP/M 1-12 system calls to talk to reserved devices
;
;   $Std_Con_Input
;   $Std_Con_Output
;   OUTT
;   TAB
;   BUFOUT
;   $Std_Aux_Input
;   $Std_Aux_Output
;   $Std_Printer_Output
;   $Std_Con_Input_Status
;   $Std_Con_Input_Flush
;
;   Revision History:
;
;       AN000    version 4.00 - Jan. 1988
;

.xlist
include v86seg.inc
.xcref
include basemaca.inc
include osmaca.inc
include oldmaca.inc
include demmac.inc
include dossymc.inc
include devsym.inc
include demdbcs.inc
include mvdmexp.inc
include mi.inc
include demsvc.inc
include dos3dev.inc
include struc30.inc
.cref
.list
        CpuMode 386

        I_Need  CARPOS,BYTE
        I_Need  CHARCO,BYTE
        I_Need  PFLAG,BYTE
        I_Need  CurrentPDB,WORD
        I_Need  InterCon,BYTE
        I_Need  SaveCurFlg,BYTE
        I_Need  VDMNotBusy,WORD                  ; VPL Idle detection

V86CODE    SEGMENT
        ASSUME  CS:V86GROUP

        EXTRN   Inter_Con_Input_No_Echo:NEAR
        EXTRN   $Std_Con_Input_No_Echo:NEAR
        EXTRN   StatChk:NEAR
        EXTRN   RawOut:NEAR
        EXTRN   Get_IO_SFT:NEAR
        EXTRN   SpoolInt:NEAR
        EXTRN   IOFunc:NEAR
        EXTRN   RawOUT2:NEAR

; The following routines form the console I/O group (funcs 1,2,6,7,8,9,10,11).
; They assume ES and DS NOTHING, while not strictly correct, this forces data
; references to be SS or CS relative which is desired.



subttl
page

; Inputs:
;       None
; Function:
;       Input character from console, echo
; Returns:
;       AL = character

procedure   $STD_CON_INPUT,NEAR   ;System call 1
        assume  DS:NOTHING,ES:NOTHING

        push    word ptr cs:[InterCon]
        mov     cs:[InterCon],01H
        invoke  INTER_CON_INPUT_NO_ECHO
        pop     word ptr cs:[InterCon]
        pushf
        push    AX
        mov     cs:[SaveCurFlg],0
        .if     z
          mov     cs:[SaveCurFlg],1
        .endif
        invoke  OUTT
        mov     cs:[SaveCurFLg],0
        pop     AX
        popf
        jz      $STD_CON_INPUT
        ret
EndProc $STD_CON_INPUT

subttl
page

; Inputs:
;       DL = character
; Function:
;       Output character to console
; Returns:
;       None

procedure   $STD_CON_OUTPUT,NEAR   ;System call 2
        assume  ds:NOTHING,ES:NOTHING

        MOV     AL,DL

        entry   OUTT
        entry   _OUT
        CMP     AL,20H
        JB      short CTRLOUT
        .if     <AL ne c_DEL>

          public  OUTCHA
OUTCHA:
          inc     byte ptr cs:[CARPOS]
        .endif
OUTCH:
        PUSH    ES
        PUSH    DI

        PUSH    DS
        PUSH    SI
        INC     BYTE PTR cs:[CHARCO]               ;invoke  statchk...
        AND     BYTE PTR CS:[CHARCO],00111111B     ; every 64th char
        .if     z
          push    ax
          invoke  STATCHK
          pop     ax
        .endif
        invoke  RAWOUT                          ;output the character
        POP     SI
        POP     DS
        POP     DI
        POP     ES
        TEST    cs:[SaveCurFlg],01H              ;print but no cursor adv?
        jnz     short OUTT_Exit
        TEST    BYTE PTR cs:[PFLAG],-1
        jz      short OUTT_Exit
        PUSH    BX
        PUSH    DS
        PUSH    SI
        PUSH    ES
        PUSH    DI
        MOV     BX,1
        invoke  GET_IO_SFT
        JC      short TRIPOPJ
        CMP     DI,-1
        JZ      short TRIPOPJ
        TEST    ES:[DI].rmdi_flags,RMDI_ISNET   ; output to NET?
        JNZ     short TRIPOPJ                   ; if so, no echo
        MOV     BX,4
        invoke  GET_IO_SFT
        JC      short TRIPOPJ

        TEST    ES:[DI].rmdi_flags,RMDI_ISNET   ; StdPrn redirected?
        JZ      short LISSTRT2J                 ; No, OK to echo
PRTOFF:
        MOV     BYTE PTR cs:[PFLAG],0           ; If a spool, NEVER echo
TRIPOPJ:
        POP     DI
        POP     ES
        JMP     TRIPOP

LISSTRT2J:
        MOV     BX,4                    ; (BX) = PRN handle
        invoke  RAWOUT2                 ; print character
        JC      PRTOFF                  ; if error turn off printer echo
        JMP     TRIPOPJ                 ; go to exit

CTRLOUT:
        CMP     AL,c_CR
        JZ      short ZERPOS
        CMP     AL,c_BS
        JZ      short BACKPOS
        CMP     AL,c_HT
        JNZ     OUTCH
        MOV     AL,cs:[CARPOS]
        OR      AL,0F8h
        NEG     AL

        entry   TAB

        PUSH    CX
        MOV     CL,AL
        MOV     CH,0
        JCXZ    POPTAB
TABLP:
        MOV     AL," "
        invoke  OUTT                    ; Possible recursion
        LOOP    TABLP
POPTAB:
        POP     CX
OUTT_Exit:
        ret

ZERPOS:
        MOV     BYTE PTR cs:[CARPOS],0
        JMP     OUTCH

BACKPOS:
        DEC     BYTE PTR cs:[CARPOS]
        JMP     OUTCH

        entry   BUFOUT

        .if     <AL ae " "> or          ;Normal char
        .if     <AL eq 9>               ;OUT knows how to expand tabs
          jmp     OUTT
        .endif

        .if     <AL ne <"U"-"@">> and   ; turn ^U to section symbol
        .if     <AL ne <"T"-"@">>       ; turn ^T to paragraph symbol
          push    ax
          mov     al,"^"
          invoke  OUTT            ;Print '^' before control chars
          pop     ax
          or      al,40h          ;Turn it into Upper case mate
        .endif

        invoke  OUTT
        ret
EndProc $STD_CON_OUTPUT

subttl
page

; Inputs:
;       None
; Function:
;       Returns character from aux input
; Returns:
;       Character in AL

procedure   $STD_AUX_INPUT,NEAR   ;System call 3
        ASSUME  DS:NOTHING,ES:NOTHING

        invoke  STATCHK
        mov     bx,3
        invoke  GET_IO_SFT
        .if     c
          ret
        .endif
        JMP     SHORT TAISTRT
AUXILP:
        invoke  SPOOLINT
TAISTRT:
        MOV     AH,1
        invoke  IOFUNC
        JZ      AUXILP
        XOR     AH,AH
        invoke  IOFUNC
        ret
EndProc $STD_AUX_INPUT

subttl
page

; Inputs:
;       Character in DL
; Function:
;       Output character to aux output
; Returns:
;       Nothing

procedure   $STD_AUX_OUTPUT,NEAR   ;System call 4
        ASSUME  DS:NOTHING,ES:NOTHING

        PUSH    BX
        MOV     BX,3
        JMP     SHORT SENDOUT

EndProc $STD_AUX_OUTPUT

subttl
page

; Inputs:
;       DL = Character
; Function:
;       Output the character to the list device
; Returns:
;       None

procedure   $STD_PRINTER_OUTPUT,NEAR   ;System call 5
        ASSUME  DS:NOTHING,ES:NOTHING

        PUSH    BX
        MOV     BX,4

SENDOUT:
        MOV     AL,DL
        PUSH    AX
        invoke  STATCHK
        POP     AX
        PUSH    DS
        PUSH    SI
LISSTRT2:
        invoke  RAWOUT2
TRIPOP:
        POP     SI
        POP     DS
        POP     BX
        ret
EndProc $STD_PRINTER_OUTPUT

subttl
page

; Inputs:
;       None
; Function:
;       Check console input status
; Returns:
;       AL = -1 character available, = 0 no character

procedure   $STD_CON_INPUT_STATUS,NEAR   ;System call 11
        ASSUME  DS:NOTHING,ES:NOTHING

;       VPL Idle detection
;       VDMNotBusy is 0 when useful non-console peek requests have
;       been made.  When greater than 1 it is a count of the
;       service 11 requests made.  Idle detection periodically
;       reinitializes this value to 1.

        push    ax
        mov     ax,cs:[VDMNotBusy]     ; Let VPOL know about polling
        .if     <NONZERO ax>           ; ax = 0 means "busy" reported
          inc     cs:[VDMNotBusy]      ; increment count
        .endif
        pop     ax

        invoke  STATCHK
        mov     al,0                    ; no xor!!
        .if     z
          ret
        .endif
        or      al,-1
        ret
EndProc $STD_CON_INPUT_STATUS

subttl
page

; Inputs:
;       AL = DOS function to be called after flush (1,6,7,8,10)
; Function:
;       Flush console input buffer and perform call in AL
; Returns:
;       Whatever call in AL returns or AL=0 if AL was not 1,6,7,8 or 10

procedure   $STD_CON_INPUT_FLUSH,NEAR   ;System call 12
        ASSUME  DS:NOTHING,ES:NOTHING

        PUSH    AX
        PUSH    DX
        xor     bx,bx
        invoke  GET_IO_SFT
        .if     nc
          mov     ah,4
          invoke  IOFUNC
        .endif

        POP     DX
        POP     AX
        mov     ah,al
        .if     <AL ne 1> and
        .if     <AL ne 6> and
        .if     <AL ne 7> and
        .if     <AL ne 8> and
        .if     <AL ne 10>
          mov     al,0
          ret
        .endif

        mov     ds,cs:[CurrentPDB]
                                  ; set DS same as one from COMMAND entry
        cli
        transfer    REDISP
EndProc $STD_CON_INPUT_FLUSH

V86CODE    ENDS
    END
