SBTTL 'Character/Attribute Memory Routines (27_Nov_84)' PAGE ;====================================================================== ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; ;---------------------------------------------------------------------- ; Index (27_Nov_84) ;------------------ ; ; SETCUR Set the Cursor Position ; SETPOS Figure the Screen Position ; LINBAS Calculate the Line Base ; CLREOLA Clear to the End of a Line ; CLEAR Clear Line Primative ; OUTCHR Output a Character to the Screen ; WRATT Write an Attribute ; ; 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, and attribute nibbles for Char/Line Insert ; DELMOVE Move characters, and attribute nibbles for Char/Line Delete PAGE ;---------------------------------------------------------------------- ; Set the Cursor Position (21_Nov_84) ;------------------------------------ ; SETCUR: LDA ROW ;A:= Current Row JSR LINBAS ;Set LB to Starting Address of Current Line ; Figure the Screen Position ;--------------------------- ; SETPOS: CLC LDA LB ADC COLMN ;A:= Low Byte Cursor Address LDX #15 ;X:= Cursor Address Register Index (Lo_Byte) STX CRTC ;Select Lo_Byte of the Cursor Adress Register STA CRTC+1 ;Install the Low Byte of the Cursor Address LDA TEMP ;(Set in LINBAS to un-truncated Hi_Byte Addr) ADC #0 ;A:= High Byte Cursor Address DEX ;X:= Cursor Address Register Index (Hi_Byte) STX CRTC ;Select Hi_Byte of the Cursor Adress Register STA CRTC+1 ;Install the Hi Byte of the Cursor Address RTS ;Return ;---------------------------------------------------------------------- ; Calculate the Line Base (21_Nov_84) ;------------------------------------ ; 1) Enter this routine with the accm equal to the desired row. The ; routine sets LB (Low_Byte) and LB+1 (High_Byte) to the absolute ; starting address of the row. ; LINBAS: ASL A TAX ;X:= Row * 2 LDA LINES,X CLC ADC SCBASE ;A:= Low Byte of Absolute Screen Address STA LB ;LB:= Low Byte Address (same for CRAM & ARAM) LDA LINES+1,X ADC SCBASE+1 ;A:= High Byte of Absolute Screen Address STA TEMP ;(Save Address for Cursor Positioning) AND #%111 ;Truncate to less than 2K ORA #HIGH CRAM ;Compute high byte of CRAM Line base STA LB+1 ;LB+1:= High Byte Address RTS ;Return PAGE ;---------------------------------------------------------------------- ; Clear Line Primitive (27_Nov_84) ;--------------------------------- ; CLEOLA: EOR #$FF SEC ADC #80 TAX CLEAR: LDY #79 CLLP1: LDA #' ' STA (LB),Y LDA ATTTAB+0 JSR WRATT DEY DEX BNE CLLP1 RTS PAGE ;---------------------------------------------------------------------- ; Output a Character to the Screen ;--------------------------------- ; 1) 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 ;---------------------------------------------------------------------- ; 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 (ATTRD),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 ; 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 PAGE ;---------------------------------------------------------------------- ; 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