;TTYHAN.P65 BY ERIC SMITH ; ;HANDLER FOR BAUDOT TELETYPE THROUGH MSB OF AN OUTPUT PORT .DEF ORIGIN=$B480 .DEF BUFADR=$BA59 .DEF BUFEND=$BD00 .DEF PORT=$FE00 .DEF PTR=$00 .DEF PAGLEN=60 .DEF MARGIN=6 .DEF WIDTH=72 .DEF WIDO8=9 .DEF DEVTAB=$BFC0 .DEF DEV=2 .DEF DEVOFS=DEV+DEV .DEF REENT=$BF06 .LOC ORIGIN TTYHAN: JMP ERROR ;OPENI NOT SUPPORTED JMP OPENO JMP ERROR ;CHIN NOT SUPPORTED JMP CHOUT JMP CLOSE ERROR: SEC RTS .PAGE ;OPEN PRINTER DEVICE OPENO: JSR RESPAG ;RESET TO TOP OF PAGE JMP FLUSH ;DISCARD BUFFER CONTENTS ;CLOSE PRINTER ROUTINE CLOSE: LDA# $0C ;ASCII FF JSR CHOUT ;LEAVE PAPER AT PAGE BOUNDARY DCMP# BUFPTR,BUFADR+1 ;IS THERE ANYTHING IN THE BUFFER? BGE PRBUF ; YES, PRINT IT DUMMY1: CLC RTS ;GENERAL OUTPUT A BYTE ENTRY CHOUT: AND# $7F ;MASK OFF HIGH BIT PHA ;SAVE THE CHARACTER DMOV BUFPTR, PTR ;MOVE POINTER TO ZERO PAGE LDY# $00 ;NO INDEX PLA ;GET CHARACTER BACK STA@Y PTR ;STORE CHARACTER IN BUFFER DINC BUFPTR ;BUMP POINTER DCMP# BUFPTR,BUFEND ;IS BUFFER FULL? BLT DUMMY1 ; NO, RETURN TO CALLER PRBUF: LDY# 100 NXTPLS: MOV# $7F,PORT LDA# 42 ;4.99 MSEC JSR TIMER MOV# $FF,PORT LDA# 91 ;21.944 MSEC JSR TIMER DEY BNE NXTPLS LDA# $00 ;INDICATE UNKNOWN STA CASE ; SHIFT STATUS DMOV# BUFADR,PTR GETCHR: LDY# $00 LDA@Y PTR PHA AND# $60 BNE PRTCHR PLA CMP# $0D ;RETURN? BEQ DOCR ; HANDLE IT CMP# $09 ;TAB? BEQ DOTAB ; GO TO IT CMP# $07 ;BELL? BEQ DOBEL ; RING IT CMP# $0C ;FORM FEED? BNE PRNEXT ; NO, IGNORE IT DOFF: JSR WFEED ;ADVANCE LINE LDA COUNT ;AT PAGE TOP NOW? CMP# PAGLEN BNE DOFF ;LOOP UNTIL COUNT ZERO JMP PRNEXT DOTAB: LDA# $10 ;SPACE JSR PRIOUT ;AT LEAST ONE SPACE LDA HPOS ;NOW CHECK HORIZONTAL AND# $07 ;FOR A TAB STOP BNE DOTAB ;AND LOOP IF REQUIRED JMP PRNEXT DOBEL: LDA# $51 ;BELL JSR PRCHAR JMP PRNEXT DOCR: JSR ENDLIN JMP PRNEXT PRTCHR: PLA CMP# $40 BLT FIG AND# $1F FIG: TAX LDAX XLTTAB NRMCHR: JSR PRIOUT PRNEXT: DINC PTR DCMP PTR,BUFPTR BLT GETCHR FLUSH: DMOV# BUFADR,BUFPTR CLC RTS ;OUTPUT A PRINTING CHARACTER ; Keep track of horizontal position, print accumulated ; overstrikes and advance to next line if necessary. ; If high bit of char set, set overstrike bit. Fall ; through to PRCHAR. PRIOUT: PHA ;Save char. temp INC HPOS ;Next position LDA HPOS CMP# WIDTH+1 ;End of line? BLT NOWRAP ; No JSR ENDLIN ; Yes, advance to next line ; line, print overstrikes if ; necessary NOWRAP: ASL OSMSK BCC NOOF INC OSIDX INC OSMSK NOOF: PLA ;Get char back BPL PRCHAR ;If MSB clear, no overstrike PHA LDX OSIDX LDA OSMSK ORAX OSFLAG STAX OSFLAG MOV HPOS,MAXPOS PLA AND# $7F ;Clear MSB for start bit ;LOW LEVEL CHARACTER OUTPUT ; If low two bits are nonzero and not equal to current ; case, shift case appropriately and change flag. Fall ; through to SERIAL. PRCHAR: PHA ;Save char temp AND# $03 ;Mask required case BEQ SENDIT ; if zero, don't care CMP CASE ;required, current case same? BEQ SENDIT ; yes STA CASE ; no, save it for later TAX ;index into shift code table LDAX CASE ;get appropriate shift code JSR SERIAL ;send it out SENDIT: PLA ;get char back ORA# $03 ;set two LSB for stop bits ;SERIAL OUTPUT ROUTINE ; Take code in A and shift out serially over MSB ; of output port, MSB first. MSB assumed zero for ; start bit, two LSB assumed one for stop bits. SERIAL: LDX# 7 ;bit count NXTBIT: PHA ;save current code STA PORT ;put MSB into output port LDA# 102 ;27.4 MSEC JSR TIMER ;one bit time delay PLA ;get code back ASLA ;shift next bit into place DEX ;decrement bit count BNE NXTBIT ;if not done, loop back RTS ; else return ENDLIN: LDA HPOS BEQ WFEED LDA# $08 ;CR JSR PRCHAR LDY# $00 STY OSIDX INY STY OSMSK LDY MAXPOS BEQ WFEED LDA# $00 ;NULL JSR PRCHAR OSLOOP: LDX OSIDX LDA OSMSK ANDX OSFLAG BEQ NOOS LDA# $5D ;'/' BNE PROS NOOS: LDA# $10 ;' ' PROS: JSR PRCHAR ASL OSMSK BCC NOOVFL INC OSIDX INC OSMSK NOOVFL: DEY BPL OSLOOP LDA# $08 ;CR JSR PRCHAR WFEED: LDA# $20 ;LF JSR PRCHAR LDA# $00 ;NULL JSR PRCHAR DEC COUNT BNE RESLIN LDA# MARGIN STA COUNT MRGLOP: LDA# $20 ;LF JSR PRCHAR DEC COUNT BNE MRGLOP RESPAG: LDA# PAGLEN STA COUNT ;STORE IN COUNTER RESLIN: LDA# 0 LDX# HPOS-OSFLAG RSLLP: STAX OSFLAG DEX BNE RSLLP LDA# $80 STA OSMSK LDA# $FF STA OSIDX RET: RTS TIMER: SEC ;DELAY (26+27A+5A^2)/2 USEC TIMER2: PHA TIMER3: SBC# $01 BNE TIMER3 PLA SBC# $01 BNE TIMER2 RTS .PAGE XLTTAB: .BYTE $E2 ;'@' .BYTE $62 ;'A' .BYTE $4E ;'B' .BYTE $3A ;'C' .BYTE $4A ;'D' .BYTE $42 ;'E' .BYTE $5A ;'F' .BYTE $2E ;'G' .BYTE $16 ;'H' .BYTE $32 ;'I' .BYTE $6A ;'J' .BYTE $7A ;'K' .BYTE $26 ;'L' .BYTE $1E ;'M' .BYTE $1A ;'N' .BYTE $0E ;'O' .BYTE $36 ;'P' .BYTE $76 ;'Q' .BYTE $2A ;'R' .BYTE $52 ;'S' .BYTE $06 ;'T' .BYTE $72 ;'U' .BYTE $3E ;'V' .BYTE $66 ;'W' .BYTE $5E ;'X' .BYTE $56 ;'Y' .BYTE $46 ;'Z' .BYTE $F9 ;'[' .BYTE $CE ;'\' .BYTE $A5 ;']' .BYTE $F2 ;'^' .BYTE $9D ;'_' .PAGE .BYTE $10 ;' ' .BYTE $59 ;'!' .BYTE $45 ;'"' .BYTE $15 ;'#' .BYTE $49 ;'$' .BYTE $B9 ;'%' .BYTE $2D ;'&' .BYTE $69 ;''' .BYTE $79 ;'(' .BYTE $25 ;')' .BYTE $AD ;'*' .BYTE $E1 ;'+' .BYTE $19 ;',' .BYTE $61 ;'-' .BYTE $1D ;'.' .BYTE $5D ;'/' .BYTE $35 ;'0' .BYTE $75 ;'1' .BYTE $65 ;'2' .BYTE $41 ;'3' .BYTE $29 ;'4' .BYTE $05 ;'5' .BYTE $55 ;'6' .BYTE $71 ;'7' .BYTE $31 ;'8' .BYTE $0D ;'9' .BYTE $39 ;':' .BYTE $3D ;';' .BYTE $A6 ;'<' .BYTE $C2 ;'=' .BYTE $AE ;'>' .BYTE $4D ;'?' .PAGE CASE: .BYTE ;CURRENT CASE .BYTE $6F ;FIGURE SHIFT CODE .BYTE $7F ;LETTER SHIFT CODE OSMSK: .BYTE OSIDX: .BYTE OSFLAG: .WORD ;WIDO8 BYTES .WORD .WORD .WORD .BYTE MAXPOS: .BYTE HPOS: .BYTE COUNT: .BYTE BUFPTR: .WORD .LOC DEVTAB+DEVOFS ;LINK HANDLER INTO DEVICE TABLE .WORD TTYHAN .END