;       SIO2PC routines relating to the printer
;
; PRINT_THRU sets up the flags for the printer function, also
; toggles the function off/on.

PRINT_THRU:
        CMP PRINTHRU,0; In PRINT_THRU mode now?
        JE >L1; If not, then set it up
        MOV PRINTHRU,0; Else, disable it
        PSTATUS NO_PTHRU, ATTR9
       CALL CLOSPFIL
        TICKS 15
        CALL PT_STATS
        RET

L1:     MOV PRINTHRU,1
        MOV PRNDEV,4; Assume printer for output device
        PSTATUS PTR_CHOICE, ATTR9
        CALL GET_TORK
        CMP AL,27; ESC?
        JNE >L1
        JMP PRINT_THRU; cancel if so

L1:     AND AL,255-32; upper
        MOV APRNDEV,AL
        CMP AL,'S'
        JNE >L0
        MOV PRNDEV,1; Make output device = screen
        MOV D_STLINE,0FFh; No status line if printing to screen
        CALL CLR_24     ; clear line 24 to avoid confusion

L0:     CMP AL,'F'; Print to a file...
        JNE >L1
        CALL GET_FSPC; Gets filespec from user
        JNC ADW;
        JMP PRINT_THRU; Disable if ESC pressed

; Now, have filespec in RFSPEC. So try to create file:

ADW:    MOV CX,0; Normal file attribute
        MOV AH,03Ch; Create file
        MOV DX, OFFSET RFSPEC; (DS assumed = CS)
        INT 021h
        MOV PRNDEV,AX; Save handle
        JNC >L1; If no error
        MOV PRNDEV, 1; default: screen
        PSTATUS ECF, ATTR10
        MOV AH,0
        ADD AL,'0'; Convert to ASCII digit
        CALL PRINT1
        TICKS 36
        CALL FLUSH
        MOV AL,'F'
        JMP L0



L1:     PSTATUS EOL_CHOICE, ATTR9
        MOV EOLFIX,0; Assume no translation
        MOV LF_TOO,0
        CALL GET_TORK
        AND AL,255-32; upper case
        CMP AL,'Y'
        JNE >L1
        MOV EOLFIX,1; Translate EOL's
        PSTATUS LFS_ALSO, ATTR9
        CALL GET_TORK
        AND AL,255-32
        CMP AL,'Y'
        JNE >L1
        MOV LF_TOO,1

L1:     MOV PRNMASK,0FFh; Assume no strip high bit
        PSTATUS PSTRIP, ATTR9
        CALL GET_TORK
        AND AL,255-32
        CMP AL,'N'
        JE >L2
        MOV PRNMASK, 01111111xB; Do strip high bit

L2:     MOV CONV_TAB, 0; ASSUME NO TAB CONV; 3.07
        PSTATUS C_TAB, ATTR9
        CALL GET_TORK
        AND AL, 255-32
        CMP AL, 'Y'
        JNE >L1
        MOV CONV_TAB, 0FFh

L1:     CALL PT_STATS
        RET




;               PRINTER
;
; This routine routes data from an Atari printer command to the
; PC's printer
;
PRINTER:
        ; fill the buffer with blanks
        PUSH AX,CX
        MOV AX,' ' + ' ' * 100h
        MOV CX,60
        MOV SI, OFFSET PRBUFF
L1:     MOV [SI],AX
        INC SI
        INC SI
        LOOP L1
        POP CX,AX

        MOV AL,'P'; XXP Holds "P" screen word for this
        CALL PUT_LOC; routine's location code
        MOV AL,CMND; Only 'W' & 'S' are valid commands
;        CALL PUT_COM ; REV 3.00 TOOK THIS OUT
        CMP AL,'S'
        JNE >L1
        JMP PRNSTAT
L1:     CMP AL,'W'
        JE >L1
        MOV ERR_CHAR,'e'; Update status line error code
        CALL PUT_ERCH
        MOV AL,'N'; Send NAK byte, invalid command
        MOV BX,1100
        JMP SNAK

L1:     MOV CL,CFAUX2; set status frame to include current AUX2
        MOV [PSTATS+2],CL; As required by status definition
        MOV PLENGTH,40  ; Assume normal print

