TITLE 'Morrow Terminal Board ROM for Pacific Bell (Revision 1.0)' SBTTL 'Main Module (3_Jan_85)' ;====================================================================== ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; Written by David Block and Jim Kearney (September 1983) ; ; ; Module Description: ;-------------------- ; This is the main body of code for the Morrow MD-70 Terminal. ; The main line, major subroutines and major support routines are in ; this module. There are five additional modules: ; ; INTpx.ASM Initialization Code ; CNTpx.ASM Control Code Processing ; ESCpx.ASM Escape Code Processing ; IOBpx.ASM IRQ, Circular Buffer and Keyboard Processing ; DATpx.ASM Data Storage Definitions ; ;---------------------------------------------------------------------- ; Index (2_Jan_85) ;----------------- ; ; -------- Revision Information ; -------- Equates ; -------- Page Zero Definitions ; MAIN Main Loop ; KYHNDLR Handle Pending Keyboard Input ; FNUM Function Code Routine (for F1-F10 keys) ; FNCNOUT Function Code Routine (all function keys except F1-F10) ; SENDC Send a Character ; PROCESS Process Pending Input Characters ; RTN Common Return for UnImplemented Escape Codes ; ESCHAND Escape Sequence Handeler ; CHKDIP Check the Dip Switch Settings ; SAVSCRN Update the Screen Saver Timeout ; OUTCHR Output a Character to the Screen ; CLREOLA Clear to the End of a Line ; CLR79 Clear From End of Line Primative ; CLR Clear Part of a Line ; SETCUR Set the Cursor Position ; SETPOS Figure the Screen Position ; LINBAS Calculate the Line Base ; KDLY Keyboard Delay ; PRNTMSG Print a Message ; -------- Include Files ; -------- Restart and interrupt vectors PAGE 62 ;---------------------------------------------------------------------- ; Equates (3_Jan_85) ;------------------- ; FRMREV EQU 0 ;Current Firmware Revision (See Read Model ID) ;Address Definitions RAM EQU $0000 ;Base of System Ram SNDBUF EQU $0300 ;Data Going out to the Host INBUF EQU $0400 ;Data Comming from the Host ARAM EQU $0800 ;Base of Attribute Ram CRAM EQU $2800 ; " " Character Ram CRTC EQU $5F00 ;6545/6845 Crt Controller S1DATA EQU $6000 ;Primary Uart Data Register S1STAT EQU $6001 ; " " Status Register S2DATA EQU $8000 ;Secondary Uart Data Register (for expansion) S2STAT EQU $8001 ; " " Status Register (for expansion) BAUD EQU $A000 ;Baud Rate Control/KeyBoard Status/Inverse Vid. DIPSW12 EQU $A001 DIPSW11 EQU $A002 ROM EQU $F000 ;Base of System Rom ;Command Codes Sent to the Keyboard SENDID EQU $7F ;Send kbrd ID BEEP EQU $7E ;Ring bell CLCKON EQU $7D ;Key click on CLCKOFF EQU $7C ;Key click off CAPSON EQU $7B ;Turn caps light on CAPSOFF EQU $7A ;Turn caps light off AUTON EQU $79 ;Auto repeat on AUTOFF EQU $78 ;Auto repeat off LOCKON EQU $77 ;keyboard lock light on LOCKOFF EQU $76 ;Keyboard lock light off OFLNON EQU $75 ;Off line light on OFLNOFF EQU $74 ;Off line light off ;Command Codes Recieved from the Keyboard ACCESS EQU %10011111 ;F1-F10 function lead in code ZERO EQU %10010000 ;Numeric kpad zero key CAPSKEY EQU $8A ;Caps lock key code SPCBAR EQU %10001100 ;Space bar CTLNSCR EQU %10100111 ;Control no scroll key NOSCROL EQU %10000111 ;No-scroll key BREAK EQU %10001001 ;Break key TABKEY EQU %10001011 ;Tab COMMA EQU %10011101 ;Numeric kpad comma key PAGE ;Special Ascii key codes CTRLC EQU $03 ; control C - sent when BREAK pressed CTRLI EQU $09 ; control I - sent when TAB pressed CTRLQ EQU $11 ; control Q - sent for X-ON by NO-SCROLL CTRLS EQU $13 ; control S - sent for X-OFF by NO-SCROLL ;Other Equates MSKNBIT EQU %00001000 ;Mask to set the 9th bit (for graphics mode) KEYMASK EQU %10011111 ;Mask to remove the Shift and CTRL bits MORLD EQU $1C ;Morrow function key lead in TELLD EQU $01 ;Televideo type function key lead in LASTLIN EQU 23*80 INSLIM EQU 64 ;Insert Input Buffer Limit to set DTR REMLIM EQU 64 ;Remove Input Buffer Limit to clear DTR INLEN EQU $400 ;Length of the Input Buffer PAGE ORG RAM ;---------------------------------------------------------------------- ; Variable Data (3_Jan_85) ;------------------------- ; ;Escape Character Handeling ESCRCVD:DS 1 ;Flag - (Monitor Mode Only) indicates that escape rcv'd NSEQ: DS 1 ;code sequence receiving if >0 (Non_Zero is SQNC Index) SQNC: DS 8 ;input code sequence storage ;Keyboard Handeling PARSTAT:DS 1 ;Flag - Parity Status (1 => disabled) BIT8: DS 1 ;if parity off, this sets what 8th bit should be PARTIAL:DS 1 ;used to store partials of keyboard input FNCLD: DS 1 ;Flag indicating if F1-F10 lead-in rcv'd FNCNTYP:DS 1 ;type of function key sequence 0 => MORROW MODE ;Other I/O BDREG: DS 1 ;baud register contents DBOUNCE:DS 1 ;DIP sw debounce counter NEWDIP: DS 1 ;set to new dip value when change detected SWDIF: DS 1 ;if change in DIP detected, then this = $FF DIP1: DS 1 ;DIP switch 1 storage TEMPDIP:DS 1 UARTCMD:DS 1 ;last command instruction to uart ;Screen Saver Data TIMECNT:DS 3 ;Screen Saver Time-Out Counter DISUPDT:DS 1 ;Flag - Character Recieved (time to turn screen on) DISOFF: DS 1 ;Flag - Screen Status (0 => screen ON) TIMEN: DS 1 ;Flag - Screen Saver Enabled (0 => enabled) ;Vectors CODE: DS 2 ;Jump location after code sequence rcvd MESG: DS 2 ;pointer to message to put on screen VCTNMI: DS 3 ;Jump to NMINRM (Normal) or NMICNT (Contention Check) NMINRM: DS 3 ;Jump to Normal NMI (Host Input) Process NMICNT: DS 2 ;Set Flag and Rti process while doing contention check PAGE ;Misc. Flags XFLAG: DS 1 ;If Non_Zero Send X-Off after char recv'd from host BRKHIT: DS 1 ;used to indicate that the BREAK key was hit BELSNT: DS 1 ;Last Character sent to the keyboard was a Bell XONOFF: DS 1 ;used to determine whether to send X-ON, or X-OFF DEFINV: DS 1 ;0 => normal video screen, 1 => inverse video KEYCLCK:DS 1 ;0 => key click enabled CAPS: DS 1 ;CAPS lock flag =1 => shift alpha to CAPS KPAD: DS 1 ;KPAD MODE 0 => Normal, $FF => Application MONITOR:DS 1 ;if non-zero, display control chars GRAPHMD:DS 1 ;if graphics mode, set to non-zero BUFFULL:DS 1 ;Input Buffer (From Host) is Full ;LOCKMD:DS 1 ;set non zero for kbrd lock ;Misc Variables ATTRIB: DS 1 ;current attribute setting DCURTYP:DS 1 ;default cursor type CLRCHAR:DS 1 ;character to clear screen to. normally, ASCII space TEMP: DS 1 ;Zero Page Temp Storage Location TEMP2: DS 1 ;Another Zero Page Temp Storage Location ;Cursor Positioning COLMN: DS 1 ;cursor horizontal 0..79 ROW: DS 1 ;cursor vertical 0..23 ;Character Movement Variables SCBASE: DS 2 ;Screen base offset (0..2047) LB: DS 2 ;Pointer to Base of Current Character Line LB2: DS 2 ;Destination Pointer for Character Moves CHARS: DS 2 ;Source Pointer for Character moves CHARD: DS 2 ;Destination Pointer for Character moves ATTRS: DS 2 ;Source Attribute Location ATTRD: DS 2 ;Destination Attribute Location TRANSFR:DS 2 ;Number of Bytes to Transfer (Insert/Delete Line/Char) ;Buffer Pointers/Counters INCNT: DS 2 ;Input Buffer (Bytes Remaining) Counter INSP: DS 2 ;start of buffer for input INEP: DS 2 ;end of buffer for input KEYSP: DS 1 ;start of keyboard buffer KEYEP: DS 1 ;end of keyboard buffer OUTSP: DS 1 ;start of output buffer OUTEP: DS 1 ;end of output buffer ;Buffer for Keyboard Input KEYBUF: DS 32 ;keyboard buffer for incoming keys PAGE ORG ROM ;---------------------------------------------------------------------- ; The Main Loop (30_Nov_84) ;-------------------------- ; COLD: SEI ;Disable USART Interrupts JSR INITC ;Cold Start Initialization WARM: JSR INITW ;Warm Start Initialization CLI ;Enable USART interrupts MAIN: JSR KYHNDLR ;Loop If (keyboard input pending) handle a key JSR PROCESS ; Print a Character from the Host JSR SENDC ; Send a Character to the Host JSR PROCESS ; Print a Character from the Host JSR CHKDIP ; If (dip switch changed) re-init JSR PROCESS ; Print a Character from the Host JSR SAVSCRN ; Update screen saver timeout JSR PROCESS ; Print a Character from the Host JMP MAIN PAGE ;---------------------------------------------------------------------- ; Handle Pending Keyboard Input (27_Dec_84) ;------------------------------------------ ; 1) All Symbols Except KYHNDLR are local to this block of code. ; KYHNDLR:LDX KEYEP ; see if key buffer empty CPX KEYSP BEQ KHEXIT ; if start of buffer = end, then no keys to process LDA #$FF ; else, set to turn reset timeout counter STA DISUPDT JSR KEYREM ; remove a key from the buffer LDX DISOFF ; see if display off BNE KHEXIT ; if screen is on then keep the character TAX ; save the key BMI NOTALFA ; branch if not ascii alpha char JMP SNDINS ; send the character NOTALFA:LDA FNCLD ; if in lead in, then not caps BNE NOTCAPS ; so jump TXA AND #KEYMASK ; mask out shift and control bits CMP #CAPSKEY ; see if caps lock key BNE NOTCAPS ; if not caps lock, then branch LDX #CAPSON ; assume CAPS LOCK to be turned on LDA CAPS ; see what current state of caps lock is EOR #$FF ; toggle it STA CAPS BNE SNDCAPS ; if caps lock being turned on, send caps lock LDX #CAPSOFF ; else, prepare to turn off CAPS LOCK SNDCAPS:TXA JMP PUTKEY ; send the proper code for CAPS LOCK on/off NOTCAPS:TXA ; get back the character LDX FNCLD ; see if function key lead in rcv'd BEQ CHKACCS ; if not, then see if this is it JMP FNUM ; else, this is an Fn key, so send code CHKACCS:CMP #ACCESS ; see if this is the lead in code for Fn keys BNE NOTLDIN ; if not, then branch LDA #$FF ; else, set flag to indicate that next key..... STA FNCLD ; .....is a Fn key KHEXIT: RTS NOTCSCR:TAX ; save the character again AND #KEYMASK ; mask out shift and control CMP #SPCBAR ; see if space bar BNE NOTSPC ; if not space bar, branch LDA #' ' ; if spacebar, then send ASCII space JMP SNDINS NOTSPC: CMP #NOSCROL ; see if no scroll key BNE NOTSCRL ; if not no scroll, then branch LDX XONOFF ; check whether to send X-ON or X-OFF BEQ SNDXOFF ; if 0, then send x-off INC XONOFF ; set flag to send x-off next time through LDA #CTRLQ ; send x-on JMP SNDINS SNDXOFF:DEC XONOFF ; set flag to send x-on next time through LDA #CTRLS ; else, send a control S to stop scrolling JMP SNDINS NOTLDIN:CMP #CTLNSCR ; check for control no scroll BNE NOTCSCR LDA UARTCMD ; issue break command ORA #$08 STA S1STAT LDY #100 XX: LDX #255 JSR KDLY ; delay 2.6 milliseconds DEY ; do it 100 times for 260 ms delay BNE XX LDA UARTCMD ; reset uart with original command STA S1STAT RTS NOTSCRL:CMP #BREAK ; see if break key BNE NOTBRK ; branch if not LDA #CTRLC ; else, send a control C to host JSR SNDINS LDA #$FF ; set BRKHIT flag to prevent more than 1 ^C STA BRKHIT RTS NOTBRK: CMP #TABKEY ; see if TAB key BNE NOTTAB ; if not, branch TXA ; else, see what we need to send CMP #TABKEY ; see if shift or ctrl TAB BNE FNCTN ; jump if shift or control TAB LDA #CTRLI ; else, send a TAB JMP SNDINS FNCTN: TXA ; get back character JMP FNCNOUT ; and send the function code sequence NOTTAB: CMP #ZERO ; see if KPAD ZERO key BCC FNCTN ; branch if not krom KPAD CMP #COMMA+1 ; check other range of KPAD BCS FNCTN ; branch if not from KPAD LDA KPAD ; see if KPAD applications mode BNE FNCTN ; branch if KPAD applications mode TXA ; else, get back character and convert to ASCII AND #%00011111 ; ignore all other bits ORA #%00100000 ; convert it to NUMERIC CMP #':' ; see if numeric BCC NMBER ; branch if it is CMP #$3A ; else, see if it's the PERIOD BNE NOTPER ; if not, branch LDA #"." ; else, send a period NMBER: JMP SNDINS NOTPER: CMP #$3B ; see if ENTER key BNE NOTENTR ; branch if not LDA #$0D ; else, send a CR JMP SNDINS NOTENTR:CMP #$3C ; see if MINUS BNE ISCOMMA ; if not, then branch LDA #$2D ; send a MINUS JMP SNDINS ISCOMMA:LDA #$2C ; its a COMMA, so send one JMP SNDINS PAGE ;---------------------------------------------------------------------- ; Function Code Routine for F1-F10 and Arrow keys (2_Jan_85) ;----------------------------------------------------------- ; 1) If the Most Signifigant Bit of the Function Code is Set then the ; Function Code Lead In (1E) is Suppressed. ; FNUM: LDX #0 ;Clear lead in flag for F1-F10 keys STX FNCLD TAX ;(save character) AND #%00010000 ;If (this is NOT the keyboard ID code) CMP #%00010000 BEQ FNBSK2 TXA ; (get character back) AND #$0F ; mask of key number STA TEMP2 ; save key number TXA ; (get char again) AND #$60 ; convert to proper table index LSR A ; (move shift/control over keyboard bit) ORA TEMP2 TAX LDA F110TBL,X ; get function code TAX ; (Save the Code) AND #$80 ; If (Lead In NOT suppressed) BNE FNBSK1 LDA #$1E JSR SNDINS ; Send the Lead In Code FNBSK1: TXA ; (Restore the Code) AND #$7F ; Remove Leadin Suppression Bit JSR SNDINS ; Send the Function Code FNBSK2: RTS ;Return PAGE ;---------------------------------------------------------------------- ; Function Code Routine for remaining function keys (2_Jan_85) ;------------------------------------------------------------- ; 1) If the Most Signifigant Bit of the Function Code is Set then the ; Function Code Lead In (1E) is Suppressed. ; FNCNOUT:AND #$7F ;Remove the 8th Bit TAX ;(save character) CMP #%00001111 ;If (keyboard NOT just powered up) BEQ FNASK2 LDA FTABLE,X ; get function code TAX ; (Save the Code) AND #$80 ; If (Lead In NOT suppressed) BNE FNASK1 LDA #$1E JSR SNDINS ; Send the Lead In Code FNASK1: TXA ; (Restore the Code) AND #$7F ; Remove Leadin Suppression Bit JSR SNDINS ; Send the Function Code FNASK2: RTS ;Return PAGE ;---------------------------------------------------------------------- ; Send a Character (2_Jan_85) ;----------------------------- ; 1) This routine sends one character to the host given that the Uart ; is ready and that there is a character to be sent. ; 2) Notice that both TxRdy AND Dsr are checked. ; SENDC: LDA S1STAT ;(get status of UART) AND #%10000001 ;Remove all bits BUT TxRdy and Dsr CMP #%10000001 ;If ( (TxRdy eq True) And (Dsr eq True) ) BNE SCSK2 JSR SNDREM ; Remove a Character from the Send Buffer CMP #$FF BEQ SCSK2 ; If (The Buffer returned a Character) LDX PARSTAT ; If (Parity Generation Disabled) BNE SCSK1 ORA #%10000000 ; (assume 8th bit set) LDX BIT8 ; If (8th bit is space) BEQ SCSK1 AND #$7F ; clear MSB SCSK1: STA S1DATA ; Transmit the character SCSK2: RTS ;Return PAGE ;---------------------------------------------------------------------- ; Process Pending Input Characters (18_Dec_84) ;--------------------------------------------- ; PROCESS:LDA BUFFULL ;If (Buffer is Full) BEQ PRSK1 LDA #BEEP ; Ring the Bell JSR PUTKEY ; (Buffer Full Cleared in INREM) PRSK1: JSR INREM ; see if any characters pending CMP #$FF BEQ RTN ; if no chars, then no input LDX #$FF STX DISUPDT ; set screen update flag LDX NSEQ ; are we getting a sequence? BEQ PRSK2 ; 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 ; Common Return for UnImplemented Escape Codes ;--------------------------------------------- ; RTN: RTS ;Common Return for UnImplemented Escape Codes PRSK2: LDX ATTRIB ;Get the current atribute setting CMP #' ' ;If ( (Recieved_Character ge 20h) And BCC PRSK4 LDY GRAPHMD ; (Graphics Mode is Enabled) ) BEQ PRSK6 CMP #'?' ; If (char gt '@') BCC PRSK6 ORA #$80 ; Convert to Graphics JMP PRSK6 ; Goto Check for Escape X Code ;Handle Control Characters PRSK4: LDY MONITOR ; see if monitor mode enabled BEQ PRSK8 ; if (monitor mode) enabled LDY #0 ; last char wasn't escape, is this???? CMP #$1B BNE PRSK5 ; if ( not escape ), then set escrcvd to 0 LDY #$FF ; else, set for escrcvd true PRSK5: STY ESCRCVD PRSK6: LDY ESCRCVD ; see if last char was escape BEQ PRSK7 ; if escrcvd = 0, then last char not escape CMP #'X' ; else, see if this is a CLRMON command BEQ PRSK7 ; if (not CLRMON) then branch, else LDA #0 ; clear escrcvd STA ESCRCVD JMP CLRMON ; clear monitor mode, and return PRSK7: JMP OUTCHR ; put character on screen PRSK8: 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 PAGE ;---------------------------------------------------------------------- ; Escape Handeler (28_Dec_84) ;---------------------------- ; ESCHAND:AND #$7F ;Remove the 8th Bit LDX #ESCLEN ;X:= Length of Lookup Table - 1 EHLP1: CMP ESCTAB,X ;Repeat If (Character eq Table) BNE EHSK1 TXA ; A:= Index TAY ; Y:= Index ASL A ; Index:= Index * 2 TAX ; X:= Index LDA ESCVCT,X STA CODE LDA ESCVCT+1,X STA CODE+1 ; Code:= Vector to the Routine LDA ESCCNT,Y STA NSEQ ; Nseq:= Number of Parameters BNE ERTN ; If (Parameters eq None) JMP (CODE) ; Execute EHSK1: DEX ; Index:= Index - 1 BPL EHLP1 ;Until (Whole Table has been Checked) ERTN: RTS ;Return PAGE ;---------------------------------------------------------------------- ; Check the Dip Switch Settings (12_Nov_84) ;------------------------------------------ ; CHKDIP: LDA DIPSW11 ; get dip switch settings ASL A STA TEMPDIP LDA DIPSW12 AND #01 ORA TEMPDIP STA TEMPDIP ;TempDip:= Dip_Switch_1 or'd with Dip_Switch_2 CMP DIP1 BEQ CKDSK3 ;If (Dip Switch Changed) LDA SWDIF BEQ CKDSK2 ; If (Different Flag eq True) LDA NEWDIP ; Get new dip setting CMP TEMPDIP BNE CKDSK1 ; If (DIP SW same as last time) DEC DBOUNCE ; Update debounce timer BNE CKDSK3 ; If (Debounce time eq 0) LDA #0 STA TEMPDIP ; Clear Temp_Dip STA SWDIF ; Clear Switch Dif JMP WARM ; Goto Warm Start CKDSK1: LDA #$FF ; Else STA DBOUNCE ; Reset Debounce RTS ; Return CKDSK2: LDA #$FF ; Else STA SWDIF ; Switch_Different_Flag:= True STA DBOUNCE ; Debounce_Timer:= Reset LDA TEMPDIP STA NEWDIP ; Install New Switch Value CKDSK3: RTS ;Return PAGE ;---------------------------------------------------------------------- ; Update the Screen Saver Timeout (12_Nov_84) ;-------------------------------------------- ; 1) If the screen is currently enabled and no character has been ; recieved then the screen timeout is incremented. If the timeout hits ; maximum then the screen is disabled. ; 2) If the screen is currently enabled and a character has been recieved ; then the screen timeout is reset. ; 3) If the screen is off and a character is recieved then the display ; is turned back on. ; SAVSCRN:LDA TIMEN BNE SVSSK1 ;If (Screen Timeout Enabled) LDA DISUPDT BNE SVSSK2 ; If ( (No Character Recieved) And LDA DISOFF ; (Display is Enabled) BNE SVSSK1 CLC ; Increment TimeOut Counter LDA #1 ADC TIMECNT STA TIMECNT LDA #0 ADC TIMECNT+1 STA TIMECNT+1 LDA #0 ADC TIMECNT+2 STA TIMECNT+2 CMP #73 BNE SVSSK1 ; If (TimeOut eq Maximum) LDA #$FF STA DISOFF ; Display_Off:= True LDX #1 ; Turn Off the Display STX CRTC DEX STX CRTC+1 ; (set horiz char to 0) SVSSK1: RTS ; Return SVSSK2: LDX #0 ; Else STX DISUPDT ; Char_Recieved_Flag:= False STX DISOFF ; Display_Off:= False STX TIMECNT STX TIMECNT+1 STX TIMECNT+2 ; Reset Timeout Counter LDX #1 ; Turn on screen STX CRTC LDX #80 STX CRTC+1 ; (set horiz char to 80) RTS ;Return PAGE ;---------------------------------------------------------------------- ; Output a Character to the Screen (27_Dec_84) ;--------------------------------------------- ; 1) On Entry: ; X = current attribute being set ; A = character to display ; OUTCHR: LDY COLMN STA (LB),Y ;Write the Character TYA 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 TXA ;A:= Attribute LDX #0 ;Index:= 0 STA (ATTRD,X) ;Write the Attribute INY CPY #80 BNE OUTSK1 ;If (Auto Line Feed Required) LDA #0 STA COLMN ; Column:= 0 JMP LF ; Do a Line Feed (this sets the cursor) OUTSK1: STY COLMN ;Update the Column JMP SETPOS ;Set the Cursor Position RTS PAGE ;---------------------------------------------------------------------- ; Clear Line Primitives (6_Dec_84) ;--------------------------------- ; ;Clear from (LB + 80) - A_Reg Characters to the end of the line CLEOLA: EOR #$FF SEC ADC #80 TAX ;Counter:= (80 - Entry Value of Accm) - 1 ;Clear X_Reg Characters from the end of the line CLR79: LDY #79 ;Offset:= End of Line ;Clear X_Reg Character from (Y_Reg + LB) from the end of the line CLR: STX TEMP2 ;Temp2:= Loop Counter LDX #0 ;Attribute Storage Offset:= 0 CLRLP1: LDA #' ' ;Repeat STA (LB),Y ; LB + Y_Reg:= Space TYA CLC 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 Base Address of the Attribute Ram STA ATTRD+1 ; ATTRD+1:= Hi_Byte of Attribute Address LDA ATTTAB+0 STA (ATTRD,X) ; Write the Attribute DEY ; Decrement the Offset DEC TEMP2 ; Decrement the Loop Counter BNE CLRLP1 ;Until (Loop Counter eq 0) RTS 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 ;---------------------------------------------------------------------- ; Keyboard Delay ;--------------- ; waits for a number of micro seconds, as specified in X REG ; the delay is in 10.3 micro second increments ; KDLY: DEX NOP NOP NOP NOP BNE KDLSK1 RTS KDLSK1: NOP JMP KDLY ;---------------------------------------------------------------------- ; Print a Message (27_Dec_84) ;---------------------------- ; 1) This routine prints the 0 terminated message string pointed to ; the MESG. ; 2) This routine is used by the memory and keyboard test routines and ; by the Print Terminal/Keyboard Revision routine. ; PRNTMSG:JSR INITBUF ;Clear the Input Buffer LDA #' ' STA CLRCHAR ;Clear_Character:= Spaces JSR CLRSCR ;Clear the Screen PMLP1: LDX #0 LDA (MESG,X) ;While (Current Character ne 0) BEQ PMSK1 LDX ATTTAB+0 ; Set the Attribute to Normal JSR OUTCHR ; Print the Character INC MESG ; Increment the Message Pointer JMP PMLP1 PMSK1: RTS ;Return ;---------------------------------------------------------------------- ; Include Files (3_Jan_85) ;------------------------- ; INCLUD INTP3.ASM ;Initialization Code INCLUD CNTP3.ASM ;Control Character Routines INCLUD ESCP3.ASM ;Escape Sequence Handelers INCLUD IOBP3.ASM ;Interrupt and I/O Routines INCLUD DATP3.ASM ;Data Storage END