;====================================================================== ; video control routines ;======================= ; ; Control program for Morrow Terminal ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; ; Written by David Block and Jim Kearney (September 1983) ; CTRLTAB DW RTN,RTN,RTN,RTN,RTN,RTN,RTN,BELL DW BS,TAB,LF,US,FS,CR,RTN,RTN DW RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN DW RTN,RTN,CLRSCR,ESC,RTN,RTN,HOME,NEWLIN ;---------------------------------------------------------------------- ; if monitor mode, print the character otherwise do the action ;------------------------------------------------------------- ; CONTROL:BIT MONITOR ; see if monitor mode enabled BPL DOCON ; if (monitor mode) enabled LDY #0 ; last char wasn't escape, is this???? CMP #$1B BNE SETRCVD ; if ( not escape ), then set escrcvd to 0 LDY #$FF ; else, set for escrcvd true SETRCVD:STY ESCRCVD OMON: LDY ESCRCVD ; see if last char was escape BEQ NOTCLR ; if escrcvd = 0, then last char not escape CMP #'X' ; else, see if this is a CLRMON command BNE NOTCLR ; if (not CLRMON) then branch, else LDA #0 ; clear escrcvd STA ESCRCVD JMP CLRMON ; clear monitor mode, and return NOTCLR: JSR OUTCHR ; put character on screen JMP SETPOS ; update cursor location, and return DOCON: AND #%11111 ; else, perform control code operation ASL A ; compute an index into control code vector table TAX LDA CTRLTAB,X ; set up vector for indirect jump STA CODE LDA CTRLTAB+1,X STA CODE+1 JMP (CODE) ; and execute control code RTN: RTS OUTC: EQU $ DISPLAY:LDX NSEQ ; are we getting a sequence? BEQ NORMCH ; if not, then normal character handling STA SQNC-1,X ; else, store character for sequence DEX ; update number of characters left in sequence STX NSEQ BNE RTN ; if ( entire sequence not received) then return JMP (CODE) ; else, sequence ready to process, so do it ; normal character input comes here. On entry, A reg = character NORMCH: LDX ATTRIB ; get the current atribute setting CMP #' ' ; if ( rcv'd character) < 20h BCC CONTROL ; then use control handler LDY GRAPHMD ; check if graphics enabled BEQ NOTGRAF ; if (graphics enabled) CMP #'?' ; see if char in range of 'A' to 'P' BCC NOTGRAF ORA #$80 ; convert to graphics char if 'A' to 'P' NOTGRAF:JMP OMON ; else, put character on screen, and update cursor BELL: LDX BAUD BPL NOINPT ; nothing from keyboard, so beep. JSR GETKEY ; else, get the key from keyboard before beeping JMP BELL ; wait for settle NOINPT LDA #BEEP ; BEEP! BEEP! JMP KBRDOUT ;UNLOCK:LDA #$0 ; STA LOCKMD ; re-enable keyboard interrupts ; LDA #LOCKOFF ; turn off keyboard lock LED ; JMP KBRDOUT ;LOCK: LDA #$FF ; STA LOCKMD ; set keyboard lock mode ; LDA #LOCKON ; turn on keyboard lock LED ; JMP KBRDOUT TAB: LDA COLMN ; tab over 8 spaces AND #$F8 CLC ADC #8 CMP #80 BNE TABOK LDA #0 STA COLMN JMP LF TABOK: STA COLMN JMP SETCUR LINBAS: ASL A ; compute index into line table TAX LDA LINES,X ; 16 bit add of line multiplier..... CLC ; and Screen base ADC SCBASE STA LB ; low byte the same for CRAM and ARAM LDA LINES+1,X ADC SCBASE+1 STA TEMP ; high byte of 16 bit add AND #%111 ; make sure not more than 2K ORA #HIGH(CRAM) ; compute high byte of CRAM Line base STA LB+1 ; save it RTS SETCUR: LDA ROW ; calculate cursor offset- to be indexed by (),ch JSR LINBAS ; figure the screen position SETPOS: CLC ; set cursor position register of CRTC LDA LB ADC COLMN LDX #15 STX CRTC STA CRTC+1 LDA TEMP ADC #0 DEX STX CRTC STA CRTC+1 RTS LF: LDA ROW ; Line feed CMP #23 ; check if scroll req'd BEQ SCROLL ; if yes, then scroll INC ROW ; else, just set new row JMP SETCUR ; and put the cursor there SCROLL: SEI ; Scroll screen LDA SCBASE CLC ADC #80 STA SCBASE LDA SCBASE+1 ; new scbase = old scbase + 80 ADC #0 AND #%111 ; wrap it around STA SCBASE+1 JSR SETCUR ; set cursor register of CRTC LDX #13 LDA SCBASE ; set starting reg of CRTC STX CRTC STA CRTC+1 DEX LDA SCBASE+1 STX CRTC STA CRTC+1 CLI CLRLIN: LDX #80 ; now, clear last line BNE CL0 CLEOLA: EOR #$FF SEC ADC #80 TAX CL0: LDY #79 CLEOL1: LDA #' ' STA (LB),Y LDA ATTTAB+0 JSR WRATT DEY DEX BNE CLEOL1 CLEOL2: RTS CR: LDA #0 ; Carriage return STA COLMN JMP SETPOS ; on entry, X = current attribute being set, and A = character to display OUTCHR: JSR XLTIN ; translate input char if req'd LDY COLMN STA (LB),Y ; put char on screen TXA JSR WRATT ; set it's attribute INY CPY #80 ; see if auto LF req'd BNE OUTC2 ; if not, just set column for next char AUTOLF: LDA #0 ; else, set column 0 STA COLMN JMP LF ; and perform a line feed OUTC2: STY COLMN RTS CLRSCR: LDA #8 ; set to clear 8 pages of CRAM STA TEMP LDA #HIGH(CRAM) ; init start of ARAM and CRAM STA LB+1 LDA #HIGH(ARAM) STA AB+1 LDY #0 STY LB STY AB LDA CLRCHAR ; get character to clear CRAM to CLR2: STA (LB),Y ; clear a location INY ; until 1 page is done BNE CLR2 INC LB+1 ; point to next page DEC TEMP ; loop until 8 pages are cleared BNE CLR2 LDA #8 ; set to clear 8 pages of ARAM STA TEMP LDY #0 LDA ATTTAB+0 ; clear ARAM to normal video CLR3: STA (AB),Y ; clear a location INY ; until 1 page is done BNE CLR3 INC AB+1 ; point to next page DEC TEMP ; loop until 4 pages have been cleared BNE CLR3 HOME: LDA #0 ; put cursor in home position STA ROW ; ROW = COLMN = 0 STA COLMN JMP SETCUR ; set new cursor position BS: LDX COLMN LDY ROW ; get the current row DEX BPL BS2 ; if on same line, branch LDX #79 ; else, set last column of line above DEY BPL BS2 LDY #0 LDX #0 BS2: STX COLMN STY ROW JMP SETCUR FS: LDX COLMN ; forespace LDY ROW INX CPX #80 BCC FS2 LDX #0 INY CPY #24 BCC FS2 LDY #23 LDX #79 FS2: STX COLMN STY ROW JMP SETCUR US: DEC ROW ; Up a line BPL US2 LDA #0 STA ROW US2: JMP SETCUR CLREOL: LDA COLMN ; clear to end of line JMP CLEOLA CLREOS: LDA COLMN ; clear to end of screen JSR CLEOLA SEC LDA #23 SBC ROW BEQ CLEO2 STA TEMP CLA: LDA LB CLC ADC #80 STA LB BCC CLB INC LB+1 CLB: JSR CLRLIN DEC TEMP BNE CLA CLEO2: JMP SETCUR NEWLIN: JSR CR ; carriage return line feed JMP LF CALCS: PHA CLC ; calculate source address for character move ADC LB2 STA CHARS LDA #0 ADC LB2+1 AND #%00110111 ; wrap around for 2000 - 27FF address range STA CHARS+1 PLA JMP CALCATT2 CALCD: PHA CLC ; calculate destination address for character move ADC LB STA CHARD LDA #0 ADC LB+1 AND #%00110111 ; wrap around for 2000 - 27FF address range STA CHARD+1 PLA JMP CALCATT WRATT: STA TEMPATT ; save attribute value TYA PHA ; save character index JSR CALCATT ; calculate address for attribute LDY #0 LDA TEMPATT ; get back attribute STA (NEWAB),Y ; write attribute back out PLA TAY RTS CALCATT CLC ; 16 bit add of LB and Y reg ADC LB STA NEWAB ; save pointer LDA #0 ADC LB+1 SEC ; subtract CRAM base address SBC #$20 AND #%00000111 ; Mask for 2K wrap around CLC ; NEWAB = absolute addr in 0 - 2K for att. ; now, make NEWAB actual address ADC #$08 ; add 800H offset to attribute address STA NEWAB+1 RTS CALCATT2 CLC ; 16 bit add of LB and Y reg ADC LB2 STA NEWAB2 ; save pointer LDA #0 ADC LB2+1 SEC ; subtract CRAM base address SBC #$20 AND #%00000111 ; Mask for 2K wrap around CLC ; NEWAB = absolute addr in 0 - 2K for att. ; now, make NEWAB actual address ADC #$08 ; add 800H offset to attribute address STA NEWAB2+1 RTS PAGE ;---------------------------------------------------------------------- ; Data Area ;---------- ; LINES DW 0*80, 1*80, 2*80, 3*80, 4*80, 5*80, 6*80, 7*80 DW 8*80, 9*80,10*80,11*80,12*80,13*80,14*80,15*80 DW 16*80,17*80,18*80,19*80,20*80,21*80,22*80,23*80 XLTVCT ; TRANSLATE TABLES FOR FOREIGN CHARACTER SETS DW USXKI-1 ; Pointers to U.S. translate tables DW USXKO-1 DW USXHI-1 DW USXHO-1 DW UKXKI-1 ; Pointers to U.K. translate tables DW UKXKO-1 DW UKXHI-1 DW UKXHO-1 DW FRXKI-1 ; Pointers to French translate tables DW FRXKO-1 DW FRXHI-1 DW FRXHO-1 DW GEXKI-1 ; Pointers to German translate tables DW GEXKO-1 DW GEXHI-1 DW GEXHO-1 DW SPXKI-1 ; Pointers to Spanish translate tables DW SPXKO-1 DW SPXHI-1 DW SPXHO-1 DW DAXKI-1 ; Pointers to Danish / Norwegian translate tables DW DAXKO-1 DW DAXHI-1 DW DAXHO-1 DW FIXKI-1 ; Pointers to Finnish / Swedish translate tables DW FIXKO-1 DW FIXHI-1 DW FIXHO-1 DW ITXKI-1 ; Pointers to Italian translate tables DW ITXKO-1 DW ITXHI-1 DW ITXHO-1 USXKI USXKO USXHI USXHO ; no translate tables for U.S. UKXKI ; U.K. translate tables for key -> ASCII (search) UKXKO ; U.K. translate tables for key -> ASCII (replace) ; no table since no xlation needed UKXHI ; translate tables for host input (SEARCH) FRENCH,UK,FIN,SPAN FRXHI ; and Danish. DB '#' FIXHI DB '~' SPXHI DB '@' DAXHI DB '[\]{|}' DB '`^' GEXHI DB '|~' ITXHI DB '<>@[\]{}^`*#' UKXHO DB $87 FRXKI ; French translate table for key -> ASCII (search) DB '!1@2#3$4%5^6&7*8(9)0_-+=?/QqWw{[}]~`Aa:;"' DB $27,'|\ZzMm<,>.' FRXKO ; French translate table for key -> ASCII (replace) DB '1&2',$7B,'3"4',$27,'5(6',$5D,'7',$7D,'8!9',$5C,'0' DB $40,$5B,')_-+=AaZz',$7E,'^*/>.?/' GEXKO DB '"',$40,'&/()=?',$7E,'\/Zz',$5D,$7D,'*+',$3E,$3C,$5C,$7C DB $5B,$7B,$27,'#Yy;:._-' GEXHO DB $95,$97,$8F,$89,$80,$90,$91,$92,$94,$96,$93 SPXKI ; Spanish translate tables DB '@_-+={[}]:;"',$27,'|\?/' SPXKO DB $40,'+=?/',$5D,$5B,'"',$27,$5C,$7C,':;',$7D,$7B,'_-' SPXHO DB $80,$9C,$9D,$9E,$89,$A0,$8A DAXKI ; Danish/Norwegian translate tables DB '_-{[}]:;"',$27,'|\?/+=' DAXKO DB '+=',$5D,$7D,'"',$27,$5B,$7B,$5C,$7C,':;_-?/' DAXHO DB $81,$82,$83,$84,$85,$86 FIXKI ; Finish/Swedish translate tables DB '_-+={[}]:;"',$27,'|\?/' FIXKO DB '+=?/',$5D,$7D,'"',$27,$5C,$7C,$5B,$7B,':;_-' FIXHO DB $96,$9F,$90,$91,$83,$94,$95,$86,$8B,$92 ITXKI ; Italian translate tables DB '!1@2#3$4%5^6&7*8(9)0_-+=Ww{[}]~`:;"',$27,'|\ZzMm<,>.?/' ITXKO DB '1&2"3',$27,'4(5',$5D,'6',$5B,'7)8+9',$3C,'0',$23,$60,$7B DB '_-Zz=',$5E,'~|',$7D,$3E,'Mm%',$2A,$5C,'$Ww?,.;/:!',$40 ITXHO DB $88,$98,$99,$8D,$87,$8A,$A5,$9B,$9A,$8E,$8C,$8B ;---------------------------------------------------------------------- ; tables of function code bytes to be sent by function keys ;---------------------------------------------------------- ; ; FTABLE is for all function keys except F1-F10 ; F110TBL is for function keys F1-F10 ; FTABLE ; unshifted DB $4A,$4B,$4C,$4D,$4E ; UP, DOWN, LEFT, RIGHT, HOME DB $49,$4F,$00,$00,$00 ; ERASE, HELP, SCROLL, SETUP, BREAK DB $00,$00,$00 ; CAPS LOCK, TAB, SPACE DB 0,0,0 ; FREE SPACE DB $30,$31,$32,$33,$34 ; KEYPAD 0, 1, 2, 3, 4 DB $35,$36,$37,$38,$39 ; KEYPAD 5, 6, 7, 8, 9 DB $2A,$2D,$3A,$3D ; KEYPAD PERIOD, ENTER, MINUS, COMMA DB 0,0 ; FREE SPACE ; Control key, and function DB $0A,$0B,$0C,$0D,$0E ; UP, DOWN, LEFT, RIGHT, HOME DB $09,$0F,$00,$00,$00 ; ERASE, HELP, SCROLL, SETUP, BREAK DB $00,$1B,$00 ; CAPS LOCK, TAB, SPACE DB 0,0,0 ; FREE SPACE DB $10,$11,$12,$13,$14 ; KEYPAD 0, 1, 2, 3, 4 DB $15,$16,$17,$18,$19 ; KEYPAD 5, 6, 7, 8, 9 DB $2C,$2F,$3C,$3F ; KEYPAD PERIOD, ENTER, MINUS, COMMA DB 0,0 ; FREE SPACE ; Shift key, and function DB $6A,$6B,$6C,$6D,$6E ; UP, DOWN, LEFT, RIGHT, HOME DB $69,$6F,$00,$00,$00 ; ERASE, HELP, SCROLL, SETUP, BREAK DB $00,$1A,$00 ; CAPS LOCK, TAB, SPACE DB 0,0,0 ; FREE SPACE DB $20,$21,$22,$23,$24 ; KEYPAD 0, 1, 2, 3, 4 DB $25,$26,$27,$28,$29 ; KEYPAD 5, 6, 7, 8, 9 DB $2B,$2E,$3B,$3E ; KEYPAD PERIOD, ENTER, MINUS, COMMA DB 0,0 ; FREE SPACE F110TBL ; Unshifted DB $40,$41,$42,$43,$44 ; F1-F5 DB $45,$46,$47,$48 ; F6-F9 DB $49,$5C,$5D,$5E,$5F,0,0 ; F10,FA,FB,FC,FD,FREE SPACE ; Control DB $00,01,$02,$03,$04 ; F1-F5 DB $05,$06,$07,$08 ; F6-F9 DB $09,$1C,$1D,$1E,$1F,0,0 ; F10,FA,FB,FC,FD,FREE SPACE ; Shift DB $60,$61,$62,$63,$64 ; F1-F5 DB $65,$66,$67,$68 ; F6-F9 DB $69,$7C,$7D,$7E,$7F,0,0 ; F10,FA,FB,FC,FD,FREE SPACE PAGE END