SBTTL 'Escape Code Routines (7_Dec_84)' PAGE ;====================================================================== ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; ;---------------------------------------------------------------------- ; Index (7_Dec_84) ;----------------- ; ; 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 ; ALIGN Fill the Screen with the alignment pattern ; SNDLIN Send the Line that Contains the Cursor to the Host ; ; 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 ; ; INSCHR Insert a Character ; DELLIN Delete a Line ; CLREOL Clear to the End of the Line ; SETMON Set the Mointor Mode ; DELCHR Delete a Character ; CLRMON Clear the Monitor Mode ; CLREOS Clear to the End of the Screen ; SETKPD Set the Applications KeyPad Mode ; CLRKPD Clear the Applications KeyPad Mode ; ; CALCD Calculate Destination Address ; CALCATT Calculate Attribute ; CALCS Calculate Source Address ; CALCATT2 Calculate Attribute 2 ; SETSD Set the Source and Destination Pointers ; ; INSMOVE Move characters/attributes for Char/Line Insert ; DELMOVE Move characters/attributes for Char/Line Delete PAGE ;---------------------------------------------------------------------- ; Print a Character in Alternate Graphics Mode (4_Dec_84) ;-------------------------------------------------------- ; HICHAR: LDA ATTRIB ORA #MSKNBIT ;Set the ninth Bit TAX ;X:= Attribute Code (9th bit set) LDA SQNC ;Get the character ORA #$80 ;Set the eigth bit (selects alternate char set) JMP OUTCHR ;Output the character ;---------------------------------------------------------------------- ; 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 PAGE ;---------------------------------------------------------------------- ; Enable Graphics Mode (5_Dec_84) ;-------------------------------- ; GRAFON: LDA #$FF STA GRAPHMD ;Enable Graphics Mode LDA ATTRIB ORA #MSKNBIT STA ATTRIB ;Set the 9th Bit RTS ;---------------------------------------------------------------------- ; Disable Graphics Mode (4_Dec_84) ;--------------------------------- ; GRAFOFF:LDA #$0 STA GRAPHMD ;Disable Graphics Mode LDA ATTRIB AND #(NOT MSKNBIT) ;Remove the 9th (graphics bit) STA ATTRIB ;Update the current attribute byte RTS ;Return ;---------------------------------------------------------------------- ; Set Normal Video (4_Dec_84) ;---------------------------- ; INVOFF: LDA ATTRIB ;Get the Current Attribute Setting AND #MSKNBIT ;Remove all bits but the 9th (graphics) bit ORA ATTTAB+0 ;Combine 9th bit with Normal Attribute STA ATTRIB ;Update the Attribute Byte RTS ;Return ;---------------------------------------------------------------------- ; Turn DIM Video On (4_Dec_84) ;----------------------------- ; INVON: LDA ATTRIB ;Get the Current Attribute Setting AND #MSKNBIT ;Remove all bits but the 9th (graphics) bit ORA ATTTAB+2 ;Combine 9th bit with Reverse Attribute STA ATTRIB ;Update the Attribute Byte RTS ;Return PAGE ;---------------------------------------------------------------------- ; 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 ;---------------------------------------------------------------------- ; Send the Line that Contains the Cursor to the Host (7_Dec_84) ;-------------------------------------------------------------- ; 1) This Routine moves the current line, from the start of the line ; to the current cursor position into the send buffer. ; 2) Notice that any change in the attribute setting causes an Esc G n ; sequence to be sent, where n is the number of the attribute (0-7). ; SNDLIN: LDA LB STA CHARS STA ATTRS LDA LB+1 STA CHARS+1 ;CharS:= Start of Current Line in Character ram AND #%00000111 ORA #HIGH ARAM STA ATTRS+1 ;AttrS:= Start of Current Line in Attribute ram LDA COLMN STA TEMP ;Counter:= Current Column LDA ATTTAB+0 STA TEMP2 ;Current_Attribute:= Normal LDX #0 SLLP1: LDA (ATTRS,X) ;Repeat CMP TEMP2 ; If (Current Attribute ne Last Attribute) BEQ SLSK2 SLLP2: STA TEMP2 ; Update Default Attribute CMP ATTTAB,X ; While (Attribute ne Table) BEQ SLSK1 INX ; Increment the Index JMP SLLP2 SLSK1: LDA #$1B JSR SNDINS ; Send an Escape LDA #'G' JSR SNDINS ; Send a G TXA CLC ADC #'0' ; Convert Index to Attribute Code JSR SNDINS ; Send the Attribute LDX #0 SLSK2: LDA (CHARS,X) JSR SNDINS ; Send the Character INC CHARS ; Inc (Lo) Source Pointers INC ATTRS BNE SLSK3 ; If (Souce Pointers eq 0) INC CHARS+1 ; Inc (Hi) Source Pointers INC ATTRS+1 LDA #$10 ; If (Pointers Ready to Wrap) CMP ATTRS+1 BNE SLSK3 LDA #$8 ; Reset Hi Pointers STA ATTRS+1 LDA #$28 STA CHARS+1 SLSK3: DEC TEMP ; Decrement the Byte Count BNE SLLP1 ;Until (Counter eq 0) LDA #$0D JSR SNDINS ;Put terminating carriage return in send buffer RTS ;Return 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 PAGE ;---------------------------------------------------------------------- ; 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 ;---------------------------------------------------------------------- ; Insert a Line (27_Nov_84) ;-------------------------- ; INSLIN: LDA #23 ; Calculate number of lines to move SEC SBC ROW BEQ INSSK1 ; if (on bottom line) CLC LDA SCBASE ; calculate pointer to last line ADC #LOW(LASTLIN)+79 STA LB LDA SCBASE+1 ADC #HIGH(LASTLIN)+HIGH(CRAM) AND #$3F ;(Keep the move in bounds) 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 INSSK1: LDA ROW ;reset pointers JSR LINBAS LDA #0 STA COLMN ;Reset Column to Starting Column LDX #80 ;X:= Number of Characters to Clear JSR CLR79 ;Clear the Line JMP SETCUR ;Reset the Cursor Position PAGE ;---------------------------------------------------------------------- ; Set a Character's Attribute (4_Dec_84) ;--------------------------------------- ; SETATT: LDA SQNC ;Get code for desired attribute AND #%111 ;Remove all but the 3 least signifigant bits TAX ;X:= Index into Attribute Byte Table LDA ATTRIB ;Get the Current Attribute Setting AND #MSKNBIT ;Remove all bits but the 9th (graphics) bit ORA ATTTAB,X ;Combine 9th bit with the new Attribute Setting STA ATTRIB ;Update the Attribute Byte RTS ;Return ;---------------------------------------------------------------------- ; 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 PUTKEY ; send keyclick on to keyboard SECSK1: LDA #CLCKOFF JMP PUTKEY ; 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 ;---------------------------------------------------------------------- ; Insert a Character (28_Nov_84) ;------------------------------- ; 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 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 LDX #1 ;Set to Clear 1 Character JMP CLR ;Clear the Character PAGE ;---------------------------------------------------------------------- ; Delete a Line (27_Nov_84) ;-------------------------- ; 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: LDA #0 STA COLMN ;Reset Column to Starting Column LDX #80 ;X:= Number of Characters to Clear JSR CLR79 ;Clear the Line JMP SETCUR ;Reset the Cursor PAGE ;---------------------------------------------------------------------- ; Clear to the End of the Line ;----------------------------- ; CLREOL: LDA COLMN ; clear to end of line JMP CLEOLA ;---------------------------------------------------------------------- ; Set Monitor Mode (7_Dec_84) ;---------------------------- ; SETMON: LDA #$FF ;Set Monitor Mode STA MONITOR JMP GRAFOFF ;Turn Off Graphics Mode ;---------------------------------------------------------------------- ; Delete a Character (28_Nov_84) ;------------------------------- ; DELCHR: LDY COLMN ;delete character CPY #79 ;if last char on line, just blank it BEQ DCSK1 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 SBC COLMN STA TRANSFR ;# to transfer = 79 - COLMN LDA #0 STA TRANSFR+1 JSR DELMOVE DCSK1: LDX #1 ;Set to Clear One Character JMP CLR79 PAGE ;---------------------------------------------------------------------- ; Clear Monitor Mode ;------------------- ; CLRMON: LDA #0 ; clear monitor mode STA MONITOR RTS ;---------------------------------------------------------------------- ; Clear to the End of the Screen (27_Nov_84) ;------------------------------------------- ; CLREOS: LDA COLMN JSR CLEOLA ;Clear to the End of the Current Line SEC LDA #23 SBC ROW BEQ CLESK2 ;If (We're NOT on the Last Line) STA TEMP ; Temp:= Number of Rows to Clear CLELP1: LDA LB ; Repeat CLC ADC #80 ; Set Line_Base to the Next Row STA LB BCC CLESK1 INC LB+1 CLESK1: LDX #80 ; Set Char to Clear Count to 80 JSR CLR79 ; Clear a Line DEC TEMP BNE CLELP1 ; Until (Remaining Rows cleared) CLESK2: JMP SETCUR ;Update the Cursor Position PAGE ;---------------------------------------------------------------------- ; Set the Keypad Applications Mode ;--------------------------------- ; SETKPD: LDA #$FF ; set keypad applications mode STA KPAD LDA #OFLNON ; turn on keypad application LED JMP PUTKEY ;---------------------------------------------------------------------- ; Clear the Keypad Applications Mode ;----------------------------------- ; CLRKPD: LDA #0 ; clear keypad applications mode STA KPAD LDA #OFLNOFF ; turn off keypad application LED JMP PUTKEY 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 ; Calculate Attribute (21_Nov_84) ;-------------------------------- ; CALCATT:CLC ;16 bit add of LB and Y reg ADC LB STA ATTRD ;ATTRD:= Lo_Byte of Attribute Address LDA #0 ADC LB+1 AND #%00000111 ;Truncate to 2k ORA #HIGH ARAM ;Or in the Base Address of the Attribute Ram STA ATTRD+1 ;ATTRD+1:= Hi_Byte of Attribute Address RTS ;Return PAGE ;---------------------------------------------------------------------- ; Calculate Source Address of Character Move ;------------------------------------------- ; 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 ; Calculate Source Address of Attribute Move (21_Nov_84) ;------------------------------------------------------- ; CALCATT2: CLC ; 16 bit add of LB and Y reg ADC LB2 STA ATTRS ;ATTRS:= Lo_Byte of Attribute Address LDA #0 ADC LB2+1 AND #%00000111 ;Truncate to 2k ORA #HIGH ARAM ;Or in the Attribute Ram Base Address STA ATTRS+1 ;ATTRS+1:= Hi_Byte of Attribute Address 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/Attributes for Char/Line Insert (21_Nov_84) ;------------------------------------------------------------ ; 1) On entry: ; CHARS Source (absolute address) of Characters in CRAM ; ATTRS " " " " Attributes in ARAM ; CHARD Destination (absolute address) of Characters in CRAM ; ATTRD " " " " Attributes in ARAM ; TRANSFR Count of the number of Attributes to move ; INSMOVE:LDY #0 ;Y_Index:= 0 (for absolute indirect) IMLP1: LDA (ATTRS),Y ;Loop STA (ATTRD),Y ; Move an Attribute LDA (CHARS),Y STA (CHARD),Y ; Move a Character DEC TRANSFR ; Decrement the Byte Count LDA #$0FF CMP TRANSFR BNE IMSK0 ; If (Lo_Byte of Count eq 0FFh) DEC TRANSFR+1 ; If (Hi_Byte - 1 eq 0) BMI IMSK2 ; Break IMSK0: DEC CHARS ; Dec (Lo) Source Pointers DEC ATTRS LDA #$FF ; If (Source Pointers eq 0FF) CMP ATTRS BNE IMSK1 DEC CHARS+1 ; Dec (Hi) Source Pointers DEC ATTRS+1 LDA #7 ; If (Address ready to Wrap) CMP ATTRS+1 BNE IMSK1 LDA #0FH STA ATTRS+1 ; Reset Hi_Byte Attribute LDA #$2F STA CHARS+1 ; Reset Hi_Byte Character IMSK1: DEC CHARD ; Dec (Lo) Destination Pointers DEC ATTRD LDA #$FF ; If (Destination Pointers eq 0FF) CMP ATTRD BNE IMLP1 DEC CHARD+1 ; Dec (Hi) Destination Pointers DEC ATTRD+1 LDA #7 ; If (Address Ready to Wrap) CMP ATTRD+1 BNE IMLP1 LDA #0FH STA ATTRD+1 LDA #$2F STA CHARD+1 ; Reset Hi_Byte Pointers JMP IMLP1 IMSK2: RTS ;Return PAGE ;---------------------------------------------------------------------- ; Move Characters/Attribute for Char/Line Delete (21_Nov_84) ;----------------------------------------------------------- ; 1) On entry: ; CHARS Source (absolute address) of Characters in CRAM ; ATTRS " " " " Attributes in ARAM ; CHARD Destination (absolute address) of Characters in CRAM ; ATTRD " " " " Attributes in ARAM ; TRANSFR Count of the number of Attributes to move ; DELMOVE:LDY #0 ;Y_Index:= 0 (for absolute indirect) DMLP1: LDA (ATTRS),Y ;Loop STA (ATTRD),Y ; Move an Attribute LDA (CHARS),Y STA (CHARD),Y ; Move a Character DEC TRANSFR ; Decrement the Byte Count LDA #$0FF CMP TRANSFR BNE DMSK0 ; If (Lo_Byte of Count eq 0FFh) DEC TRANSFR+1 ; If (Hi_Byte - 1 eq 0FFh) BMI DMSK2 ; Break DMSK0: INC CHARS ; Inc (Lo) Source Pointers INC ATTRS BNE DMSK1 ; If (Souce Pointers eq 0) INC CHARS+1 ; Inc (Hi) Source Pointers INC ATTRS+1 LDA #$10 ; If (Pointers Ready to Wrap) CMP ATTRS+1 BNE DMSK1 LDA #8 ; Reset Hi Pointers STA ATTRS+1 LDA #$28 STA CHARS+1 DMSK1: INC CHARD ; Inc (Lo) Destination Pointers INC ATTRD BNE DMLP1 ; If (Destination Pointers eq 0) INC CHARD+1 ; Inc (Hi) Destination Pointers INC ATTRD+1 LDA #$10 ; If (Pointers Ready to Wrap) CMP ATTRD+1 BNE DMLP1 LDA #8 STA ATTRD+1 LDA #$28 STA CHARD+1 ; Reset Hi Pointers JMP DMLP1 DMSK2: RTS ;Return END