; 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