;====================================================================== ; video control routines (9_Nov_84) ;================================== ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; Written by David Block and Jim Kearney (September 1983) ; ;---------------------------------------------------------------------- ; Index (9_Nov_84) ;----------------- ; ; BELL Bell Code ; BS BackSpace ; TAB Tab ; LF Line Feed ; US Up Space ; FS ForeSpace ; CR Carriage Return ; CLRSCR Clear Screen ; ESC Escape ; HOME Home ; NEWLIN NewLine (Carriage Return Line Feed) PAGE ;---------------------------------------------------------------------- ; 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: 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 PAGE ;---------------------------------------------------------------------- ; Ring the Bell ;-------------- ; BELL: LDX BAUD BPL BLSK1 ;nothing from keyboard, so beep. JSR GETKEY ;else, get the key from keyboard before beeping JMP BELL ;wait for settle BLSK1: LDA #BEEP ;BEEP! BEEP! JMP KBRDOUT ;---------------------------------------------------------------------- ; BackSpace ;---------- ; BS: LDX COLMN LDY ROW ;get the current row DEX BPL BSSK1 ;if on same line, branch LDX #79 ;else, set last column of line above DEY BPL BSSK1 LDY #0 LDX #0 BSSK1: STX COLMN STY ROW JMP SETCUR ;---------------------------------------------------------------------- ; Tab ;---- ; TAB: LDA COLMN ;tab over 8 spaces AND #$F8 CLC ADC #8 CMP #80 BNE TABSK1 LDA #0 STA COLMN JMP LF TABSK1: STA COLMN JMP SETCUR PAGE ;---------------------------------------------------------------------- ; Line Feed ;---------- ; LF: LDA ROW ;Line feed CMP #23 ;check if scroll req'd BEQ LFSK1 ;if yes, then scroll INC ROW ;else, just set new row JMP SETCUR ;and put the cursor there LFSK1: 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 JMP CLRLIN ;---------------------------------------------------------------------- ; UpSpace ;-------- ; US: DEC ROW ;Up a line BPL USSK1 LDA #0 STA ROW USSK1: JMP SETCUR PAGE ;---------------------------------------------------------------------- ; ForeSpace ;---------- ; FS: LDX COLMN ;forespace LDY ROW INX CPX #80 BCC FSSK1 LDX #0 INY CPY #24 BCC FSSK1 LDY #23 LDX #79 FSSK1: STX COLMN STY ROW JMP SETCUR ;---------------------------------------------------------------------- ; Carriage Return ;---------------- ; CR: LDA #0 ;Carriage return STA COLMN JMP SETPOS PAGE ;---------------------------------------------------------------------- ; Clear Screen (9_Nov_84) ;------------------------ ; CLRSCR: LDA #HIGH CRAM ;init start of ARAM and CRAM STA LB+1 LDA #HIGH ARAM STA AB+1 LDY #0 STY LB STY AB LDX #8 ;X:= Page Counter LDA CLRCHAR ;A:= Character to clear CRAM to CLCLP1: STA (LB),Y ;Repeat Repeat Clear a Location INY ; Increment the Index BNE CLCLP1 ; Until (Index wraps around) INC LB+1 ; Increment the Page Pointer DEX ;Until (8 pages are cleared) BNE CLCLP1 LDX #8 ;set to clear 8 pages of ARAM LDY #0 LDA ATTTAB+0 ;A:= Character to clear ARAM to (normal video) CLCLP2: STA (AB),Y ;Repeat Repeat Clear a location INY ; Increment the Index BNE CLCLP2 ; Until (Index wraps around) INC AB+1 ; Increment the Page Pointer DEX ;Until (8 pages have been cleared) BNE CLCLP2 JMP HOME ;Home the Cursor ;---------------------------------------------------------------------- ; Escape Recieved ;---------------- ; ESC: LDA #1 ;escape handler STA NSEQ ;set up to save next char LDA #LOW ESCHAND ;routine to handle next char STA CODE LDA #HIGH ESCHAND STA CODE+1 RTS ;---------------------------------------------------------------------- ; Home the Cursor ;---------------- ; HOME: LDA #0 ;put cursor in home position STA ROW ;ROW = COLMN = 0 STA COLMN JMP SETCUR ;set new cursor position ;---------------------------------------------------------------------- ; Print a Carriage Return followed by a Line Feed ;------------------------------------------------ ; NEWLIN: JSR CR ;carriage return line feed JMP LF PAGE ;---------------------------------------------------------------------- ; Set the Cursor Position ;------------------------ ; SETCUR: LDA ROW JSR LINBAS ;calculate cursor offset-to be indexed by (),ch ; 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 ;---------------------------------------------------------------------- ; Calculate the Line Base ;------------------------ ; 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 PAGE ;---------------------------------------------------------------------- ; Clear Line Primative ;--------------------- ; CLRLIN: LDX #80 ; now, clear last line BNE CLLSK1 CLEOLA: EOR #$FF SEC ADC #80 TAX CLLSK1: LDY #79 CLLP1: LDA #' ' STA (LB),Y LDA ATTTAB+0 JSR WRATT DEY DEX BNE CLLP1 RTS ;---------------------------------------------------------------------- ; on entry, X = current attribute being set & 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 OUTSK1 ; if not, just set column for next char LDA #0 ; else, set column 0 STA COLMN JMP LF ; and perform a line feed OUTSK1: STY COLMN RTS PAGE ;---------------------------------------------------------------------- ; Write an Attribute ;------------------- ; 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 PAGE ;---------------------------------------------------------------------- ; Calculate Destination Address ;------------------------------ ; 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 ; Calculate Attribute ;-------------------- ; 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 PAGE ;---------------------------------------------------------------------- ; Calculate Source Address ;------------------------- ; 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 ; Calculate Attribute 2 ;---------------------- ; 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 ;---------------------------------------------------------------------- ; Keyboard Lock/UnLock ;--------------------- ; ;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 PAGE ;---------------------------------------------------------------------- ; Data Area ;---------- ; ;Control Lookup Table 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 ;Line Base Table 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 ; TRANSLATE TABLES FOR FOREIGN CHARACTER SETS XLTVCT: 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 ; French translate table for key -> ASCII (search) FRXKI: DB '!1@2#3$4%5^6&7*8(9)0_-+=?/QqWw{[}]~`Aa:;"' DB $27,'|\ZzMm<,>.' ; French translate table for key -> ASCII (replace) FRXKO: 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 ; Spanish translate tables SPXKI: DB '@_-+={[}]:;"',$27,'|\?/' SPXKO: DB $40,'+=?/',$5D,$5B,'"',$27,$5C,$7C,':;',$7D,$7B,'_-' SPXHO: DB $80,$9C,$9D,$9E,$89,$A0,$8A ; Danish/Norwegian translate tables DAXKI: DB '_-{[}]:;"',$27,'|\?/+=' DAXKO: DB '+=',$5D,$7D,'"',$27,$5B,$7B,$5C,$7C,':;_-?/' DAXHO: DB $81,$82,$83,$84,$85,$86 ; Finish/Swedish translate tables FIXKI: DB '_-+={[}]:;"',$27,'|\?/' FIXKO: DB '+=?/',$5D,$7D,'"',$27,$5C,$7C,$5B,$7B,':;_-' FIXHO: DB $96,$9F,$90,$91,$83,$94,$95,$86,$8B,$92 ; Italian translate tables ITXKI: 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 PAGE ;---------------------------------------------------------------------- ; 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 ; ; unshifted FTABLE: 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 ; Unshifted F110TBL: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