;====================================================================== ; Escape code interpretation (9_Nov_84) ;====================================== ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; ; Written by David Block and Jim Kearney (September 1983) ; ; HICHAR Print a Character in Alternate Graphics Mode ; CURSRT Set the Cursor Type ; DISREV Display the Code Revision Message ; GRAFON Graphics Mode On ; GRAFOFF Graphics Mode Off ; INVOFF Dim Video On ; INVON Dim Video Off ; CLRSCR In the Control Module ; CLRSCR In the Control Module ; ALIGN Fill the Screen with the alignment pattern ; GOTOXY Direct Cursor Addressing ; READCR Read the Cursor Location ; SCRNDIS Enable/Disable Screen Saver ; INSLIN Insert a Line ; SETATT Set a Character's Attribute ; BACKTB Back-Tab ; SETCLK Enable/Disable the Keyclick ; SETREV Enable/Disable Reverse Video Screen ; RDLPEN Read the Light Pen ; RTRV22 Restore the Last Two Lines on the Screen ; INSCHR Insert a Character ; DELLIN Delete a Line ; SAVE22 Save the Last Two Characters on the Screen ; CLREOL In the Control Module ; SETMON Set the Mointor Mode ; DELCHR Delete a Character ; CLRMON Clear the Monitor Mode ; CLREOS In the Control Module ; SETKPD Set the Applications KeyPad Mode ; CLRKPD Clear the Applications KeyPad Mode PAGE ;---------------------------------------------------------------------- ; Escape Handeler ;---------------- ; ESCHAND:AND #$7F ; mask 8th bit LDA SQNC ; process received char SEC SBC #' ' ; in $20-$5F ? BMI ESCSK1 CMP #64 ; see if valid escape code BCS ERTN ; return if invalid code TAY ; save char ASL A ; compute table index TAX LDA ESCTAB,X ; set up code address for function STA CODE LDA ESCTAB+1,X STA CODE+1 LDA ESCMOR,Y ; get number of parameters req'd ; by esc sequence STA NSEQ BNE ERTN ; wait if entire sequence not rcv'd JMP (CODE) ; no, execute it ESCSK1: LDX ATTRIB ; handle <0..31> as request to ADC #' ' ; print ASCII character JSR OUTCHR ; put char on screen JMP SETPOS ; update cursor position ERTN: RTS ;Error Return ;---------------------------------------------------------------------- ; Print a Character in Alternate Graphics Mode ;--------------------------------------------- ; HICHAR: LDA SQNC ; Get the character ORA #$80 ; set msb to select alternate character set LDX ATTRIB JSR OUTCHR ; and output the character JMP SETPOS PAGE ;---------------------------------------------------------------------- ; Set the Cursor Type ;-------------------- ; CURSRT: LDA SQNC ; set the cursor type ;Enter Here from Warm Start Code CURST2: AND #%111 ; enter here to set cursor as in A reg CMP #7 BEQ NOCSK1 STA DCURTYP ASL A TAX LDY #10 STY CRTC LDA CURTYPE,X STA CRTC+1 INY STY CRTC LDA CURTYPE+1,X STA CRTC+1 NOCSK1: RTS ;---------------------------------------------------------------------- ; Display Code Revision Message ;------------------------------ ; DISREV: LDA RVMESG ; set up for message to print STA MESG LDA RVMESG+1 STA MESG+1 JMP PRNTMSG ; print the message ;---------------------------------------------------------------------- ; Enable Graphics Mode ;--------------------- ; GRAFON: LDA #$FF STA GRAPHMD ; enable graphics mode RTS ;---------------------------------------------------------------------- ; Disable Graphics Mode ;---------------------- ; GRAFOFF:LDA #$0 STA GRAPHMD ; disable graphics mode RTS PAGE ;---------------------------------------------------------------------- ; set Normal video ;----------------- ; INVOFF: LDA ATTTAB+0 ; everything off STA ATTRIB RTS ;---------------------------------------------------------------------- ; turn DIM video on ;------------------ ; INVON: LDA ATTTAB+2 STA ATTRIB RTS ;---------------------------------------------------------------------- ; Put the Alignment Pattern on the Screen (9_Nov_84) ;--------------------------------------------------- ; ALIGN: LDA #'H' ; fill screen with "H" for alignment STA CLRCHAR JSR CLRSCR LDA #' ' STA CLRCHAR JMP SETREV PAGE ;---------------------------------------------------------------------- ; Direct Cursor Addressing ;------------------------- ; GOTOXY: LDA SQNC+1 ; Direct Cursor Addressing SEC ; Get Row, and subtract offset SBC #' ' CMP #24 ; see if out of range BCC GOTSK1 ; if not, then set new row LDA #23 ; else, set last row GOTSK1: STA ROW LDA SQNC ; get Column SEC ; subtract offset SBC #' ' CMP #80 ; check if out of range BCC GOTSK2 ; if not, then set new column LDA #79 ; else, set for last column GOTSK2: STA COLMN JMP SETCUR ; and put the cursor there ;---------------------------------------------------------------------- ; Read the Cursor's Position ;--------------------------- ; READCR LDA ROW ; get row ORA #' ' ; add offset JSR SNDINS ; put in send buffer LDA COLMN ; get column CLC ADC #' ' ; add offset JMP SNDINS ; put in send buffer ;---------------------------------------------------------------------- ; Enable/Disable Screen Saver Function ;------------------------------------- ; SCRNDIS:LDA SQNC ; enable/disable screen saver function AND #1 ; see if enable or disable BEQ SCRSK1 ; if (disable) then LDA #$FF ; set screen saver disable flag SCRSK1: STA TIMEN ; else, clear screen saver disable flag RTS PAGE ;---------------------------------------------------------------------- ; Insert a Line ;-------------- ; INSLIN: LDA #23 ; Calculate number of lines to move SEC SBC ROW BNE INSSK1 ; if (on bottom line) JMP DELL99 ; Clear the Last Line INSSK1: CLC LDA SCBASE ; calculate pointer to last line ADC #LOW(LASTLIN)+79 STA LB LDA SCBASE+1 ADC #HIGH(LASTLIN)+HIGH(CRAM) STA LB+1 SEC ; LB = last line - 80 = source for move LDA LB SBC #80 STA LB2 LDA LB+1 SBC #0 STA LB2+1 LDA #0 ; setup source and dest. for attribute move JSR CALCATT2 LDA #0 JSR CALCATT LDA ROW ; calculate number of attributes to be moved ASL A ; compute index into line table TAX SEC ; # ATTRibutes = 23 * 80 - (80 * ROW) LDA #LOW(LASTLIN) SBC LINES,X STA TRANSFR LDA #HIGH(LASTLIN) SBC LINES+1,X STA TRANSFR+1 JSR SETSD ; set source and destination pointers JSR INSMOVE ; move the characters and attributes LDA LB2 STA LB LDA LB2+1 STA LB+1 LDA ROW ; reset pointers, and then clear the line JSR LINBAS JSR DELL99 JMP SETCUR PAGE ;---------------------------------------------------------------------- ; Set a Character's Attribute ;---------------------------- ; SETATT: LDA SQNC ; get code for desired attribute AND #%111 ; lower 3 bits only TAX LDA ATTTAB,X ; get appropriate settings STA ATTRIB ; set as current attribute RTS ;---------------------------------------------------------------------- ; BackTab ;-------- ; BACKTB: LDA COLMN BEQ BAKSK1 SEC SBC #1 BMI BAKSK1 AND #$F8 STA COLMN BAKSK1: JMP SETCUR ;---------------------------------------------------------------------- ; Enable/Disable Keyclick ;------------------------ ; SETCLK LDA SQNC ; turn keyclick on or off AND #$01 ; 0 => keyclick off 1 => keyclick on BEQ SECSK1 LDA #CLCKON JMP KBRDOUT ; send keyclick on to keyboard SECSK1: LDA #CLCKOFF JMP KBRDOUT ; send keyclick off to keyboard PAGE ;---------------------------------------------------------------------- ; Set Screen to Normal/Reverse Video ;----------------------------------- ; SETREV: LDA SQNC ; set reverse/normal video AND #$01 ; 0 => normal, 1 => reverse BEQ SERSK1 ; if 0, then turn off reverse video LDA BDREG ; else, turn reverse video on ORA #$20 STA BDREG STA BAUD RTS SERSK1: LDA BDREG ; turn reverse video off AND #$DF STA BDREG STA BAUD RTS ;---------------------------------------------------------------------- ; Read Lightpen ;-------------- ; RDLPEN: RTS ; Just in case!!!! ;---------------------------------------------------------------------- ; Restore Last Two Lines of the Screen ;------------------------------------- ; RTRV22: LDA #22 JSR LINBAS LDA #0 JSR CALCATT LDY #0 RTRLP1: LDA ATTLINE,Y ; get attribute of character STA (NEWAB),Y LDA CHRLINE,Y ; get the character STA (LB),Y INY CPY #160 BNE RTRLP1 LDA TMPROW STA ROW LDA TMPCLMN STA COLMN JMP SETCUR PAGE ;---------------------------------------------------------------------- ; Insert a Character ;------------------- ; INSCHR: LDA LB ; Move CRAM and ARAM over 1 space STA LB2 ; now, move the attributes, 1st init LB2 LDA LB+1 STA LB2+1 LDA #78 ; set up source for character moves JSR CALCS LDA #79 ; set up destination for character moves JSR CALCD SEC ; now, figure how many bytes to transfer LDA #79 ; number to move = 79 - COLMN SBC COLMN CMP #0 BEQ INCSK1 ; if no characters to move, just blank position STA TRANSFR LDA #0 STA TRANSFR+1 JSR INSMOVE ; move the characters and attributes INCSK1: LDY COLMN ; now, blank the character position JMP CLRIT PAGE ;---------------------------------------------------------------------- ; delete line- move lines below up and clear last line ;----------------------------------------------------- ; DELLIN: LDA #23 SEC SBC ROW BEQ DLLSK1 ; if on bottom line STA TEMP ; save # of rows to move CLC LDA LB ; calculate start of next line ADC #80 ; in both ARAM and CRAM STA LB2 LDA LB+1 ADC #0 STA LB2+1 JSR SETSD ; set source and destination pointers LDA #0 JSR CALCATT2 ; calculate source for attribute move LDA #0 JSR CALCATT ; calculate destination for attribute move LDA TEMP ; get number of rows to move up ASL A ; convert to table index TAX LDA LINES,X ; get number of bytes to transfer and set up for move STA TRANSFR LDA LINES+1,X STA TRANSFR+1 JSR DELMOVE ; move the characters CLC ; set to clear last line LDA #1 ADC CHARD ; set LB to point to 1st character of last line STA LB LDA #0 ADC CHARD+1 STA LB+1 DLLSK1: JSR DELL99 ; now, clear last line JMP SETCUR ; and put the cursor where it should be PAGE ;---------------------------------------------------------------------- ; save last 2 lines of screen ;---------------------------- ; SAVE22: LDA ROW STA TMPROW LDA COLMN STA TMPCLMN LDA #22 JSR LINBAS LDA #0 JSR CALCATT ; get starting location in ARAM of line 22 LDY #0 SAVLP1: LDA (LB),Y ; get next char from CRAM STA CHRLINE,Y ; put it in RAM LDA (NEWAB),Y ; get the attribute STA ATTLINE,Y ; put it into RAM LDA #$20 STA (LB),Y ; clear space just saved LDA ATTTAB+0 STA (NEWAB),Y INY CPY #160 BNE SAVLP1 LDA #0 STA COLMN LDA #22 STA ROW JMP SETCUR ; set cursor to beginning of line 22 ;---------------------------------------------------------------------- ; Set Monitor Mode ;----------------- ; SETMON: LDA #$FF ; set monitor mode STA MONITOR RTS PAGE ;---------------------------------------------------------------------- ; Delete a Character (9_Nov_84) ;------------------------------ ; DELCHR: LDY COLMN ; delete character CPY #79 ; if last char on line, just blank it BEQ CLRIT INY ; else, get next character up the line, (SOURCE) LDA LB ; set up to calculate source and dest. for att move STA LB2 LDA LB+1 STA LB2+1 TYA JSR CALCS ; source = LB + COLMN + 1 LDA COLMN ; destination = LB + COLMN JSR CALCD SEC LDA #79 ; 80? SBC COLMN STA TRANSFR ; # to transfer = 79 - COLMN LDA #0 STA TRANSFR+1 JSR DELMOVE LDY #79 ; Clear the Last Character Position ;---------------------------------- ; 1) This code also used by the insert character routine (INSCHR) ; CLRIT: LDA ATTTAB+0 ; now, clear the space for the insert character JSR WRATT ; write the attribute LDA #' ' ; write a space STA (LB),Y RTS ;---------------------------------------------------------------------- ; Clear Monitor Mode ;------------------- ; CLRMON: LDA #0 ; clear monitor mode STA MONITOR RTS PAGE ;---------------------------------------------------------------------- ; Set the Keypad Applications Mode ;--------------------------------- ; SETKPD: LDA #$FF ; set keypad applications mode STA KPAD LDA #OFLNON ; turn on keypad application LED JMP KBRDOUT ;---------------------------------------------------------------------- ; Clear the Keypad Applications Mode ;----------------------------------- ; CLRKPD: LDA #0 ; clear keypad applications mode STA KPAD LDA #OFLNOFF ; turn off keypad application LED JMP KBRDOUT ;---------------------------------------------------------------------- ; now just clear the last line ;----------------------------- ; DELL99: LDY #0 STY COLMN LDY #79 DLLP1: LDA #' ' STA (LB),Y LDA ATTTAB+0 JSR WRATT DEY BPL DLLP1 RTS ;---------------------------------------------------------------------- ; Set the Source and Destination Pointers ;---------------------------------------- ; SETSD: LDA LB ; set up character destination pointer STA CHARD LDA LB+1 STA CHARD+1 LDA LB2 ; and source pointer STA CHARS LDA LB2+1 STA CHARS+1 RTS PAGE ;---------------------------------------------------------------------- ; move characters, and attribute nibbles for Char/Line Insert ;------------------------------------------------------------ ; on entry, NEWAB2 = absolute address in ARAM of source ; NEWAB = absolute address in ARAM of destination ; TRANSFR = count of number of attributes to move ; ; CHARS = absolute address in CRAM of source ; CHARD = absolute address in CRAM of destination ; INSMOVE:JSR MVCHAR ; move a character and attribute JSR DECXFR ; adjust number of bytes to be transferred BNE MORINS ; if ( no more chars to insert) RTS ; then return MORINS: DEC NEWAB2 ; adjust source pointer for move LDA #$FF ; see if time to adjust upper nibble CMP NEWAB2 BNE ADJTO ; if not, then adjust destination pointer DEC NEWAB2+1 LDA #07H ; see if ARAM needs wrapping CMP NEWAB2+1 BNE ADJTO ; if ARAM ok, adjust dest. pointer LDA #0FH ; else, put at top of ARAM STA NEWAB2+1 ADJTO: DEC NEWAB ; adjust destination pointer for move LDA #$FF ; see if time to adjust upper nibble CMP NEWAB BNE ADJCHAR ; if not, then move another attribute DEC NEWAB+1 LDA #07H ; see if ARAM needs wrapping CMP NEWAB+1 BNE ADJCHAR ; if ARAM ok, move another byte LDA #0FH ; else, put at top of ARAM STA NEWAB+1 ADJCHAR:DEC CHARS ; adjust source for character move LDA #$FF ; see if time to adjust high byte CMP CHARS BNE NXTADJ ; if not, adjust destination DEC CHARS+1 LDA #$1F ; see if time to put at top of CRAM CMP CHARS+1 BNE NXTADJ LDA #$27 ; if so , then set top page of CRAM STA CHARS+1 NXTADJ: DEC CHARD ; adjust destination for character move LDA #$FF ; see if time to adjust high byte CMP CHARD BNE ANOTHER ; if not, move another character DEC CHARD+1 LDA #$1F ; see if time to put at top of CRAM CMP CHARD+1 BNE ANOTHER LDA #$27 ; if so , then set top page of CRAM STA CHARD+1 ANOTHER:JMP INSMOVE PAGE ;---------------------------------------------------------------------- ; move characters, and attribute nibbles for Char/Line Delete ;------------------------------------------------------------ ; on entry, NEWAB2 = absolute address in ARAM of source ; NEWAB = absolute address in ARAM of destination ; TRANSFR = count of number of attributes to move ; ; CHARS = absolute address in CRAM of source ; CHARD = absolute address in CRAM of destination ; DELMOVE:JSR MVCHAR ; move a character and attribute JSR DECXFR ; adjust number of bytes to move BNE MOREDEL ; if non-zero, then more characters to delete RTS MOREDEL:INC NEWAB2 ; adjust source pointer for move BNE ADJTOD ; if not, then adjust destination pointer INC NEWAB2+1 LDA #10H ; see if ARAM needs wrapping CMP NEWAB2+1 BNE ADJTOD ; if ARAM ok, adjust dest. pointer LDA #08H ; else, put at top of ARAM STA NEWAB2+1 ADJTOD: INC NEWAB ; adjust destination pointer for move BNE ADJCHARD ; if not, then move another attribute INC NEWAB+1 LDA #10H ; see if ARAM needs wrapping CMP NEWAB+1 BNE ADJCHARD ; if ARAM ok, move another byte LDA #08H ; else, put at top of ARAM STA NEWAB+1 ADJCHARD: INC CHARS ; adjust source for character move BNE NXTADJD ; if not, adjust destination INC CHARS+1 LDA #$28 ; see if time to put at top of CRAM CMP CHARS+1 BNE NXTADJD LDA #$20 ; if so , then set top page of CRAM STA CHARS+1 NXTADJD:INC CHARD ; adjust destination for character move BNE ANOTHERD ; if not, move another character INC CHARD+1 LDA #$28 ; see if time to put at top of CRAM CMP CHARD+1 BNE ANOTHERD LDA #$20 ; if so , then set top page of CRAM STA CHARD+1 ANOTHERD: JMP DELMOVE PAGE ;---------------------------------------------------------------------- ; move a character and an attribute ;---------------------------------- ; MVCHAR: LDY #0 ; set y to zero for absolute indirect addr. LDA (NEWAB2),Y ; get an attribute STA (NEWAB),Y ; write new attribute byte LDA (CHARS),Y ; get a character STA (CHARD),Y ; put character in new position RTS ; Decrement the Transfer Address ;------------------------------- ; DECXFR: LDX #0 ; to be used later, so set up now DEC TRANSFR ; adjust low byte of transfer count BNE CHKFF ; if non zero, then check if FF CPX TRANSFR+1 ; see if high byte of transfer count is 0 too RTS ; if zero, then done, else more to XFR CHKFF: DEX CPX TRANSFR ; if transfr count = ff, then dec transfr+1 BNE NOTFF ; else, adjust source pointer DEC TRANSFR+1 LDA TRANSFR ; set flags for<>0 (won't be here if =0) NOTFF: RTS PAGE ;---------------------------------------------------------------------- ; video attribute table ;---------------------- ; the 3rd byte of the code sequence sets the mode ; in a bit-mapped fashion... the bit assignments ; are related to the LSI ADM-31 bit maps: ; ; b7 ... b2 b1 b0 ; Inverse vid. Brightness underline ; (1=inv) (1=dim) (1=underline) ; ; so, for example, to set inverse underline, you output ESC G 5 ; ATTTAB: DB %00000010 ; Normal video DB %00000011 ; Underline DB %00000000 ; Half intensity DB %00000001 ; Half intensity and Underline DB %00000110 ; Inverse Video DB %00000111 ; Inverse and Underline DB %00000100 ; Inverse and Half intensity DB %00000101 ; Inverse, Half intensity, and Underline ;---------------------------------------------------------------------- ; Escape Sequence Lookup Tables ;------------------------------ ; this table contains counts for each escape sequence. the count ; is the number of chars that are needed to complete the ; escape sequence. the main character output routine buffers NSEQ chars ; and then calls (CODE), which was set from the next table. ESCMOR: DB 0,1,1,0,0,0,0,0 ;space..' DB 0,0,0,0,0,0,0,0 ;(../ DB 0,0,0,0,0,0,0,0 ;0..7 DB 0,0,0,0,0,2,0,0 ;8..? DB 1,0,0,0,0,0,0,1 ;@..G DB 0,0,1,1,0,0,0,0 ;H..O DB 0,0,0,0,0,0,0,0 ;P..W DB 0,0,0,0,0,0,0,0 ;X.._ ESCTAB: DW ERTN,HICHAR,CURSRT,DISREV,GRAFON,GRAFOFF,ERTN,ERTN ;space..' DW INVOFF,INVON,CLRSCR,CLRSCR,ERTN,ERTN,ERTN,ERTN ;(../ DW ALIGN,ERTN,ERTN,ERTN,ERTN,ERTN,ERTN,ERTN ;0..7 DW ERTN,ERTN,ERTN,ERTN,ERTN,GOTOXY,ERTN,READCR ;8..? DW SCRNDIS,ERTN,ERTN,ERTN,ERTN,INSLIN,ERTN,SETATT ;@..G DW ERTN,BACKTB,SETCLK,SETREV,RDLPEN,ERTN,ERTN,ERTN ;H..O DW RTRV22,INSCHR,DELLIN,SAVE22,CLREOL,SETMON,ERTN,DELCHR ;P..W DW CLRMON,CLREOS,ERTN,SETKPD,ERTN,CLRKPD,ERTN,ERTN ;X.._ END