COMMENT \


        CMP CL,053h     ; Sideways print
        JNE >L1
        MOV PLENGTH,29; 29 Char frame for sideways
L1:     CMP CL,057h     ; wide print
        JNE >L1
        MOV PLENGTH,20

ENDOFCOMMENT \

L1:     MOV BX,T1
        CALL TIMER_0
        MOV AL,'A'
        CALL PUT1

        MOV CX,PLENGTH; Set up to get 40 bytes from serial bus
        MOV SI,0
        MOV AH,0        ; AH will be checksum
        LOCATION '1'
PABE:   CALL GET1       ; read a byte from port
        JNC >L1         ; carry set = timed out
        EROR 'q'
        RET

L1:     CLC
        ADC AH,AL       ; compute checksum
        ADC AH,0
        MOV [PRBUFF+SI],AL ; store data
        INC SI
        LOOP PABE

; Now, get one more byte (checksum)

        CALL GET1
        CMP AH,AL
        JE >L1
        MOV BX,1100
        EROR 'r'
        JMP SNAK        ; Send NAK byte and RET from there


L1:     MOV BX,T2
        CALL TIMER_0
        MOV AL,'A'
        CALL PUT1

; Now, if EOL is to be translated, do it

        MOV CX,PLENGTH; Write 40 bytes default
        CMP EOLFIX,0
        JE NEOLT; No EOL translation
        CALL DO_FIX_IT


; Now send the  data from buffer to printer or screen
; PRNDEV will contain handle of selected display, 1 for screen,
; 4 for printer:

NEOLT:
        LOCATION '4'
        PUSH CX

; Strip high bit if appropriate:

        CMP PRNMASK,01111111xB
        JNE NOSTRIP
        MOV CX,PLENGTH
        MOV SI,OFFSET PRBUFF
L1:     AND BYTE PTR [SI],01111111xB
        INC SI
        LOOP L1

NOSTRIP:
        CMP CONV_TAB, 0; 3.07
        JE >L2
        MOV CX, PLENGTH
        MOV SI, PRBUFF
B1:     CMP B[SI], 07Fh ; ATASCII tab
        JNE >L3
        MOV B[SI], 09 ; Standard ASCII tab
L3:     INC SI
        LOOP B1

; REV 2.4 CHANGE: if real printer, get status via BIOS
; and send error STATUS if printer is in error status

L2:     CMP PRNDEV,4; Is it real printer we're talking about?
        JNE ABW
        CALL GET_PSTAT; Get printer status in AH
        AND AH,00101000xB; No ERROR, not out of paper
        JZ >L1
        MOV BX,250
        CALL TIMER_0
        MOV AL,'E'; Error status
        CALL PUT1
        POP CX
        EROR 's'
        RET

; time out if printer doesn't respond in 7.5 seconds
; BELOW 255 WAS 135 BEFORE REV 3.13

L1:     MOV VARBL,270; For 7.5 seconds; REV 3.13: TRY 15 SEC
L1:     CMP VARBL,0
        JNE ABV
        MOV ERR_CHAR,'p'        ; 'P' in error field for time-out
        CALL PUT_ERCH
        POP CX
        RET

ABV:    CALL ONE_TIK; Wait 55ms between status calls
        CALL GET_PSTAT; Check for timeout
        AND AH,10000000xB
        JE L1; Busy printer

ABW:    POP CX
        MOV BX,PRNDEV
        MOV AH,040h
        PUSH CS
        POP DS
        MOV DX, OFFSET PRBUFF
        CMP PRNDEV,4; Real printer?; THIS TIME DELAY FROM REV 2.10
        JNE >L1
        PUSH AX
        MOV AX,T8
   MOV VARBL,AX; Delay for each record to printer
   POP AX
L1:   CMP VARBL,0
   JNE L1
        MOV CRITIC,0; No critical error
        LOCATION '5'
        INT 021h; Carry will be set if error
        CMP CRITIC,0
        JE >L1
        EROR 't'
        RET; Don't send "C" if critical error ignored

