;       SCCSID = @(#)cpmio.asm  6.3 91/09/11
;       SCCSID = @(#)cpmio.asm  6.3 91/09/11
TITLE   CPMIO - device IO for MSDOS
NAME    CPMIO
;
; Standard device IO for MSDOS (first 12 function calls)
;
;********************************************************************;73078;
; 08/25/93 73078 - Lisa M. Primm                                     ;73078;
;          FSFILTER was not discarding LFs at the beginning of a     ;73078;
;          line in $STD_CON_STRING_INPUT                             ;73078;
; 10/28/93 75149 - Change Team                                       ;75149;
;          Added code to RAWOUT to set the int 21 function type to 5 ;75149;
;          if the output is being sent to a printer.                 ;75149;
;********************************************************************;75149;

.xlist
include v86seg.inc
.xcref
.cref
include basemaca.inc
include osmaca.inc
include oldmaca.inc
include demmac.inc
include dos3dev.inc
include devsym.inc
include demdbcs.inc
include vector.inc
include dossymc.inc
include mi.inc
include doscntry.inc
include dos34.inc
include mvdmexp.inc
include demsvc.inc
.list

;
; Old style CP/M 1-12 system calls to talk to reserved devices
;
;   $Std_Con_Input_No_Echo
;   $Std_Con_String_Output
;   $Std_Con_String_Input
;   $RawConIO
;   $RawConInput
;   RAWOUT
;
;   Revision history:
;
;     A000     version 4.00 - Jan 1988
;     A002     PTM    -- dir >lpt3 hangs
;
;     B001  9/11/91  CP20 PTR B726834  Mark Rogalski
;           Remove code which diplays strings in segments.
;

V86CODE SEGMENT
        ASSUME  CS:V86GROUP,SS:NOTHING

        EXTRN   GET_IO_SFT:NEAR
        EXTRN   IOFUNC:NEAR
        EXTRN   Str$Len:NEAR
        extrn   VMcheck_handle:NEAR
        extrn   get_user_stack:NEAR
        extrn   VSFNFromHandle:NEAR
        extrn   spoolint:NEAR

        extrn   pOldInt21:DWORD
        extrn   max_in:BYTE
        extrn   fl_printer_output:BYTE                                   ;75149


; 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.


csoMaxChars     equ  255        ; maximum chars to output at one time in
                                ; cons_string_output


;**     $Std_Con_Input_No_Echo
;
;       ENTRY   none
;
;       EXIT    AL = read char
;
;       USES    All

        procedure   $STD_CON_INPUT_NO_ECHO,NEAR   ; System call 8
ASSUME  DS:NOTHING,ES:NOTHING

        mov     bx,0                    ; mdr check stdin handle
        call    VMcheck_handle          ; mdr return if DOS handle

        call    Get_IO_SFT              ; mdr setup dev pointer
        call    RAW_CON_IN              ; get char
        ret

endproc $STD_CON_INPUT_NO_ECHO


;**     $Std_Con_String_Output - print '$' terminated string
;**     Cons_String_Output - print string given length
;
;       Print the string on the console device
;
;       ENTRY   DS:DX   Point to output string
;               CX      number of characters in string (Cons_String_Output only)
;
;       EXIT    None
;
;       USES    All

        ASSUME  DS:NOTHING,ES:NOTHING,SS:NOTHING

procedure   $Std_Con_String_Output,NEAR         ; System call 9

        invoke  Str$Len
        push    ax
        call    Cons_String_Output
        pop     ax

        ret

entry   Cons_String_Output

        mov     bx,1                    ; mdr check stdout handle
        call    VMcheck_handle          ; mdr return if DOS handle

        call    Get_IO_SFT
        jcxz    cso9                    ; nothing to do?

;BD001  remove segmented printing

        mov     ah,IO_OUTPUT_STRING
        invoke  IOFunc                  ; print the string
cso9:
        xor     ax,ax
        return

EndProc $Std_Con_String_Output

;
;   kstrin.inc contains $Std_Con_String_Input
;
;   include kstrin.inc


; Inputs:
;       DS:DX Point to an input buffer
; Function:
;       Fill buffer from console input until CR
; Returns:
;       None

procedure   $STD_CON_STRING_INPUT,NEAR   ;System call 10
ASSUME  DS:NOTHING,ES:NOTHING

        mov     bx,0                   ; mdr check stdin handle
        call    VMcheck_handle         ; mdr return if DOS handle

        mov     si,dx
        mov     al,ds:[si]             ; get first word from buffer
        OR      AL,AL
        retz                           ; Buffer is 0 length!!?
        dec     al
        MOV     max_in,al              ; save buffer length
        push    ds
        pop     es
        mov     di,dx                  ; put buffer address in ES:DI
        inc     di                     ; skip over first two bytes
        inc     di
        xor     cx,cx                  ; init char count to zero

get_next_char:
        SaveReg <es,di>
next:   call    $STD_CON_INPUT_NO_ECHO ; mdr get char

        cmp     al,c_LF                ;73078; if LF is at beginning of line
        jz      next                   ;73078; eat the LF...

        CMP     AL,c_CR                ; ENTER pressed?
        jz      print_char

        cmp     cl,max_in              ; room in buffer for it?
        jl      print_char             ; yes? then print char

        MOV     AL,7                   ; Bell to signal full buffer
        mov     bx,1                   ; mdr
        call    RAWOUT                 ; mdr
        JMP     next

print_char:
        push    ax                     ; save character to be displayed
        mov     bx,1                   ; display char
        call    RAWOUT
        pop     ax
        RestoreReg <di,es>
        stosb                          ; store byte in buffer

        CMP     AL,c_CR                ; ENTER pressed?
        jz      finished

        inc     cx                     ; increment buffer count
        jmp     get_next_char

finished:
        mov     ds:[si+1],cl           ; store character count in buffer
        clc
        ret

endproc $STD_CON_STRING_INPUT

Break

; Inputs:
;       DL = -1 if input
;       else DL is output character
; Function:
;       Input or output raw character from console, no echo
; Returns:
;       AL = character

        procedure   $RAW_CON_IO,NEAR   ; System call 6
ASSUME  DS:NOTHING,ES:NOTHING

        mov     al,dl
        cmp     dl,-1
        jz      get_char
        mov     bx,1                    ; mdr output char to stdout
        call    RAWOUT                  ; mdr
        ret

get_char:
        mov     bx,0                    ; mdr check stdin handle
        call    VMcheck_handle          ; mdr return if DOS handle

        call    GET_IO_SFT              ; mdr setup dev pointer
        call    get_user_stack          ; mdr
        MOV     AH,1                    ; mdr see if char available
        invoke  IOFUNC
        jz      no_char_avail
        AND     BYTE PTR [SI.user_F],NOT F_ZERO ; Reset user's zero flag
        call    RAW_CON_IN              ; get char
        ret

no_char_avail:
        OR      BYTE PTR [SI.user_F],F_ZERO ; Set user's zero flag
        XOR     AL,AL
        ret

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

entry   $RAW_CON_INPUT          ; System call 7

        mov     bx,0                    ; mdr check stdin handle
        call    VMcheck_handle          ; mdr return if DOS handle
        call    Get_IO_SFT              ; mdr setup dev pointer

entry RAW_CON_IN
        XOR     AH,AH
        invoke  IOFUNC
        return


;
;       Output the character in AL to handle in BX
;
entry   RAWOUT

        call    VSFNFromHandle          ; mdr determine if redirection
        jz      dos_output              ; mdr send char to DOS

        call    Get_IO_SFT              ; mdr setup dev pointer
        jmp     RAWOTRY

ROLP:
        invoke  SPOOLINT
RAWOTRY:
        PUSH    AX
        MOV     AH,3
        invoke  IOFUNC
        POP     AX
        JZ      ROLP
        MOV     AH,2
        invoke  IOFUNC
        CLC                     ; Clear carry indicating successful
        return

dos_output:
        mov     ah,2
        cmp     fl_printer_output,1    ; output to printer?               75149
        jne     dos_output1            ;                                  75149
        mov     ah,5                   ; yes, request int 2f function 5   75149
dos_output1:                           ;                                  75149
        mov     fl_printer_output,0    ; reset printer output flag        75149
        mov     dl,al
        pushf                   ; mdr call DOS to output char
        call    cs:[pOldInt21]
        ret

EndProc $RAW_CON_IO


V86CODE ENDS
    END
