SBTTL 'Character/Attribute Memory Routines (21_Nov_84)' PAGE ;====================================================================== ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; ;---------------------------------------------------------------------- ; Index (21_Nov_84) ;------------------ ; ; SETCUR Set the Cursor Position ; SETPOS Figure the Screen Position ; LINBAS Calculate the Line Base ; CLRLIN Clear Line Primitive ; DELL99 Clear the Last Line ; 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 ;--------------------- ; 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 ;---------------------------------------------------------------------- ; 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 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 (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 ; Calculate Attribute (21_Nov_84) ;-------------------------------- ; CALCATT:CLC ;16 bit add of LB and Y reg ADC LB STA NEWAB ;NewAb:= 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 NEWAB+1 ;NewAb+1:= Hi_Byte of Attribute Address RTS ;Return 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 ; Calculate Attribute 2 (21_Nov_84) ;---------------------------------- ; CALCATT2: CLC ; 16 bit add of LB and Y reg ADC LB2 STA NEWAB2 ;NewAb2:= 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 NEWAB2+1 ;NewAb2+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 ; NEWAB2 " " " " Attributes in ARAM ; CHARD Destination (absolute address) of Characters in CRAM ; NEWAB " " " " Attributes in ARAM ; TRANSFR Count of the number of Attributes to move ; INSMOVE:LDY #0 ;Y_Index:= 0 (for absolute indirect) IMLP1: LDA (NEWAB2),Y ;Loop STA (NEWAB),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 NEWAB2 LDA #$FF ; If (Source Pointers eq 0FF) CMP NEWAB2 BNE IMSK1 DEC CHARS+1 ; Dec (Hi) Source Pointers DEC NEWAB2+1 LDA #7 ; If (Address ready to Wrap) CMP NEWAB2+1 BNE IMSK1 LDA #0FH STA NEWAB2+1 ; Reset Hi_Byte Attribute LDA #$2F STA CHARS+1 ; Reset Hi_Byte Character IMSK1: DEC CHARD ; Dec (Lo) Destination Pointers DEC NEWAB LDA #$FF ; If (Destination Pointers eq 0FF) CMP NEWAB BNE IMLP1 DEC CHARD+1 ; Dec (Hi) Destination Pointers DEC NEWAB+1 LDA #7 ; If (Address Ready to Wrap) CMP NEWAB+1 BNE IMLP1 LDA #0FH STA NEWAB+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 ; NEWAB2 " " " " Attributes in ARAM ; CHARD Destination (absolute address) of Characters in CRAM ; NEWAB " " " " Attributes in ARAM ; TRANSFR Count of the number of Attributes to move ; DELMOVE:LDY #0 ;Y_Index:= 0 (for absolute indirect) DMLP1: LDA (NEWAB2),Y ;Loop STA (NEWAB),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 NEWAB2 BNE DMSK1 ; If (Souce Pointers eq 0) INC CHARS+1 ; Inc (Hi) Source Pointers INC NEWAB2+1 LDA #$10 ; If (Pointers Ready to Wrap) CMP NEWAB2+1 BNE DMSK1 LDA #8 ; Reset Hi Pointers STA NEWAB2+1 LDA #$28 STA CHARS+1 DMSK1: INC CHARD ; Inc (Lo) Destination Pointers INC NEWAB BNE DMLP1 ; If (Destination Pointers eq 0) INC CHARD+1 ; Inc (Hi) Destination Pointers INC NEWAB+1 LDA #$10 ; If (Pointers Ready to Wrap) CMP NEWAB+1 BNE DMLP1 LDA #8 STA NEWAB+1 LDA #$28 STA CHARD+1 ; Reset Hi Pointers JMP DMLP1 DMSK2: RTS ;Return PAGE END