;**************************************************************************;
; ;
; ALPHA MICRO AM-62A TERMINAL DRIVER ;
; ;
;**************************************************************************;
; ASL- -00
; NOTICE
;
;All rights reserved. This software is the property of Alpha Microsystems
;and the material contained herein is the proprietary property and trade
;secrets of Alpha Microsystems, embodying substantial creative efforts and
;confidential information, ideas and expressions, no part of which may be
;reproduced or transmitted in any form or by any means, electronic,
;mechanical, or otherwise, including photocopying or input into any
;information storage or retrieval system without the express written
;permission of Alpha Microsystems.
;
;CAUTION: Unauthorized distribution or reproduction of this material may
;subject you to legal action.
;
;Copyright (C) 1982 - Alpha Microsystems
;
;Edit History:
;[112] January 18, 1996 10:41 AM Edited by Bob Rubendunst
; Modified start-up string to initialize a modem to a reasonable
; state. The assumption is that when the system boots, there is no
; terminal attached to the port, only a modem, and that terminal
; initialization strings have been known to make some modems not
; work properly. This version of the AM62A driver, by sending
; modem commands to turn off modem echoing, and turn on quiet mode,
; will prevent problems. This driver also disables terminal
; echoing until after the final AT sequence is sent to the modem.
;
; Modified the routine that outputs strings to the terminal/modem
; to be easier to change without introducing programming errors.
;
;[111] 24 October 1994 Edited by David Canfield
; Speed up TRMDEF by replacing SLEEP call in INI routine with a TIMER
; executed routine so we don't put the boot job to sleep. Also only
; allow INI routine to display "System booting" message when the system
; actually IS booting-up.
;[110] September 15, 1994 03:09 PM Edited by Bob Currier
; Make sure that status line lengths returned by TRMCHR reflect current
; 80/132 column setting.
;[109] 12 June 1986
; Fixed SPRs 3000 and 3001; TCRT 129 did not work. /VHS
;[108] 20 March 1986
; Fixed problem with AlphaWRITE when going from text to menus in
; wide mode. /VHS
;[107] 8 May 1985
; Correct my boo-boo in edit 106. /RJH
;[106] 2 May 1985
; Fixed problem with rubbing out control characters. /RJH
;[105] 7 Jan 1985
; Fix 132 column problem. Use -32 instead. /RJH
;[104] 7 November 1984
; Update to conform to new standard: update TRMCHR routine to support
; new fields and bitmap. /RBC
;[103] 7 Sept 1984
; Converted from AM6X code
;[102] 24 April 1984
; Updated to include latest video attribute TCRT calls. /RBC
;[101] 3 January 1983
; Updated to support revised AM-61.
;[100] 6 May 1983
; Convert from AM-60.
;
;VEDIT = 111.
;
;********************
;* AM62A *
;********************
;Terminal driver communications area
AM62: WORD TD$NEW!TD$TCH ; terminal attributes
BR JMPINP ; input routine
RTN ; output routine
BR ECHO ; echo routine
BR JMPCRT ; crt control
BR JMPINI ; INIT routine
WORD 2. ; impure area of one word (2 bytes)
ROWCNT: BYTE 24. ; number of rows
BYTE 80. ; number of columns
LWORD TDVFLG ; terminal flags
BR JMPTCH ; entry for TRMCHR
JMPINP: JMP INP ; go handle input characters
JMPCRT: JMP CRT ; go handle TCRT codes
JMPINI: JMP INI ; go handle initialization
JMPTCH: JMP TCH ; go handle TRMCHR call
PAGE
;********************
;* ECHO *
;********************
;Special echo processing is performed here
;Rubouts will backspace and erase the previous character
;Control-U will erase the entire line by backspacing and erasing
ECHO: CMPB D1,#25 ; control-U
BEQ CTRLU
CMPB D1,#177 ; rubout
BNE ECHX
;Rubouts are handled by the old backspace-and-erase game
;Special handling must be performed if we are rubbing out a tab
;D6 contains the character being rubbed out
RUBOUT: CMPB D6,#11 ; was it a tab?
BEQ RBTB ; yes -
CMPB D6,#40 ; no, was it a control char. ? [106]
BLO RBX ; yes - [106][107]
;Rubout was of a printable character - queue up the backspace sequence
KRTG: MOV #3,D3 ; set character count
LEA A6,ERUB ; set buffer address
MOV A6,D1 ; into D1
TRMBFQ ; queue the backspace sequence
RBX: RTN ; [106]
ERUB: BYTE 10,40,10,0
;Rubout was of a tab - we must calculate how big the tab was and backup over it
RBTB: CLR D3 ; preclear D3
MOVW T.POB(A5),D3 ; set beginning position count
MOV T.ICC(A5),D2 ; set input character count
MOV T.IBF(A5),A6 ; set input buffer base
KRTS: DEC D2 ; done with scan?
BMI KRTQ ; yes -
MOVB (A6)+,D1 ; scan forward calculating position
CMPB D1,#11 ; tab -
BEQ KRTT
CMPB D1,#15 ; carriage return -
BEQ KRTC
CMPB D1,#33 ; escape -
BEQ KRTI
CMPB D1,#40 ; control-char -
BLO KRTS
CMPB D1,#172
BHI KRTS
KRTI: INC D3 ; increment position for one character
BR KRTS
KRTT: ADD #10,D3 ; adjust position for tab
AND #^C7,D3
BR KRTS
KRTC: CLR D3 ; clear position for cr
BR KRTS
KRTQ: COM D3 ; calculate necessary backspaces
AND #7,D3
INC D3
MOV #10,D1 ; set immediate backspace character
TRMBFQ ; queue the backspaces
ECHX: RTN
;Echo a control-U by erasing the entire line
CTRLU: TST D6 ; no action if nothing to erase
BEQ CTUX
CLR D3 ; preclear D3
MOVW T.POO(A5),D3 ; calculate backspace number to erase line
SUBW T.POB(A5),D3
BEQ ECHX
CMP D3,T.ILS(A5) ; insure not greater than terminal width
BLOS CLUA
MOV T.ILS(A5),D3
CLUA: MOV #10,D1 ; queue up backspaces
TRMBFQ
ASL D1,#2 ; queue up spaces
TRMBFQ
MOV #10,D1 ; queue up backspaces
TRMBFQ
CTUX: RTN
PAGE
;********************
;* INP *
;********************
;Input character processing subroutine
;Return a negative flag to indicate possible multi-byte key codes
;Detect a negative flag which indicates the multi-byte processing return
INP: BMI INMLT ; skip if multi-byte processing
CMPB D1,#1 ; function code?
BEQ INPM ; yes - could be multi-byte sequence
CMPB D1,#33 ; escape?
BEQ INPM ; yes - could be multi-byte sequence
LCC #0 ; no - normal processing
RTN
INPM: LCC #PS.N ; possible multi-byte - return N flag
RTN
;Multi-byte processing is done here
;This occurs when TRMSER has accumulated all bytes of a multi-byte keystroke
;D0 contains the character count and A0 indexes the data string
;A5 indexes the terminal definition block and must be preserved
;The translated character must be returned in D1 for storage
;This routine may destroy only A0,A3,A6,D0,D6,D7
INMLT: MOVB (A0)+,D1 ; get the first character
DECB D0 ; no translation if single character
BEQ INMX
CMPB D1,#1 ; function sequences start with SOH
BEQ INMF ; function sequence -
;Escape sequences are translated directly by setting bit 7 on
;This will cause them to map to 240-377
MOVB (A0)+,D1 ; get the second character
INMG: ORB #200,D1 ; set bit 7 on
BIT #T$XLT,@A5 ; are we doing translation?
BEQ INMNOT ; no - check for another translation
INMX: LCC #0 ; reset the flags
INMX2: RTN
;Function codes require additional translation so that they become 200-237
INMF: MOVB (A0)+,D1 ; get the second character
SUBB #'@,D1 ; offset so that F1 becomes 0
BR INMG ; and go finish up
;Come here if program is not doing translation and we must do our own
INMNOT: LEA A6,XLTTBL ; index the translation table
10$: MOVB (A6)+,D7 ; get character
BEQ INMX2 ; end of table - ignore the character
CMPB D1,D7 ; is it in the table?
BEQ 20$ ; yes -
INC A6 ; no - bypass translation
BR 10$ ; loop for more -
;Come here to translate the character
20$: MOVB @A6,D1 ; translate the character
BR INMX
PAGE
;********************
;* INI *
;********************
;Handle initialization of the *MODEM*
INI: MOV T.IMP(A5),A6 ; index impure area
MOVW #80.,@A6 ; preset to 80 columns
MOV T.IDV(A5),A6 ; index the interface driver [106]
CMP -(A6),#<[PSE]_16.>+[UDO]; is it the pseudo interface driver? [106]
BEQ 100$ ; yes - no modem initialization wanted [106]
CMP QFREE,#12. ; are there at least 12 queue blocks? [106]
BLO 100$ ; no - skip the initialization [106]
MOV SYSTEM,D7 ;
BTST #SY%UP,D7 ; booting up ?
BNE 100$ ; no - don't init modem
ORW #<T$ECS!T$DAT!T$IMI>,@A5; disable echoing, enable image mode
QGET A6 ;
CLR (A6) ;
MOV #10000.,4(A6) ; use a timer routine to finish
PEA TMRCOD ; terminal initialization
POP 8.(A6) ;
MOV A5,12.(A6) ; set TDV pointer for interrupt handler
PEA INISEQ
POP 16.(A6) ; store address of start up structure
TIMER (A6) ; start up stuff executes later
; by timer routine until end of
; start up structure.
100$: RTN ;
; define INISTR macro to allow any normal M68 expressions to be used to
; define a terminal/modem init string. The TMRCOD routine queues up output
; and then delays for DELAY timer ticks before executing the next term/modem
; init string. When TMRCOD sees that the delay is 0, it dequeues its
; timer block and that concludes the extended init sequence.
DEFINE INISTR DELAY,A,B,C
LWORD 20$$-10$$ ; output count
LWORD 30$$-10$$ ; offset to next entry
LWORD DELAY ; ticks to next timer
10$$: A
B
C
20$$: EVEN
30$$:
ENDM
;routine executed each time timer expires until all strings and delays
;complete.
TMRCOD: SAVE A1,A3,A5,D0,D1
MOV (A0)+,A5 ; get port's TCB pointer
MOV @A0,A1 ; get pointer to ini sequence
SUB #16.,A0 ; get queue block base address
CMP QFREE,#12. ; are there at least 12 queue blocks? [106]
BLO 20$ ; no - abort entire sequence.
LEA A3, T.OQX(A5) ; Index the output queue.
QINS A3 ; Insert a queue block.
MOV (A1)+,4(A3) ; Set output count. [103]
MOV (A1)+,D0 ; get offset to next entry
MOV (A1)+,D1 ; get next timer count
MOV A1,10(A3) ; Set address of output string
TINIT @A5 ; kickstart the transmitter
TST D1 ; do we have another entry?
BEQ 20$ ; no next timer, reclaim timer block
ADD D0,A1 ; update seq ptr to next entry
CLR (A0) ;
MOV D1,4(A0) ; ticks till next output
PEA TMRCOD ; terminal initialization
POP 8.(A0) ;
MOV A5,12.(A0) ; set TDV pointer for interrupt handler
MOV A1,16.(A0) ; store address of start up structure
TIMER (A0) ; start up stuff executes later
BR 100$
20$: CLR T.ICC(A5)
CLR T.ECC(A5)
CLR T.BCC(A5) ; flush the input buffers
ANDW #^C<T$ECS!T$DAT!T$IMI>,@A5; re-enable normal echoing & line mode
QRET A0 ; and give it back to system
100$: REST A1,A3,A5,D0,D1 ; restore regs we used
RTN ; return to the shadows (timer service)
PAGE
;********************
;* TCH *
;********************
;Handle TRMCHR call
;A1 points to argument block, A2 indexes this TDV, D2 contains flags
;Can only use A1,A2,A6,D1,D2,D6,D7
TCH: MOV TD.FLG(A2),TC.FLG(A1) ; transfer flags
MOV JOBCUR,A6 ; index job
MOV JOBTRM(A6),A6 ; index terminal control area
MOV T.IMP(A6),A6 ; index impure area
CLR D6 ; preclear register
MOVB ROWCNT(A2),D6 ; get row count
MOVW D6,TC.ROW(A1) ; transfer row count
MOVW @A6,TC.COL(A1) ; transfer column count
CLRW TC.CLR(A1) ; no colors
MOVW @A6,D6 ; get current width [110]
MOVW D6,TC.SSL(A1) ; set length of shifted status line [104][110]
MOVW D6,TC.USL(A1) ; set length of unshifted status line [104][110]
SUBW #7.,D6 ; adjust for CAPS/LOCK indicator [110]
MOVW D6,TC.TSL(A1) ; set length of top status line [104][110]
MOV D2,D7 ; get TRMCHR argument flags [104]
AND #TC$BMP,D7 ; does user want bitmap? [104]
BEQ 20$ ; no - skip bitmap transfer code [104]
;User has requested bitmap -- return it to him [104]
PUSH A1 ; save argument block index [104]
ADDW #TC.BMP,A1 ; index bitmap return area [104]
LEA A6,TCHBMP ; index our bitmap [104]
MOV #<256./16.>-1,D7 ; get amount to transfer [104]
10$: MOVW (A6)+,(A1)+ ; transfer to user [104]
DBF D7,10$ ; loop until done [104]
POP A1 ; restore register [104]
20$: RTN ; return to TRMCHR monitor routine [104]
PAGE
;********************
;* CRT *
;********************
;Special CRT control processing
;D1 contains the control code for x,y positioning or special commands
;If D1 is positive we have screen positioning (row in hi byte, col in lo byte)
;If D1 is negative we have the special command in the low byte
CRT: TSTW D1 ; is it cursor position?
BMI CRTS ; no -
TTYI ; send position command
BYTE 33,'=,0
EVEN
PUSH D2 ; save off the register.
MOVB D1,D2 ; save the value in D2
CMPB D2,#96. ; is it beyond column 96?
BLOS 10$ ; no...send as is.
SUBB #96.-32.,D2 ; yes..get offset past column 96. [105]
CLRB D1 ; and clear the low byte.
10$: ADDW #^H1F1F,D1 ; convert to coded format
RORW D1,#8. ; send row first
TTY
ROLW D1,#8. ; send column second
TTY
CMPB D1,#^H1F ; is there a third byte to send?
BNE 20$ ; no..all done.
MOVB D2,D1 ; yes.. send it then.
TTY
20$: POP D2 ; restore the register.
RTN
;Special commands - D1 contains the command code in the low byte
CRTS: CMPB D1,#80. ; set to wide format?
BEQ CRTWID ; yes - special handling
CMPB D1,#81. ; set to normal format?
BEQ CRTNOR ; yes - special handling
;[103]
; Special handling of the printer port calls...
;
CMPB D1,#82. ; Turn on the printer port ?
BEQ PRTON ; Yes.
CMPB D1,#83. ; No. Turn port off ?
BEQ PRTOFF ; Yes.
;
;
AND #377,D1 ; strip the high byte
BNE CRTU ; and branch unless clear screen
TTYI ; special case for clear screen
BYTE 33,';,0
EVEN
CRTZ: RTN
;Set terminal to wide format
CRTWID: TTYI
BYTE 33,'`,';,0
EVEN
MOV #132.,D1 ; get new width
WIDSET: MOV T.IMP(A5),A6 ; index impure area
MOVW D1,@A6 ; store the new width
SLEEP #5000. ; pause while command completes [108]
RTN
;Set terminal to normal format
CRTNOR: TTYI
BYTE 33,'`,':,0
EVEN
MOV #80.,D1 ; get the new width
BR WIDSET ; go store it
;[103]
;
; Code to handle the printer port on/off feature.
; We must sl
eep after we either turn it on or off.
;
PRTON: TTYI
BYTE 24,0 ; Printer port on command. [103]
EVEN
PRTDUN: SLEEP #5000. ; pause while command completes. [103]
RTN
; Turn printer port off and wait the same as when turning it on.
;
PRTOFF: TTYI
BYTE 30,0 ; Printer port off command. [103]
EVEN ;
BR PRTDUN ; go store it [103]
;Command processing per director tables
CRTU: PUSH A2
ASL D1 ; times 2 (word offset)
CMP D1,#CRCB-CRCA ; check for valid code
BHI CRTX ; and bypass if bad
LEA A2,CRCA-2 ; index the table
ADD D1,A2 ; add command code
MOVW @A2,D1 ; pick up data field offset
ADD D1,A2 ; make absolute data address
TTYL @A2 ; print the data field
CRTX: POP A2 ; restore A2
RTN
DEFINE OFFTAB A1,A2,A3,A4,A5,A6,A7,A8,A9,A10
IF NB, A1, WORD A1-.
IF NB, A2, WORD A2-.
IF NB, A3, WORD A3-.
IF NB, A4, WORD A4-.
IF NB, A5, WORD A5-.
IF NB, A6, WORD A6-.
IF NB, A7, WORD A7-.
IF NB, A8, WORD A8-.
IF NB, A9, WORD A9-.
IF NB, A10, WORD A10-.
ENDM