L1: CMP CX,AX;  ***** REV 2.7 CHECK FOR DISK FULL ERROR *******
        JE >L1
        CMP APRNDEV,'F'; Are we printing to a file?
        JNE >L1
        MOV AL,'N'
        CALL PUT1

        PSTATUS DISKFULL, ATTR10
        TICKS 72
        CALL PRINT_THRU; Close file and disable PRINT_THRU
        RET


L1: MOV BX,T3

        CALL TIMER_0
        MOV AL,'C'
        CALL PUT1

        RET



DO_FIX_IT:
        LOCATION '2'
        PUSH DX
        PUSH CS
        POP ES
        MOV DI,OFFSET PRBUFF
        CLD; "UP" direction
        MOV AL,09Bh
        MOV CX,PLENGTH; Max # of bytes to check
        REPNE SCASB; Find EOL in string
        JE >L1
        MOV CX,40
        JNE ABU; EOL not found

; Now, count how many more EOL's there are:

L1:     PUSH DI         ; Points past first EOL
        PUSH CX         ; Ref count for first finding
        REPE SCASB      ; Continue scan until NOT EOL
        POP DX          ; CX decrements by 1 + number found
        SUB DX,CX       ; Give count of number found
        MOV CX,DX
        POP DI          ; Points to 1 + first found
        AND CX,CX       ; If EOL was 40th byte found, CX will = 0
        JNZ >L1           ; And an adjustment is needed for loop
        INC CX
L1:    DEC DI          ; adjust

ABX:    MOV BYTE PTR [DI],13    ; CR
        INC DI
        CMP LF_TOO,0    ; If 0, just do CR, not LF
        JE >L1
        MOV BYTE PTR [DI],10    ; LF
        INC DI
;L1:     MOV BYTE PTR [DI],' '   ; Space CANCELLED REV 2.8
;    INC DI
L1:  LOOP ABX        ; Repeat for # of EOL's

; In this mode (850 style), ignore bytes after 09bH
; I will allow > 40 if the CR/LF translations make
; total > 40

        MOV CX,DI
;    INC CX  ; EXPERIMENTALLY FOUND CX TOO BIG BY 1 REV 2.8
        SUB CX,OFFSET PRBUFF; Get # of bytes to print, incl. CR/LF/spc

ABU:    POP DX
        RET

; This routine gets the printer's status via BIOS function

GET_PSTAT:
        LOCATION '3'
        PUSH DX
        MOV AH,02; Get status function
        MOV DX,0; Printer # 0 (I guess)
        INT 017h
        POP DX
        RET

PRNSTAT:
        LOCATION '6'
        MOV BX,T1
        CALL TIMER_0
        MOV AL,'A'
        CALL PUT1

; REV 2.4 CHANGE: if real printer, get status via BIOS
; and send error STATUS if printer is in error status

        CMP PRNDEV,4; Is it real printer we're talking about?
        JNE >L1
        CALL GET_PSTAT; Get printer status in AH
        AND AH,00101000xB; No ERROR, not out of paper
        JZ >L1
        MOV BX,250
        CALL TIMER_0
        MOV AL,'E'; Error status
        CALL PUT1
        RET

L1:     MOV BX,T4
        CALL TIMER_0
        MOV AL,'C'
        CALL PUT1

        MOV BX,T5
        CALL TIMER_0; REV 1.08

        MOV CX,04       ; 4 bytes
        MOV BL,0
L1:     MOV SI,CX
        MOV AL, [PSTATS-1][SI]
        CLC
        ADC BL,AL       ; checksum
        ADC BL,0        ; plus carry
        CALL PUT1A
        LOOP L1
        MOV AL,BL
        CALL PUT1
        RET

; Sub. to put a CR and LF to the printer:

CRLF2P:
        MOV BX,4; handle for printer
        MOV AH,040h
        MOV CX,2
        MOV DX,OFFSET CRLF
        INT 021h
        RET

; A routine to close the printer output file, if one is open

CLOSPFIL:
        CMP [APRNDEV],'F'
        JNE >L1
        CMP [PRNDEV],5; Don't wanna close screen or printer...
        JB >L1
        PSTATUS ACPF, ATTR9
        MOV BX,PRNDEV; up shop
        MOV AH,03Eh; Close file
        INT 021h
        TICKS 15
        MOV APRNDEV,0
L1:     RET



