       ASB,HEX   ;PT774 - 11/10/76 - 1130 HOURS 
;*********************
; VERSION LEVEL CODE *
;*********************
VERSN  EQU  120Q      ;P => VERSION 0 
VERSN1 EQU  121Q      ;Q => VERSION 1 
; 
;  NOTE:  THE SECOND ROM WAS RE-ORDERED TO FIX
;  A BUG, SO ONLY THAT ROM HAS VERSION NUMBER 1.
; 
; 
;  COMMON EQUATES - CM35 - 6/27/76 - 1830 HOURS 
; 
FSTRAM EQU  110400Q   ;FAST RAM LOWER LIMIT 
;***************************************
; KBDCSW - KEYBOARD DATA COMM SWITCHES *
;***************************************
FULDUP EQU  200Q      ;HALF/FULL DUPLEX 
;************************************** 
; KBJMPR - KEYBOARD INTERFACE JUMPERS * 
;************************************** 
; 
;  JUMPERS SENSED AS 0' WHEN INSERTED 
; 
;  ALL JUMPERS ARE NORMALLY INSERTED
; 
CONDIS EQU 001Q     ;CONTROL CODE DISABLE 
;                     (0=DISABLED)
SPLDIS EQU 002Q     ;SPOW LATCH DISABLE 
;                     (0=DISABLED)
LINWRP EQU 004Q     ;COLUMN 80 AUTO CR,LF 
;                     (0=ENABLED) 
PAGSTR EQU 010Q     ;PAGE MODE STRAP
;                     (0=LINE-FIELD MODE) 
LFPOS  EQU 20Q      ;LINE FEED POSITION 
;                     (0 = POSITION LINE FEED 
;                         AT START OF NEXT I/O
;                         READ
;                      1 = PUT LINE FEED AT END 
;                         OF RECORD)
FSTSND EQU 40Q      ;9600 BAUD DATACOM SHIFT
;                     (0=9600 BAUD FOR ESC,E) 
HNDSHK EQU 100Q     ;BLOCK TRANSFER HANDSHAKE 
;                     (0 = FOLLOW DC2SND SETTING
;                      1 = SEND DC2 BEFORE DATA)
DC2SND EQU 200Q 
;                     (0 = SEND DC2 ON ENTER
;                          AND FUNCTION KEY IN
;                          BLOCK MODE 
;                      1 = INHIBIT ALL DC2
;                          HANDSHAKE) 
 
;****************************************** 
; KBJMP2 - SECOND SET OF KEYBOARD JUMPERS * 
;****************************************** 
AUTTRM EQU  1Q        ;AUTO TERMINATE ON "ENTER"
CLRTRM EQU  2Q        ;CLEAR TERMINATOR ON TRANSMI
NOTEST EQU  4Q        ;INHIBIT TERMINAL SELF-TEST 
EDTWRP EQU  10Q       ;INVERT SENSE OF EDIT WRAP
PRNTAL EQU  20Q       ;SEND ALL CODES TO PRINTER
DCJMP0 EQU  200Q      ;DATA COMM JUMPER 
;*****************************************
; KBJMP3 - THIRD SET OF KEYBOARD JUMPERS *
;*****************************************
DCJMP1 EQU  1Q        ;DATA COMM JUMPERS
DCJMP2 EQU  2Q              ;.
DCJMP3 EQU  4Q              ;.
DCJMP4 EQU  10Q             ;.
NODCST EQU  20Q       ;INHIBIT DATA COMM SELF-TEST
;                       (0 = DISABLED)
SETCH  EQU  40Q       ;TURN ON "CH" CONTROL LINE
;                       (0 = OFF, 1 = ON) 
CHEKCC EQU  100Q      ;MONITOR CC CONTROL LINE
;                       (1 = ENABLED) 
FRCPTY EQU  200Q      ;FORCE PARITY ON/NO IN CHECK
;                       (1 = ENABLED) 
;************************ 
; CMFLGS - COMMON FLAGS * 
;************************ 
BLKTRG EQU  1Q        ;BLOCK TRANSFER TRIGGER 
INSWRP EQU  2Q        ;INSERT WITH WRAP AROUND
FRCRST EQU  4Q        ;FORCE FULL TERMINAL RESET
DEFSKY EQU  10Q       ;DEFINE SOFT KEY MODE ENABLE
REMSET EQU  20Q       ;REMOTE MODE ENABLED
RCVMDE EQU  40Q       ;TERMINAL IN RECEIVE MODE 
;***********************
; ERRFLG - ERROR FLAGS *
;***********************
DCMERR EQU  1Q        ;DATACOM (1 = ERROR)
TESTOK EQU  2Q        ;SELF-TEST (0 = ERROR)
LDRCHK EQU  4Q        ;LOADER CHECKSUM (0 = ERROR)
;************************** 
; INTFLG - INTERRUPT FLAG * 
;************************** 
TMRINT EQU  3         ;TIMER INTERRUPT
 
;***********************************
; PRCCTL - PROCESSOR CONTROL FLAGS *
;***********************************
TMIACK EQU  0Q        ;ACKNOWLEDGE TIMER INTERRUPT
;                       (BIT 1 OFF) 
TMRON  EQU  1Q        ;SET TIMER ON 
TMIEN  EQU  2Q        ;RE-ENABLE TIMER INTERRUPT
DCIOFF EQU  20Q       ;DISABLE DATA COMM INTERRUPT
TMIOFF EQU  40Q       ;DISABLE TIMER INTERRUPTS 
POLL   EQU  100Q      ;POLL CTU INTERRUPTS
SETROM EQU  200Q      ;DISABLE (1)/ENABLE (0) ROM 
;*********************************
; MDFLG1 - TERMINAL MODE FLAGS 1 *
;*********************************
DSPFNC EQU  1Q        ;DISPLAY FUNCTIONS ENABLED
INSCHR EQU  2Q        ;INSERT CHARACTER ENABLED 
MEMLOK EQU  4Q        ;MEMORY LOCK ENABLED
FORMAT EQU  10Q       ;FORMAT MODE ENABLED
EDIT   EQU  20Q       ;EDIT MODE ENABLED
SELECT EQU  40Q       ;SELECT MODE ENABLED
RECORD EQU  100Q      ;RECORD MODE ENABLED
FORGN  EQU  200Q      ;FOREIGN MODE ENABLED 
;*********************************
; MDFLG2 - TERMINAL MODE FLAGS 2 *
;*********************************
CAPSLK EQU  1Q        ;CAPS LOCK ENABLED
BLKMDE EQU  2Q        ;BLOCK MODE ENABLED 
AUTOLF EQU  4Q        ;AUTO LF ENABLED
REMOTE EQU  10Q       ;REMOTE ENABLED 
WBSR   EQU  40Q       ;WRITE-BACKSPACE-READ MODE
;********************************************** 
; RADIX - BASE OF INPUT PARAMETER FOR ESC SEQ * 
;********************************************** 
DECRDX EQU  10        ;DECIMAL NUMBERS
OCTRDX EQU  8         ;OCTAL NUMBERS
 
;*******************
; COMMON VARIABLES *
;*******************
INTVEC EQU  FSTRAM+145Q  ;CENTRAL INTERRUPT VECTOR
SCNVEC EQU  INTVEC+3  ;FOREIGN TERMINAL DISPLY SCA
; 
COMMON EQU  177777Q   ;UPPER LIMIT OF COMMON AREA 
CMBASE EQU  COMMON/256  ;MSB OF COMMON ADDRESSES
CMSTOR EQU  CMBASE*256  ;MSB ADJUSTMENT FACTOR
; 
DISPST EQU  COMMON-1  ;DISPLAY REFRESH START PTR
TRMTYP EQU  DISPST-1  ;TERMINAL TYPE NUMBER 
KBDCSW EQU  TRMTYP-1  ;KEYBOARD DATACOM SWITCHES
KBJMPR EQU  KBDCSW-1  ;KEYBOARD STRAPS
KBJMP2 EQU  KBJMPR-1    ;SET 2
KBJMP3 EQU  KBJMP2-1    ;SET 3
CMFLGS EQU  KBJMP3-1  ;COMMON FLAGS 
ERRFLG EQU  CMFLGS-1  ;ERROR FLAGS
INTFLG EQU  ERRFLG-1  ;INTERRUPT FLAG 
PRCCTL EQU  INTFLG-1  ;PROCESSOR CONTROL FLAGS
MDFLG1 EQU  PRCCTL-1  ;TERMINAL MODE FLAGS 1
MDFLG2 EQU  MDFLG1-1    ;AND 2
MSGPT1 EQU  MDFLG2-2  ;MESSAGE POINTERS 
MSGPT2 EQU  MSGPT1-2       ;. 
MSGPT3 EQU  MSGPT2-2       ;. 
MSGPT4 EQU  MSGPT3-2       ;. 
MSGPT5 EQU  MSGPT4-2       ;. 
MSGPT6 EQU  MSGPT5-2       ;. 
MSGPT7 EQU  MSGPT6-2       ;. 
MSGPT8 EQU  MSGPT7-2       ;. 
CTIVEC EQU  MSGPT8-2  ;CTU INTERRUPT VECTOR 
CTIJMP EQU  CTIVEC-1  ;JUMP CODE FOR VECTOR 
IODATA EQU  CTIJMP-2  ;ESQ SEQ PARM ACCUMULATOR 
IOCSGN EQU  IODATA-1  ;SIGN FOR PARAMETER 
IOPSGN EQU  IOCSGN-1  ;PARAMETER SIGN 
PARM1  EQU  IOPSGN-1  ;ESCAPE SEQUENCE PARAMETERS 
PARM2  EQU  PARM1-1        ;. 
PARM3  EQU  PARM2-1        ;. 
PARM4  EQU  PARM3-1        ;. 
PARM5  EQU  PARM4-1        ;. 
PARM6  EQU  PARM5-2        ;. 
RADIX  EQU  PARM6-1   ;RADIX OF PARAMETERS
RNGTA  EQU  RADIX-2   ;CHAR FUNCTION TABLE ADDRESS
ESCFLG EQU  RNGTA-1   ;ESCAPE SEQUENCE FLAG 
;                       = 0, NOT IN ESCAPE SEQ
;                       # 0, ESC SEQ IN PROGRESS
RSTTMR EQU  ESCFLG-1  ;SOFT RESET TIMER 
; * * * * * * * * * * * * * * * * * * * * * * * * 
;  END OF COMMON EQUATES                        * 
;^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^* 
 
;*********************************
; KEYBOARD ENTRY VECTOR POINTERS *
;*********************************
ZKBBAS EQU  44000Q    ;KEYBOARD START ADDRESS 
ZINIKB EQU  ZKBBAS+2  ;INITIALIZE KEYBOARD
ZGETKY EQU  ZINIKB+3  ;GET KEYBOARD KEY 
ZKBCTL EQU  ZGETKY+3  ;PERFORM KEYBOARD CONTROL 
ZKBMON EQU  ZKBCTL+3  ;MONITOR KEYBOARD 
ZSTMD1 EQU  ZKBMON+3  ;SET MODE 1 FLAGS 
ZCLMD1 EQU  ZSTMD1+3  ;CLEAR MODE 1 FLAGS 
ZBELL  EQU  ZCLMD1+3  ;SOUND THE BELL 
ZSTXMT EQU  ZBELL+3   ;TURN ON TRANSMIT LED 
ZCLXMT EQU  ZSTXMT+3  ;TURN OFF TRANSMIT LED
ZSTJPR EQU  ZCLXMT+3  ;SET JUMPERS ESC SEQ ROUTINE
ZSTLKY EQU  ZSTJPR+3  ;SET LATCHING KEYS ROUTINE
ZALPCK EQU  ZSTLKY+3  ;ALPHA KEY ENTRY CHECK
ZNUMCK EQU  ZALPCK+3  ;NUMERIC KEY ENTRY CHECK
; 
;  KEYBOARD CONSTANTS 
; 
FRSALT EQU  ZNUMCK+3  ;INITIAL ALTERNATE CHAR SET 
ALTOUT EQU  FRSALT+1  ;INITIAL ALTERNATE CHAR OUT 
; 
;  KEYBOARD CONTROL CALLS 
; 
LOCKKB EQU  1         ;LOCK KEYBOARD
UNLKKB EQU  2         ;UNLOCK KEYBOARD
RPTKEY EQU  3         ;REPEAT LAST KEY HIT
STBLMD EQU  4         ;SET PERMANENT BLOCK MODE 
STRTST EQU  5         ;START SELF-TEST
ENDTST EQU  6         ;END SELF-TEST
RSETKB EQU  7         ;RESET KEYBOARD 
CKIOKY EQU  8         ;CHECK FOR I/O CONTROL KEY
STPRPT EQU  9         ;STOP KEY REPEAT
CKBRKY EQU  10        ;CHECK FOR BREAK KEY DOWN 
SWCHAR EQU  11        ;SWITCH CHARACTER SET 
SETFRN EQU  12        ;UPDATE FOREIGN MODE
STCHST EQU  13        ;SET FOREIGN OUTPUT MODE
FRNMD1 EQU  14        ;SET FOREIGN MODE 1 
FRNMD2 EQU  15        ;SET FOREIGN MODE 2 
 
;*************************************************
; 
;        DATACOM CONSTANTS
; 
;*************************************************
ZDCBAS EQU  50000Q    ;DATACOM START ADDRESS
TRIGGR EQU  ZDCBAS+2  ;BLOCK TRANSFER TRIGGER 
RECSEP EQU  TRIGGR+1  ;RECORD SEPARATOR CHARACTER 
BLKTRM EQU  RECSEP+1  ;BLOCK TERMINATOR CHARACTER 
DCJMSK EQU  BLKTRM+1  ;DATA COMM JUMPER MASK
DCJMS2 EQU  DCJMSK+1  ;DATA COMM JUMPER MASK #2 
;*************************************************
; 
;        DATACOM ENTRY VECTOR POINTERS
; 
;*************************************************
ZINIDC EQU  ZDCBAS+10Q   ;INITIALIZE DATACOM
ZIN2DC EQU  ZINIDC+3  ;INITIALIZATION CONTINUATOR 
ZDCMON EQU  ZIN2DC+3  ;MONITORING ROUTINE 
ZDCCTL EQU  ZDCMON+3  ;MISC CONTROL FUNCTIONS 
ZDCTST EQU  ZDCCTL+3  ;SELF-TEST
ZGETDC EQU  ZDCTST+3  ;GET DC CHARACTER 
ZPUTDC EQU  ZGETDC+3  ;PUT DC CHARACTER 
ZGTBIN EQU  ZPUTDC+3  ;GET BINARY DC CHARACTER
ZSTBIN EQU  ZGTBIN+3  ;START BINARY OUTPUT
ZNDBIN EQU  ZSTBIN+3  ;END BINARY OUTPUT
ZDCINT EQU  ZNDBIN+3  ;DATACOM INTERRUPTS 
;*************************************************
; 
;        DATACOM CONTROL CALL CODES 
; 
;*************************************************
CLRTRG EQU  0         ;CLEAR BLOCK TRANSFER TRIGGE
SETTRG EQU  1         ;SET BLOCK TRANSFER TRIGGER 
RSETDC EQU  2         ;RESET DATACOM
SETREM EQU  3         ;SET REMOTE MODE
SETLCL EQU  4         ;SET LOCAL MODE 
PUTBRK EQU  5         ;OUTPUT BREAK SIGNAL
DISCNT EQU  6         ;MODEM DISCONNECT 
ENDBLK EQU  7         ;TERMINATE OUTPUT MESSAGE 
SETMON EQU  8         ;ENTER MONITOR MODE 
SETNRM EQU  9         ;ENTER NORMAL MODE
FSTBIN EQU  10        ;ENTER FAST BINARY OUT MODE 
SNDATN EQU  11        ;SEND ATTENTION CODE
SNDFCT EQU  12        ;SEND FUNCTION DATA 
PROMPT EQU  13        ;SEND PROMPT CODE 
 
;****************************** 
; ALTERNATE I/O ENTRY VECTORS * 
;****************************** 
ALTORG EQU  60000Q    ;ALTERNATE I/O START ADDRESS
ZINIAL EQU  ALTORG+2  ;INITIALIZATION ROUTINE 
ZIN2AL EQU  ZINIAL+3  ;INITIALIZATION CONTINUATOR 
ZINTAL EQU  ZIN2AL+3  ;INTERRUPT PROCESSOR
ZMONAL EQU  ZINTAL+3  ;MONITORING ROUTINE 
ZGETAL EQU  ZMONAL+3  ;INPUT ROUTINE
ZPUTAL EQU  ZGETAL+3  ;OUTPUT ROUTINE 
ZCTLAL EQU  ZPUTAL+3  ;CONTROL ROUTINE
ZSTAAL EQU  ZCTLAL+3  ;STATUS ROUTINE 
ZMSGAL EQU  ZSTAAL+3  ;ALTERNATE DEVICE NAME
 
;************************** 
; ASCII CHARACTER EQUATES * 
;************************** 
NULL   EQU  0Q        ;NULL 
LF     EQU  12Q       ;LINE FEED
FF     EQU  14Q       ;FORM FEED
CR     EQU  15Q       ;RETURN 
SO     EQU 016Q 
SI     EQU 017Q 
DC2    EQU  22Q       ;DEVICE CONTROL 2 
DC3    EQU  23Q       ;DEVICE CONTROL 3 
ESC    EQU  33Q       ;ESCAPE 
CTLLIM EQU  40Q       ;CONTROL CODE UPPER LIMIT 
ABLNK  EQU 040Q     ;ASCII BLANK
AMPSND EQU  46Q       ;(&) - AMPERSAND
QUOTE  EQU  47Q       ;(') - SINGLE QUOTE 
ARPARN EQU  51Q       ;[)] - RIGHT PARENTHESIS
PLUS   EQU  53Q       ;PLUS SIGN
COMMA  EQU  54Q       ;COMMA
MINUS  EQU  55Q       ;MINUS SIGN 
PERIOD EQU  56Q       ;(.) - PERIOD 
SLANT  EQU  57Q       ;(/) - SLANT
ZERO   EQU  60Q       ;ASCII ZERO 
TWO    EQU  62Q       ;ASCII TWO
THREE  EQU  63Q       ;ASCII THREE
FOUR   EQU  64Q       ;ASCII FOUR 
FIVE   EQU  65Q       ;ASCII FIVE 
SIX    EQU  66Q       ;ASCII SIX
SEVEN  EQU  67Q       ;ASCII SEVEN
; 
ATSIGN EQU  100Q      ;"AT" SIGN (@)
A      EQU  101Q      ;UPPER CASE A 
C      EQU  103Q      ;UPPER CASE C 
D      EQU  104Q      ;UPPER CASE D 
F      EQU  106Q      ;UPPER CASE F 
H      EQU  110Q      ;UPPER CASE H 
L      EQU  114Q      ;UPPER CASE L 
N      EQU  116Q      ;UPPER CASE N 
P      EQU  120Q      ;UPPER CASE P 
R      EQU  122Q      ;UPPER CASE R 
S      EQU  123Q      ;UPPER CASE S 
T      EQU  124Q      ;UPPER CASE T 
U      EQU  125Q      ;UPPER CASE U 
Y      EQU  131Q      ;UPPER CASE Y 
Z      EQU  132Q      ;UPPER CASE Z 
LFTBKT EQU  133Q      ;LEFT BRACKET 
ABCKSL EQU  134Q      ;(\) - BACK SLANT 
 
;*********************
; LOWER CASE EQUATES *
;*********************
SMALLA EQU  141Q      ;LOWER CASE A 
ALCC   EQU 143Q     ;ASCII LOWER CASE C 
SMALLD EQU  144Q      ;LOWER CASE D 
SMALLF EQU  146Q      ;LOWER CASE F 
SMALLI EQU  151Q      ;LOWER CASE I 
SMALLK EQU  153Q      ;LOWER CASE K 
SMALLP EQU  160Q      ;LOWER CASE P 
SMALLX EQU  170Q      ;LOWER CASE X 
LFTBRC EQU  173Q      ;LEFT BRACE 
VRTBAR EQU  174Q      ;VERTICAL BAR 
ADEL   EQU  177Q      ;DELETE (RUBOUT)
 
;************************ 
; DISPLAY FLAGS EQUATES * 
;************************ 
ENHLIM EQU  277Q      ;MAXIMUM ENHANCEMENT CODE 
STPR   EQU  300Q      ;START PROTECTED FIELD
ENDPR  EQU  301Q      ;END PROTECTED FIELD
XMONLY EQU  302Q      ;START TRANSMIT-ONLY FIELD
FILL   EQU  303Q      ;EOL FILL CHARACTER 
STPFLG EQU  304Q      ;NON-DISPLAYING TERMINATOR
ALPHA  EQU  305Q      ;ALPHABETIC ONLY
NUMBER EQU  306Q      ;NUMERIC ONLY 
ALPHNM EQU  307Q      ;ALPHANUMERIC FIELD 
SFKYAT EQU  310Q      ;SOFT KEY ATTRIBUTE FIELD 
; 
FLDSEP EQU  304Q      ;FIELD SEPARATOR FOR I/O BUF
EOL    EQU 314Q 
EOP    EQU 316Q 
LNKLIM EQU 320Q     ;LOWEST VALUE FOR A LINK
NUM2K  EQU  4000Q     ;NUMBER 2048 (2K) 
B15    EQU  100000Q   ;BIT 15 
JMP    EQU  303Q      ;JUMP INSTRUCTION CODE
RET    EQU  311Q      ;RETURN INSTRUCTION CODE
;************************ 
; MISCELLANEOUS EQUATES * 
;************************ 
MAXROW EQU  23        ;MAXIMUM ROW NUMBER 
MAXCOL EQU  79        ;MAXIMUM COLUMN NUMBER
SFTEND EQU  16        ;LAST SOFT KEY DEFINITION RO
BELLIM EQU  8         ;SPACE FROM RHTMGN FOR BELL 
BLKSM  EQU  17Q       ;BLOCK SIZE MASK
BLKSZ  EQU  16        ;BLOCK SIZE 
IOERRB EQU  10Q       ;I/O ERROR STATUS BIT 
REXMIT EQU  1Q        ;RE-TRANSMIT I/O FLAG 
BINXMT EQU  2         ;SEND BINARY DATA 
SFTDLY EQU  50        ;SOFT RESET PERIOD - .50 SEC
NOSIGN EQU  200Q      ;NO SIGN FLAG FOR INPUT DATA
 
;*********************
; I/O MODULE EQUATES *
;*********************
RESET  EQU  0Q        ;RESET TERMINAL VECTOR
RSTJMP EQU  1Q        ;VECTOR FOR RESTART "PCHL"
PROCSR EQU  160Q      ;PROCESSOR "OUT" PORT 
IOBASE EQU 200Q     ;I/O ADDRESS MSB'S
; 
;  KEYBOARD 
; 
IOKB   EQU  (3Q+IOBASE)*256;MODULE 11 BASE ADDRESS
IOKBCO EQU  IOKB+200Q  ;RESET KEY CONTROL 
RSTON  EQU  2Q         ;RESET ON
RSTOFF EQU  4Q         ;RESET OFF 
NMFCTK EQU  8         ;NUMBER OF FUNCTION KEYS
; 
;  CURSOR CONTROL 
; 
IODISP EQU  (7Q+IOBASE)*256;MODULE 13 BASE ADDRESS
IOCRCL EQU  IODISP+0  ;CURSOR COLUMN ADDRESS
IOCRRW EQU  IODISP+40Q  ;CURSOR ROW ADDRESS 
MAYEOP EQU  40Q       ;DMA ON, EOP IF DMA ROW = RO
MAYEOL EQU  100Q      ;DMA OFF, SKIP EOP IF ROWS =
DMAOFF EQU  140Q      ;DMA OFF
CRTOFF EQU  200Q      ;DISPLAY OFF
INVRS  EQU  202Q      ;INVERSE VIDEO ON 
NORMAL EQU  200Q      ;NORMAL VIDEO ON
; 
;  CARTRIDGE TAPE 
; 
IOCTU  EQU  (13Q+IOBASE*256);MODULE 15 BASE ADDRES
IOCTCO EQU  IOCTU+0Q  ;COMMAND TO CTU 
IOCTSI EQU  IOCTU+0Q  ;STATUS FROM CTU
IOCTDO EQU  IOCTU+40Q  ;DATA TO CTU 
IOCTDI EQU  IOCTU+40Q  ;DATA FROM CTU 
 
; 
;  9866 PRINTER 
; 
IOPTR1 EQU  (15Q+IOBASE)*256;MODULE 16 BASE ADDRES
PTROT1 EQU  IOPTR1+40Q  ;PRINTER DATA OUT 
PTRST1 EQU  IOPTR1+0Q  ;PRINTER STATUS IN 
PTRCL1 EQU  IOPTR1+2Q  ;PRINTER CLEAR 
; 
;  RS-232 PRINTER 
; 
IOPTR2 EQU  (5Q+IOBASE)*256;MODULE 12 BASE ADDRESS
PTROT2 EQU  IOPTR2+100Q  ;INTERFACE CONTROL OUT 
PTRST2 EQU  IOPTR2+40Q  ;PRINTER STATUS IN
PTRDA2 EQU  IOPTR2+140Q  ;PRINTER DATA OUT
PTRCF2 EQU  IOPTR2+100Q  ;OPTION JUMPERS IN 
 
;****************** 
; PRINTER EQUATES * 
;****************** 
; 
;  RS-232 OPTION STRAPS 
; 
;     BITS 2-0   MEANING IF SET 
;     000        EXT BAUD RATE
;     001        110  " 
;     010        150  " 
;     011        300  " 
;     100       1200  " 
;     101       2400  " 
;     110       4800  " 
;     111       9600  " 
; 
;     BIT 3      PARITY SELECT
;       1        EVEN 
;       0        ODD
; 
;     BIT 4      PARITY INHIBIT 
;       1        NO PARITY
;       0        PARITY 
;     BITS 7-5   # OF FILLS 
;     000        HANDSHAKE DEVICE 
;     001        8
;     010        16 
;     011        24 
;     100        32 
;     101        40 
;     110        48 
;     111        56 
;*****************
; DRIVER EQUATES *
;*****************
PTDLY  EQU  1500      ;15 SECOND PRINTER TIME OUT 
;***********************
; 9866 PRINTER EQUATES *
;***********************
PTRDY1 EQU 1        ;PRINTER READY
PTRPO1 EQU 200Q     ;PRINTER OUT OF PAPER 
;*************************
; RS-232 PRINTER EQUATES *
;*************************
PTRDY2 EQU 2        ;PRINTER READY MASK 
PTRSB2 EQU 100Q     ;RS-232 SB LINE STROBE
PTROL2 EQU 40Q      ;PRINTER READY MASK 
PTRHD2 EQU 340Q     ;RS-232 HANDSHAKE PROTOCOL
PTRBD2 EQU 37Q      ;PARITY AND BAUD RATE MASK
 
;**************************** 
; VARIABLE SPACE ALLOCATION * 
;**************************** 
DSPLIM EQU  175777Q   ;DISPLAY UPPER LIMIT
LWDSP  EQU  150000Q/256  ;DISPLAY LOWER LIMIT 
IOBUF  EQU  176000Q 
IOBUFH EQU  IOBUF/256 
IOBUFL EQU  -IOBUFH*256+IOBUF 
IOBUF1 EQU  176000Q 
IOBUF2 EQU  176400Q 
DSPSTR EQU  177000Q+79  ;MESSAGE BUFFER 
PTRBLN EQU  256       ;PRINTER INPUT BUFFER SIZE
;***************************
; OPERATING SYSTEM STORAGE *
;***************************
STACK  EQU  FSTRAM+140Q  ;STACK AREA (96 BYTES) 
OPSTOR EQU  177720Q   ;VARIABLES STORAGE AREA 
BASEH  EQU  OPSTOR/256  ;MSB OF DATA PAGE ADDRESSE
BASE   EQU  BASEH*256  ;DATA PAGE BASE ADDRESS
BASEH2 EQU  BASEH-1   ;BASE VALUES FOR SECOND PAGE
BASE2  EQU  BASEH2*256  ;OF VARIABLES SPACE 
;***************************
; VARIABLE SUBROUTINE CALL *
;***************************
ECONTF EQU OPSTOR-3 ;JUMP SUBROUTINE
CNTFAD EQU  ECONTF+1  ;CHARACTER FUNCTION ADDRESS 
 
;*********************************************
; NORMAL/SOFT KEY SWAPPED DISPLAY PARAMETERS *
;*********************************************
TOPLIN EQU  ECONTF-2  ;LSB PART OF NEXT LINE
;                       POINTER IN TOP DISPLAY
;                       LINE
LSTLIN EQU  TOPLIN-2  ;POINTER TO LSB PART OF 
;                       NEXT LINE POINTER IN
;                       LAST LINE PROCESSED 
LSTCOL EQU  LSTLIN-1  ;COLUMN AND ROW POSITION OF 
LSTROW EQU  LSTCOL-1    ;LAST CHARACTER PROCESSED 
;                       (CORRESPONDS TO CHARACTER 
;                          GIVEN BY "CURADR") 
LSTDCD EQU  LSTROW-1  ;LAST DISPLAY CODE USED 
LSTFMT EQU  LSTDCD-1  ;LAST FORMAT CONTROL USED 
CURADR EQU  LSTFMT-2  ;ADDRESS OF LAST CHARACTER
;                       PROCESSED 
PROFLD EQU  CURADR-1  ;PROTECT STATE OF (CURADR)
;                       = -1, PROTECTED 
;                       # -1, NOT PROTECTED 
;************************ 
; CURRENT CURSOR VALUES * 
;************************ 
CURCOL EQU  PROFLD-1  ;CURRENT COLUMN AND ROW 
CURROW EQU  CURCOL-1    ;POSITION OF CURSOR 
LFTMGN EQU  CURROW-1  ;LEFT MARGIN SETTING
RHTMGN EQU  LFTMGN-1  ;RIGHT MARGIN SETTING 
NUMSWP EQU  ECONTF-RHTMGN  ;# OF SWAP VARIABLES 
SWPSTR EQU  RHTMGN-NUMSWP  ;SWAP BUFFER 
DSPTYP EQU  SWPSTR-1  ;DISPLAY CURRENTLY ENABLED
;                       0 = NORMAL DISPLAY
;                      -1 = SOFT KEY DISPLAY
;*****************************************
; FIXED DISPLAY PARAMETERS (NOT SWAPPED) *
;*****************************************
FRBLKS EQU  DSPTYP-2  ;FREE BLOCKS LIST HEAD
DSPBGN EQU  FRBLKS-2  ;LOW ADDRESS OF DISPLAY AREA
DSPEND EQU  DSPBGN-2  ;HIGH ADDR OF DISPLAY AREA
SFTKYS EQU  DSPEND-2  ;SOFT KEY DISPLAY START ADDR
CURFKY EQU  SFTKYS-2  ;CURRENT FUNCTION KEY CHAR
TLINO  EQU  CURFKY-1  ;TOP LINE ABSOLUTE ROW NUMBE
LLINE  EQU  TLINO-2   ;LAST DISPLAY LINE START ADD
FLINE  EQU  LLINE-2   ;POINTER TO LSB PART OF NEXT
;                       LINE POINTER IN FIRST 
;                       LINE OF NORMAL DISPLAY
 
;******************** 
; SCRATCH VARIABLES * 
;******************** 
TEMP1  EQU  FLINE-1 
TEMP   EQU  TEMP1-1   ;TEMPORARY STORAGE
CHARIN EQU  TEMP-1    ;CHARACTER FROM KEYBOARD
NCHAR  EQU  CHARIN-1  ;NUMBER OF CHARS TO BE ADDED
NROWS  EQU NCHAR-1  ;NO. OF ROWS TO BE ADDED
NBLKS  EQU NROWS-1  ;NO. OF BLOCKS TO BE ADDED
CHSAV  EQU NBLKS-1  ;SAVE AREA FOR CHAR 
;                     PRECEDING LINK
LNKSAV EQU CHSAV-2  ;LINK SAVE AREA 
EOLADR EQU LNKSAV-2 ;ADDR OF LAST EOL 
FRSTBL EQU EOLADR-2 ;FIRST BLOCK IN DISPL1
BLKFIL EQU FRSTBL-1 ;FILL FLAG FOR FNDCHR 
EOLMV  EQU BLKFIL-1 ;FLAG FOR EOLMOV
FILCHR EQU EOLMV-1  ;FILL CHAR SAVE FOR GTBLK 
BFSPCE EQU  147777Q   ;UPPER LIMIT OF BUFFER
LWBUF  EQU  130000Q/256  ;LOWER LIMIT 
BUFBGN EQU  FILCHR-2  ;LOW ADDR OF NON-DISPLY BUFF
BUFEND EQU  BUFBGN-2  ;HIGH ADDR FOR BUFFER 
;**************************************** 
;  STORAGE FOR CHARACTERS TO BE STORED  * 
;**************************************** 
FMTCTL EQU  BUFEND-1  ;FORMAT CONTROL TO BE ENTERE
DCHAR  EQU  FMTCTL-1  ;NEXT CHAR TO BE DISPLAYED
CHAR   EQU  DCHAR-1   ;CURRENT CHAR BEING PROCESSE
CHKRTN EQU  CHAR-2    ;CURRENT TYPE CHECK ROUTINE 
TMPCOL EQU  CHKRTN-1  ;COLUMN # STORAGE FOR RCADDR
;*********************************
; STORAGE FOR CURSOR POSITIONING *
;*********************************
COUNT  EQU  TMPCOL-1  ;NUMBER OF BYTES TO FILL
NMROLL EQU  COUNT-1   ;NUMBER OF LINES TO ROLL
ROLLCT EQU  NMROLL-1  ;ROLL COUNTER 
; 
NEWCOL EQU  PARM1     ;NEW COLUMN NUMBER
NEWROW EQU  PARM2     ;NEW ABSOLUTE ROW NUMBER
SCRNRW EQU  PARM3     ;NEW SCREEN ROW SETTING 
 
;***********************
; HORIZONTAL TAB TABLE *
;***********************
HTBLEN EQU  10        ;TABLE LENGTH (= 10 X 8)
HTBTBL EQU  ROLLCT-HTBLEN 
;***********************
; DISPLAY SEND STORAGE *
;***********************
CDSPEN EQU HTBTBL-1 ;CURRENT ENHANCEMENT IN 
ENHOUT EQU CDSPEN-1 ;LAST ENHANCEMENT OUT 
CALTST EQU ENHOUT-1 ;CURRENT ALTERNATE SET OUT
GETADR EQU  CALTST-2  ;CURRENT CHARACTER ADDRESS
;***************************
; FLAGS AND TABLE POINTERS *
;***************************
CHRSET EQU  GETADR-1  ;CURRENT ALTERNATE CHAR SET 
KBFCTK EQU  CHRSET-1  ;KEYBOARD FUNCTION CODE 
;*************************************************
MFLGS  EQU  KBFCTK-1  ;BLOCK TRANSFER PENDING FLAG
;*************************************************
SDC2   EQU  1Q*256    ;DC2 PENDING
SSTAT  EQU  2Q*256    ;TERMINAL STATUS PENDING
SSTAT2 EQU  4Q*256    ;TERMINAL STATUS 2 PENDING
SDVST  EQU  10Q*256   ;DEVICE STATUS PENDING
SCRSEN EQU  20Q*256   ;CURSOR SENSE PENDING 
SFCTKY EQU  40Q*256   ;FUNCTION KEY PENDING 
SENTER EQU  100Q*256  ;DISPLAY SEND PENDING 
SDVDUN EQU  200Q*256  ;DEVICE DONE PENDING
;*****************************************
MFLGS2 EQU  MFLGS-1   ;MAIN CODE MODE FLAGS 
;*****************************************
SDVREC EQU  1Q        ;DEVICE RECORD PENDING
SBINRY EQU  2Q        ;BINARY RECORD PENDING
RELSNS EQU  4Q        ;RELATIVE CURSOR SENSE
ESCINP EQU 10Q      ;ESC RECEIVED IN BLOCK MODE 
FRSOUT EQU  20Q       ;FIRST SOFT KEY DATA OUT
WRPDEL EQU  40Q       ;DELETE CHAR W/ WRAP AROUND 
WRPFLG EQU  100Q      ;LINE WRAP AROUND OCCURRED
NWRWST EQU  200Q      ;NEW ABSOLUTE ROW SET 
;**************************************** 
DFLGS  EQU  MFLGS2-1  ;DATA TRANSFER FLAGS
;**************************************** 
SDACOM EQU 001Q     ;DATACOM/KEYBOARD 
CNTXFR EQU  2Q        ;CONTINUE BUFFER TO DATA COM
NOSEND EQU  4Q        ;NO DISPLAY DATA TO SEND
SKPTRM EQU  10Q       ;SKIP BLOCK TERMINATOR
FCTK2D EQU  20Q       ;FUNCTION KEY TO DISPLAY
KBDLOK EQU  100Q      ;KB LOCKED BY ESCAPE SEQUENC
XBF2DS EQU  200Q      ;I/O BUFFER TO DISPLAY MODE 
 
;********************************************** 
TRMFCT EQU  DFLGS-1   ;NON-DISPLAYING TERMINATOR
;********************************************** 
STPXFR EQU  -1        ;TERMINATE TRANSFER 
DELTRM EQU  0         ;DELETE TERMINATOR
IGNTRM EQU  1         ;IGNORE TERMINATOR
;****************************************** 
SPOWL  EQU  TRMFCT-1  ;SPACE OVERWRITE LATCH
;****************************************** 
SPOWON EQU  40Q       ;SPOW LATCH ON
SPOWOF EQU  377Q      ;SPOW LATCH OFF 
;*************************************************
MLKROW EQU  SPOWL-1   ;MEMORY LOCK ROW
MLKFLG EQU  MLKROW-1  ;MEMORY LOCK FLAG 
LCHAR  EQU  MLKFLG-1  ;LAST CHARACTER PROCESSED 
TCHAR  EQU  LCHAR-1   ;CURRENT TEST PATTERN CHAR
CRAFLG EQU  TCHAR-1   ;CURSOR ADVANCE FLAG
;*****************************
; POINTERS FOR BINARY LOADER *
;*****************************
LADDR  EQU  PARM6     ;BYTE ADDRESS PARAMETER 
LDATA  EQU  IODATA    ;INPUT DATA ACCUMULATOR 
LCHKSM EQU  PARM5     ;16-BIT CHECKSUM
 
;V*V*V*V*V*V*V*V*V*V*V*V*V*V*V*V*V*V
; 
;  CTU/IO EQUATES - 4/11/76 - 2255 HOURS
; 
; TAPE DISTANCE MEASUREMENT 
; ========================= 
; 
; AS OF 3/1/75, .017125" OF TAPE MOTION IS
; EQUIVALENT TO 1 TACH EDGE.  THE COUNT IS
; IN ERROR WHEN STARTING OR STOPPING BY 
; 1 TACH EDGE (STOPPING IN A GAP MAY CAUSE
; AN ERROR OF TWO TACH EDGES).
; 
;*******************************
CTSTAT EQU  CRAFLG-1  ;CTU STATUS 
;*******************************
TKI    EQU  200Q      ;TACH INTERRUPT 
RDY    EQU 100Q     ;BYTE READY 
GAP    EQU 40Q
HOL    EQU 20Q      ;TAPE HOLE
TAK    EQU 10Q      ;TACH (58.4 EDGES/IN) 
RIP    EQU 4Q       ;RECORD IN PROGRESS 
CIR    EQU  2Q        ;RIGHT CARTRIDGE INSERTED 
CIL    EQU  1Q        ;LEFT CARTRIDGE INSERTED
;******************************** 
IOFLGS EQU  CTSTAT-1  ;I/O FLAGS 1
;******************************** 
RDWOWT EQU  1Q        ;READ WITHOUT WAIT MODE 
USREAD EQU  2Q        ;READ KEY INITIATED READ
FILRED EQU  4Q        ;FILE READ
RECRWD EQU  10Q       ;RECORD DISPLAY AND REWIND
;                       OLD OUTPUT CTU (LOGGING)
RECINI EQU  20Q       ;START "RECORD" MODE
RECPGE EQU  40Q       ;FILE COPY FROM DISPLAY - 
;                       INHIBIT ROLL UP 
VERIFY EQU  200Q      ;"CTU2BF" PERFORMS VERIFY 
;******************************** 
IOFLG2 EQU  IOFLGS-1  ;I/O FLAGS 2
;******************************** 
EXTB2D EQU  1Q        ;EXTERNAL BUFFER TO DATA COM
XDS2BF EQU  40Q       ;TRANSFER DISPLAY TO BUFFER 
DSPBTM EQU  100Q      ;BOTTOM OF DISPLAY REACHED
ENDDSP EQU  200Q      ;END OF DISPLAY REACHED 
 
;******************************** 
UNIT0  EQU  IOFLG2-1  ;UNIT STATUS
;******************************** 
LPM    EQU    1Q      ;TAPE AT OR BEFORE LOAD POIN
LSTFWD EQU    2Q      ;TAPE LAST MOVED FORWARD
FPS    EQU    4Q      ;TAPE WRITE PROTECTED 
CMDEXC EQU   10Q      ;SUCCESSFUL COMMAND EXECUTIO
DBLHOL EQU   20Q      ;DOUBLE HOLE FOUND
BOT    EQU   40Q      ;TAPE PAST BOT HOLES
LP     EQU  100Q      ;TAPE PAST LP HOLE
EW     EQU  200Q      ;TAPE PAST EW HOLE
;*******************************************
CNTRL0 EQU  UNIT0-1   ;DATA TRANSFER FLAGS: * 
;*******************************************
EOF    EQU    1Q      ;END OF FILE
EVD    EQU    2Q      ;END OF VALID DATA
HRDERR EQU    4Q      ;HARD ERROR 
SFTERR EQU   10Q      ;SOFT ERROR 
HRDER1 EQU   20Q      ;INTERRUPT ERROR FLAG 
WRTERR EQU   40Q      ;WRITE ERROR
DATATR EQU  100Q      ;DATA RECORDED
;***********************************************
RELTAK EQU  CNTRL0-1  ;GAP LENGTH COUNTER 
;****************************************** 
ABSTAK EQU  RELTAK-2  ;ABSOLUTE TACH COUNTER
;****************************************** 
STRTAK EQU  40137Q    ;STARTING VALUE 
;*************************************************
FILNUM EQU  ABSTAK-1  ;CURRENT FILE NUMBER
SFTCNT EQU  FILNUM-1  ;SOFT ERRORS PER PASS 
OTHER  EQU  SFTCNT-7  ;STORAGE FOR UNIT NOT SEL.
;*******************************************
CMND   EQU  OTHER-1   ;CURRENT CTU COMMAND: * 
;*******************************************
RUN    EQU 1Q       ;MOVE TAPE
FWD    EQU 2Q       ;FORWARD
FST    EQU 4Q       ;FAST 
REC    EQU 10Q      ;RECORD 
USL    EQU  20Q       ;SELECT LEFT UNIT 
GEN    EQU 40Q      ;GAP GENERATE 
ANR    EQU  100Q      ;LIGHT FOR RIGHT UNIT 
ANL    EQU  200Q      ;LIGHT FOR LEFT UNIT
;*****************************************
;  INPDEV, OUTDEV, BXSTAT - I/O DEVICES  *
;*****************************************
LFTCTU EQU    1Q      ;LEFT CARTRIDGE TAPE UNIT 
RGTCTU EQU    2Q      ;RIGHT CARTRIDGE TAPE UNIT
DISPLY EQU    4Q      ;DISPLAY
PRINTR EQU   10Q      ;PRINTER
ALTIO  EQU   20Q      ;ALTERNATE I/O
DATCOM EQU   40Q      ;DATA COMM
BUFBSY EQU  200Q      ;BUF HELD BY UNSPECIFIED DEV
 
SCNCNT EQU  CMND-1    ;NUM. OF KBSCAN PER CTU SCAN
CTBLNK EQU  SCNCNT-1  ;BLINK MASK FOR EJECT LIGHTS
CTBLTM EQU  CTBLNK-1  ;BLINK TIMER
CTBDLY EQU  40Q       ;BLINK DELAY
HOLCNT EQU  CTBLTM-1  ;HOLE COUNTER 
TPSTAL EQU  HOLCNT-1  ;TAPE STALL COUNTER 
;***************
; I/O VARIBLES *
;***************
IOCERR EQU  TPSTAL-1  ;I/O ERROR FLAG 
;                       0 = NO ERROR
;                      -1 = ERROR OCCURRED
INPDEV EQU  IOCERR-1  ;CURRENT INPUT DEVICE 
OUTDEV EQU INPDEV-1 ;CURRENT OUTPUT DEVICE
IOCDPT EQU OUTDEV-1 ;DEVICE FLAG POINTER
IOSTA3 EQU  IOCDPT-1  ;DEVICE STATUS BYTE 3 
IOSTA2 EQU  IOSTA3-1  ;DEVICE STATUS BYTE 2 
IOSTA1 EQU  IOSTA2-1  ;DEVICE STATUS BYTE 1 
IOSTA0 EQU  IOSTA1-1  ;DEVICE NUMBER FOR STATUS 
XFRLIM EQU  IOSTA0-1  ;TRANSFER LIMIT 
CMPLIM EQU  XFRLIM-1  ;COMPARE LIMIT
B2DBUF EQU  CMPLIM-9  ;BIN TO DECIMAL CONV BUFFER 
B2DBFL EQU  B2DBUF-BASE  ;LSB PART OF "B2DBUF"
B2DPTR EQU  B2DBUF-1  ;B2DBUF "GET" POINTER (LSB) 
B2DEND EQU B2DPTR-1 ;B2DBUF END POINTER 
; 
;  I/O CONTROL VARIABLES
; 
IOCDEV EQU  PARM1     ;DEVICE FLAG
IOCOUT EQU  PARM2     ;OUTPUT DEVICE ACCUMULATOR
IOCINP EQU  PARM3     ;INPUT DEVICE ACCUMULATOR 
IOCTYP EQU  PARM4     ;COMMAND MODIFIER FLAG
IOCMND EQU  PARM5     ;COMMAND TYPE FLAG
IOCCNT EQU  PARM6     ;DATA COUNT (2 BYTES) 
 
; 
;  I/O BUFFER INFORMATION STORAGE 
; 
B1STAT EQU  B2DEND-1  ;STATUS OF FIRST BUFFER 
B1TYPE EQU  B1STAT-1  ;TYPE (-1=NORM, 0=EOF, 1=EVD
B1LEN  EQU  B1TYPE-1  ;LENGTH OF RECORD 
B2STAT EQU  B1LEN-1   ;STATUS OF SECOND BUFFER
B2TYPE EQU  B2STAT-1  ;TYPE (-1=NORM, 0=EOF, 1=EVD
B2LEN  EQU  B2TYPE-1  ;LENGTH OF RECORD 
; 
;  STORAGE FOR CARTRIDGE TAPE INTERRUPT ROUTINES
; 
CTIADR EQU  B2LEN-2   ;ADDRESS (HAS SEVERAL USES) 
CTISPT EQU  CTIADR-2  ;POINTER TO BUFFER STATUS 
CTIBPT EQU  CTISPT-2  ;POINTER TO BUFFER
CTICNT EQU  CTIBPT-3  ;GENERAL COUNTERS 
CTITRL EQU  CTICNT-1  ;RE-READ COUNTER, HOLE CNTR 
CTICSM EQU  CTITRL-1  ;CHECKSUM COUNTER 
CTISTA EQU  CTICSM-1  ;COMMAND SOURCE FLAG
; 
;  STORAGE FOR READ AND RECORD
; 
NXTRED EQU  CTISTA-2  ;PTR INTO BUF FOR NEXT READ 
LSTRED EQU  NXTRED-2  ;PTR INTO BUF FOR READ REPEA
SWPCTU EQU  LSTRED-1  ;SWAP CTU IN LOGGING MODE 
;                       -1 = SWAP ENABLED 
;                        0 = DISABLED 
SAVINP EQU  SWPCTU-1  ;"INPDEV" SAVE FOR LOCAL RCR
SAVOUT EQU  SAVINP-1  ;SAVE OUTDEV DURING LCL READ
; 
;  DATA FOR FORMAT DISPLAY STORAGE
; 
ENDCOL EQU  SAVOUT-1  ;ENDING COLUMN AND ROW FOR
ENDROW EQU  ENDCOL-1    ;PREV NON-PROTECTED FIELD 
 
; 
;  EXTENDED MAIN CODE RAM AREA
; 
XTRASP EQU  177200Q 
;**************************************** 
DEVFLG EQU  XTRASP-1  ;DEVICE PRESENT FLAG
;**************************************** 
CTUIN  EQU  200Q      ;CTU CODE PRESENT 
ALTIN  EQU  100Q      ;ALTERNATE I/O PRESENT
;******************** 
; PRINTER VARIABLES * 
;******************** 
PTRBBG EQU  DEVFLG-2  ;START OF PRINTER BUFFER
PTRSPT EQU  PTRBBG-2  ;LOAD POINTER 
PTRBPT EQU  PTRSPT-2  ;UNLOAD POINTER 
PTRABT EQU  PTRBPT-1  ;PRINTER ERROR FLAG 
;                       =  0, NO PRINTER ERROR
;                       = -1, PRINT ERROR OCCURRED
PTRFLG EQU  PTRABT-1  ;PRINTER TYPE FLAG
;                       = 0, NO PRINTER 
;                       = 1, PARALLEL INTERFACE 
;                       = 2, RS-232 INTERFACE 
 
;******************************** 
; ENTRY VECTORS TO I/O ROUTINES * 
;******************************** 
; 
;  KEYBOARD INITIATED FUNCTIONS 
; 
IOORG  EQU  24000Q    ;START OF I/O CODE
IOCKEY EQU  IOORG+2   ;I/O CONTROL KEY
REDKEY EQU  IOCKEY+3  ;READ KEY 
CTLRED EQU  REDKEY+3  ;CONTROL READ KEY 
RECKEY EQU  CTLRED+3  ;RECORD KEY 
SELKEY EQU  RECKEY+3  ;SELECT KEY 
TSTCTU EQU  SELKEY+3  ;CTU SELF-TEST
CONDTN EQU  TSTCTU+3  ;CONDITION CARTRIDGE TAPES
RSTCTU EQU  CONDTN+3  ;SOFT RESET FOR CTU 
; 
;  EXTERNALLY INITIATED FUNCTIONS 
; 
IOCNTL EQU  RSTCTU+3  ;I/O CONTROL ESCAPE SEQUENCE
IOSTGO EQU  IOCNTL+3  ;SEND DEVICE STATUS 
IODNGO EQU  IOSTGO+3  ;SEND COMPLETION CODE 
IORDGO EQU  IODNGO+3  ;SEND I/O RECORD
RCRDGO EQU  IORDGO+3  ;START REMOTE RECORD FUNCTIO
BNRYGO EQU  RCRDGO+3  ;SEND BINARY DATA 
CTDCDP EQU  BNRYGO+3  ;SEND BINARY FILE 
;******************** 
; INTERNAL ROUTINES * 
;******************** 
CTMON  EQU  CTDCDP+3  ;MONITOR CARTRIDGE DRIVES 
PTTPLN EQU  CTMON+3   ;PUT TOP LINE ONTO I/O DEV'S
DO0CTI EQU  PTTPLN+3  ;INITIAL CTU INTERRUPT VECTO
RDABRT EQU  DO0CTI+2  ;ABORT USER INITIATED READ
BSYCHK EQU  RDABRT+3  ;WAIT UNTIL TAPE I/O DONE 
CTINTR EQU  BSYCHK+3  ;CTU INTERRUPT ROUTINE
 
;******************** 
; TERMINAL START-UP * 
;******************** 
       ORG  0Q
BEGIN  EQU  $ 
       DB   VERSN     ;ROM PRESENT FLAGS
       DB   BEGIN/256   ;(= MOV D,B; NOP) 
       DI             ;DISABLE INTERRUPTS 
       MVI  A,SETROM+TMIEN+TMRON
       JMP  GO        ;GO TO START UP ROUTINE 
;*****************************
; FIRMWARE INVOKED INTERRUPT *
;*****************************
       PCHL           ;USE AS PCHL SUBROUTINE CALL
       ORG  BEGIN+20Q 
;************************** 
; TOP PLANE INTERRUPT 20B * 
;************************** 
       PUSH PSW       ;SAVE A-REGISTER AND FLAGS
       ORA  A         ;CLEAR C-FLAG 
       MVI  A,TWO     ;SET INTERRUPT CODE 
       JMP  INTRPT    ;HANDLE UNKNOWN INTERRUPTS
       ORG  BEGIN+30Q 
;****************** 
; TIMER INTERRUPT * 
;****************** 
       PUSH PSW       ;SAVE A-REGISTER, FLAGS 
       PUSH B           ;AND REGISTER B AND C 
       MVI  A,THREE   ;SET INTERRUPT CODE 
       JMP  TMINTR    ;CONTINUE TIMER ROUTINE 
       ORG  BEGIN+40Q 
;********************** 
; DATA COMM INTERRUPT * 
;********************** 
       PUSH PSW       ;SAVE A-REGISTER AND FLAGS
       MVI  A,FOUR    ;SET INTERRUPT CODE 
       JMP  DCMINT    ;CONTINUE INTERRUPT PROCESS 
       ORG  BEGIN+50Q 
;***********************
; I/O DEVICE INTERRUPT *
;***********************
       PUSH PSW       ;SAVE A-REG, STATUS 
       PUSH H           ;AND H,L
       MVI  A,FIVE    ;SET INTERRUPT CODE 
       JMP  IOINTR    ;CONTINUE I/O ROUTINE 
       ORG  BEGIN+60Q 
 
;************************** 
; TOP PLANE INTERRUPT 60B * 
;************************** 
       PUSH PSW       ;SAVE A-REGISTER AND FLAGS
       ORA  A         ;CLEAR THE C-FLAG 
       MVI  A,SIX     ;SET INTERRUPT CODE 
       JMP  INTRPT    ;HANDLE UNKNOWN INTERRUPTS
       ORG  BEGIN+70Q 
;***********************
; TEST POINT INTERRUPT *
;***********************
       PUSH PSW       ;SAVE A-REGISTER AND FLAGS
       ORA  A         ;CLEAR THE C-FLAG 
       MVI  A,SEVEN   ;SET INTERRUPT CODE 
       JMP  INTRPT    ;HANDLE UNKNOWN INTERRUPTS
       ORG  BEGIN+100Q
 
;******************************** 
; VECTORS TO MAIN CODE ROUTINES * 
;******************************** 
ZDSPMS:JMP  DSPMSG    ;DISPLAY MESSAGE
       JMP  RSTDSP    ;RESTORE NORMAL DISPLAY 
       JMP  DCNUM     ;ACCUMULATE DIGIT AND SIGN
       JMP  DCPLUS      ;FOR PARAMETERIZED ESCAPE 
       JMP  DCMNUS      ;SEQUENCES
       JMP  ESCEND    ;TERMINATE ESCAPE SEQUENCE
       JMP  CHKLIM
       JMP  CLBLXF
       JMP  SBLXF0
       JMP  SBLXFA    ;KEYBOARD INITIATED BLK XFR 
       JMP  STRTBL    ;START BLOCK RECORD 
       JMP  CURPH     ;HOME CURSOR (-XMIT ONLY) 
       JMP  CURPHD    ;CURSOR HOME DOWN 
       JMP  FRECNT    ;CHECK NUMBER OF FREE BLOCKS
       JMP  PTBLK     ;RELEASE BLOCKS FROM DISPLAY
       JMP  CLEARL    ;CLEAR LINE 
       JMP  CLEARS    ;CLEAR DISPLAY FROM CURSOR
       JMP  FNDTB2    ;SET BIT N (B-REG = N)
       JMP  SDTERM    ;SEND TERMINATORS 
       JMP  SDTRM1    ;SEND TERMINATOR ONLY 
       JMP  XPUTDC    ;TRANSMIT CHARACTER IN A-REG
       JMP  TRMTST    ;TERMINAL SELF-TEST 
       JMP  CHINT0    ;EXECUTE CHARACTER FUNCTION 
       JMP  INITD0    ;INIT FOR DISPLAY GET 
       JMP  GETDSP    ;GET DISPLAY BYTE 
       JMP  LNFEED    ;DO LINE FEED 
       JMP  EXPAND    ;EXPAND DISPLAY CONTROL CHAR
       JMP  NXTCHR    ;GET NEXT DISPLAY CHARACTER 
       JMP  GETDCM    ;PROCESS DATA COMM INPUT
       JMP  MLKSC0    ;LOCATE FIRST UNLOCKED ROW
       JMP  MLKOF0    ;TURN OFF MEMORY LOCK 
       JMP  HANGU0    ;HANG TERMINAL ON FATAL ERRO
       DW   BUFMSG    ;BUFFER OVERFLOW MESSAGE
       JMP  DCTEST    ;DATA COMM SELF-TEST
       JMP  IORMGO    ;EXECUTE CODE FROM OPTION RO
       JMP  BN2DEC    ;CONVERT BINARY TO DECIMAL
       JMP  BN2DE0    ;CONVERT SINGLE BYTE TO DEC 
       JMP  RCADRA    ;LOCATE CURSOR LOCATION 
       JMP  GTMODE    ;CHECK FOR PAGE MODE
 
;*************************************
; TERMINAL RESET - START UP TERMINAL *
;*************************************
GO     EQU  $ 
       OUT  PROCSR    ;SET INITIAL PROCESSOR STATE
       STA  PRCCTL    ;SET PROCESSOR STATE
       LXI  SP,STACK  ;SET STACK POINTER
       LDA  ECONTF
       CPI  JMP       ;FIRST TURN ON? 
;************************************************ 
       JNZ  INIT      ;YES - INITIALIZE TERMINAL
;************************************************ 
       LDA  CMFLGS    ;NO - GET COMMON FLAGS
       ANI  FRCRST    ;FORCE FULL RESET?
       JNZ  INIT      ;YES - INITIALIZE TERMINAL
       LXI  H,RSTTMR  ;NO - GET SOFT RESET TIMER
       ORA  M         ;FULL RESET ACTIVE? 
       JZ   GO010     ;NO - START SOFT RESET
       CPI  SFTDLY    ;STILL IN SOFT RESET START? 
;                       (CAUSED BY CONTACT BOUNCE)
       JNZ  INIT      ;NO - DO FULL RESET 
GO010  EQU  $         ;YES - RESTART SOFT RESET 
       MVI  M,SFTDLY  ;NO - SET 0.5 SEC TIME OUT
;**************** 
; DO SOFT RESET * 
;**************** 
GO1    EQU  $         ;ENTRY FOR SOFT RESET 
       STA  DFLGS     ;CLEAR DATA TRANSFER FLAGS
       MVI  A,RSETKB
       CALL ZKBCTL    ;RESET THE KEYBOARD 
       MVI  A,RSETDC
       CALL DCMCT1    ;RESET THE DATA COMM
       LXI  H,RSTCTU  ;RESET CARTRDIGE TAPES
       CALL IORMGO      ;IF CTU CODE PRESENT
       CALL RSTDSP    ;RESTORE NORMAL DISPLAY 
       EI             ;ENABLE INTERRUPTS
       JMP  START     ;RESTART THE WAIT LOOP
 
;*********************************************
; INIT - DO COMPLETE TERMINAL INITIALIZATION *
;*********************************************
INIT   EQU  $ 
       XRA  A         ;CLEAR TO ZERO
       STA  ECONTF    ;CLEAR "JMP" TO FORCE FULL
;                       RESET 
       LXI  H,FSTRAM  ;SET FIRST ADDRESS
INI010 EQU  $ 
       MOV  M,A       ;SET BYTE TO ZERO 
       INR  L         ;ALL BYTES DONE?
       JNZ  INI010    ;NO - CLEAR NEXT BYTE 
; 
;  CLEAR SLOW RAM AREA
; 
       MOV  E,L       ;SET E = 0 FOR 256 BYTES
       MVI  H,IOBUF1/256  ;SET START ADDRESS
INI020 EQU  $ 
       CALL CLRAL1    ;CLEAR A 256 BYTE SECTION 
       CMP  H         ;ALL SECTIONS CLEARED?
       JNZ  INI020    ;NO - CONTINUE CLEARING 
;***************************
; LOCATE NON-DISPLAY SPACE *
;***************************
       LXI  H,BFSPCE  ;SET UPPER BOUNDARY ADDRESS 
       SHLD BUFEND      ;OF NON-DISPLAY BUFFER ARE
       MVI  B,LWBUF   ;SET B TO MSB OF LOWER LIMIT
       CALL FNDRAM
       SHLD BUFBGN    ;STORE BUFFER START ADDRESS 
; 
;  LOCATE DISPLAY SPACE 
; 
       LXI  H,DSPLIM  ;SET UPPER BOUNDARY ADDRESS 
       SHLD DSPEND      ;OF DISPLAY AREA
       MVI  B,LWDSP   ;SET B TO MSB OF LOWER LIMIT
       CALL FNDRAM
       SHLD DSPBGN    ;STORE DISPLAY START ADDRESS
 
;********************************************** 
; INITIALIZE PROCESSOR BOARD STATE, KEYBOARD, * 
; AND DATA COMM                               * 
;********************************************** 
       MVI  A,SETROM+TMIEN+TMRON
       STA  PRCCTL    ;ENABLE ROM'S AND TIMER 
       MVI  A,RET     ;PUT RETURN CODE INTO 
       STA  INTVEC      ;INTERRUPT VECTOR AND 
       STA  SCNVEC      ;DISPLAY SCAN VECTOR
;             ********************************* 
;             * INTERRUPTS ARE ENABLED BY THE * 
;             * DISPLAY ROUTINES USED DURING  * 
;             * INITIALIZATION OF SOFT KEYS   * 
;             ********************************* 
       CALL ZINIKB    ;SET JUMPERS AND DC SWITCHES
       CALL ZINIDC    ;FETCH BUFFER REQUIREMENTS
       CALL GETBUF    ;ALLOCATE BUFFER SPACE
       CALL ZIN2DC    ;COMPLETE DATA COMM INIT
       JC   HANGU0      ;(PROCESS ERROR IF ANY) 
;******************************** 
; SET DEFAULT I/O CONFIGURATION * 
;******************************** 
       LXI  H,1*256+2  ;OUTPUT = RIGHT CTU (2)
       SHLD OUTDEV     ;INPUT = LEFT CTU (1)
       LHLD DO0CTI    ;SET INITIAL CARTRIDGE TAPE 
       SHLD CTIVEC      ;INTERRUPT VECTOR 
       MVI  A,JMP     ;SET JUMP COMMAND FOR 
       STA  CTIJMP      ;CTU INTERRUPT VECTOR 
;*******************************************
; IDENTIFY OPTION I/O INCLUDED IN TERMINAL *
;*******************************************
       LXI  H,ZINIAL  ;INITIALIZE ALTERNATE I/O 
       CALL IORMGO      ;DEVICE 
       MVI  A,0         ;(SET FOR NO ALTERNATE I/O
       JC   INI110    ;BYPASS INIT IF NO ALT I/O
       CALL GETBUF      ;ELSE, ALLOCATED BUFFER 
       CALL ZIN2AL      ;AND CONTINUE INIT
       MVI  A,ALTIN   ;SET ALT I/O PRESENT BIT
INI110 EQU  $ 
       MOV  B,A       ;SAVE ALTERNATE I/O STATUS
       LXI  H,IOORG   ;SET I/O START ADDRESS
       CALL IORMG1    ;DOES I/O CODE EXIST? 
       MOV  A,B         ;(GET CURRENT I/O OPTIONS)
       JNZ  INI130    ;NO - DON'T SET I/O BIT 
       ORI  CTUIN     ;ELSE SET CTU PRESENT BIT 
       LXI  H,TRMTYP  ;SET TERM TYPE TO INDICATE
       INR  M           ;I/O CODE INCLUDED
INI130 EQU  $ 
       STA  DEVFLG    ;SET I/O OPTIONS FLAG 
 
;**************************************** 
; GENERATE FREE BLOCKS LIST FOR DISPLAY * 
;**************************************** 
       LHLD DSPEND    ;COMPUTE ADDRESS OF HIGHEST 
       LXI  D,1-BLKSZ  ;ADDRESSED DISPLAY BLOCK 
       DAD  D 
       MOV  A,L       ;COMPUTE ADDRESS OF LSB PART
       ORI  BLKSM       ;OF PREVIOUS LINE POINTER 
       MOV  L,A         ;IN HIGHEST ADDRESSED 
       DCX  H           ;DISPLAY BLOCK
       MVI  M,0       ;SET IT TO ZERO TO INDICATE 
       DCX  H           ;END OF FREE LIST 
       XCHG           ;SET NEXT BLOCK LINK OF 
       LHLD DSPBGN      ;LOWEST ADDRESSED DISPLAY 
       MOV  M,E         ;BLOCK TO POINT TO MSB
       INX  H           ;PART OF NEXT LINE LINK IN
       MOV  M,D         ;HIGHEST BLOCK
       XCHG           ;SWAP HIGH AND LOW ADDRESSES
       INX  D         ;ADJUST LOW ADDR TO LOW LIMI
;                       FOR LINKING DISPLAY BLOCKS
       DCX  H         ;SET FREE BLOCKS HEAD TO LSB
       SHLD FRBLKS      ;PART OF NEXT LINE POINTER
;                       IN HIGHEST BLOCK
       SUI  BLKSZ-2   ;SET B,L TO ADDRESS OF MSB
       MOV  B,H         ;PART OF NEXT BLOCK POINTE
       MOV  L,A         ;IN HIGHEST DISPLAY BLOCK 
 
;******************** 
; CHAIN FREE BLOCKS * 
;******************** 
; 
;  B,A = ADDRESS OF UPPER BYTE IN NEXT LOWER BLOCK
;  D,E = LOWER LIMIT OF DISPLAY AREA
;  H,L = ADDRESS OF MSB PART OF NEXT BLOCK LINK 
;    IN CURRENT BLOCK 
; 
INI210 EQU  $ 
       MOV  A,L       ;COMPUTE ADDRESS OF UPPERMOS
       SUI  2           ;BYTE IN NEXT LOWER BLOCK 
       JNC  INI220
       DCR  B 
INI220 EQU  $ 
       MOV  M,B       ;LINK CURRENT BLOCK TO NEXT 
       DCX  H           ;LOWER BLOCK
       MOV  M,A 
       SUI  BLKSZ-2   ;SET H,L TO ADDRESS OF MSB
       MOV  L,A         ;PART OF NEXT BLOCK LINK I
       MOV  H,B         ;NEXT LOWER BLOCK 
       SUB  E         ;COMPARE AGAINST LOWER LIMIT
       MOV  A,B 
       SBB  D         ;DISPLAY AREA EXHAUSTED?
       JNC  INI210    ;NO - CONTINUE LINKING BLOCK
;                     YES - SET UP INITIAL DISPLAY
 
; 
;  SET UP INITIAL SOFT KEYS DISPLAY 
; 
       CALL INITDS    ;START A NEW DISPLAY LIST 
       DCX  H         ;SET SOFT KEY START ADDRESS 
       SHLD SFTKYS      ;TO FIRST CHARACTER 
       MVI  A,CRTOFF  ;SET CURRENT AND LAST ROW 
       STA  CURROW      ;TO CONTROL FOR DISPLAY OF
       STA  LSTROW
; 
;  SET UP KEY DEFINITIONS 
; 
       LXI  B,DSPSTR-1
       LXI  H,ATBLIN  ;TRANSFER ATTRIBUTE LINE
       CALL MOVCHR
       MVI  C,NMFCTK  ;SET NUMBER OF KEYS TO DEFIN
; 
;  BUILD ATTRIBUTE LINE 
; 
INI310 EQU  $ 
       MVI  A,ZERO+9  ;COMPUTE FUNCTION KEY NUMBER
       SUB  C 
       STA  DSPSTR-ATBLEN+2 
; 
;  BUILD DEFINITION LINE
; 
       MVI  A,SMALLX  ;COMPUTE CHAR AFTER <ESC> 
       SUB  C           ;(LOWER CASE <P>-<W>) 
       LXI  H,DSPSTR-CHRLOC 
       MOV  M,A       ;SET DATA CHARACTER 
       MVI  L,DSPSTR-ATBLEN-BASE2 
       PUSH B         ;TRANSFER SOFT KEY DEFINITIO
       CALL XMS2DS      ;TO DISPLAY MEMORY
       POP  B 
       DCR  C         ;ALL KEYS DEFINED?
       JNZ  INI310    ;NO - DO NEXT KEY 
 
;*********************************************
; SOFT KEYS DONE - SET INITIAL DISPLAY STATE *
;*********************************************
       XRA  A         ;CLEAR LAST LINE POINTER
       STA  LLINE 
       DCR  A         ;SET DISPLAY TYPE TO SOFT 
       STA  DSPTYP      ;KEY DISPLAY
       CALL CURPH     ;HOME THE CURSOR
       CALL SWAP      ;SAVE SOFT KEY PARAMETERS 
;***********************************
; INITIALIZE FIRST LINE OF DISPLAY *
;***********************************
       CALL INITDS    ;START A NEW DISPLAY LIST 
;*************************
; INITIALIZE I/O DEVICES *
;*************************
; 
;      PRINTER INITIALIZATION ROUTINE 
; 
;  CHECK FOR 9866 PRINTER FIRST 
; 
       LDA  PTRST1    ;GET STATUS FROM 9866 PCA 
       ORA  A         ;IS INTERFACE INSTALLED?
       JZ   PTRI10    ;NO - LOOK FOR RS-232 PRNTR 
       LDA  PTRCL1    ;YES - CLEAR THE PRINTER
       MVI  A,1       ;SET PRINTER FLAG FOR 
       JMP  PTR120      ;9866 PRINTER (= 1) 
; 
;     RS-232        PRINTER 2 
; 
PTRI10 EQU $
       LDA  PTRST2    ;GET STATUS FROM RS-232 PCA 
       ORA  A         ;IS RS-232 PCA INSTALLED? 
       JZ   PTR120    ;NO - SET FOR NO PRINTER
; 
       LDA  PTRCF2    ;YES - GET CONFIG. STRAPS 
       ANI  PTRBD2    ;ISOLATE BAUD AND PARITY
       RAL            ;ADJUST FOR CONTROL OUTPUT
       STA  PTROT2    ;SET BOARD TO CONFIGURATION 
       MVI  A,2       ;SET FLAG FOR RS-232 PRINTER
; 
PTR120 EQU  $ 
       STA  PTRFLG    ;SET PRINTER FLAG 
       LXI  H,TRMRDY  ;DISPLAY "TERMINAL READY" 
       CALL DSPMS1      ;MESSAGE
       MVI  A,JMP     ;SET JUMP COMMAND FOR 
       STA  ECONTF      ;CHARACTER FUNCTION VECTOR
 
;*******************************************
; INITIALIZE FLAGS AND RANGE TABLE ADDRESS *
;*******************************************
START  EQU  $ 
       CALL ESCEND    ;RESET NORMAL RANGE TABLE 
       LDA  FRSALT    ;SET INITIAL ALTERNATE
       STA  CHRSET      ;CHARACTER SET
       CALL CRADV1    ;CLEAR CURSOR ADVANCE FLAG
       DCR  A         ;CLEAR SPOW LATCH 
       STA  SPOWL 
 
; 
;  WAIT LOOP
; 
WTLOOP EQU  $ 
       LXI  SP,STACK  ;SET STACK POINTER
       CALL GETDC1    ;SET DISPLAY CURSOR 
;**************************** 
; CHECK FOR DATA COMM INPUT * 
;**************************** 
WTL010 EQU  $ 
       CALL GETDCM    ;GET DATA COMM INPUT IF ANY 
;***************************
; CHECK FOR KEYBOARD INPUT *
;***************************
       LDA  MFLGS2    ;GET MODE FLAGS 
       ANI  ESCINP    ;ESCAPE SEQUENCE LOCK OUT?
       JNZ  WTL020    ;YES - IGNORE KEYBOARD
       LDA  DFLGS     ;NO - GET DATA TRANSFER FLAG
       ANI  FCTK2D    ;FUNCTION KEY TO DISPLAY? 
       CNZ  GTFCTK    ;YES - GET FUNCTION KEY CHAR
       JNZ  WTL200    ;PROCESS IF AVAILABLE 
       CALL ZGETKY    ;ANY KEYBOARD INPUT?
       JZ   WTL200    ;YES - PROCESS IT 
; 
; IF KEYBOARD LOCKED, A = CHARACTER HIT, IF ANY 
; OTHERWISE A = 377B
; 
       CPI  CR        ;RETURN KEY HIT?
       JNZ  WTL020    ;NO - CHECK CTU & DISPATCHER
       LDA  IOFLGS    ;USER READ OR FILE READ 
       ANI  USREAD+FILRED  ;PENDING?
       CNZ  RDABRT    ;YES - ABORT READ KEY 
 
;****************************************** 
; CHECK CTU'S AND PENDING BLOCK TRANSFERS * 
;****************************************** 
WTL020 EQU  $ 
       LXI  H,SCNCNT  ;DECREMENT SCAN COUNT 
       DCR  M         ;11 SCANS DONE? 
       JP   WTL010    ;NO - RESTART DO NOTHING LOO
       MVI  M,10      ;YES - RESET SCAN COUNT 
       CALL SCNVEC    ;DO OPTIONAL DISPLAY SCAN 
       CALL IOCTMN    ;MONITOR TAPE DRIVES
       CALL DSPTCH    ;CHECK PENDING BLOCK XFRS 
       JMP  WTL010    ;RESTART DO NOTHING LOOP
 
; 
;  KEY HIT - CHECK FOR FUNCTION KEY 
; 
WTL200 EQU  $ 
       STA  CHARIN    ;SAVE KEYBOARD CHARACTER
       MOV  C,A       ;SAVE THE BYTE IN C-REGISTER
       MVI  A,377Q-SDACOM 
       CALL CLRDFL    ;CLEAR DATA COMM INPUT FLAG 
       LDA  CMFLGS    ;GET COMMON FLAGS 
       CMA            ;BOTH RECEIVE MODE FLAG SET 
       ANI  RCVMDE+REMSET  ;AND REMOTE ENABLED? 
       JNZ  WTL205    ;NO - PROCESS KEYBOARD INPUT
       CALL ZBELL     ;YES - SOUND BELL AND 
       JMP  WTL010      ;IGNORE KEY 
; 
WTL205 EQU  $ 
       XRA  A         ;NO - PROCESS THE KEY 
       MOV  D,A         ;(SET A,D = 0)
       ORA  C         ;FUNCTION KEY?
       JP   WTL300    ;NO - PROCESS ASCII KEY 
       CPI  FNCLIM    ;TABLE FUNCTION?
       JP   WTL210    ;NO - CHECK FOR F1-F8 
       SUI  FNCLWR    ;COMPUTE TABLE INDEX
       ADD  A 
       MOV  E,A       ;COMPUTE TABLE ADDRESS
       LXI  H,FNCTAB    ;(D = 0)
       DAD  D 
       CALL CHAIN     ;GET THE FUNCTION ADDRESS 
       RST  RSTJMP    ;G0 PERFORM FUNCTION
       JMP  WTLOOP    ;RESTART WAIT LOOP
; 
;  CHECK FOR F1-F8 KEY
; 
WTL210 EQU  $ 
       CPI  F1CODE    ;IS THE KEY F1-F8?
       JC   WTL250    ;NO - EXPAND ESCAPE SEQUENCE
       CPI  F8CODE+1
       JNC  WTL250    ;NO - EXPAND ESCAPE SEQUENCE
       CALL CHKSFK    ;SOFT KEY MODE? 
       CZ   FCTKEY    ;NO - PROCESS FCT KEY 
       JMP  WTLOOP    ;RESTART WAIT LOOP
 
;************************ 
; PROCESS FUNCTION KEYS * 
;************************ 
WTL250 EQU  $ 
       MVI  C,ESC     ;SET ESCAPE AS INPUT CHAR 
WTL260 EQU  $ 
       CALL LOCLI0    ;PROCESS KEYBOARD INPUT 
       LXI  H,CHARIN  ;RECALL KEYBOARD INPUT
       MOV  A,M 
       CPI  ENHNCF    ;DISPLAY ENHANCEMENT CODE?
       JZ   WTL270    ;YES - EXPAND INTO AMPERSAND
       CPI  STFOR1    ;ENTER FOREIGN MODE CONTROL?
       JZ   WTL280    ;YES - CONTINUE SEQUENCE
       CPI  STFOR2    ;COMPLETE FOREIGN MODE SET? 
       JZ   WTL290    ;YES - SET ENDING SEQUENCE
       ANI  177Q      ;NO - MASK OUT UPPER BIT
       CMP  M         ;FUNCTION COMPLETED?
       JZ   WTLOOP    ;YES - RESTART WAIT LOOP
       MOV  M,A       ;NO - SET NEW KEYBOARD CHAR 
       MOV  C,A 
       JMP  WTL260    ;PERFORM THE DESIRED FUNCTON
; 
WTL270 EQU  $ 
       MVI  M,ESCLWD  ;SET <ESC>-<LOWER CASE D> AS
       MVI  C,AMPSND    ;CURRENT KEYBOARD CHARACTE
       JMP  WTL260    ;PROCESS AMPERSAND
; 
WTL280 EQU  $ 
       DCR  M         ;SET TO NEXT STEP CODE
       MVI  C,ARPARN  ;ENTER RIGHT PARENTHESIS
       JMP  WTL260    ;PROCESS RIGHT PARENTHESIS
; 
WTL290 EQU  $ 
       MVI  M,ESCSO   ;SET <ESC>-<SO> AS CURRENT
       MVI  C,C         ;KEYBOARD CHARACTER 
       JMP  WTL260    ;PROCESS LETTER <C> 
 
; 
;  DISPLAYABLE CHARACTER - CHECK FOR APPROACHING
;    END OF LINE WARNING
; 
WTL300 EQU  $ 
       CPI  CTLLIM    ;CONTROL CODE?
       JC   WTL310    ;YES - DON'T LOOK FOR BELL
       LDA  DFLGS     ;NO - GET DATA TRANSFER FLAG
       ANI  FCTK2D    ;PROCESSING FUNCTION KEY OR 
       CZ   CHKFMS      ;FORMAT/SOFT KEY MODE?
       JNZ  WTL310    ;YES - SKIP BELL COLUMN CHEC
       LDA  ESCFLG    ;NO - GET ESCAPE SEQ FLAG 
       ORA  A         ;CURRENTLY IN ESCAPE SEQ? 
       JNZ  WTL310    ;YES - DON'T LOOK FOR BELL
       LDA  CURCOL    ;NO - GET CURRENT COLUMN
       LXI  H,RHTMGN  ;COMPARE TO RIGHT MARGIN
       SUB  M         ;CLOSE ENOUGH TO RIGHT MARGI
       ADI  BELLIM      ;TO SOUND BELL? 
       CZ   ZBELL     ;YES - SOUND BELL 
;***************************
; PROCESS THE KEY FUNCTION *
;***************************
WTL310 EQU  $ 
       CALL LOCLIN    ;PERFORM LOCAL INPUT ROUTINE
       LDA  CHARIN    ;RECALL KEYBOARD INPUT CHAR 
       CPI  CR        ;WAS IT A RETURN? 
       JNZ  WTLOOP    ;NO - RESTART WAIT LOOP 
       LDA  MDFLG2    ;YES - GET MODE FLAGS 
       ANI  AUTOLF    ;AUTO LINE FEED ENABLED?
       JZ   WTLOOP    ;NO - RESTART WAIT LOOP 
       MVI  L,1       ;YES - DELAY 10 MILLISECONDS
       CALL DELAY       ;THEN SEND LINE FEED
       MVI  A,LF
       JMP  WTL200    ;FAKE LINE FEED FROM KEYBOAR
 
;************************ 
; S U B R O U T I N E S * 
;************************ 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  CHINT - INTERPRET INPUT CHARACTER
; 
;      ENTRY:  C = INPUT CHARACTER
; 
;      EXIT :  Z - FAST STORE USED
;              NZ - FULL PROCESSING USED
;              A-E,L DESTROYED
; 
;  TRY FAST STORE FIRST 
; 
CHINT0 EQU  $         ;ENTRY FOR I/O INPUT
       LXI  H,MFLGS2  ;SET H,L TO MODE FLAGS 2
       MOV  A,C       ;PUT INPUT CHAR IN A-REG
       CPI  LF        ;CHARACTER = LINE FEED? 
       JNZ  CHI000    ;NO - CHECK FOR CR/DC3
       MOV  A,M       ;YES - GET MODE FLAGS 2 
       ORI  WRPFLG    ;TURN ON WRAP FLAG
       CMP  M         ;WRAP FLAG ALREADY ON?
       JZ   CHINT     ;YES - EXECUTE LINE FEED
       MOV  M,A       ;NO - SET WRAP FLAG 
       RET              ;AND IGNORE LINE FEED 
; 
CHI000 EQU  $ 
       CPI  CR        ;CHARACTER = RETURN?
       JZ   CHINT1    ;YES - DON'T SET WRAP FLAG
       CPI  DC3       ;CHARACTER = DC3? 
       JZ   CHINT     ;YES - DON'T SET WRAP FLAG
       MOV  A,M       ;NO - SET WRAP FLAG 
       ORI  WRPFLG
       MOV  M,A       ;UPDATE MODE FLAGS 2
CHINT  EQU  $ 
       LXI  H,CRAFLG
       MOV  B,M       ;WAS LAST CHARACTER FUNCTION
       DCR  B           ;A CURSOR ADVANCE?
       JM   CHI100    ;NO - DO FULL PROCESSING
       MOV  M,B       ;YES - CLEAR FLAG 
       MOV  A,C       ;PUT INPUT CHARACTER IN A-RE
       CPI  CTLLIM    ;IS CHARACTER A CONTROL CODE
       JM   CHI050    ;YES - CHECK FOR DISPLAY FCT
;                     NO - DO FAST STORE
 
; 
;  FAST STORE PROCESSING
; 
CHI010 EQU  $ 
       MVI  L,SPOWL-BASE
       MOV  B,M       ;GET THE SPOW LATCH IN B-REG
       LHLD CURADR    ;GET LAST CHAR DONE ADDRESS 
       MOV  A,M       ;GET LAST CHARACTER DONE
       ORA  A         ;IS IT ASCII? 
       JM   CHI100    ;NO - DO FULL PROCESSING
       DCX  H         ;YES - GET NEXT CHARACTER 
       MOV  A,M 
       ORA  A         ;IS IT ASCII? 
       JP   CHI020    ;YES - OVERLAY EXISTING CHAR
       CPI  EOL       ;IS IT EOL? 
       JNZ  CHI100    ;NO - DO FULL PROCESSING
       MOV  B,A       ;YES - SAVE EOL AND CLEAR 
       DCX  H           ;SPOW LATCH COMPARE 
       MOV  A,M       ;GET NEXT CHARACTER 
       CPI  FILL      ;IS IT AN END OF LINE FILL? 
       JNZ  CHI100    ;NO - DO FULL PROCESSING
       LDA  CURROW    ;YES - ADD CHAR TO DISPLAY
       ORI  MAYEOL    ;SET DMA OFF WITH EOL SKIP
       DI             ;DISABLE INTERRUPTS 
       STA  IOCRRW    ;TURN OFF DMA 
       MVI  A,RSTOFF  ;DISABLE RESET KEY
       STA  IOKBCO
       MOV  M,B       ;STORE NEW EOL
       INX  H         ;SET TO OLD EOL ADDRESS 
 
; 
;  ADD CHARACTER TO DISPLAY 
; 
CHI020 EQU  $ 
       MOV  A,C       ;RECALL THE INPUT CHARACTER 
       CMP  B         ;STORE INHIBITED BY SPOW? 
       JZ   CHI030    ;YES - BYPASS STORE 
       MOV  M,C       ;NO - STORE THE BYTE
CHI030 EQU  $ 
       CALL DISLN1    ;TURN DISPLAY BACK ON 
       SHLD CURADR    ;STORE NEW CURRENT ADDRESS
       LXI  H,LSTCOL  ;INCREMENT LSTCOL 
       INR  M 
       CALL CURADV    ;ADVANCE CURSOR 
;**************************************** 
; CHINT2 - SET CURSOR COLUMN ON DISPLAY * 
;**************************************** 
; 
;  EXIT :  Z TRUE 
;          A DESTROYED
; 
CHINT2 EQU  $ 
       CMP  A 
       LDA  CURCOL    ;GET CURRENT COLUMN NUMBER
       STA  IOCRCL    ;SET DISPLAY CURSOR COLUMN
       RET            ;RETURN 
; 
;  CONTROL CODE - CHECK FOR DISPLAY FUNCTIONS 
; 
CHI050 EQU  $ 
       CALL CKDSPF    ;DISPLAY FUNCTIONS ENABLED? 
       JZ   CHI100    ;NO - DO FULL PROCESSING
       MOV  A,C       ;YES - RECALL INPUT CHARACTE
       CPI  CR        ;IS IT RETURN CHARACTER?
       JZ   CHI100    ;YES - DO FULL PROCESSING 
       CPI  ESC       ;IT IT AN ESCAPE? 
       JNZ  CHI010    ;NO - DO FAST PROCESSING
;                     YES - DO FULL PROCESSING
 
; 
;  FULL PROCESSING
; 
CHINT1 EQU  $ 
CHI100 EQU  $ 
       MOV  H,C 
       MOV  L,C       ;SET "CHAR" AND "DCHAR" TO
       SHLD CHAR        ;CURRENT CHARACTER
       CALL CRADV1    ;CLEAR CURADV FLAG
;*******************************
; DETERMINE CHARACTER FUNCTION *
;*******************************
       LHLD RNGTA     ;GET CURRENT RANGE TABLE ADD
;****************************** 
; ADVANCE TO NEXT TABLE ENTRY * 
;****************************** 
CHI110 EQU  $ 
       INX  H 
       INX  H 
       INX  H 
;*************************************
; COMPARE CHARACTER TO CURRENT RANGE *
;*************************************
       MOV  A,C       ;PUT CHARACTER IN A-REGISTER
       SUB  M         ;CHARACTER >= LOWER BOUND?
       INX  H           ;(SET H,L TO UPPER BOUND) 
       JC   CHI110    ;NO - ADVANCE TO NEXT ENTRY 
       RLC            ;YES - DOUBLE DIFFERENCE AND
       MOV  B,A         ;SAVE VALUE IN B-REGISTER 
       MOV  A,M       ;GET UPPER BOUND
       CMP  C         ;CHARACTER <= UPPER BOUND?
       JC   CHI110    ;NO - ADVANCE TO NEXT ENTRY 
;***********************************************
; CHARACTER FUNCTION FOUND - GET FUNCTION ADDR *
;***********************************************
       INX  H 
       MOV  E,M       ;PUT ADDRESS ENTRY IN 
       INX  H           ;A (= MSB), E (= LSB) 
       MOV  A,M 
       ANI  177Q      ;MASK OUT HIGH ORDER BIT
       MOV  D,A         ;(PUT NEW MSB INTO D-REG) 
       SUB  M         ;USE INDEX TABLE? 
       JNZ  CHI200    ;NO - USE AS FUNCTON ADDRESS
       MOV  L,B       ;YES - PUT DIFFERENCE IN H,L
       MOV  H,A         ;(A = 0)
       DAD  D         ;COMPUTE TABLE ADDRESS
       MOV  E,M       ;GET INDEX TABLE VALUE
       INX  H 
       MOV  D,M 
 
;*****************************
; PERFORM CHARACTER FUNCTION *
;*****************************
CHI200 EQU  $ 
       XCHG 
       SHLD CNTFAD    ;SET FUNCTION ADDRESS 
       MVI  B,1       ;SET INITIAL FUNCTION INDEX 
       MVI  H,BASEH   ;SET H TO DATA PAGE 
       MVI  A,RSTOFF  ;DISABLE RESET KEY
       STA  IOKBCO
;***********************************************
       CALL ECONTF    ;EXECUTE CHARACTER FUNCTION 
;***********************************************
       CALL DISLN3    ;RE-ENABLE RESET KEY
       CALL CKDSPF    ;DISPLAY FUNCTIONS ENABLED? 
       JNZ  CHI270    ;YES - DON'T END ESCAPE SEQ'
       LXI  H,ESCFLG  ;NO - CHECK ESCAPE FLAG 
       MOV  B,M 
       DCR  B         ;ESCAPE SEQUENCE IN PROGRESS
       JM   CHI270    ;NO - DON'T CHANGE ESC FLAG 
       MOV  M,B       ;YES - UPDATE ESCAPE COUNTER
       CZ   ESCEND    ;RESET RANGE TABLE POINTER
;                       COUNTER BECAME ZERO 
CHI270 EQU  $ 
       LDA  CHAR      ;SAVE THE LAST CHARACTER
       STA  LCHAR       ;PROCESSED
       CMP  H         ;SET Z FALSE
       RET            ;RETURN 
 
;********************************************** 
; CHECK CONTROL CODES FOR BLOCK TERMINATOR OR * 
;   BLOCK TRANSFER TRIGGER                    * 
;********************************************** 
; 
;  ENTRY:  C = INPUT CHARACTER
; 
CHKCTL EQU  $ 
       LDA  BLKTRM    ;GET BLOCK TERMINATOR CHAR
       CMP  C         ;INPUT = BLOCK TERMINATOR?
       JZ   SFKYDS    ;YES - DISPLAY INPUT
       LDA  DFLGS     ;GET TRANSFER FLAGS 
       ANI  SDACOM    ;INPUT FROM DATA COMM?
       RZ             ;NO - DO NOTHING
       LDA  TRIGGR    ;IS INPUT CHARACTER THE 
       CMP  C           ;BLOCK TRANSFER TRIGGER?
       RNZ            ;NO - DO NOTHING
; 
CHKCT1 EQU  $         ;SET BLOCK TRANSFER TRIGGER 
       MVI  A,SETTRG  ;GO TO DATA COMM ROUTINE TO 
       JMP  DCMCTL      ;SET BLOCK TRANSFER TRIGGE
 
;******************************************** 
; DSPTCH - DISPATCH PENDING BLOCK TRANSFERS * 
;******************************************** 
DSPTCH EQU  $ 
       LDA  CMFLGS    ;GET COMMON FLAGS 
       ANI  BLKTRG    ;BLOCK TRANSFER TRIGGER SET?
       RZ             ;NO - RETURN
       LDA  MFLGS     ;YES - RELEASE ANY PENDING
       LXI  H,DSPTAB    ;BLOCK TRANSFERS
       MVI  C,NMPNDG
; 
DSP010 EQU  $ 
       RRC            ;TRANSFER PENDING BIT SET?
       JC   DSP020    ;YES - GO DO TRANSFER 
       INX  H         ;NO - CHECK NEXT BIT
       INX  H         ;INCREMENT FUNCTION TABLE AD
       DCR  C         ;ALL BITS CHECKED?
       JNZ  DSP010    ;NO - CONTINUE CHECKING 
; 
       LDA  MFLGS2    ;YES - CHECK 2ND SET OF FLAG
       RRC            ;DEVICE RECORD PENDING? 
       JC   IORDGO    ;YES - SEND I/O RECORD
       RRC            ;BINARY DATA PENDING? 
       JC   BNRYGO    ;YES - TRANSMIT THE DATA
       RET            ;NO - RETURN
;********************************************** 
; PENDING BIT FOUND - GO TO TRANSMIT FUNCTION * 
;********************************************** 
DSP020 EQU  $ 
       CALL CHAIN     ;GET TRANSMIT FUNCTION ADDR 
       PCHL           ;GO TO THE FUNCTION 
; 
DSPTAB EQU  $ 
       DW   DC2GO     ;SEND DC2 
       DW   STATGO    ;SEND TERMINAL STATUS 
       DW   STA2GO    ;SEND TERMINAL STATUS 2 
       DW   IOSTGO    ;SEND I/O STATUS
       DW   CRSNGO    ;SEND CURSOR ADDRESS
       DW   FKEYGO    ;SEND FUNCTION KEY DATA 
       DW   DPSGO     ;SEND DISPLAY DATA
       DW   IODNGO    ;SEND I/O TERMINATION CODE
; 
NMPNDG EQU  ($-DSPTAB)/2
 
;****************************** 
; ESCAPE CHARACTER PROCESSING * 
;****************************** 
ESCAPE EQU $
       LDA  DFLGS 
       ANI  SDACOM    ;DATA FROM DATACOM? 
       JZ   ESC010    ;NO - DON'T LOCK KEYBOARD 
       LDA  MDFLG2    ;YES - GET MODE FLAGS 
       ANI  BLKMDE    ;BLOCK MODE?
       MVI  A,ESCINP    ;(PUT IGNORE FLAG IN A-REG
       CNZ  SETMF2    ;YES - SET IGNORE KEYBD FLAG
ESC010 EQU  $ 
       CALL CHKSFK    ;SOFT KEY MODE? 
       LXI  H,ESCTAB    ;(SET FOR NORMAL ESC TABLE
       JZ   ESCAP0    ;NO - SET RANGE TABLE 
       LXI  H,SESCTB  ;YES - USE SOFT KEY TABLE 
;***********************************************
; ESCAP0 - SET RANGE TABLE FOR ESCAPE SEQUENCE *
;***********************************************
; 
;  ENTRY:  A = RADIX (BASE) FOR DIGIT PARAMETERS
;          H,L = ADDRESS OF NEW RANGE TABLE 
; 
;  EXIT :  H,L = ESCFLG 
; 
;  ESCAPA - USE DECIMAL RADIX 
; 
ESCAPA EQU  $ 
       MVI  A,DECRDX  ;SET RADIX FOR BASE 10 DIGIT
ESCAP0 EQU  $ 
       STA  RADIX     ;SET PARAMETER RADIX
       SHLD RNGTA     ;SET NEW RANGE TABLE
ESCAPB EQU  $         ;ENTRY TO CLEAR ACCUMULATOR 
       LXI  H,IOCSGN  ;CLEAR OUT THE PARAMETER
       MVI  E,3         ;ACCUMULATOR AREA 
       CALL CLRAL1
ESCAP1 EQU  $ 
       LXI  H,ESCFLG  ;SET FLAG TO RESET AFTER
       MVI  M,2         ;FOLLOWING CHARACTER
       RET            ;RETURN 
 
;*********************************************
; ESCEND - END OF ESCAPE SEQUENCE PROCESSING *
;*********************************************
ESCEND EQU  $ 
       LXI  H,RTABLE  ;SET FOR NORMAL RANGE TABLE 
       CALL CHKSFK    ;SOFT KEY MODE? 
       JZ   ESCEN1    ;NO - USE NORMAL TABLE
       LXI  H,DFSTB0  ;YES - USE SOFT KEY TABLE 
ESCEN1 EQU  $ 
       SHLD RNGTA     ;RESET RANGE TABLE POINTER
       XRA  A         ;CLEAR ESCAPE FLAG AND
       STA  ESCFLG      ;ESCAPE KEYBOARD LOCKOUT
       MVI  A,377Q-ESCINP  ;FLAG
;************************************ 
; CLRMF2 - CLEAR FLAG BIT IN MFLGS2 * 
;************************************ 
; 
;  ENTRY:  A = 377B - FLAG BIT TO BE CLEARED
; 
;  EXIT :  A = UPDATED MFLGS2 VALUE 
;          H,L = MFLGS2 
; 
CLRMF2 EQU  $ 
       LXI  H,MFLGS2
       ANA  M         ;CLEAR THE FLAG BIT 
       MOV  M,A       ;STORE NEW SETTINGS 
       RET            ;RETURN 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  FNDRAM - LOCATE END OF RAM SPACE 
; 
;      ENTRY:  B = MSB OF RAM SPACE LOWER LIMIT 
;              H,L = ADDR OF UPPER BOUNDARY 
; 
;      EXIT :  H,L = ADDRESS OF LOWER BOUNDARY
;              A DESTROYED
; 
FNDRAM EQU  $ 
       XRA  A 
       MOV  L,A       ;SET ADDRESS'S LSB TO ZERO
       MOV  M,A       ;SET RAM LOCATION TO ZERO 
       CMP  M         ;ALL ZEROES STORED? 
       JNZ  FRM010    ;NO - RAM LIMIT FOUND 
       DCR  M         ;YES - TRY TO SET TO ALL ONE
       INR  M         ;ALL ONES STORED? 
       JNZ  FRM010    ;NO - RAM LIMIT FOUND 
       MOV  A,H       ;YES - MOVE TO NEXT 1K
       SUI  4 
       MOV  H,A 
       CMP  B         ;RAM LIMIT REACHED? 
       JP   FNDRAM    ;NO - TRY NEXT 1K 
; 
;  RAM LIMIT FOUND - RETURN LOW BOUNDARY
; 
FRM010 EQU $
       MOV  A,H       ;ADJUST H,L TO TRUE LOWER 
       ADI  4           ;BOUNDARY 
       ANI  374Q      ;MASK FOR 1K START ADDRESS
       MOV  H,A 
       RET            ;RETURN 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  GETBUF - GET BUFFER SPACE
; 
;      ENTRY:  B,C = LENGTH OF BUFFER REQUIRED
; 
;      EXIT :  A,H,L DESTROYED
;              P - BUFFER SPACE ALLOCATAED
;                D,E = BUFFER START ADDRESS 
;              M - BUFFER SPACE NOT ALLOCATED 
;                D,E DESTROYED
; 
;  THIS ROUTINE ALLOCATES A CONTIGUOUS AREA OF
;    RAM.  THE BUFFER SPACE MAY NOT START ON A
;    256 BYTE PAGE BOUNDARY.
; 
GETBUF EQU $
       LHLD BUFEND    ;GET CURRENT BUFFER END AND 
       LXI  D,BUFBGN+1  ;ADDRESS OF BEGIN PTR'S MS
       CALL GTB100    ;ENOUGH SPACE?
       JM   GTB010    ;NO - TRY DISPLAY AREA
       SHLD BUFEND    ;YES - STORE NEW BUFFER END 
GTB005 EQU  $ 
       XCHG           ;SET D,E TO LOW ADDRESS 
       INX  D           ;OF BUFFER
       RET            ;RETURN 
; 
;  NOT ENOUGH NON-DISPLAY RAM - TRY DISPLAY AREA
; 
GTB010 EQU  $ 
       LHLD DSPEND    ;GET CURRENT DISPLAY END AND
       LXI  D,DSPBGN+1  ;ADDR OF BEGIN PTR'S MSB
       CALL GTB100    ;ENOUGH SPACE?
       SHLD DSPEND      ;(STORE NEW DISPLAY END)
       JP   GTB005    ;YES - RETURN BUFFER ADDRESS
       LXI  H,BUFMSG  ;NO - REPORT ERROR
       JMP  HANGU0
; 
;  GTB100 - CHECK FOR AVAILABLE SPACE 
; 
GTB100 EQU  $ 
       MOV  A,L       ;SUBTRACT DESIRED SPACE 
       SUB  C           ;FROM END OF REGION 
       MOV  L,A 
       MOV  A,H 
       SBB  B 
       MOV  H,A 
       XCHG           ;COMPARE NEW MSB OF END TO
       CMP  M           ;MSB OF BEGINNING 
       XCHG           ;PUT NEW END ADDRESS IN H,L 
       RET            ;RETURN (P = ENOUGH)
 
;****************************************** 
; GETDCM - PROCESS DATA COMM INPUT IF ANY * 
;****************************************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  NC 
;          NZ - DATA COMM INPUT BUFFER EMPTY
;          Z - EXIT ON FULL INPUT PROCESSING
;          ALL REGISTERS DESTROYED
; 
GETDCM EQU  $ 
       LDA  MDFLG2    ;GET HARD MODE FLAGS
       ANI  REMOTE    ;REMOTE MODE ENABLED? 
       LDA  CMFLGS      ;(GET COMMON FLAGS) 
       JZ   GDC100    ;NO - IGNORE DATA COMM
       ANI  REMSET    ;WAS REMOTE ON BEFORE?
       CZ   ENTREM    ;NO - SET REMOTE MODE 
;********************** 
; GET DATA COMM INPUT * 
;********************** 
GDC010 EQU  $ 
       CALL ZGETDC    ;ANY DATA COMM INPUT? 
       JC   GDC050      ;(PROCESS ERROR IF ANY) 
       RNZ            ;NO - RETURN
       MOV  C,A       ;YES - SAVE INPUT INTO C-REG
;************************** 
; PROCESS DATA COMM INPUT * 
;************************** 
GDC020 EQU  $ 
       CALL SETDF0    ;SET DATA COMM INPUT FLAG 
       LDA  MDFLG1    ;GET SOFT MODE FLAGS
       ANI  RECORD    ;RECORD MODE ENABLED? 
       JZ   GDC030    ;NO - PROCESS THE INPUT 
       MOV  A,C       ;YES - LOOK FOR RECORD TRIGG
       CPI  CR        ;INPUT = RETURN?
       JZ   GDC030    ;YES - PROCESS THE CHARACTER
       CPI  LF        ;IS IT LINE FEED? 
       JNZ  RCRDGO    ;NO - EXECUTE RECORD FUNCTIO
GDC030 EQU  $         ;YES - PROCESS THE CHARACTER
       CALL CHINT     ;PERFORM INPUT PROCEDURE
       JZ   GDC010    ;FAST STORE - DO SHORT LOOP 
; 
GETDC1 EQU  $         ;SET THE DISPLAY CURSOR 
       CALL DISLN1    ;SET DISPLAY CURSOR ROW AND 
       JMP  CHINT2      ;COLUMN AND EXIT Z-TRUE 
 
;******************************** 
; PROCESS DATA COMM INPUT ERROR * 
;******************************** 
GDC050 EQU  $ 
       JNZ  HANGU0    ;REPORT AND HANG IF FATAL 
       CALL CKDSPF    ;DISPLAY FUNCTIONS ENABLED? 
       CZ   ESCEND    ;NO - FORCE ESC SEQ ABORT 
       MVI  C,ADEL    ;FORCE RUBOUT CHARACTER TO
       JMP  GDC020      ;BE DISPLAYED 
;*******************************************
; NOT IN REMOTE MODE - SET TO LOCAL IF NOT *
;   IN LOCAL MODE ALREADY                  *
;*******************************************
GDC100 EQU  $ 
       ANI  REMSET    ;FIRST TIME IN LOCAL? 
       CNZ  ENTLCL    ;YES - SET TO LOCAL MODE
       INR  A         ;FORCE Z FALSE
       RET            ;RETURN NO DATA COMM INPUT
 
;********************************** 
; GTBLK - GET A NEW DISPLAY BLOCK * 
;********************************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  Z - NO BLOCKS AVAILABLE (MEMORY LOCKED)
;            ALL REGISTERS DESTROYED
;          NZ - BLOCK ALLOCATED 
;            B,A = H,L = ADDRESS OF CHARACTER 
;              PRECEDING NEXT BLOCK LINK IN BLOCK 
;            C,D,E DESTROYED
; 
GTBLKF EQU  $         ;GET BLOCK FOR SINGLE CHAR I
       MVI  A,FILL    ;SET FILL CHARACTER TO FILL 
; 
GTBLK  EQU  $ 
       STA  FILCHR    ;SAVE FILL CHARACTER
       LHLD FRBLKS    ;GET POINTER TO FIRST 
       XCHG             ;FREE BLOCK IN D,E
       MOV  A,E       ;PUT LSB OF LINK IN A-REG 
       ORA  A         ;ANY BLOCKS AVAILABLE?
       CZ   PTBLK     ;NO - RELEASE BLOCKS
       JZ   MLOCK       ;AND FORCE MEMORY LOCK ON 
       ANI  377Q-BLKSM  ;COMPUTE ADDRESS OF 
       MOV  L,A           ;NEXT BLOCK LINK
       MOV  H,D 
       MOV  A,M       ;GET LSB OF NEXT BLOCK LINK 
       MOV  C,A       ;SAVE LSB IN C-REGISTER 
       CMA            ;END OF LINE LINK (LOWER
       ANI  BLKSM       ;FOUR BITS # ALL ONES)? 
       JZ   GBL100    ;NO - RELEASE NEXT BLOCK
;*****************************
; RELEASE LAST BLOCK OF LINE *
;*****************************
       INX  D         ;SET H,L TO LSB PART OF PREV
       INX  D           ;LINE LINK
       MOV  L,E 
       CALL CHAIN     ;GET PREV LINE ADDR IN H,L
       SHLD FRBLKS    ;SET AS NEW FREE BLOCKS HEAD
       MOV  B,D       ;PUT CURRENT BLOCK ADDRESS
       MOV  A,E         ;IN B,A 
       JMP  GBL200    ;FILL BLOCK WITH FILL CHARS 
 
;*****************************
; RELEASE NEXT BLOCK OF LINE *
;*****************************
GBL100 EQU  $ 
       INX  H         ;GET MSB OF NEXT BLOCK LINK 
       MOV  B,M 
       DCX  H         ;RESTORE H,L TO ADDRESS OF
;                       OF LSB PART IN FIRST BLOCK
       MOV  A,C       ;COMPUTE ADDRESS OF NEXT
       ANI  377Q-BLKSM  ;BLOCK LINK IN SECOND BLOC
       MOV  C,A 
       LDAX B         ;TRANSFER NEXT BLOCK LINK OF
       MOV  M,A         ;SECOND BLOCK TO NEXT BLOC
       INX  B           ;LINK IN FIRST BLOCK
       INX  H 
       LDAX B 
       MOV  M,A 
       MOV  A,C       ;SET A-REGISTER FOR "BLNKFL"
;*******************************************
; FILL BLOCK WITH SPECIFIED FILL CHARACTER *
;*******************************************
; 
;  B,A = ANY ADDRESS IN BLOCK 
;  FILCHR = CHARACTER TO FILL BLOCK WITH
; 
GBL200 EQU  $ 
       ORI  BLKSM     ;SET H,L TO ADDRESS OF LAST 
       MOV  L,A         ;DISPLAY CHARACTER POSITIO
       MOV  H,B         ;IN BLOCK 
       MVI  C,BLKSZ-3  ;SET FILL COUNT
       LDA  FILCHR    ;GET THE FILL CHARACTER 
GBL210 EQU  $ 
       MOV  M,A       ;STORE THE FILL CHARACTER 
       DCX  H         ;MOVE TO NEXT BYTE
       DCR  C         ;BLOCK FILL COMPLETED?
       JNZ  GBL210    ;NO - CONTINUE FILLING
       MOV  M,A       ;YES - WRITE LAST PAD 
       MOV  A,L       ;SET B,A TO EXIT ADDRESS
       ORA  A         ;SET NZ 
       RET            ;RETURN 
 
;**************************** 
; GTNWLN - START A NEW LINE * 
;**************************** 
; 
;  ENTRY:  LLINE = ADDRESS OF PREVIOUS LINE 
; 
;  EXIT :  NZ - NO BLOCKS AVAILABLE (MEMORY LOCK) 
;            ALL REGISTERS DESTROYED
;          Z - LINE ALLOCATED 
;            H,L = ADDR OF FIRST CHAR IN NEW LINE 
;            LLINE = ADDR OF LSB PART OF NEXT LINE
;              POINTER IN THE NEW LINE
;            A-E DESTROYED
; 
;  NEW LINE IS LINKED TO PREVIOUS LINE IF PREVIOUS
;  LINE EXISTS (I.E., LSB OF PREV LINE ADDR # 0)
; 
GTNWLN EQU  $ 
       MVI  A,STPR    ;SET LAST FORMAT CONTROL COD
       STA  LSTFMT      ;TO START PROTECT 
       CALL GTBLKF    ;GET A BLOCK FROM FREE LIST 
       JZ   NZEXIT    ;RETURN NZ IF NO BLOCKS 
       XCHG           ;D,E = NEW BLOCK ADDRESS
       LHLD LLINE     ;GET ADDRESS OF PREVIOUS
       XCHG             ;LINE IN D,E
       ORI  BLKSM     ;COMPUTE ADDRESS OF LSB PART
       SUI  2           ;OF NEXT LINE LINK
       DCX  H         ;STORE ADDRESS INTO NEXT
       MOV  M,B         ;BLOCK LINK 
       DCR  L           ;(USE DCR TO AVOID CARRY) 
       MOV  M,A 
       ADI  2         ;SET ADDRESS TO MSB PART OF 
       MOV  L,A         ;PREVIOUS LINE LINK 
       MOV  M,D       ;SET PREVIOUS LINE LINK TO
       DCX  H           ;POINT TO OLD LINE
       MOV  M,E 
       DCX  H 
       MVI  M,EOP     ;SET NEXT LINE LINK TO "EOP"
       DCX  H 
       XRA  A         ;SET TERMINATOR (LSB = 0) 
       MOV  M,A 
       SHLD LLINE     ;STORE NEW LAST LINE ADDRESS
       DCX  H 
       CALL STCHR1    ;SET FIRST DISPLAY CHARACTER
 
;*******************************************
; LINK NEW LINE BACK TO PREVIOUS LAST LINE *
;*******************************************
       ORA  E         ;PREVIOUS LINE EXIST (LSB#0)
       RZ             ;NO - RETURN
       XCHG           ;YES - LINK NEW LINE TO 
       MOV  M,E         ;PREVIOUS LINE
       INX  H 
       MOV  M,D 
       XCHG           ;RESTORE H,L
       CMP  A         ;SET Z TRUE 
       RET            ;RETURN 
 
;*****************************************
; INITDS - SET UP INITIAL DISPLAY VALUES *
;*****************************************
; 
;  EXIT :  H,L = ADDRESS OF THE LSB PART OF THE 
;            NEXT LINE POINTER IN THE INITIAL 
;            DISPLAY BLOCK
;          A DESTROYED
; 
;  THIS ROUTINE ALLOCATES THE INITIAL LINE OF 
;  THE DISPLAY AND INITIALIZES THE DISPLAY
;  PARAMETERS:
; 
;    DISPST,CURADR =  ADDRESS OF THE FIRST DISPLAY
;      CHARACTER IN THE INITIAL DISPLAY BLOCK 
; 
;    LSTLIN,FLINE,TOPLIN =  ADDRESS OF THE LSB
;      PART OF THE NEXT LINE POINTER IN THE 
;      INITIAL DISPLAY BLOCK
; 
;    RHTMGN = MAXCOL (= 79) 
; 
INITDS EQU  $ 
       CALL GTNWLN    ;GET INITIAL DISPLAY BLOCK
       SHLD DISPST    ;SET THE DISPLAY POINTER
       SHLD CURADR      ;AND THE CURRENT CHAR ADDR
       INX  H 
       SHLD LSTLIN    ;SET THE CURRENT LINE 
       SHLD FLINE       ;PARAMETERS 
       SHLD TOPLIN
       MVI  A,MAXCOL  ;INITIALIZE THE RIGHT MARGIN
       STA  RHTMGN      ;TO THE LAST COLUMN 
       RET            ;RETURN 
 
;************************************ 
; LOCLIN - PROCESS LOCAL DATA ENTRY * 
;************************************ 
; 
;  ENTRY:  C = INPUT CHARACTER
;          (CHARIN) = KEYBOARD INPUT CODE 
; 
;  EXIT :  ALL REGISTERS DESTROYED
; 
;  THIS ROUTINE PROCESSES INPUT CHARACTERS FROM 
;  KEYBOARD.  THE ROUTINE DETERMINES WHETHER OR 
;  NOT THE CHARACTER SHOULD BE TRANSMITTED OR 
;  PROCESSED LOCALLY
; 
;  LOCLI0 - PROCESS FUNCTIONAL KEY INPUT
; 
LOCLI0 EQU  $ 
       LDA  KBJMPR    ;GET KEYBOARD JUMPERS A-H 
       ANI  CONDIS    ;DISPLAY ALL FUNCTIONS OR 
       CZ   CKDSPF      ;DISPLAY FUNCTIONS ENABLED
       JZ   LCI050    ;NO - PROCESS LOCALLY ONLY
;******************************************** 
; TRANSMIT CODE IF IN REMOTE CHARACTER MODE * 
;******************************************** 
LOCLIN EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       JNZ  LCI050    ;YES - PROCESS LOCALLY ONLY 
       LDA  MDFLG2    ;NO - GET HARD MODE FLAGS 
       ANI  REMOTE+BLKMDE 
       XRI  REMOTE    ;REMOTE AND NOT BLOCK MODE? 
       JNZ  LCI050    ;NO - PROCESS LOCALLY ONLY
       MOV  A,C       ;YES - RECALL THE INPUT 
       CALL XPUTDC    ;OUTPUT THE CHARACTER 
       RC               ;(RETURN IF OUTPUT ERROR) 
       LDA  KBDCSW    ;GET THE DATA COMM SWITCHES 
       ANI  FULDUP    ;FULL DUPLEX? 
       RNZ            ;YES - RETURN 
;                     NO - PROCESS INPUT LOCALLY
;**************************** 
; PROCESS THE INPUT LOCALLY * 
;**************************** 
; 
;  INPUT CHARACTER IN C-REGISTER
; 
LCI050 EQU  $ 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JNZ  CHINT1    ;YES - FORCE FULL PROCESSING
       JMP  CHINT     ;NO - 1ST TRY FAST PROCESSIN
 
;***********************************************
; PTBLK - RELEASE A LINE TO THE FREE LIST FROM *
;   THE DISPLAY LIST                           *
;***********************************************
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  Z - LINE NOT RELEASED
;            NC - MEMORY LOCKED 
;            C - OUTPUT FAILED FOR EDIT MODE
;            ALL REGISTERS DESTROYED
;          NZ - LINE RELEASED 
;            D,E = ADDRESS OF FIFTH BYTE FROM 
;            A = E
;            B,C,H,L DESTROYED
; 
PTBLK  EQU  $ 
       CALL CHKMLK    ;MEMORY LOCK ENABLED? 
       JZ   MLOCK     ;YES - FLAG MEMORY FULL 
       CALL PTB100    ;SWITCH DISPLAY PARAMETERS
;                       IF IN SOFT KEY MODE 
       LDA  NROWS     ;GET NUMBER OF ROWS NEEDED
       ORA  A         ;NEW ROWS BEING ADDED?
       CZ   CKEDIT    ;NO - EDIT MODE?
       JNZ  PTB200    ;YES - RELEASE TOP LINE 
       LHLD LSTLIN    ;NO - GET CURRENT LINE ADDR 
       ORA  M         ;CURRENTLY IN THE LAST LINE 
       JZ   PTB200    ;YES - RELEASE TOP LINE 
;                     NO - RELEASE BOTTOM LINE
 
;****************************** 
; RELEASE LAST LINE OF MEMORY * 
; UPDATE LAST LINE POINTER    * 
;****************************** 
       LHLD LLINE     ;GET LAST LINE ADDRESS
       INX  H         ;GET PREVIOUS LINE ADDRESS
       INX  H 
       MOV  E,M 
       INX  H 
       MOV D,M
       XCHG 
       SHLD LLINE     ;SET PREV LINE AS LAST LINE 
;*****************************
; STORE EOP IN NEW LAST LINE *
;*****************************
       MVI  M,0       ;SET TERMINATOR CODE IN 
       INX  H           ;NEW LAST LINE
       MVI  M,EOP 
       DCX  D         ;SET D,E TO POINT TO LSB PAR
       DCX  D           ;NEXT LINE POINTER IN OLD 
       DCX  D           ;LAST LINE
       JMP  PTB300    ;ADD LINE TO FREE LIST
;*****************************************
; PTB100 - SET PROPER DISPLAY PARAMETERS *
;*****************************************
PTB090 EQU  $         ;I/O OUTPUT FAIL EXIT 
       CALL MLK010    ;CLEAR ROWS ALLOCATED FLAG
PTB100 EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       STC              ;(SET C-FLAG FOR I/O FAIL)
       JNZ  SWAP1     ;YES - SWAP DISPLAY PARMS 
       RET            ;NO - RETURN
       NOP            ;"NOP'S" FOR PATCH TO "PT772
       NOP
 
;*******************************
; RELEASE FIRST LINE OF MEMORY *
;*******************************
PTB200 EQU $
       LHLD TOPLIN    ;GET TOP LINE ADDRESS 
       INX  H         ;SET FOR PREVIOUS LINE
       INX  H           ;ADDRESS
       MOV A,M
       ORA A        ;TOP LINE = FIRST LINE? 
       JNZ PTB220   ;FIRST LINE IS NOT TOP LINE 
;********************************************** 
; TOP LINE OF DISPLAY IS FIRST LINE OF MEMORY * 
; DO ROLL-UP                                  * 
;********************************************** 
       LXI  H,CURROW
       LDA  MLKROW    ;USER WORKING IN FIRST
       CMP  M           ;UNLOCKED ROW?
       CNZ  ROLLUP    ;NO - ROLL UP DISPLAY 
       JZ   MLOCK0    ;ROLL UP FAIL - LOCK MEMORY 
       LXI  H,CURROW  ;DECREMENT CURSOR ROW 
       MOV  B,M 
       DCR B
       JM  PTB220   ;DON'T STORE IF ROW = 0 
       MOV M,B
;*****************************
; ADVANCE FIRST LINE POINTER *
;*****************************
PTB220 EQU  $ 
       LHLD FLINE     ;GET ADDRESS OF FIRST DISPLA
       XCHG             ;LINE 
       CALL CKEDIT    ;EDIT MODE ENABLED? 
       CNZ  PTTPLN    ;YES - TRY TO OUTPUT LINE 
       JC   PTB090    ;OUTPUT FAILED - RETURN FAIL
       XCHG           ;PUT ADDRESS BACK INTO D,E
       MOV  E,M       ;GET ADDRESS OF NEW FIRST 
       INX  H           ;FIRST LINE 
       MOV  D,M 
       INX  D         ;SET TO NEXT LINE POINTER 
       XCHG 
       SHLD  FLINE    ;STORE AS NEW FIRST LINE
;*********************************************
; CLEAR PREVIOUS LINE PNTR IN NEW FIRST LINE *
;*********************************************
       INX  H         ;ADVANCE TO PREVIOUS LINE 
       INX  H           ;POINTER
       MVI  M,0       ;ZERO LSB TO FLAG AS TOP LIN
       DCX  D         ;SET D,E TO LSB OF NEXT LINE
;                       POINTER IN LINE TO BE 
;                       RELEASED
 
;****************************** 
; RELEASE LINE                * 
; D,E = START ADDRESS OF LINE * 
;****************************** 
PTB300 EQU  $ 
       PUSH D         ;SAVE REGISTERS D,E 
       CALL PTB100    ;RESTORE PROPER DISPLAY PARM
       POP  D         ;RESTORE D,E
 
;*********************************
; PUTLIN - ADD LINE TO FREE LIST *
;*********************************
; 
;  ENTRY:  D,E = ADDRESS OF NEXT LINE FIELD'S LSB 
;            OF LINE TO BE RELEASED 
; 
;  EXIT :  D,E UNCHANGED
;          A = E
;          Z FALSE
;          H,L DESTROYED
;          FREE BLOCKS LIST UPDATED TO INCLUDE
;            RELEASE LINE 
; 
PUTLIN EQU  $ 
       CALL MLKOF     ;RESET MEMORY LOCKED FLAG 
       LHLD FRBLKS    ;GET CURRENT FREE BLOCKS HEA
       XCHG           ;SET H,L TO MSB PART OF NEXT
       SHLD FRBLKS    ;SET FREE BLOCKS POINTER TO 
       MOV  A,L         ;RELEASED LINE
       INX  H         ;PUT PREVIOUS FREE BLOCKS 
       INX  H           ;HEAD INTO PREVIOUS LINE
       MOV  M,E         ;POINTER OF RELEASED LINE 
       INR  L           ;(USE INR TO FORCE NZ)
       MOV  M,D 
       XCHG           ;RELEASED LINE ADDRESS IN D,
       MOV  E,A       ;SET A = E
       RET            ;RETURN 
 
;*********************************************
; RCADRA - LOCATE CURRENT CURSOR POSITION    *
;   IF POSITION EXIST - DON'T EXTEND DISPLAY *
;*********************************************
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  SEE "RCADDR" 
; 
RCADRA EQU  $ 
       CALL CRADV1    ;CLEAR CURSOR ADVANCE FLAG
       MVI  A,IGNTRM  ;SET TO IGNORE NON-DISPLAYIN
       STA  TRMFCT      ;TERMINATOR 
RCADRB EQU  $ 
       MVI  A,377Q    ;SET "BLKFIL" TO INHIBIT
       STA  BLKFIL      ;LINE EXTENSION 
       JMP  RCADR2    ;LOCATE CURSOR POSITION 
;****************************************** 
; LOCATE ADDR CORRESPONDING TO ROW/COLUMN * 
; DO NOT ADD ROWS IF ROW DOES NOT EXIST   * 
;****************************************** 
RCADR1 EQU  $ 
       XRA  A         ;SET TO LOCATE COLUMN 0 
       STA  CURCOL      ;IN DESIRED ROW 
RCADR2 EQU  $ 
       LDA  CURCOL    ;GET THE CURRENT COLUMN 
RCADR3 EQU  $ 
       LXI  H,NROWS   ;SET "NROWS" TO INHIBIT 
       MVI  M,377Q      ;BUILDING OF NEW ROWS 
       CALL RCADR0    ;FIND CHARACTER ADDRESS 
       LXI  H,NROWS   ;RESET BUILD INHIBIT FLAGS
       MVI  M,0         ;WITHOUT CHANGING PROCESSO
       MVI  L,BLKFIL-BASE  ;FLAGS 
       MVI  M,0 
       RET            ;RETURN 
 
;************************************************ 
; RCADR4 - GET ADDRESS OF FIRST CHARACTER AFTER * 
;   AFTER PREVIOUS ROW AND COLUMN               * 
;************************************************ 
; 
;      ENTRY:  CURROW = CURRENT ROW 
;              CURCOL = CURRENT COLUMNN 
; 
;      EXIT :  Z - CHARACTER FOUND
;                C = COLUMN NUMBER
;                D,E = CHARACTER ADDRESS
;                IF FORMAT MODE ENABLED 
;                  B = -1, CHARACTER PROTECTED
;                    # -1, CHARACTER NOT PROTECTED
;                OTHERWISE, B DESTROYED 
;              A,H,L DESTROYED
;              NZ - CHARACTER NOT FOUND 
;                ALL REGISTERS DESTROYED
; 
RCADR4 EQU $
       LDA  CURCOL    ;GET CURRENT COLUMN NUMBER
       DCR  A         ;SET FOR PREVIOUS COLUMN
       CALL RCADR3    ;DOES CHARACTER EXIST 
       RNZ            ;NO - RETURN
       MOV  C,A       ;YES - SAVE COLUMN FOUND IN 
       INR  C         ;ADVANCE TO NEXT COLUMN 
       CALL NXTCHR    ;GET NEXT CHARACTER 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       MOV  B,A         ;(SET B TO INDICATE NOT 
;                         PROTECTED IF NOT FORMAT)
;                         NEXT STATEMENT RETURNS) 
       RZ           ;NO - RETURN
 
; 
;  FORMAT MODE - SEE IF NEXT ASCII CHAR PROTECTED 
; 
       CALL CKPROT    ;PREVIOUS CHAR PROTECTED? 
       JZ   RCA440    ;YES - SEE IF NEXT CHAR UNPR
;******************************** 
; LAST CHAR WAS UNPROTECTED     * 
; SEE IF NEXT CHAR IS PROTECTED * 
;******************************** 
       CALL FNDCH0    ;IS NEXT CHARACTER PROTECTED
       JNZ  RCA440    ;YES - SEE IF NEXT IS UNPROT
       LHLD CURADR    ;NO - RECALL CURRENT CHAR 
       XCHG             ;ADDRESS AND PUT INTO D,E 
RC4010 EQU  $ 
       CALL NXTCHR    ;GET NEXT DISPLAY CHARACTER 
       MVI  B,0       ;SET B FOR NOT PROTECTED
       JMP  RCA460    ;EXIT CHARACTER FOUND 
;***********************************
; PROTECT CHAR FOUND               *
; SEE IF SUBSEQUENT UNPROTECT CHAR *
;***********************************
RCA440 EQU $
       LXI  H,ENDPR*256+XMONLY  ;IS NEXT CHARACTER
       CALL FNDCH       ;AN UNPROTECT OR XMIT ONLY
       JNZ  RC4010    ;YES - RETURN UNPROTECTED 
       MVI  B,-1      ;NO - RETURN CHAR PROTECTED 
RCA460 EQU $
       LXI  H,CURCOL
       MOV  C,M       ;RECALL CURSOR COLUMN 
; 
;  ZRETRN - RETURN WITH Z-FLAG TRUE 
; 
ZRETRN EQU  $ 
       XRA A        ;SET ZERO FLAG
       RET          ;RETURN 
 
;*************************************************
; RCADDR - DETERMINE LOCATION OF ASCII CHARACTER *
;   AT SPECIFIED ROW AND COLUMN OF DISPLAY LIST  *
;*************************************************
; 
;  ENTRY:  CURROW,CURCOL = DESIRED ROW/COLUMN 
;          LSTROW,LSTCOL = LAST ROW/COLUMN DONE 
;          CURADR = ADDRESS CORRESPONDING TO
;            LSTROW, LSTCOL 
;          LSTLIN = ADDRESS OF LINE CORRESPONDING 
;            TO LSTROW
;          NROWS = 0, BUILD NEW ROWS AS NEEDED
;                # 0, DON'T BUILD NEW ROWS
;          BLKFIL = 0, EXTEND LINE AS NEEDED
;                 # 0, DON'T EXTEND LINE
; 
;  EXIT :  Z - CHARACTER FOUND
;            A,B,C,L DESTROYED
;          NZ - CHARACTER NOT FOUND 
;            M - ROWS NOT BUILT 
;              E = NUMBER OF ROWS NEEDED
;            P - ROW LOCATED
;              A = COLUMN NUMBER FOUND
;              B = ROW NUMBER FOUND 
;              C = NUMBER OF CHARACTERS NEEDED
;          D,E = ADDRESS OF LAST CHARACTER FOUND
;          H = BASEH
; 
;          LSTROW,LSTCOL,LSTLIN,CURADR ARE UPDATED
;          TO THE LAST CHARACTER FOUND. 
; 
RCADDR EQU  $ 
       LDA  CURCOL    ;GET DESIRED COLUMN NUMBER
RCADR0 EQU  $ 
       STA  TMPCOL    ;SAVE DESIRED COLUMN NUMBER 
       LDA  CURROW    ;GET THE DESIRED ROW NUMBER 
       LHLD LSTROW    ;GET LAST ROW AND COLUMN DON
       MOV  B,H       ;PUT LAST COLUMN IN B-REG 
       SUB  L         ;MOVED TO A NEW ROW?
       LHLD LSTLIN      ;(GET LAST LINE DONE ADDR)
       JZ   RCA240    ;YES - LOCATE COLUMN
;************************** 
; ROW HAS CHANGED         * 
; LOCATE START OF NEW ROW * 
;************************** 
       MOV E,A      ;SAVE COUNT 
       ORA A        ;SET FLAGS
       JP  RCA140   ;ROW IS AHEAD OF THIS ROW 
 
;**************************** 
; ROW IS BEFORE CURRENT ROW * 
; SEARCH BACK               * 
;**************************** 
RCA120 EQU $
       INX  H         ;SET ADDRESS TO PREVIOUS
       INX  H           ;LINE POINTER 
       CALL CHAIN   ;GET ADDRESS OF PREVIOUS ROW
       INR  E         ;ROW FOUND? 
       JNZ  RCA120    ;NO - CONTINUE BACKING UP 
       JMP  RCA220    ;YES - SET NEW ROW
;****************************** 
; ROW IS AHEAD OF CURRENT ROW * 
; SEARCH AHEAD                * 
;****************************** 
RCA130 EQU  $ 
       CALL CHAIN     ;GET ADDRESS OF NEXT ROW
       INX  H         ;SET TO NEXT LINE PTR ADDRES
       DCR  E         ;ROW FOUND? 
       JZ   RCA220    ;YES - LOCATE COLUMN
RCA140 EQU  $         ;NO - CHECK FOR ANOTHER ROW 
       MOV  A,M       ;GET LSB OF NEXT ROW POINTER
       ORA  A         ;DOES NEXT ROW EXIST? 
       JNZ  RCA130    ;YES - CHECK FOR ROW FOUND
;******************** 
; ROW NOT IN MEMORY * 
; CREATE NEW ROW    * 
;******************** 
RCA200 EQU $
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JNZ  NZEXIT    ;YES - DO NOT BUILD ROWS
       LXI  H,NROWS   ;NO - GET BUILD FLAG
       ORA  M         ;INHIBIT ROW BUILD? 
       RNZ            ;YES - RETURN (A = 377B)
       MOV  M,E       ;NO - STORE # OF ROWS NEEDED
 
;****************************** 
; GET NEW ROW AND LINK TO OLD * 
;****************************** 
RCA210 EQU  $ 
       CALL GTNWLN    ;ADD A LINE TO THE DISPLAY
       RNZ            ;RETURN FAIL IF MEMORY LOCKE
       LXI  H,NROWS   ;DECREMENT # OF ROWS NEEDED 
       DCR  M         ;ALL NEEDED ROWS ALLOCATED? 
       JNZ  RCA210    ;NO - GET ANOTHER ROW 
;************************************ 
; ALL REQUIRED ROWS HAVE BEEN ADDED * 
;************************************ 
       LHLD LLINE     ;GET START ADDRESS OF ROW 
RCA220 EQU  $         ;UPDATE LOCATE COLUMN 
       CALL LSTLUP    ;SET "LSTLIN" TO NEW ROW
       LDA  TMPCOL    ;RECALL COLUMN TO BE FOUND
       MOV  C,A       ;PUT COLUMN NUMBER INTO C-RE
       JMP  RCA245    ;GO LOCATE THE COLUMN 
 
;**************************** 
; CURRENT ROW = DESIRED ROW * 
; CHECK COLUMN              * 
;**************************** 
RCA240 EQU  $ 
       LDA  TMPCOL    ;GET THE DESIRED COLUMN 
       MOV  C,A       ;PUT IT INTO THE C-REGISTER 
       SUB  B         ;COLUMN WANTED >= LAST DONE?
       JP   RCA250    ;YES - SCAN FORWARD 
;****************************************** 
; DESIRED COLUMN LESS THAN CURRENT COLUMN * 
; START SEARCH AT BEGINNING OF ROW        * 
;****************************************** 
       CALL LSTLU1    ;SET LINE START PARAMETERS
;                       (PUTS H,L INTO D,E) 
RCA245 EQU  $ 
       MVI  A,IGNTRM  ;SET FUNCTION FLAG TO IGNORE
       STA  TRMFCT      ;NON-DISPLAYING TERMINATOR
       JMP RCA255   ;GO LOCATE COLUMN 
;*******************************************
; DESIRED COLUMN AT OR PAST CURRENT COLUMN *
; START SEARCH AT CURRENT COLUMN           *
;*******************************************
RCA250 EQU $
       MOV  C,A       ;SAVE # OF COLUMNS TO ADVANC
       LHLD CURADR    ;GET ADDR OF LAST CHAR DONE 
       XCHG 
       INR B        ;DOES LSTCOL = -1?
       JNZ RCA260   ;NO 
       DCR C        ;DECREMENT COLUMN COUNT 
RCA255 EQU $
       DCX  D         ;SET TO NEXT DISPLAY BYTE 
 
;**************************** 
; ROW HAS BEEN FOUND        * 
; SEARCH FOR DESIRED COLUMN * 
;**************************** 
RCA260 EQU $
       LXI  H,DISPST  ;SET FOR NO CHARACTER MATCH 
       CALL FNDCHR    ;DOES CHARACTER EXIST?
       MVI  A,DELTRM  ;SET FUNCTION FLAG TO DELETE
       STA  TRMFCT      ;NON-DISPLAYING TERMINATOR
       CZ   EOLMV0    ;NO - TRY TO MOVE EOL 
       XCHG           ;SET NEW CURRENT CHAR ADDRES
       SHLD CURADR
       XCHG 
       LXI  H,CURROW
       MOV  B,M       ;GET DESIRED ROW AND COLUMN 
       LDA  TMPCOL
       DCR C        ;CONVERT TO COLUMN FOUND
       JM  RCA270 
       SUB C
RCA270 EQU $
       MOV  L,B       ;UPDATE LAST ROW AND COLUMN 
       MOV  H,A         ;DONE 
       SHLD LSTROW
       MVI  H,BASEH   ;SET H TO DATA PAGE 
       INR C        ;RESTORE ZERO FLAG
       RET          ;RETURN 
 
;*****************************
; TIMER INTERRUPT PROCESSING *
;*****************************
; 
;  ENTRY:  "PSW" AND B,C PUSHED 
;          A = INTERRUPT CODE 
; 
TMINTR EQU $
       CALL INTVEC    ;TRY ALTERNATE INTERRUPT
       LDA  PRCCTL    ;GET PROCESSOR STATE
       PUSH D         ;SAVE REMAINING REGISTERS 
       PUSH H 
       ANI  377Q-TMIEN
       OUT  PROCSR    ;ACKNOWLEDGE TIMER INTERRUPT
       ORI  TMIEN 
       OUT  PROCSR    ;RE-ENABLE THE TIMER
       LXI  H,RSTTMR  ;DECREMENT SOFT RESET DELAY 
       MOV  A,M         ;TIMER
       DCR  A         ;COUNTING DOWN? 
       JM   TMI010    ;NO - DON'T UPDATE TIMER
       MOV  M,A       ;YES - STORE NEW VALUE
       MVI  A,ENDTST    ;(SET FOR RESET LED'S)
       CZ   ZKBCTL    ;RESET LED'S IF TIME DONE 
TMI010 EQU  $ 
       MVI  L,TPSTAL-BASE  ;DECREMENT TAPE STALLED
       MOV  A,M         ;COUNTER
       DCR  A         ;STALL LIMIT REACHED? 
       JM   TMI020    ;YES - DON'T UPDATE COUNTER 
       MOV  M,A       ;NO - STORE NEW VALUE 
TMI020 EQU  $ 
       MVI  L,CTBLTM-BASE  ;DECREMENT BLINK TIMER 
       DCR  M         ;TIME OUT?
       JNZ  TMI100    ;NO - EXIT
       MVI  M,CTBDLY  ;YES - RESET TIMER
       INX  H 
       MOV  A,M       ;GET CTU BLINK MASK 
       MVI  L,CMND-BASE 
       XRA  M         ;TOGGLE BLINKING LIGHTS 
       MOV  M,A       ;UPDATE LIGHT STATE 
       STA  IOCTCO    ;SET CTU LIGHTS 
 
;*****************************************
; PERFORM KEYBOARD AND DATA COMM MONITOR *
; ROUTINES                               *
;*****************************************
TMI100 EQU  $ 
       LXI  H,INTFLG  ;GET INTERRUPT FLAG 
       MVI  A,TMRINT+1  ;TIMER INTERRUPT ALREADY
       CMP  M           ;IN PROGRESS? 
       JZ   TMI110    ;YES - DON'T DO MONITOR CALL
       MOV  M,A       ;NO - SET IN-PROGRESS FLAG
       LDA  DEVFLG    ;GET DEVICE FLAGS 
       ADD  A         ;ALTERNATE I/O INSTALLED? 
       CM   ZMONAL    ;YES - MONITOR ALT DEVICE 
       CALL ZKBMON
       DI             ;***************************
       CALL ZDCMON    ;* KEYBOARD MONITOR ROUTINE 
;                     * RE-ENABLES INTERRUPTS    *
;                     ****************************
       LXI  H,INTFLG  ;SET INTERUPT CODE TO 
       DCR  M           ;INDICATE TIMER INTERRUPT 
TMI110 EQU  $ 
       POP  H         ;RESTORE CONTENTS OF
       POP  D           ;ALL REGISTERS AND
       POP  B           ;ALL CONDITION FLAGS
       POP  PSW 
       EI             ;RE-ENABLE INTERRUPTS 
       RET            ;RETURN TO NORMAL PROCESSING
 
;************************** 
;  R O M   B R E A K   1  * 
;************************** 
       ORG  BEGIN+4000Q 
ZBRK1  EQU  $ 
       DB   VERSN1    ;ROM PRESENT FLAGS
       DB   ZBRK1/256 
 
;*****************************************
; BINOCT - CONVERT BINARY TO OCTAL ASCII *
;*****************************************
; 
;  ENTRY:  A = DIGIT TO BE CONVERTED
;          H,L = ADDRESS OF OUTPUT BUFFER'S 
;            HIGH ORDER BYTE
; 
;  EXIT :  H,L = H,L(ENTRY)+4 
;          A-C DESTROYED
; 
;  FIRST BYTE IS SET TO BLANK.  THE NEXT THREE
;  BYTES CONTAIN THE ASCII OCTAL EQUIVALENT OF
;  THE INPUT VALUE.  THE FIFTH BYTE IS SET TO 
;  ZERO (NULL). 
; 
BINOCT EQU  $ 
       MVI  M,ABLNK   ;SET FIRST BYTE TO BLANK
       INX  H 
       MVI  B,3       ;SET B TO NUMBER OF DIGITS
       RLC            ;ROTATE DOWN TWO HIGH ORDER 
       RLC              ;BITS 
       MOV  C,A       ;SAVE VALUE IN C-REGISTER 
       ANI  3Q        ;MASK OUT TWO HIGH ORDER BIT
BNO010 EQU  $ 
       ANI  7Q        ;MASK OUT NEXT THREE BITS 
       ORI  ZERO      ;ADD IN ASCII ADJUSTMENT
       MOV  M,A       ;STORE ASCII CHARACTER
       INX  H         ;INCREMENT TO NEXT BYTE 
       MOV  A,C       ;RECALL INPUT 
       RLC            ;ROTATE  TO NEXT THREE BITS 
       RLC
       RLC
       MOV  C,A       ;SAVE VALUE 
       DCR  B         ;ALL BITS DONE? 
       JNZ  BNO010    ;NO - SET NEXT BYTE 
       MOV  M,B       ;YES - STORE NULL IN BUFFER 
       RET            ;RETURN 
 
;********************************** 
; BN2DE0 - CONVERT SINGLE BYTE TO * 
;   ASCII DECIMAL                 * 
;********************************** 
; 
;  ENTRY:  A = BYTE TO BE CONVERTED 
;          H,L = ADDRESS OF OUTPUT BUFFER'S 
;            HIGH ORDER ADDRESS 
; 
;  EXIT :  NZ 
;          H,L = H,L(ENTRY)+3 
;          A-E DESTROYED
; 
BN2DE0 EQU  $ 
       SHLD LNKSAV    ;SAVE BUFFER ADDRESS
       LXI  H,B2D200  ;SET OUTPUT ROUTINE TO BUFFE
BN2DE1 EQU  $           ;STORE ROUTINE
       SHLD CNTFAD    ;SET OUTPUT ROUTINE ADDRESS 
BN2DE2 EQU  $         ;ENTRY FOR "ASCOUT" 
       MOV  E,A       ;CHANGE INPUT INTO DOUBLE 
       MVI  D,0         ;BYTE VALUE 
       MVI  C,1       ;SET ZERO SUPPRESS FLAG 
       JMP  B2D050    ;GO TO CONVERT ROUTINE
 
;*************************************************
; BN2DEC - CONVERT DOUBLE WORD BINARY TO DECIMAL *
;*************************************************
; 
;  ENTRY:  D,E = BINARY VALUE 
;          H,L = ADDRESS OF HIGH ORDER BYTE IN
;            BUFFER 
; 
;  EXIT :  H,L = H,L(ENTRY)+5 
;          A-E DESTROYED
;          LNKSAV DESTROYED 
; 
;  THE FIRST FIVE BYTES OF THE BUFFER CONTAIN THE 
;  ASCII DECIMAL VALUE.  THE SIXTH BYTE IS SET TO 
;  ZERO (NULL).  LEADING ZEROES ARE BLANKED 
; 
BN2DEC EQU  $ 
       SHLD LNKSAV    ;SAVE BUFFER ADDRESS
       LXI  H,B2D200  ;SET OUTPUT ROUTINE TO BUFFE
       SHLD CNTFAD      ;STORE ROUTINE
       MVI  C,1       ;SET ZERO SUPPRESS FLAG 
       LXI  H,-10000
       CALL B2D100    ;EXTRACT 10,000'S VALUE 
       LXI  H,-1000 
       CALL B2D100    ;EXTRACT 1,000'S VALUE
B2D050 EQU  $ 
       LXI  H,-100
       CALL B2D100    ;EXTRACT 100'S VALUE
       LXI  H,-10 
       CALL B2D100    ;EXTRACT 10'S VALUE 
       MOV  A,E       ;CONVERT UNITS DIGIT TO 
       ORI  ZERO        ;ASCII AND STORE IN 
       DCR  C         ;SET C TO FORCE ZERO STORE
       JMP  ECONTF    ;GO TO OUTPUT ROUTINE 
 
;*******************************
; B2D100 - EXTRACT RADIX VALUE *
;*******************************
; 
;  ENTRY:  C = 0, SUPPRESS ZERO 
;            < 0, DON'T SUPPRESS ZEROES 
;          D,E = VALUE TO BE CONVERTED
;          H,L = -RADIX 
;          LNKSAV = CURRENT BUFFER ADDRESS
; 
;  EXIT :  C < 0, CHARACTER STORED
;            = 0, ZERO SUPPRESSED 
;          (LNKSAV) = (LNKSAV)+1
;          A-C, H,L DESTROYED 
; 
B2D100 EQU  $ 
       MVI  B,ZERO-1  ;SET INITIAL ASCII VALUE
       XCHG           ;EXCHANGE RADIX AND INPUT 
B2D110 EQU  $ 
       INR  B         ;INCREMENT ASCII VALUE
       DAD  D         ;SUBTRACT RADIX 
       JC   B2D110    ;CONTINUE IF INPUT>RADIX
       MOV  A,L       ;ADD BACK RADIX TO EXTRACT
       SUB  E           ;REMAINDER
       MOV  E,A       ;SAVE REMAINDER IN D,E
       MOV  A,H 
       SBB  D 
       MOV  D,A 
       MOV  A,B       ;GET CONVERTED VALUE
       JMP  ECONTF    ;GO TO OUTPUT ROUTINE 
;************************************************ 
; B2D200 - STORE DECIMAL VALUE FOR INTERNAL USE * 
;************************************************ 
; 
;  ENTRY:  A = CONVERTED VALUE
; 
B2D200 EQU  $ 
       CPI  ZERO      ;CONVERTED VALUE = ZERO?
       JNZ  B2D210    ;NO - STORE THE DIGIT 
       DCR  C         ;NON-ZERO CHAR ALREADY DONE?
       JM   B2D220    ;YES - STORE THE DIGIT
       INR  C         ;NO - RESTORE ZERO FLAG 
       RET              ;AND EXIT 
B2D210 EQU  $ 
       DCR  C         ;CLEAR ZERO SUPPRESS FLAG 
B2D220 EQU  $ 
       LHLD LNKSAV    ;GET BUFFER POINTER 
       MOV  M,A       ;STORE CONVERTED VALUE
       INX  H         ;INCREMENT BUFFER POINTER 
       MVI  M,0       ;SET NEXT BYTE TO NULL
       SHLD LNKSAV    ;STORE NEW POINTER VALUE
       RET            ;RETURN 
 
;*********************************
; CALCULATE CHECKSUM             *
;                                *
; ENTRY:                         *
;      (H,L) = ADDRESS OF AREA   *
;      TO BE CHECKSUMED          *
;                                *
;      D = NO. BYTES IN AREA/256 *
; WE ASSUME THE AREA BEGINS ON A *
; 256 BYTE BOUNDARY, I.E., L=0.  *
;      CALL CHKSUM               *
; EXIT:                          *
;      A = CHECKSUM              *
;      ALL OTHER REGS. UNCHANGED *
;      FLAGS DESTROYED           *
;*********************************
CHKSUM EQU  $ 
       PUSH D         ;SAVE REGISTER D-H
       PUSH H 
       XRA  A         ;ZERO SUM 
CSU100 EQU  $ 
       ADD  M         ;ADD BYTE 
       ACI  0         ;ADD CARRY
       INR  L         ;BUMP ADDRESS POINTER 
       JNZ  CSU100    ;ADD NEXT BYTE
; 
       INR  H         ;FINISHED A 256 BYTE BLOCK
       DCR  D 
       JNZ  CSU100    ;DO NEXT 256 BYTES
; 
       INX  B         ;INCREMENT TO NEXT STORE ADD
       MOV  D,A       ;SAVE CHECKSUM IN D-REGISTER
       POP  H         ;RECALL STARTING ADDRESS
       MOV  A,H 
       CPI  170000Q/256  ;LAST RAM BLOCK? 
       JNZ  CSU110    ;NO - EXIT
       MOV  C,L       ;YES - SET B,C TO FIRST 
;                       CHECKSUM STORE ADDRESS
CSU110 EQU  $ 
       MOV  A,D       ;PUT CHECKSUM BACK INTO A-RE
       POP  D         ;RESTORE D,E
       RET            ;RETURN 
 
;******************************************** 
; CLEAR - RESET TERMINAL BY ESCAPE SEQUENCE * 
;******************************************** 
CLEAR  EQU  $ 
       CALL IOBSYC    ;WAIT UNTIL TAPES NOT BUSY
       MVI  A,FRCRST  ;SET FLAG TO FORCE FULL 
       CALL STCMFL      ;TERMINAL RESET 
       MVI  A,CRTOFF  ;TURN OFF THE DISPLAY 
       STA  IOCRRW
       RST  RESET     ;GO DO TERMINAL RESET 
 
;********************************************** 
; DISPL1 - ADD ENOUGH BLOCKS TO REACH DESIRED * 
;   COLUMN                                    * 
;********************************************** 
; 
;  ENTRY:  C = NUMBER OF CHARACTERS NEEDED - 1
;          D,E = LOCATION OF EOL IN LINE
; 
;  EXIT :  A = 0, NOT ENOUGH BLOCKS (MEMORY LOCK) 
;            B-L DESTROYED
;          A # 0, MEMORY ALLOCATED
;            D,E = FIRST CHAR ADDR IN NEW BLOCKS
;            B,C,H,L DESTROYED
; 
;  IF ONLY ONE CHARACTER IS TO BE ADDED, THE
;  CHARACTER IS ADDED TO THE LINE.  OTHERWISE, ALL
;  REQUIRED BLOCKS ARE ADDED TO THE LINE AND THE
;  LINE IS FILLED WITH BLANKS UP TO THE DESIRED 
;  CHARACTER ONLY.
; 
DISPL1 EQU $
       INR C        ;MOVE EOL IF NECESSARY
       CALL EOLMOV
       DCR C
       JM   DIS220    ;CHARACTER POSITION FOUND 
       LXI  H,NCHAR   ;SAVE NUMBER OF CHARACTERS
       MOV  M,C             ;TO BE ADDED - 1
DISPL2 EQU  $ 
       XCHG 
       SHLD EOLADR  ;SAVE EOL ADDRESS 
       DCR  C         ;SINGLE CHARACTER ADDED?
       JM   DIS400    ;YES - DO FAST EXTEND 
       MVI  A,ABLNK   ;NO - GET A DISPLAY BLOCK 
       CALL GTBLK       ;FILLED WITH BLANKS 
       RZ             ;RETURN IF MEMORY LOCKED
       XCHG           ;PUT BLOCK ADDRESS IN D,E 
       ORI  BLKSM     ;COMPUTE HIGH ADDR OF BLOCK 
       MOV  C,A       ;SAVE ADDRESS OF FIRST NEW
       PUSH B           ;BLOCK ADDED
       LDA  NCHAR     ;GET # OF CHARS TO BE ADDED 
       MVI B,0      ;INITIALIZE COUNT 
DIS120 EQU $
       INR B        ;INCREMENT COUNT
       SUI BLKSZ-2  ;SUB. NO. OF CHARS IN BLOCK 
       JP  DIS120   ;JUMP IF MORE BLOCKS NEEDED 
       STA  COUNT     ;SAVE LAST CHAR BLOCK POS 
       DCR B        ;SINGLE BLOCK?
       JZ  DIS160   ;YES
 
;***************************
; MULTIPLE BLOCKS REQUIRED *
;***************************
       LXI  H,NBLKS   ;SAVE BLOCK COUNT 
       MOV M,B
;************************ 
; GET SUBSEQUENT BLOCKS * 
;************************ 
       PUSH D         ;SAVE ADDRESS OF LAST BLOCK 
DIS140 EQU  $ 
       MVI  A,ABLNK   ;GET A DISPLAY BLOCK FILLED 
       CALL GTBLK       ;WITH BLANKS
       XCHG           ;PUT BLOCK ADDRESS IN D,E 
       POP  H         ;RECALL ADDRESS OF LAST BLOC
       JZ   DIS240    ;EXIT IF MEMORY LOCKED
       PUSH D         ;SAVE NEW LINE ADDRESS
       DCX  H         ;LINK NEW BLOCK TO PREVIOUS 
       ORI BLKSM
       MOV M,B      ;MSB'S
       DCX  H 
       MOV  M,A       ;STORE LSB
       LXI  H,NBLKS 
       DCR  M         ;ALL BLOCKS ALLOCATED?
       JNZ  DIS140    ;NO - GET ANOTHER BLOCK 
       POP  PSW       ;YES - POP THE STACK
 
;*****************************
; ALL BLOCKS HAVE BEEN ADDED *
;*****************************
DIS160 EQU  $ 
       LDA  COUNT     ;COMPUTE NUMBER OF BYTES
       CMA              ;TO FILL
       INR  A 
       MOV C,A      ;SAVE IN C
       ADD E        ;GET FIRST FILL ADDR
       DCR  A         ;SET FIRST LSB FILL ADDRESS 
       MOV  L,A       ;PUT LSB INTO L 
       MOV  H,D       ;GET MSB FROM D 
       MVI  B,EOL     ;SET "EOL" CHARACTER
       LDA  CURCOL    ;GET CURRENT COLUMN 
       CPI  MAXCOL    ;CHAR ADDED TO LAST COLUMN? 
       JNZ  DIS170    ;NO - SET "EOL" CHARACTER 
       LDA  DCHAR     ;YES - GET CHARACTER STORED 
       ORA  A         ;IS IT ASCII? 
       JP   DIS175    ;YES - DON'T ADD "EOL"
;                     NO - SET "EOL" CHARACTER
;********************************************** 
; FILL UNUSED PART OF BLOCK WITH "FILL" CODES * 
;********************************************** 
DIS170 EQU  $ 
       MOV  M,B       ;STORE FILL/EOL CHARACTER 
DIS175 EQU  $ 
       DCX  H         ;GO TO NEXT BYTE
       DCR  C         ;ALL UNUSED BYTES FILLED? 
       MVI  B,FILL      ;(SET "FILL" CODE)
       JNZ  DIS170    ;NO - SET NEXT BYTE 
;************************** 
; WRITE LINK TO NEXT LINE * 
;************************** 
DIS180 EQU $
       LHLD LSTLIN    ;GET ADDR CURRENT LINE
       XCHG 
       DCX  H         ;STORE AS NEXT BLOCK POINTER
       MOV  M,D 
       DCX  H 
       INX  D         ;POINT TO NEXT LINE POINTER 
       MOV  M,E 
 
;***************************
; LINK NEW BLOCK(S) TO OLD *
;***************************
       POP  D         ;RECALL FIRST NEW BLOCK ADDR
       LDA  NCHAR     ;GET # OF CHARS ADDED - 1 
       ORA  A         ;DOES NEW CHAR REPLACE EOL? 
       LDA  DCHAR       ;(DEFAULT TO ADD 1 CHAR)
       JZ   DIS210    ;YES - OVERWRITE EOL
       MVI  A,ABLNK   ;NO - STORE BLANK OVER EOL
DIS210 EQU  $ 
       MOV  B,A       ;SAVE CHARACTER TO BE STORED
       LHLD EOLADR    ;RECALL EOL ADDRESS 
       LDA  CURROW
       ORI  MAYEOL    ;SET FOR POSSIBLE EOL SKIP
       DI             ;DISABLE INTERRUPTS 
       STA  IOCRRW    ;TURN OFF DISPLAY DMA 
       MOV  M,B       ;OVERWRITE EOL
       DCX  H 
       MOV  M,D       ;CHANGE NEXT BLOCK LINK TO
       DCX  H           ;POINT TO NEW BLOCKS
       MOV  M,E 
       CALL DISLN1    ;TURN DISPLAY BACK ON 
       ORA  H         ;SET Z-FALSE
       RET            ;RETURN 
;*****************************
; EOL MOVE SATISFIED REQUEST *
; CHECK FOR SINGLE CHARACTER *
;*****************************
DIS220 EQU $
       DCR  A         ;SINGLE CHARACTER?
       STA  NCHAR     ;(SET NCHAR)
       RNZ            ;NO - RETURN
       LDA  DCHAR     ;YES - GET THE CHARACTER
       STAX D         ;STORE THE CHARACTER
       RET          ;RETURN 
;***************************
; ALL BLOCKS NOT AVAILABLE *
; INITIALIZE END OF LINE   *
;***************************
DIS240 EQU $
       MVI  M,EOL     ;STORE AN EOL 
       XCHG           ;PUT ADDRESS INTO D,E 
       JMP DIS180 
 
;**************************** 
; SINGLE CHARACTER ADDITION * 
;**************************** 
DIS400 EQU  $ 
       CALL GTBLKF    ;GET A DISPLAY BLOCK
       RZ             ;RETURN IF MEMORY LOCKED
       MOV  D,H       ;SAVE BLOCK ADDRESS IN D,E
       MOV  E,L 
       ORI  BLKSM     ;PUT AN EOL AT THE FIRST
       MOV  L,A         ;DISPLAY CHARACTER
       MVI  M,EOL       ;LOCATION IN THE BLOCK
       PUSH H         ;SAVE ADDRESS OF BLOCK
       JMP  DIS180    ;LINK BLOCK TO DISPLAY
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  EOLMOV - MOVE EOL IN A BLOCK 
; 
;      ENTRY:  C = NUMBER OF BYTES NEEDED 
;              D,E = ADDRESS OF EXISTING EOL
; 
;      EXIT :  A = NUMBER OF CHARACTERS ADDED 
;              C = 0, CHARACTER FOUND 
;                D,E = ADDRESS OF CHARACTER 
;              C = NUMBER OF CHARACTERS NEEDED
;                D,E = ADDRESS OF LAST BYTE IN BLK
;              H = BASEH
;              B,L DESTROYED
; 
;  EOLMV0 - MOVE ONLY IF UNPROTECTED
; 
EOLMV0 EQU  $ 
       LDA  BLKFIL    ;GET BLOCK FILL INHIBIT FLAG
       INR  A         ;BLOCK FILL INHIBITED OR
       CNZ  CKPROT      ;CURSOR IN PROTECTED FIELD
       RZ             ;YES - RETURN 
; 
EOLMOV EQU  $ 
       MOV  A,E       ;COMPUTE NUMBER OF BYTES
       ANI  BLKSM       ;AVAILABLE IN BLOCK 
       SUI  2           ;(DELETE BYTES FOR LINK)
       RZ             ;RETURN IF NONE AVAILABLE 
       XCHG           ;PUT CURRENT ADDRESS IN H,L 
       CMP  C         ;ENOUGH CHARACTERS? 
       MOV  B,A         ;(SET B TO FILL BLOCK)
       LXI  D,EOL*256+MAYEOL  ;(SET FOR PARTIAL 
;                       LINE EXTENSION) 
       JM   ELM100    ;NO - BLANK REST OF BLOCK 
       MOV  B,C       ;YES - BLANK WHAT'S NEEDED
       LDA  CURCOL    ;GET CURRENT COLUMN POSITION
       CPI  MAXCOL    ;ADDING TO LAST COLUMN? 
       JNZ  ELM100    ;NO - NEED EOL AT LINE END
       LDA  DCHAR     ;YES - GET NEW CHARACTER
       ORA  A         ;IS IT  ASCII?
       JM   ELM100    ;NO - NEED EOL AT LINE END
       MVI  D,FILL    ;YES - DON'T NEED EOL 
 
; 
;  FILL THE BLOCK 
; 
ELM100 EQU  $ 
       MOV  A,C       ;COMPUTE NUMBER OF ADDITIONA
       SUB  B           ;BYTES NEEDED 
       MOV  C,A       ;SAVE IT IN C FOR RETURN
       LDA  CURROW    ;SET CONTROL TO TURN OFF DMA
       ORA  E 
       MOV  E,B       ;SAVE NUMBER OF BYTES ADDED 
       DI             ;DISABLE INTERRUPTS 
       STA  IOCRRW  ;TURN OFF DMA 
; 
ELM110 EQU  $ 
       MVI  M,ABLNK   ;FILL BLOCK WITH BLANKS 
       DCX  H         ;MOVE TO NEXT BYTE
       DCR  B         ;FILL COMPLETED?
       JNZ  ELM110    ;NO - DO NEXT BYTE
       MOV  M,D       ;YES - ADD EOL OR EOL FILL
       CALL DISLN1    ;TURN DISPLAY BACK ON 
       XRA  A         ;CLEAR A-REGISTER 
       ORA  C         ;ALL CHARACTERS DONE? 
       JNZ  ELM130    ;NO - RETURN ADDRESS OF EOL 
       INX  H         ;YES - RETURN ADDR OF LAST C
ELM130 EQU  $ 
       MOV  A,E       ;PUT # OF CHARS DONE IN A-RE
       XCHG           ;PUT CHARACTER ADDRESS IN D,
       LXI  H,EOLMV     ;(SET H TO DATA PAGE) 
       MVI  M,1       ;SET EOLMV FLAG 
       RET            ;RETURN 
 
;*******************
; LD - LINE DELETE *
;*******************
LINDEL EQU $
       CALL CHKFMS  ;FORMAT MODE? 
       CZ  RCADR1   ;FIND LINE IF NOT 
       RNZ          ;LINE NOT FOUND 
       LHLD LSTLIN    ;GET ADDR OF LAST LINE DONE 
       MOV  A,M       ;GET PREVIOUS LINE'S LSB
       ORA  A         ;ANY PREVIOUS LINES?
       JZ   LID050    ;NO - DO CLEAR LINE ONLY
       CALL LINDL0    ;YES - DELETE CURRENT LINE
;************************************** 
; UPDATE LSTLIN AND CURADR TO ADDRESS * 
; OF NEXT LINE                        * 
;************************************** 
       MOV  H,B       ;PUT NEW LINE ADDRESS INTO
       MOV  L,C         ;H,L
       CALL BACKT5    ;UPDATE CURRENT LINE AND ADD
       CALL LININ0    ;GO UPDATE TOP LINE IF NEEDE
       JMP  PUTLIN    ;ADD LINE TO FREE LIST
LID050 EQU  $ 
       CALL CLEARL    ;CLEAR THE LINE 
       JMP  CURPRT    ;SET CURSOR AT LEFT MARGIN
 
;***************************************
; LINDL0 - RMOVE LINE FROM LINKED LIST *
;***************************************
; 
;  ENTRY:  H,L = ADDRESS OF NEXT LINE FIELD 
;            (LSB) OF LINE TO BE DELETED
; 
;  EXIT :  B,C = ADDRESS OF LSB PORTION OF
;            NEXT LINE POINTER IN NEW LINE
;          D,E = H,L(ENTRY) 
;          A,H,L DESTROYED
; 
LINDL0 EQU  $ 
       MOV  E,L       ;SAVE ADDRESS OF LINE TO BE 
       MOV  D,H         ;DELETED IN D,E 
       MOV  C,M       ;GET ADDRESS OF NEXT LINE 
       INX  H 
       MOV  B,M 
       INX  H         ;GET ADDRESS OF PREVIOUS LIN
       MOV  A,M 
       INX  H 
       MOV  H,M 
       ORA  A         ;DOES PREVIOUS LINE EXIST?
       JNZ  LID200    ;YES - LINK 2 LINES TOGETHER
;************************************** 
;  FIRST LINE DELETED - UPDATE FLINE  * 
;************************************** 
       MOV  H,B       ;MOVE NEW CURRENT LINE TO H,
       MOV  L,C 
       INX  H         ;SET ADDR TO NEXT LINE FIELD
       SHLD FLINE 
       JMP  LID300    ;SET NEW PREV LINE POINTER
 
;****************************************** 
; UPDATE NEXT LINE FIELD IN PREVIOUS LINE * 
;****************************************** 
LID200 EQU $
       MOV  L,A       ;PUT LSB INTO L-REGISTER
       INX  H         ;SET TO MSB OF NEXT LINE FLD
       CALL DISLNK    ;SET NEW NEXT LINE LINK TO
;                       CURRENT ROW 
;***************************************
; SET PREVIOUS LINE FIELD IN NEXT LINE *
;***************************************
       MOV  A,L       ;SAVE PREV LINE ADDR'S LSB
LID300 EQU  $ 
       INX  B         ;INCREMENT TO NEXT LINE PTR 
       PUSH B         ;SAVE ADDRESS 
       INX  B         ;SET ADDRESS TO PREVIOUS
       INX  B           ;LINE FIELD 
       STAX B         ;STORE LSB VALUE
       INX  B 
       MOV  A,H 
       STAX B         ;STORE MSB VLAUE
       POP  B         ;RESTORE CONTENTS OF B,C
       RET            ;RETURN 
 
;*******************
; LI - LINE INSERT *
;*******************
LININS EQU $
       CALL CHKFMS  ;FORMAT MODE? 
       CZ  RCADR1   ;FIND LINE IF NOT 
       RNZ          ;RETURN IF LINE NOT FOUND 
       CALL GTBLKF  ;GET BLOCK FOR NEW LINE 
       RZ           ;RETURN IF NOT AVAILABLE
;******************************** 
; STORE LINK AT END OF NEW LINE * 
;******************************** 
       ADI BLKSZ-5  ;GET ADDR OF NEXT LINE FIELD
       DCR L
       MOV M,H      ;STORE LINK MSB'S 
       DCR L
       MOV M,A      ;STORE LINK LSB'S 
       SUI 2        ;STORE EOL IN NEW LINE
       MOV L,A
       CALL STCHR1    ;SET FIRST DISPLAY CHARACTER
;*********************************************
; ADJUST LSTLIN AND CURADR PNTRS TO NEW LINE *
;*********************************************
       SHLD CURADR    ;SET CURADR TO 1ST CHAR 
       INX  H         ;SET TO NEXT LINE POINTER 
       MOV  A,L       ;PUT LSB INTO A-REGISTER
       XCHG 
       LHLD LSTLIN    ;GET CURRENT LINE ADDRESS 
       XCHG 
       SHLD LSTLIN    ;SET NEW CURRENT LINE ADDRES
       CALL LININ1    ;ADD LINE TO DISPLAY LIST 
;**************************** 
; UPDATE TOPLIN IF ROW ZERO * 
;**************************** 
LININ0 EQU  $ 
       CALL LSTLU2    ;SET INITIAL LINE STATE 
       CALL CURPRT    ;SET CURSOR TO LEFT MARGIN
       XRA  A         ;SET LAST COLUMN DONE TO
       STA  LSTCOL      ;ZERO 
       LXI  H,CURROW  ;GET CURRENT ROW NUMBER 
       ORA  M         ;DID TOP ROW CHANGE?
       RNZ            ;NO - RETURN
       JMP  TOPUP1    ;YES - UPDATE TOP LINE VALUE
 
;****************************************** 
; LININ1 - ADD LINE TO LINK LIST          * 
; ENTRY: D,E=NEXT PAGE FIELD ADDR IN LINE * 
;            BEFORE WHICH NEW LINE IS     * 
;            TO BE INSERTED               * 
;        A,B=NEXT PAGE FIELD ADDR OF LINE * 
;            TO BE INSERTED 
;      EXIT :  C,B = A,B(ENTRY) 
;              D-L DESTROYED
;****************************************** 
LININA EQU  $ 
       MOV  A,E       ;PUT ROLLED LINE ADDRESS INT
       MOV  B,D         ;B,A
       XCHG           ;PUT CHAR ADDRESS INTO D,E
LININ1 EQU  $ 
       MOV L,E      ;UPDATE PREV LINE PTR 
       MOV H,D      ;IN NEXT LINE 
       INX  H         ;SET ADDRESS TO PREVIOUS
       INX  H           ;LINE POINTER 
       MOV C,M      ;GET ADDR OF PREV LINE
       MOV M,A      ;STORE ADDR OF NEW LINE 
       INX  H 
       MOV D,M
       MOV M,B
;******************************** 
; UPDATE NEXT/PREVIOUS POINTERS * 
; IN NEW LINE                   * 
;******************************** 
       MOV L,A      ;GET ADDR OF NEXT LINE FIELD
       MOV A,H
       MOV H,B
       DCR E        ;SKIP OVER POINTERS 
       MOV M,E      ;STORE NEXT LINE LSB'S
       INX  H 
       MOV M,A      ;STORE NEXT LINE MSB'S
       INX  H 
       MOV M,C      ;STORE PREV LINE LSB'S
       INX  H 
       MOV M,D      ;STORE PREV LINE MSB'S
 
;******************************** 
; SEE IF NEW LINE IS FIRST LINE * 
;******************************** 
       MOV A,C      ;GET PREV LINE LSB'S
       ORA A        ;SET FLAGS
       MOV A,L      ;(PUT LSB OF ADDR IN A-REG) 
       JZ  LII200   ;JUMP IF NEW LINE IS
;                     FIRST LINE
;*********************************
; NEW LINE IS NOT FIRST LINE     *
; LINK PREVIOUS LINE TO NEW LINE *
;*********************************
       SUI 4        ;GET ADDR OF NEW LINE DATA
       MOV L,C      ;GET ADDR OF NEXT PAGE FIELD
       MOV H,D      ;OF PREVIOUS LINE 
       MOV  C,A       ;NEW LINE'S LSB TO C
       INX  H         ;SET TO MSB PART OF FIELD 
       CALL DISLNK    ;LINK PREV LINE TO NEW LINE 
       INR C
       RET          ;RETURN 
;*************************
; NEW LINE IS FIRST LINE *
;*************************
LII200 EQU $
       SUI 3        ;GET ADDR OF NEXT PAGE FIELD
       MOV C,A      ;PUT LSB INTO C-REGISTER
       MOV  L,A       ;SET NEW FIRST LINE POINTER 
       SHLD FLINE 
       RET            ;RETURN 
 
;********************** 
; LINE FEED PROCESSOR * 
;********************** 
CONDLF EQU $
       LDA  KBJMPR    ;GET THE STRAP SETTINGS 
       ANI LINWRP     ;WRAP AROUND ENABLED? 
       RZ           ;YES - LF NOT REQUIRED
LNFEED EQU $
       LXI  H,SPOWL   ;CLEAR SPOW LATCH 
       MVI  M,SPOWOF
       MVI  L,CURROW-BASE  ;GET CURSOR ROW
       MOV A,M
       CPI MAXROW   ;IS CURSOR IN BOTTOM ROW? 
       JZ   LNF100    ;YES - ROLL UP THE DISPLAY
       INR  A         ;NO - MOVE CURSOR TO NEXT RO
       MOV  M,A       ;STORE NEW ROW NUMBER 
       STA  IOCRRW    ;SET SCREEN CURSOR
LNF100 EQU  $ 
       CZ   ROLLUP      ;(ROLL UP IF AT BOTTOM) 
; 
;  BUILD FIRST BLOCK OF NEW ROW IF NECESSARY
; 
       LDA  MFLGS     ;GET BLOCK XFR PENDING FLAGS
       ANI  SENTER/256  ;ENTER PENDING? 
       RNZ            ;YES - DO NOT BUILD NEW ROW 
       LDA  IOFLG2    ;NO - GET I/O FLAGS 
       ANI  XDS2BF    ;DISPLAY TO I/O BUFFER? 
       RNZ          ;YES - DO NOT BUILD NEW ROW 
; 
;  ACQUIRE MEMORY FOR EDIT MODE IF NEEDED 
; 
       MVI  A,-1      ;LOCATE BEGINNING OF NEW
       CALL RCADR0      ;ROW
       CALL CKEDIT    ;CHECK FOR SUFFICIENT FREE
       CNZ  FRECNT
       RET            ;RETURN 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  LSTLUP - UPDATE "LSTLIN" 
; 
;      ENTRY:  H,L = ADDRESS TO BE STORED 
; 
;      EXIT :  D,E = LSTLIN = H,L(ENTRY)
;              A,H,L DESTROYED
;              LSTDCD = 0 
;               PROFLD SET TO INDICATE PROTECTED
;                FIELD OF FORMAT MODE ENABLED 
; 
LSTLUP EQU  $ 
       SHLD LSTLIN    ;SET NEW "LSTLIN" VALUE 
LSTLU1 EQU  $ 
       XCHG           ;PUT "LSTLIN" VALUE INTO D,E
LSTLU2 EQU  $ 
       XRA  A         ;CLEAR LAST DISPLAY CODE
       STA  LSTDCD
       MVI  A,STPR    ;INITIALIZE LAST FORMAT 
       STA  LSTFMT      ;CONTROL CODE TO "STPR" 
       CALL CHKFMS  ;FORMAT MODE? 
       RZ           ;NO - RETURN
       MVI  A,-1      ;YES - SET PROTECT FLAG TO
       STA  PROFLD      ;INDICATE PROTECTED FIELD 
       LXI  H,ZRETRN  ;INITIALIZE FIELD CHECKING
       SHLD CHKRTN      ;ROUTINE
       RET
 
;****************** 
; MEMORY LOCK OFF * 
;****************** 
MLKOF0 EQU  $ 
       LDA  MLKROW    ;GET MEMORY LOCK ROW
       ORA  A         ;SET FOR FULL LOCK OUT? 
       JNZ  MLKOF     ;NO - CLEAR LOCK OUT ONLY 
MLKOFF EQU  $         ;YES - TURN OFF MEMORY LOCK 
       LXI  H,0       ;SET MEMORY LOCK ROW AND
       SHLD MLKFLG      ;FLAG TO ZERO 
       MVI  A,MEMLOK  ;TURN OFF MEMORY LOCK 
       JMP  ZCLMD1      ;FLAG 
;*****************
; MEMORY LOCK ON *
;*****************
MLKON  EQU  $ 
       LDA  CURROW    ;GET CURRENT CURSOR ROW 
       ORA  A         ;SET FOR OVERFLOW INHIBIT?
       JNZ  MLO005    ;NO - SET MEMORY LOCK ROW 
       CALL CKEDIT    ;EDIT MODE? 
       RNZ            ;YES - DON'T ALLOW LOCK OUT 
MLO005 EQU  $         ;NO - SET MEMORY LOCK ROW 
       STA  MLKROW
MLO010 EQU  $ 
       MVI  A,MEMLOK  ;TURN MEMORY LOCK FLAG
       MVI  B,0         ;ON AND DON'T BLINK LED 
       LXI  H,MLKFLG    ;(CLEAR THE MEMORY LOCK 
       MOV  M,B          ;FLAG) 
       JMP  ZSTMD1
 
;********************************** 
; MLKSCH - LOCATE MEMORY LOCK ROW * 
;********************************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  Z - MEMORY LOCK ROW NOT FOUND
;            A,C,H,L DESTROYED
;          NZ - MEMORY LOCK ROW FOUND 
;            H,L = ADDRESS OF LAST LOCK ROW 
;              (POINTS TO LSB OF NEXT LINE
;               POINTER)
;            A,C DESTROYED
; 
MLKSC0 EQU  $         ;LOCATE FIRST UNLOCKED ROW
       LDA  MLKROW    ;GET MEMORY LOCK ROW
       ORA  A         ;SET FOR PARTIAL SCREEN LOCK
       LHLD TOPLIN      ;(SET FOR TOP DISPLAY LINE
       JZ   NZEXIT    ;NO - RETURN FOUND (NZ) 
;                     YES - LOCATE MEMORY LOCK ROW
MLKSCH EQU  $ 
       LDA  MLKROW  ;GET MEMORY LOCK ROW
       ORA  A         ;SET FOR PARTIAL SCREEN LOCK
       RZ             ;NO - RETURN
;*****************
; SEARCH FOR ROW *
;*****************
       LHLD TOPLIN    ;GET TOP LINE ADDRESS 
MLKSC1 EQU  $         ;LOCATE LINE (A-REG)
       MOV  C,A       ;PUT LINE NUMBER IN C-REG 
MLS120 EQU  $ 
       CALL CHAIN     ;GET ADDRESS OF NEXT LINE 
       ORA  A         ;DOES NEXT LINE EXIST?
       RZ             ;NO - RETURN FAIL (Z) 
       INX  H         ;YES - SET TO NEXT LINE PTR 
       DCR  C         ;ALL LINES FOUND? 
       JNZ  MLS120    ;NO - DO NEXT LINE
; 
NZEXIT EQU  $ 
       ORI  377Q      ;SET NZ, S
       RET          ;RETURN(ZERO FLAG FALSE)
 
;*********************************************
; MLOCK - TURN ON MEMORY LOCK FULL CONDITION *
;*********************************************
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  A = 0
;          Z = T
;          MLKTMR = -1 (377B) 
; 
MLOCK0 EQU  $ 
       CALL PTB100    ;RESTORE PROPER DISPLAY PARM
MLOCK  EQU  $ 
       LXI  H,MLKFLG  ;SET H,L TO MEMORY LOCK FLAG
       ORA  M         ;MEMORY ALREADY LOCKED? 
       JNZ  MLK010    ;YES - DON'T SOUND BELL 
       MVI  A,MEMLOK  ;NO - FORCE MEMORY LOCK ON
       MVI  B,377Q      ;AND BLINKING 
       MOV  M,B       ;SET MEMORY LOCK FLAG 
       CALL ZSTMD1
MLOCK1 EQU  $         ;SOUND BELL AND RETURN A = 0
       CALL ZBELL     ;SOUND THE BELL 
MLK010 EQU  $ 
       XRA  A         ;SET Z-FLAG 
       LXI  H,NROWS     ;(SET H TO DATA PAGE) 
       MOV  M,A       ;CLEAR NROWS FOR RCADDR 
       RET            ;RETURN (A = 0, Z= T) 
       NOP            ;NOP FOR PATCH TO "PT772" 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  MOVCHR - MOVE CHARACTER STRING 
; 
;      ENTRY:  H,L = SOURCE POINTER 
;              B,C = DESTINATION POINTER
; 
;      EXIT :  B,C = NEXT STORAGE LOCATION
;              H,L = END OF SOURCE STRING 
;              Z - TERMINATED BY A NULL BYTE
;              NZ - TERMINATED BY AN EOP
; 
MOVCHR EQU  $ 
       MOV  A,M       ;GET DATA BYTE
       ORA  A         ;IS IT A NULL?
       RZ             ;YES - RETURN (Z - TRUE)
       STAX B         ;NO - STORE THE BYTE
       INX  H         ;INCREMENT TO NEXT SOURCE BY
       DCX  B         ;DECREMENT TO NEXT DEST BYTE
       CPI  EOP       ;WAS LAST BYTE AN EOP?
       JNZ  MOVCHR    ;NO - DO NEXT BYTE
       ORA  A         ;YES - SET Z-FALSE
       RET            ;RETURN 
 
;************ 
; NEXT PAGE * 
;************ 
NEXTPG EQU $
       MVI  A,MAXROW+1  ;COMPUTE NUMBER OF LINES
       MVI  L,MLKROW      ;TO ROLL UP 
       SUB  M 
       CALL NXT100
NXT040 EQU  $ 
       LDA  MLKROW    ;SET CURRENT CURSOR POSITION
       STA  CURROW      ;TO MEMORY LOCK ROW AND 
       CALL CURPRT      ;LEFT MARGIN
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JNZ  FLDSR     ;YES - TAB TO NEXT FIELD
       RET            ;NO - RETURN
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  NXTPG1 - ROLL UP N LINES 
; 
;      ENTRY:  A = NUMBER OF ROWS TO ROLL UP
;              H = BASEH
; 
;      EXIT :  C = NUMBER OF LINES ROLLED 
;              H,L = NMROLL+
;              A,B,D,E DESTROYED
NXT100 EQU $
NXTPG1 EQU $
       MOV  C,A       ;PUT ROLL PARAMETER IN C-REG
       MVI  L,ROLLCT  ;SAVE ROLL PARAMETER
       MOV  M,C 
       INX  H 
NXT110 EQU  $ 
       MOV  M,C 
       CALL ROLLUP    ;ROLL UP SUCCESSFUL?
       LXI  H,ROLLCT    ;(RECALL ROLL COUNT)
       MOV  C,M 
       JZ   NXT120    ;NO - EXIT
       DCR  C         ;ALL LINES DONE?
       JNZ  NXT110    ;NO - ROLL UP ANOTHER LINE
;                     YES - EXIT (C = 0)
;*********************************************
; TERMINATE ROLL UP - RETURN NUMBER OF LINES *
;   ROLLED                                   *
;*********************************************
NXT120 EQU  $ 
       INX  H         ;GET NUMBER OF LINES TO BE
       MOV  A,M         ;ROLLED UP
       SUB  C         ;COMPUTE ACTUAL NUMBER DONE 
       MOV  C,A       ;RETURN VALUE IN C-REGISTER 
       RET            ;RETURN 
 
;*****************************************
; GET ADDRESS OF NEXT                    *
; RAM BLOCK.                             *
; ENTRY:                                 *
; E, BIT 7 = 0, 4K INCREMENTS            *
;          = 1, 256                      *
;                                        *
;    BIT 0 = 0, IN NON-DISPLAY RAM       *
;          = 1, DISPLAY RAM              *
;                                        *
; H = 0 IF FIRST ENTRY OF ROUTINE        *
;                                        *
;      CALL NXSBLK                       *
;                                        *
; EXIT:                                  *
;      (H,L) = ADDRESS OF NEXT           *
;              BLOCK                     *
;      A = 0 IF END OF MEMORY            *
;      E SET TO INDICATE APPROP. RAM     *
;      OTHER REGS. UNCHANGED, FLAGS ARE. *
;*****************************************
NXSBLK EQU  $ 
       PUSH B 
       XRA  A 
       CMP  H         ;H = 0? 
       JNZ  NXB100    ;NO - ADVANCE TO NEXT BLOCK 
       LHLD BUFBGN    ;IS THERE ANY NON DISPLAY 
NXB060 EQU  $ 
       LDA  BUFEND+1    ;MEMORY?
       CMP  H 
       JNC  NXB200    ;YES, EXIT
       LHLD DSPBGN    ;NO, USE DISPLAY MEMORY 
       INR  E         ;INDICATE DISPLAY MEMORY
       JMP  NXB200    ;EXIT 
NXB100 EQU  $ 
       ORA  E         ;INCREMENT BY 4K (BIT 7 = 0)
       LXI  B,10000Q    ;(SET FOR 4K INCREMENT) 
       JP   NXB150    ;YES - COMPUTE NEXT BLOCK AD
       MVI  B,256/256  ;NO - INCREMENT BY 256 ONLY
NXB150 EQU  $ 
       DAD  B         ;BUMP POINTER 
       RRC            ;TESTING NON-DISPLAY AREA?
       JNC  NXB060    ;YES - CHECK UPPER BOUNDARY 
NXB200 EQU  $ 
       MOV  A,H       ;IF WE WENT OVER TOP OF 
;                       MEMORY H,= 0
       POP  B 
       RET
 
;********************************************** 
; NXTCHR - GET NEXT CHARACTER IN DISPLAY LIST * 
;********************************************** 
; 
;  ENTRY:  D,E = ADDRESS OF CURRENT CHARACTER 
; 
;  EXIT :  Z = T, CHARACTER IS NOT AN EOL LINK
;                A = DISPLAY CHARACTER
;                D,E = ADDRESS OF CHARACTER 
;              F, NEXT CHARACTER IS EOL LINK
;                A DESTROYED
;                D,E = ADDRESS OF NEXT LINE LINK
; 
NXTCH0 EQU  $ 
       XCHG           ;PUT POINTER INTO D,E 
NXTCHR EQU  $ 
       DCX  D         ;GET THE NEXT DISPLAY 
       LDAX D           ;CHARACTER
       CPI  LNKLIM    ;IS IT A LINK?
       JC   NCH010    ;NO - EXIT
       XCHG           ;YES - GET NEW ADDRESS
       DCX  H         ;GET LSB OF LINK
       MOV  L,M 
       MOV  H,A 
       XCHG           ;PUT ADDRESS INTO D,E 
       MOV  A,E       ;PUT LSB INTO A-REGISTER
       CMA            ;END OF LINE LINK (LOWER FOU
       ANI  BLKSM       ;BITS NOT ALL ONES)?
       RNZ            ;YES - RETURN Z FALSE 
       LDAX D         ;NO - GET THE DATA BYTE 
; 
NCH010 EQU  $ 
       CMP  A         ;SET Z TRUE 
       RET            ;RETURN 
 
;**************************** 
; PAROUT - SEND STATUS BITS * 
;**************************** 
; 
;  ENTRY:  A = PARITY BITS TO BE SENT 
; 
;  EXIT :  A-E DESTROYED
; 
PAROT4 EQU  $         ;ROTATE DOWN 4 BITS FIRST 
       RRC
PAROT3 EQU $
       RRC
PAROT2 EQU $
       RRC
PAROT1 EQU $
       RRC
PAROUT EQU $
       ANI 17Q      ;GET BITS 0-3 
       ADI  ZERO      ;ADD IN ZERO BASE TO FORCE
       PUSH H           ;DISPLAYABLE CHARACTER
       CALL ECONTF    ;PERFORM OUTPUT FUNCTION
       POP  H         ;RESTORE H,L
       RET            ;RETURN 
 
;**************** 
; PREVIOUS PAGE * 
;**************** 
PREVPG EQU $
       MVI  A,-MAXROW-1 
       MVI  L,MLKROW  ;COMPUTE NUMBER OF ROWS TO
       ADD  M           ;ROLL DOWN
       CALL PRV100
       JMP NXT040 
; 
;  PRVPG1 - ROLL DOWN FOR CURSOR POSITIONING
; 
;      ENTRY:  H,L = CURROW+
; 
PRVPG1 EQU $
       MVI M,0      ;SET CURRENT ROW TO ZERO
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  PRV100 - ROLL DOWN N LINES 
; 
;      ENTRY:  A = -NUMBER OF LINES TO ROLL DOWN
;              H = BASEH
; 
;      EXIT :  A-L DESTROYED
; 
; 
PRV100 EQU $
       STA  ROLLCT  ;SAVE THE ROLL COUNT
PRV110 EQU  $ 
       CALL ROLLDN    ;LINE ROLLED DOWN?
       LXI  H,ROLLCT  ;(SET H TO DATA PAGE) 
       RZ             ;NO - RETURN
       INR  M         ;ALL LINES DONE?
       JNZ  PRV110    ;NO - DO ANOTHER LINE 
       RET            ;YES - RETURN 
 
;************************************** 
; ROLLDN - ROLL DISPLAY DOWN ONE LINE * 
;************************************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  NZ - ROLL DOWN SUCCESSFUL
;          Z - ROLL DOWN FAILED 
;          ALL REGISTERS DESTROYED
; 
ROLLDN EQU $
       CALL MLKSCH
       JZ  RLD080 
;************************ 
; MEMORY LOCK ROLL DOWN * 
;************************ 
       XCHG           ;LAST LOCKED LINE ADDR TO D,
       LHLD TOPLIN    ;GET TOP LINE ADDRESS 
       INX  H         ;SET ADDRESS TO PREVIOUS LIN
       INX  H           ;POINTER
       CALL CHAIN     ;GET PREVIOUS LINE'S ADDRESS
       ORA  A         ;PREVIOUS LINE EXIST? 
       RZ             ;NO - RETURN
       PUSH D         ;YES - ROLL DOWN THE LINE 
       CALL LINDL0    ;DELETE 1ST LINE ABOVE DISP 
       LXI  H,TLINO   ;DECREMENT TOP LINE 
       DCR  M           ;NUMBER 
       POP  H         ;RECALL LAST LOCKED LINE ADD
       CALL LININA    ;ADD LINE BELOW LOCKED LINES
       LDA  MLKROW    ;GET LOCK ROW NUMBER
       DCR  A         ;ADJUST FOR COMPARE 
       LXI  H,LSTROW  ;COMPARE TO LAST ROW DONE 
       CMP M        ;DID IT ROLL DOWN?
       JM   RLD090    ;YES - UPDATE DISPLAY PTRS
       ORA  H         ;NO - FORCE NZ AND EXIT 
       RET            ;RETURN 
 
;*******************
; NORMAL ROLL DOWN *
;*******************
RLD080 EQU $
       LDA  MLKROW    ;GET MEMORY LOCK ROW
       ORA  A         ;IS IT ZERO?
       JZ   RLD085    ;YES - DO NORMAL ROLL DOWN
       LXI  H,CURROW  ;NO - TRY TO ALLOCATE LINES 
       MOV  B,M         ;TO MEMORY LOCK ROW 
       MOV  M,A 
       PUSH B         ;SAVE CURRENT ROW NUMBER
       MVI  A,-1        ;(SET FOR COLUMN ZERO)
       CALL RCADR0    ;IS MEMORY AVAILABLE? 
       POP  B           ;(RESTORE CURRENT ROW 
       MOV  A,B            ;NUMBER) 
       STA  CURROW
       RNZ            ;NO - RETURN FAIL 
       JMP  ROLLDN    ;YES - RETRY MEMORY LOCK ROL
; 
;  DISPLAY NOT LOCKED - DO NORMAL ROLL DOWN 
; 
RLD085 EQU  $ 
       LHLD TOPLIN    ;GET TOP LINE ADDRESS 
       INX  H         ;SET TO PREVIOUS LINE 
       INX  H           ;ADDRESS
       ORA  M         ;ANY PREVIOUS LINES?
       RZ             ;NO - DON'T DO ROLL DOWN
;                     YES - ROLL ONE LINE DOWN
;*****************************
; TOP LINE IS NOT FIRST LINE *
; ADVANCE POINTERS           *
;*****************************
       MVI D,-1     ;FLAG TO DECREMENT TLINO
       CALL TOPUPD  ;UPDATE TOP LINE POINTERS 
       MVI  L,LSTROW-BASE  ;GET LAST ROW PROCESSED
RLD090 EQU $
       MOV A,M
       INR  A         ;INCREMENT
       CPI MAXROW+1 
       JNZ STOREA   ;NOT ROLL OFF - STORE ROW 
       LHLD LSTLIN    ;GET ADDR OF LAST LINE DONE 
       INX  H         ;SET TO PREVIOUS LINE 
       INX  H           ;ADDRESS
       JMP ROL200 
 
;************************************ 
; ROLLUP - ROLL UP DISPLAY ONE LINE * 
;************************************ 
ROLLUP EQU $
       CALL MLKSCH
       JZ  ROL080 
;********************** 
; MEMORY LOCK ROLL-UP * 
;********************** 
       MOV A,M      ;IS THERE A NEXT LINE?
       ORA A
       RZ             ;NO - DON'T DO ROLL UP
       CALL LINDL0    ;YES - REMOVE FIRST UNLOCKED
       LXI  H,TLINO     ;LINE 
       INR  M         ;INCREMENT TOP LINE NUMBER
       LHLD TOPLIN    ;GET TOP DISPLAY LINE ADDRES
       LDA  MLKROW    ;FORCE END-OF-PAGE IF DISPLA
       ORI  MAYEOP      ;IS CURRENTLY REFRESHING
       STA  IOCRRW      ;MEMORY LOCK BOUNDARY ROW 
       CALL LININA    ;ADD LINE ABOVE DISPLAY 
       LDA  MLKROW  ;GET LOCK ROW NUMBER
       LXI  H,LSTROW  ;GET LAST ROW PROCESSED 
       SUB  M           ;DID IT ROLL UP?
       JM   ROL090      ;YES - UPDATE LINE POINTER
       RNZ              ;NO - RETURN (Z = FALSE)
       MOV  M,A         ;SAME - FORCE LAST ROW = 0
ROL100 EQU  $ 
       MVI L,TOPLIN ;SET CURRENT LINE TO TOP LINE 
ROL200 EQU $
       MOV E,M
ROLUP2 EQU $
       INR L
       MOV D,M
; 
;  ROLUP3 - UPDATE LSTLIN AND CURADR
; 
ROLUP3 EQU  $ 
       XCHG           ;SET LSTLIN TO NEW ROW
ROLUPC EQU  $ 
       CALL LSTLUP
       XCHG           ;PUT NEW ROW ADDRESS INT H,L
       DCX  H         ;SET TO LSB OF NEXT LINE PTR
       SHLD CURADR    ;SET CURADR TO TOP LINE 
       XCHG           ;RESTORE D,E AND H,L
       XRA  A         ;SET LAST COLUMN PROCESSED
       STA  LSTCOL      ;DONE TO ZERO 
       ORA  E         ;SET Z-FLAG FALSE 
       RET            ;RETURN 
 
;*****************
; NORMAL ROLL-UP *
;*****************
ROL080 EQU $
       LHLD TOPLIN    ;GET TOP LINE ADDRESS 
       ORA  M         ;IS TOP LINE LAST LINE? 
       RZ             ;YES - RETURN, DON'T ROLL UP
       MVI  D,1       ;NO - SET D TO INCREMENT
;                       "TLINO" 
       INR  A         ;SET LSB TO NEXT LINE POINTE
;**************************** 
; TOP LINE IS NOT LAST LINE * 
; ADVANCE POINTERS          * 
;**************************** 
ROLUP1 EQU $
       CALL TOPUPD    ;UPDATE TOP LINE POINTERS 
       LXI  H,LSTROW  ;GET LAST ROW # PROCESSED 
ROL090 EQU  $ 
       MOV C,M
       DCR C        ;DECREMENT
       JM  ROL100   ;LINE ROLLED OFF SCREEN 
       MOV M,C      ;STORE UPDATED LSTROW 
       ORA H        ;SET Z-FLAG TO FALSE
       RET
 
;****************** 
; CHAR SET SELECT * 
;****************** 
SCHRST EQU $
       LXI  H,CHRSTB  ;SET FOR CHARACTER SET SELEC
       JMP ESCAP0 
; 
;  SET NEW ALTERNATE CHARACTER SET
; 
SCHST1 EQU  $ 
       MOV  A,C       ;PUT INPUT CHARACTER IN A-RE
       ANI  17Q       ;EXTRACT CHARACTER SET NUMBE
       RLC            ;SHIFT TO POSITION FOR
       RLC              ;ALTERNATE CHARCTER SET 
       RLC
       RLC
       STA  CHRSET  ;STORE CHAR SET SELECT CTL
       RET            ;RETURN 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  SFKYOF - PUT NORMAL DISPLAY ON SCREEN
; 
;      ENTRY:  DON'T CARE 
; 
;      EXIT :  ALL REGISTERS DESTROYED
; 
SFKYOF EQU  $ 
       CALL CHKSFK    ;NORMAL DISPLAY ENABLED?
       RZ             ;YES - RETURN 
       MVI  A,377Q-DEFSKY  ;NO - SWAP DISPLAY 
       CALL CLCMFL    ;CLEAR SOFT KEY MODE FLAG 
       CALL CKDSPF    ;DISPLAY FUNCTIONS ENABLED? 
       JNZ  SFO010    ;YES - DON'T RESET RANGE TBL
       LXI  H,RTABLE  ;NO - RESTORE NORMAL
       SHLD RNGTA       ;CHARACTER FUNCTION TABLE 
       JMP  SFO010    ;TURN ON NORMAL DISPLAY 
 
;****************************************** 
; SFKYON - PUT SOFT KEY DISPLAY ON SCREEN * 
;****************************************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  NZ 
;          ALL REGISTERS DESTROYED
; 
SFKYON EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       RNZ            ;YES - RETURN 
       MVI  A,DEFSKY  ;NO - SWAP DISPLAY
       CALL STCMFL    ;SET SOFT KEY MODE FLAG 
; 
;  EXCHANGE DISPLAY 
; 
SFO010 EQU  $ 
       CALL SWAP      ;SWAP DISPLAY PARAMETERS
       CALL RSTDSP    ;TURN ON THE DISPLAY
       CALL FLDSRX    ;RESCAN LINE TO SET PROPER
       JMP  RCADRA      ;FIELD ATTRIBUTE
;********************************************** 
; SFKYDS - DISPLAY CHARACTER IN SOFT KEY MODE * 
;********************************************** 
; 
;  ENTRY:  DCHAR = CHARACTER TO BE DISPLAYED
; 
;  EXIT :  IF CHARACTER FROM KEYBOARD,
;            CHARACTER IS ADDED TO DISPLAY
;            OTHERWISE, NORMAL DISPLAY IS RESTORED
; 
SFKYDS EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       JZ   DSPCHR    ;NO - USE NORMAL ROUTINE
       CALL DCXB2D    ;INPUT FROM KEYBOARD? 
       CNZ  SFKYOF    ;NO - SWAP DISPLAY
       JNZ  DSPCHR      ;AND USE NORMAL ROUTINE 
       JMP  FDESC1    ;YES - DISPLAY CHARACTER
;                       AND KILL "CURADV" FLAG
 
;********************** 
; SFTRST - SOFT RESET * 
;********************** 
SFTRST EQU  $ 
       CALL IOBSYC    ;WAIT UNTIL CTU'S FREE
       DI             ;DISABLE INTERRUPTS 
       MVI  A,1       ;SET RESET TIMER FOR ONE
       STA  RSTTMR      ;SECOND ONLY
       JMP  GO1       ;DO SOFT RESET
 
;*****************
; SO - SHIFT OUT *
;*****************
SHFTOT EQU $
       CALL CHKSFK    ;DEFINE SOFT KEY MODE?
       RNZ            ;YES - DON'T SWITCH CHAR SET
       LDA  CHRSET  ;GET CURRENT ALT CHAR SET 
SHFT1  EQU  $ 
       MOV  B,A       ;PUT NEW CHAR SET IN B-REG
       MVI  A,SWCHAR  ;SET CHARACTER SWITCH IN
       CALL ZKBCTL      ;KEYBOARD FOR POSSIBLE
;                       FOREIGN MODE ENABLE 
       MOV  A,B       ;RECALL NEW CHARACTER SET 
SHFT2  EQU  $         ;ENTRY FOR SELF-TEST
       MVI  B,17Q     ;SET MASK TO SAVE DISPLAY 
;                       ENHANCEMENT BITS
       JMP  DISPC1    ;ADD CODE TO DISPLAY
;**************** 
; SI - SHIFT IN * 
;**************** 
SHFTIN EQU $
       CALL CHKSFK    ;DEFINE SOFT KEY MODE?
       RNZ            ;YES - DON'T SWITCH CHAR SET
       XRA A        ;SET FOR BASE CHARACTER 
       JMP  SHFT1       ;SET CODE 
 
;********************************** 
; STATUS - RETURN TERMINAL STATUS * 
;********************************** 
STATUS EQU  $ 
       LXI  B,SSTAT   ;SET BLOCK TRANSFER FOR 
       JMP  SBLXF0      ;FOR TERMINAL STATUS
;************************************ 
; STATGO - TRANSMIT TERMINAL STATUS * 
;************************************ 
STATGO EQU  $ 
       LXI  B,-1-SSTAT
       CALL CLBLXF    ;CLEAR STATUS PENDING FLAG
       MVI  B,ABCKSL  ;SEND <ESC>-<\> 
       CALL ESCOUT
       LXI  H,XPUTDC  ;SET OUTPUT ROUTINE ADDRESS 
       CALL STAPAR    ;OUTPUT STATUS BITS 
       LXI  H,ERRFLG  ;CLEAR DATA COMM ERROR FLAG 
       MOV  A,M 
       ANI  377Q-DCMERR 
       MOV  M,A 
       JMP  SDTERM    ;SEND TERMINATOR AND RETURN 
 
;****************************** 
; STAPAR - OUTPUT STATUS BITS * 
;****************************** 
; 
;  ENTRY:  H,L = ADDRESS OF OUTPUT ROUTINE
; 
;  EXIT :  CNTFAD = ADDRESS OF OUTPUT ROUTINE 
;          ALL REGISTERS DESTROYED
; 
STAPAR EQU  $ 
       SHLD CNTFAD    ;SET OUTPUT ROUTINE VECTOR
; 
;  OUTPUT SIZE OF RAM 
; 
       LDA  DSPBGN+1  ;COMPUTE NUMBER OF 256-BYTE 
       CMA              ;RAM BLOCKS IN DISPLAY
       INR  A           ;AREA 
       CALL PAROT2    ;TRANSMIT MEMORY SIZE IN K'S
; 
;  OUTPUT KEYBOARD INTERFACE STRAP SETTINGS 
; 
       LDA  KBJMPR    ;TRANSMIT STRAPS A-D
       MOV  L,A       ;SAVE JUMPER VALUES 
       CALL PAROUT
       MOV  A,L       ;RECALL JUMPER VALUES 
       CALL PAROT4    ;TRANSMIT STRAPS E-H
; 
;  OUTPUT LATCHING KEYS STATUS
; 
       LDA  MDFLG2    ;GET TERMINAL MODE FLAGS 2
       ANI  CAPSLK+BLKMDE+AUTOLF  ;EXTRACT BITS 
       ORI  10Q       ;ADD BIT 3 TO INDICATE 2645 
       CALL PAROUT    ;SEND LATCHING KEY STATUS 
; 
;  OUTPUT TERMINAL (2640) TRANSFER PENDING FLAGS
; 
       LHLD MFLGS2    ;GET TERMINAL MODE FLAGS
       MOV  A,H       ;MASK FOR SECONDARY STATUS
       ANI  SSTAT2/256  ;PENDING BIT
       RRC            ;SHIFT BIT INTO STATUS
       RRC              ;RESPONSE POSITION
       RRC
       MOV  B,A 
       MOV  A,H       ;GET OTHER DISPLAY RELATED
       ANI  (SENTER+SFCTKY+SCRSEN)/256;XFR BITS 
       ORA  B         ;ADD IN SECONDARY STATUS
       CALL PAROT4    ;SEND TRANSFER PENDING BITS 
 
; 
;  OUTPUT ERROR CONDITION FLAGS 
; 
       MVI  B,0       ;SET FOR NO I/O ERROR 
       LDA  IOCERR    ;GET I/O ERROR FLAG 
       CPI  F         ;I/O ERROR OCCURRED?
       JNZ  STA010    ;NO - GET OTHER ERROR FLAGS 
       MVI  B,IOERRB  ;YES - SET I/O ERROR BIT
STA010 EQU  $ 
       NOP            ;INSTR. DELETED TO FIX BUG
       LDA  ERRFLG    ;GET THE ERROR FLAGS
       ORA B        ;MERGE WITH EXISTING BITS 
       CALL PAROUT    ;TRANSMIT ERROR STATUS
; 
;  OUTPUT DEVICE TRANSFER PENDING FLAGS 
; 
       MOV  A,H       ;GET TERMINAL MODE 1 FLAGS
       RLC            ;PUT I/O DONE FLAG IN C-FLAG
       MOV  A,L       ;GET TERMNAL MODE 2 FLAGS 
       RAL              ;ADD IN I/O DONE FLAG 
       MOV  B,A       ;SAVE TEMPORARY RESULTS 
       MOV  A,H       ;RECALL TERMINAL MODE 1 FLAG
       RRC            ;PUT DEVICE STATUS INTO 
       RRC              ;C-FLAG 
       RRC
       RRC
       MOV  A,B         ;RECALL ACCUMULATED BITS
       RAL              ;ADD IN DEVICE STATUS 
       JMP  PAROUT    ;SEND DEVICE XFR PENDING BIT
 
;******************************************** 
; STCHR1 - SET INITIAL DISPLAY CHARACTER IN * 
;   NEW DISPLAY BLOCK                       * 
;******************************************** 
; 
;  ENTRY:  H,L = ADDRESS OF FIRST DISPLAY 
;            IN BLOCK 
; 
;  EXIT :  A = 0
;          H,L UNCHANGED
; 
STCHR1 EQU  $ 
       LDA  MDFLG1    ;GET SOFT MODE FLAGS
       ANI  FORGN     ;FOREIGN MODE ENABLED?
       MVI  A,EOL       ;(SET TO STORE EOL) 
       JZ   STC010    ;NO - STORE EOL ONLY
       DCX  H         ;YES - STORE EOL AND DISPLAY
       MOV  M,A         ;CONTROL BYTE TO CAUSE
       LDA  FRSALT      ;FOREIGN CHARACTER SET TO 
       ORI  200Q        ;BE DISPLAYED 
       INX  H 
STC010 EQU  $ 
       MOV  M,A       ;STORE FIRST DISPLAY CHAR 
       XRA  A         ;CLEAR A-REGISTER 
       RET            ;RETURN 
 
;************************************ 
; TEST - PERFORM TERMINAL SELF TEST * 
;************************************ 
TEST   EQU  $ 
       CALL CKEDIT    ;EDIT MODE ENABLED? 
       RNZ            ;YES - DON'T DO SELF-TEST 
       MVI  A,CKIOKY
       CALL ZKBCTL    ;I/O CONTROL KEY DOWN ALSO? 
       LXI  H,TSTCTU    ;(SET FOR CTU SELF-TEST)
       JNZ  IORMGO    ;YES - DO CTU SELF-TEST 
;                     NO - DO TERMINAL SELF-TEST
; 
;  PERFORM TERMINAL SELF-TEST 
; 
TRMTST EQU  $ 
       LDA  KBJMP2    ;GET KEYBOARD JUMPERS 2 
       ANI  NOTEST    ;SELF-TEST INHIBITED
       LXI  H,NOTSMS    ;(SET MESSAGE ADDRESS)
       JNZ  DSPMS1    ;YES - DISPLAY MSG AND EXIT 
       LDA  DFLGS     ;GET DATA TRANSFER FLAGS
       ANI  XBF2DS    ;DATA FROM I/O BUFFER 
       JNZ  DSPMS1    ;YES - DON'T DO SELF-TEST 
       CALL IOBSYC    ;WAIT UNTIL CTU'S IDLE
       DI             ;DISABLE INTERRUPTS 
       MVI  A,STRTST  ;SET KEYBOARD FOR SELF-TEST 
       CALL ZKBCTL      ;START-UP 
 
;*********************
; ROM TEST           *
;                    *
; CALCULATE CHECKSUM *
; FOR EACH 2K ROM    *
;*********************
       LXI  H,-NUM2K  ;SET FOR START ADDRESS = 0
; 
TST010 EQU  $ 
       LXI  D,NUM2K   ;INCREMENT START ADDR BY 2K 
       DAD  D 
; 
; IS CURRENT ADDRESS A ROM? 
; 
       MOV  A,H       ;PUT MSB INTO A-REGISTER
       CPI  134000Q/256-1  ;ADDRESS > 48K?
       JNC  TST050    ;YES - GO TO NEXT TEST
       CPI  100000Q/256  ;IN I/O SPACE? 
       JZ   TST010    ;YES - GO TO NEXT ROM BLOCK 
       CPI  104000Q/256 
       JZ   TST010    ;YES - GO TO NEXT ROM BLOCK 
       CALL IORMG1    ;DOES THE ROM EXIST?
       JZ   TST020    ;YES - CHECK THE ROM
       XRA  A         ;NO - CHECK FOR NO ROM
       ORA  L         ;ROM INSTALLED? 
       JZ   TST010    ;NO - GO TO NEXT ROM
       MOV  A,H       ;YES - REPORT POSSIBLE
       JMP  TST030      ;MISPLACED ROM
;*********************
; CALCULATE CHECKSUM *
;*********************
TST020 EQU  $ 
       DCX  H         ;RESTORE START ADDRESS
       MVI  D,NUM2K/256  ;SET TO SUM 2K SPACE 
       CALL CHKSUM    ;CALCULATE CHECKSUM 
       INR  A         ;= 377 ?
;******************************************** 
       JZ   TST010    ;YES - DO NEXT ROM BLOCK
;******************************************** 
       XRA  A         ;NO - REPORT BAD ROM
TST030 EQU  $ 
       LXI  D,ROMERR  ;SET ROM ERROR MESSAGE ADDR 
       MOV  C,A       ;SAVE EXPECTED VALUE
       MOV  B,M       ;GET VALUE FOUND
       MOV  A,H       ;CONVERT ROM ADDRESS TO 
       RRC              ;ROM NUMBER (0,2,4,...) 
       RRC
       MOV  L,A       ;SET AS ERROR ADDRESS 
       MVI  H,0 
       MOV  A,C       ;RECALL EXPECTED VALUE
       JMP  TST600    ;REPORT ERROR 
 
;****************************** 
; RAM TEST                    * 
;                             * 
; CALCULATE CHECKSUM ON       * 
; EACH 4K BLOCK.              * 
; TEST EACH 256 BYTE SECTION  * 
; RECHECK CHECKSUM.           * 
;****************************** 
; 
;  E = 0
; 
TST050 EQU  $ 
       MVI  A,CRTOFF  ;TURN OFF VIDEO 
       STA  IOCRRW
       LXI  H,IOBUF   ;SET H,L TO I/O BUFFER #1 
       CALL CLRAL1    ;CLEAR THE I/O BUFFER 
       MOV  B,H       ;SET B,C = IOBUF2 
       MOV  C,L         ;(H,L = IOBUF2) 
       MVI  D,10000Q/256  ;SET D,E FOR 4K INCREMEN
       MOV  H,E       ;SET H TO 0 TO INDICATE STAR
       STAX B         ;SET CHECKSUM FOR LAST
;                       BLOCK TO ZERO 
;******************************************** 
; CALCULATE CHECKSUM FOR EACH RAM BLOCK AND * 
;   STORE CHECKSUM IN "IOBUF2"              * 
;******************************************** 
TST060 EQU  $ 
       CALL NXSBLK    ;GET NEXT BLOCK ADDRESS 
       CALL CHKSUM    ;COMPUTE CHECKSUM 
       STAX B         ;STORE CHECKSUM VALUE 
       JNZ  TST060    ;CONTINUE IF NOT LAST BLOCK 
 
; 
; CHECK EACH 256 BYTE RAM SECTION 
; 
       MOV  E,L       ;SET E TO ZERO TO INDICATE
;                       TESTING OF FAST RAM AREA
       MVI  H,FSTRAM/256  ;START OF FAST RAM (L=0)
TST090 EQU  $ 
; 
; TEST THE RAM IN THE FOLLOWING STEPS 
; 
; 1. SAVE THE SECTION'S CONTENTS
       LXI  B,IOBUF   ;I/O BUFFER 
TST100 EQU  $ 
       MOV  A,M       ;BYTE TO BE SAVED 
       STAX B 
       INR  C         ;SET TO NEXT SAVE ADDRESS 
; 2  SET EACH BYTE = MSB .XOR. LSB OF ADDR
       MOV  A,L 
       XRA  H 
       MOV  M,A 
       INR  L         ;ALL BYTES DONE?
       JNZ  TST100    ;NO - DO THE NEXT BYTE
; 3. WAIT 
;      APPROX 2 MS, 5000 CLOCK CYCLES 
TST115 EQU  $ 
       MOV  A,A       ;NO OP
       INR  L 
       JNZ  TST115
; 4. CHECK EACH MEMORY LOCATION 
;    COMPLEMENT IT
       MOV  D,L       ;D = 0, COUNTER 
       DCR  L         ;L= 377B
TST120 EQU  $ 
       MOV  A,L       ;CALCULATE EXPECTED VALUE 
       XRA  H 
       CMP  M         ;SAME AS BEFORE?
       JNZ  TST510    ;NO - REPORT ERROR WITH 
;                       EXPECTED/FOUND BYTES
       CMA
       MOV  M,A       ;SET COMPLEMENT 
       DCR  L 
       DCR  D         ;DONE WITH THIS SECTION?
       JNZ  TST120    ;NO 
; 5. WAIT AGAIN 
;      APPROX 2 MS, 5000 CLOCK CYCLES 
TST125 EQU  $ 
       MOV  A,A       ;NO OP
       DCR  L 
       JNZ  TST125    ;LOOP FOR 256 TIMES 
 
; 6. CHECK VALUES. RESTORE ORIGINAL VALUE 
;  B,C = IOBUF
; 
TST130 EQU  $ 
       MOV  A,L 
       XRA  H 
       CMA
       CMP  M         ;SAME AS BEFORE?
       JNZ  TST510    ;NO - REPORT ERROR WITH 
;                       EXPECTED/FOUND BYTES
       LDAX B 
       MOV  M,A       ;RESTORE
       INX  B 
       INR  L         ;BLOCK COMPLETED? 
       JNZ  TST130    ;NO - DO NEXT BYTE
;***************************
; DONE WITH THIS SECTION.  *
; DO NEXT?                 *
;***************************
       INR  E         ;IF E = 0, WE JUST TESTED 
       DCR  E           ;FAST RAM 
       JNZ  TST140
       MOV  H,E       ;H=0, INDICATE START
       MVI  E,200     ;BIT 7 = 1 MEANS 256
;                       BYTE INCREMENTS 
; 
TST140 EQU  $ 
       CALL NXSBLK    ;GET NEXT BLOCK ADDRESS 
       ORA  A         ;LAST BLOCK DONE? 
       JNZ  TST090    ;NO, TEST NEXT
 
;***************************
; CHECK ORIGINAL CHECKSUMS *
;***************************
; 
;  B,C = IOBUF2 
; 
       MOV  E,C       ;SET E TO ZERO
       MVI  H,IOBUF/256  ;SET H TO I/O BUFFER #1
       CALL CLRAL1    ;CLEAR THE I/O BUFFER 
;  (H,L) = IOBUF2, TOP HALF OF I/O BUFFER 
       MVI  D,10000Q/256  ;SET D,E FOR 4K INCREMEN
       MOV  A,M       ;GET CHECKSUM FOR TOP BLOCK 
       MOV  M,E       ;SET STORE BYTE TO ZERO 
       PUSH PSW       ;SAVE TOP BLOCK CHECKSUM
       MOV  H,E       ;SET H TO 0 TO INDICATE STAR
;***********************************************
; RE-CALCULATE CHECKSUM FOR EACH RAM BLOCK AND *
;   COMPARE TO INITIAL STORED VALUE            *
;***********************************************
TST150 EQU  $ 
       CALL NXSBLK    ;GET NEXT BLOCK ADDRESS 
       CALL CHKSUM    ;COMPUTE CHECKSUM FOR BLOCK 
       MOV  L,A       ;SAVE COMPUTED VALUE IN L-RE
       JZ   TST160    ;LAST BLOCK - CHECK 1ST VALU
       LDAX B         ;RECALL ORIGINAL CHECKSUM 
       SUB  L         ;DO CHECKSUMS MATCH?
       MOV  L,A         ;(SET L TO ZERO IF TRUE)
       JZ   TST150    ;YES - GO TO NEXT BLOCK 
       JMP  TST500    ;NO - REPORT ERROR
; 
TST160 EQU  $ 
       POP  PSW       ;RECALL 1ST STORED CHECKSUM 
       SUB  L         ;DO CHECKSUMS MATCH?
       JNZ  TST500    ;NO - REPORT ERROR
 
;***********************
; DISPLAY TEST PATTERN *
;***********************
       CALL ZBELL     ;SOUND THE BELL 
       MVI  A,300Q    ;SET INITIAL CHARACTER SET
TST200 EQU  $ 
       SUI  20Q       ;SET TO NEXT CHARACTER SET
       PUSH PSW       ;SAVE CURRENT ENHANCEMENT 
       XRA  A         ;SET CHARACTER TO NULL
       STA  TCHAR 
TST220 EQU  $ 
       CALL CRRET   ;DO CR
       CALL CONDLF  ;DO LF IF WRAPAROUND DISABLED 
       POP  PSW       ;RECALL CURRENT ENHANCEMENT 
       PUSH PSW         ;AND SAVE IT AGAIN
       CALL SHFT2     ;PUT ENHANCEMENT ON DISPLAY 
TST240 EQU  $ 
       LDA  TCHAR     ;GET CURRENT ENHANCEMENT COD
       STA  DCHAR   ;STORE CHAR FOR DISPLAY 
       ANI 7        ;EVERY 8 CHARS INSERT 2 BLNKS 
       CPI  4         ;TIME TO ADD TWO BLANKS?
       CZ   CURAD2    ;YES - ADVANCE CURSOR TWICE 
       CALL DSPCHR    ;DISPLAY THE CHARACTER
       LXI  H,TCHAR 
       INR  M         ;INCREMENT DISPLAY CHARACTER
       MOV  A,M       ;GET NEW CHARACTER
       CPI 64 
       JZ  TST220   ;IF 64 THEN NEW LINE
       ORA A        ;ALL CHARACTERS DONE? 
       JP  TST240   ;NO - CONTINUE
       CALL CRLF      ;YES - DOUBLE SPACE BETWEEN 
       POP  PSW         ;CHARACTER SETS 
       CPI  200Q      ;ALL CHARACTER SETS DONE? 
       JNZ  TST200    ;NO - CONTINUE DISPLAY
 
;****************************** 
; DISPLAY ENHANCEMENT PATTERN * 
;****************************** 
       PUSH PSW       ;SAVE ENHANCEMENT CODE
       CALL CONDLF    ;DO LF IF WRAPAROUND DISABLE
TST420 EQU  $ 
       POP  PSW       ;RECALL CURRENT ENHANCEMENT 
       PUSH PSW       ;SAVE ENHANCEMENT AGAIN 
       SUI  100Q      ;COMPUTE ASCII DISPLAY CODE 
       CALL DSPTST    ;DISPLAY THE CHARACTER
       POP  PSW       ;RECALL CURRENT ENHANCEMENT 
       INR  A         ;INCREMENT ENHANCEMENT
       CPI  220Q      ;LAST ENHANCEMENT DONE? 
       JZ   TST440    ;YES - DISPLAY STATUS 
       PUSH PSW       ;NO - SAVE ENHANCEMENT CODE 
       CALL DISPC0    ;ADD ENHANCEMENT TO DISPLAY 
       JMP  TST420    ;DISPLAY ASCII DISPLAY CODE 
; 
TST440 EQU  $ 
       XRA  A 
       CALL DISPC0    ;RETURN TO NORMAL VIDEO 
       CALL CURAD2    ;ADVANCE CURSOR TWICE 
;************************** 
; DISPLAY TERMINAL STATUS * 
;************************** 
       LXI  H,ERRFLG  ;SET ERROR FLAG TO
       MOV  A,M         ;SELF-TEST SUCCESSFUL 
       ORI  TESTOK
       MOV  M,A 
       LXI  H,DSPTST  ;SET H,L TO OUTPUT ROUTINE
       CALL STAPAR    ;DISPLAY TERMINAL STATUS
       CALL CURADV    ;PUT SPACE BETWEEN STATUS 
       CALL STA2G2
       CALL CRLF
       CALL CRLF
;********************** 
; TERMINATE SELF-TEST * 
;********************** 
       MVI  A,ENDTST  ;RESTORE KEYBOARD LED'S 
       CALL ZKBCTL
       EI             ;RE-ENABLE INTERRUPTS 
       JMP  CRADV1    ;RESET CURSOR ADVANCE FLAG
 
TST500 EQU  $         ;REPORT RAM ERROR 
       XRA  A         ;SET Z TRUE FOR ADDRESS ONLY
       MOV  L,A       ;FORCE L-REGISTER TO BE ZERO
TST510 EQU  $ 
       MOV  B,M       ;PUT VALUE FOUND INTO B-REG 
       LXI  D,RAMERR  ;SET D,E TO ERROR MESSAGE 
;**************************** 
; REPORT ROM/RAM TEST ERROR * 
;**************************** 
; 
;  ENTRY:  D,E = ADDRESS AT WHICH ERROR OCCURRED
;          H,L = ERROR MESSAGE ADDRESS
;          Z - DISPLAY ERROR ADDRESS ONLY 
;          NZ - DISPLAY PARAMETERS ALSO 
;            A = EXPECTED VALUE 
;            (H,L) = VALUE FOUND
; 
TST600 EQU  $ 
       XCHG           ;(H,L) = MESSAGE ADDRESS
;                     (D,E) = ERROR ADDRESS 
       PUSH H         ;SAVE THE MESSAGE ADDRESS 
       LXI  H,ERREOP  ;SET EOP FOR SHORT MESSAGE
       SHLD MSGPT4
       JZ   TST610    ;Z - SHOW ADDRESS ONLY
       LXI  H,IOBUF2  ;SET BUFFER ADDRESS 
       SHLD MSGPT4
       PUSH B         ;SAVE VALUE FOUND 
       CALL BINOCT    ;CONVERT BINARY TO OCTAL
       POP  PSW       ;RECALL VALUE FOUND 
       CALL BINOCT    ;CONVERT BINARY TO OCTAL
       MVI  M,EOP     ;TERMINATE WITH "EOP" 
TST610 EQU  $ 
       LXI  H,IOBUF2+16  ;CONVERT FAILURE ADDRESS 
       SHLD MSGPT3
       CALL BN2DEC    ;CONVERT TO DECIMAL ASCII 
       LXI  H,RXMERR  ;SET REST OF LITERAL
       SHLD MSGPT2
       LDA  DFLGS     ;GET DATA TRANSFER FLAGS
       ANI  SDACOM    ;TEST FROM DATA COMM? 
       POP  H           ;(RECALL MESSAGE ADDRESS) 
       JZ   HANGU0    ;NO - SHOW MESSAGE AND HANG 
       RST  0         ;YES - RESET THE TERMINAL 
 
;****************** 
; MESSAGE STORAGE * 
;****************** 
BUFMSG EQU  $ 
       DB   'BUFFER OVERFLOW',EOP 
; 
ROMERR EQU  $ 
       DB   'ROM',0 
; 
RAMERR EQU  $ 
       DB   'RAM',0 
; 
INERMS EQU  $ 
       DB   'I/O' 
; 
RXMERR EQU  $ 
       DB   ' ERROR ',0 
; 
LDRMSG EQU  $ 
       DB   'LOADER'
ERREOP EQU  $ 
       DB   EOP 
; 
NOTSMS EQU  $ 
       DB   'NO TEST',EOP 
; 
NODRVR EQU  $ 
       DB   'NO DEVICE DRIVER',EOP
; 
TRMRDY EQU  $ 
       DB   'TERMINAL READY',EOP
 
;************************************ 
; TOPUPD - UPDATE TOP LINE POINTERS * 
;************************************ 
TOPUPD EQU $
       INX  H         ;PUT THE MSB INTO THE 
       MOV  B,M         ;B-REGISTER 
       MOV  C,A       ;SAVE TOP LINE'S LSB IN C-RE
       LXI  H,TLINO   ;UPDATE TOP LINE NUMBER 
       MOV A,D
       ORA A        ;IS TLINO TO BE RESET?
       JZ  TOP100   ;YES
       ADD M        ;NO - INCREMENT OR DECREMENT
TOP100 EQU $
       MOV M,A      ;STORE UPDATED TLINO
TOPUP1 EQU  $ 
       MOV  H,B       ;SET NEW TOP LINE POINTER 
       MOV  L,C 
       SHLD TOPLIN
       LDA  CMFLGS    ;GET COMMON FLAGS 
       ANI  DEFSKY    ;SOFT KEY DEFINE MODE?
       RNZ            ;YES - DON'T CHANGE SCREEN
       LXI  H,DISPST+1  ;GET DISPLAY START ADDRESS
       DCX  B         ;SET TO FIRST CHAR ADDRESS
;************************************** 
; DISLNK - STORE LINK IN DISPLAY AREA * 
;************************************** 
; 
;  ENTRY:  B,C = LINK TO BE STORED
;          H,L = STORE ADDRESS FOR MSB PART 
; 
;  EXIT :  H,L = LSB OF STORE ADDRESS 
;          A DESTROYED
;          INTERRUPTS ENABLED 
; 
DISLNK EQU  $ 
       MVI  A,DMAOFF  ;SET TO TURN OFF THE DMA
       DI             ;DISABLE INTERRUPTS 
       STA  IOCRRW    ;TURN OFF DMA 
       MOV  M,B       ;STORE LINK'S MSB 
       DCX  H 
       MOV  M,C       ;STORE LINK'S MSB 
DISLN1 EQU  $         ;SET CURSOR ROW POSITION
       LDA  CURROW    ;TURN DMA BACK ON WITH
DISLN2 EQU  $ 
       STA  IOCRRW      ;CURRENT CURSOR ROW ADDRES
DISLN3 EQU  $ 
       EI             ;RE-ENABLE INTERRUPTS 
DISLN4 EQU  $         ;RE-ENABLE RESET KEY
       MVI  A,RSTON 
       STA  IOKBCO
       RET            ;RETURN 
 
;*******************************
; TYPSET - SET TYPE DEFINITION *
;*******************************
TYPSET EQU  $ 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       RNZ            ;YES - DO SET TYPE
       LDA  DCHAR     ;NO - COMPUTE TYPE DEFINITIO
       ADI  ALPHA-ZERO-6  ;CHARACTER
       JMP  DISPC1    ;ADD CHARACTER TO DISPLAY 
;************************************ 
; SFKCHK - SOFT KEY ATTRIBUTE CHECK * 
;************************************ 
SFKCHK EQU  $ 
       ANI  377Q-40Q  ;FORCE INPUT TO UPPER CASE
       LHLD CURADR    ;RECALL CHARACTER ADDRESS 
       MOV  M,A       ;STORE UPPER CASE VALUE 
       CPI  N         ;NORMAL ATTRIBUTE SET?
       RZ             ;YES - RETURN SUCCESSFUL
       CPI  L         ;LOCAL ATTRIBUTE SET? 
       RZ             ;YES - RETURN SUCCESSFUL
       CPI  T         ;TRANSMIT ONLY SET? 
       RZ             ;YES - RETURN SUCCESSFUL
       MOV  M,B       ;NO - RESTORE ORIGINAL
       RET              ;ATTRIBUTE AND RETURN NZ
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  XMS2DS - TRANSFER MESSAGE TO NORMAL DISPLAY
; 
;      ENTRY:  H,L = POINTER TO MESSAGE 
; 
;      EXIT :  A-L DESTROYED
;              Z - TERMINATED BY A NULL BYTE
;              NZ - TERMINATED BY AN EOP
; 
XMD000 EQU  $ 
       CALL DSPTST    ;DISPLAY ASCII CHARACTER AND
;                       ADVANCE CURSOR
XMD010 EQU  $ 
       POP  H         ;RESTORE H AND L
       INX  H         ;MOVE TO NEXT BYTE
;                     PROCESS THE NEXT BYTE 
XMS2DS EQU  $ 
       MOV  A,M       ;SET THE SOURCE BYTE
       ORA  A         ;IS IT A NULL BYTE? 
       RZ             ;YES - RETURN (Z - TRUE)
       CPI  EOP       ;IS IT END OF PAGE FLAG?
       JZ   XMD030    ;YES - EXIT 
       PUSH H         ;NO - SAVE H,L
       CPI  EOL       ;IS IT AN END OF LINE?
       JZ   XMD020    ;YES - START A NEW LINE 
       ORA  A         ;IS CHARACTER ASCII?
       JP   XMD000    ;YES - DISPLAY IT 
       MVI  B,0       ;NO - FORCE ENHANCEMENT CODE
       CALL DISPC2      ;TO BE STORED AS IS 
       JMP  XMD010    ;GO TO NEXT BYTE
; 
;  EOL CODE - TERMINATE THE LINE
; 
XMD020 EQU  $ 
       CALL CRLF      ;PERFORM RETURN AND LINE FEE
       JMP  XMD010    ;DO NEXT BYTE 
; 
;  EOP CODE - TERMINATE LINE AND EXIT 
; 
XMD030 EQU  $ 
       CALL CRLF      ;PUT CURSOR IN NEXT LINE
       ORA  H         ;SET Z FALSE
       RET            ;RETURN TEMINATED BY EOP
 
;******************************************** 
; CARRET - PERFORM DISPLAY FUNCTIONS RETURN * 
;******************************************** 
CARRET EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       JZ   CAR010    ;NO - DO NORMAL PROCESSING
;************************** 
;  R O M   B R E A K   2  * 
;************************** 
       JMP  ZBRK2C    ;GO TO NEXT ROM BLOCK 
       ORG  ZBRK1+4000Q 
ZBRK2  EQU  $ 
       DB   VERSN     ;ROM PRESENT FLAGS
       DB   ZBRK2/256 
ZBRK2C EQU  $ 
;************************************************ 
       CALL DCXB2D    ;DATA FROM KEYBOARD?
       JZ   DSPCHR    ;YES - DISPLAY RETURN CODE
       CALL SFKYOF    ;NO - RESTORE NORMAL DISPLAY
CAR010 EQU  $ 
       LXI  H,CRLF    ;SET NORMAL ROUTINE EXIT
       JMP  DSPCH0    ;DISPLAY THE CHARACTER
 
;***********************************************
; CHKLIM - CHECK PARAMETER BOUNDARY CONDITIONS *
;***********************************************
; 
;  ENTRY:  B = CURRENT VALUE
;          C = MAXIMUM ALLOWABLE VALUE
;          D,E = ADDRESS OF PARAMETER TO BE SET 
;          IODATA = PARAMETER VALUE (2 BYTES) 
;          IOPSGN = -1, NEGATIVE ADJUSTMENT 
;                 =  0, ABSOLUTE VALUE
;                 = +1, POSITIVE ADJUSTMENT 
; 
;  EXIT :  NEW VALUE IN WORD ADDRESSED BY D,E 
;          A,C,H,L DESTROYED
; 
;  THIS ROUTINE SET THE NEW VALUE BY EITHER 
;  OR ABSOLUTE ADJUST WITHING THE LIMITS OF 
;  ZERO AND THE MAXIMUM ALLOWABLE AS SPECIFIED
;  THE C-REGISTER ON ENTRY
; 
;  THE LARGEST MAXIMUM VALUE IS 255 
; 
CHKLI0 EQU  $ 
       LDA  IOCSGN    ;SET PARAMETER SIGN TO
       STA  IOPSGN      ;INPUT SIGN 
CHKLIM EQU  $ 
       LDA  IODATA+1  ;GET MSB OF INPUT VALUE 
       ORA  A         ;MAXIMUM EXCEEDED?
       LDA  IOPSGN      ;(GET PARAMETER SIGN) 
       JZ   CHK050    ;NO - CONTINUE EVALUATION 
       ADD  A         ;NEGATIVE ADJUSTMENT? 
       JP   CHK070    ;NO - SET TO MAXIMUM VALUE
; 
;  DEFAULT TO MINIMUM VALUE (0) 
; 
CHK010 EQU $        ;SET TO ZERO
       XRA A
       STAX D         ;STORE NEW VALUE
       RET            ;RETURN 
 
; 
;  PARAMETER < 256, EVALUATE FOR RELATIVE AMOUNT
; 
CHK050 EQU $
       LXI  H,IODATA  ;SET H,L TO GET INPUT VALUE 
       ADD  A         ;RELATIVE POSITIONING?
       MOV A,B      ;(LOAD CURRENT VALUE) 
       JM  CHK160   ;MINUS - SUBTRACT INPUT 
       JNZ CHK150   ;PLUS - ADD INPUT 
       MOV A,M      ;NONE - ABSOLUTE ASSIGNMENT 
; 
;  CHECK UPPER LIMIT + 1
; 
CHK060 EQU  $ 
       STAX D         ;STORE ASSIGNED VALUE 
       CMP  C         ;MAXIMUM EXCEEDED?
       RC             ;NO - RETURN
CHK070 EQU  $         ;YES - USE MAXIMUM VALUE
       MOV  A,C 
;************************ 
; STORE PARAMETER VALUE * 
;************************ 
CHK100 EQU  $ 
       STAX D         ;STORE PARAMETER VALUE
       RET            ;RETURN 
; 
;  POSITIVE ADJUSTMENT - ADD INPUT
; 
CHK150 EQU $
       ADD M        ;OVERFLOW?
       JNC CHK060   ;NO - USE SPECIFIED VALUE 
       JMP CHK070   ;YES - USE MAXIMUM VALUE
; 
;  NEGATIVE ADJUSTMENT - SUBTRACT INPUT 
; 
CHK160 EQU $
       SUB M        ;UNDERFLOW? 
       JC   CHK010    ;YES - USE ZERO 
       STAX D         ;NO - USE COMPUTED VALUE
       RET            ;RETURN 
 
;***********************************************
; CKDSPF - CHECK FOR DISPLAY FUNCTIONS ENABLED *
;***********************************************
CKDSPF EQU  $ 
       LDA  MDFLG1    ;GET SOFT MODE FLAGS
       ANI  DSPFNC    ;MASK FOR DISPLAY FUNCTIONS 
       RET              ;FLAG AND RETURN
;***************************************
; CKEDIT - CHECK FOR EDIT MODE ENABLED *
;***************************************
CKEDIT EQU  $ 
       LDA  MDFLG1    ;GET SOFT MODE FLAGS
       ANI  EDIT      ;MASK FOR EDIT FLAG AND 
       RET              ;RETURN 
;************************************** 
; GTMODE - DETERMINE MODE OF TERMINAL * 
; Z = TRUE IF CHARACTER MODE          * 
; Z = FALSE IF PAGE MODE              * 
;************************************** 
GTMOD1 EQU  $ 
       LDA  IOFLG2    ;GET I/O FLAGS
       ANI  XDS2BF    ;DISPLAY TO BUFFER TRANSFER?
       RNZ            ;YES - RETURN PAGE MODE 
GTMODE EQU  $         ;NO - CHECK REAL PAGE MODE
       LDA  MDFLG2    ;GET TERMINAL MODE FLAGS 2
       ANI  BLKMDE    ;BLOCK MODE ENABLED?
       RZ           ;NO - RETURN (Z=TRUE) 
; 
;  CKLNMD - CHECK LINE MODE 
; 
;      EXIT :  Z = TRUE, LINE MODE
;                = FALSE, PAGE MODE 
;              A,L DESTROYED
; 
CKLNMD EQU $
       LDA  KBJMPR    ;GET THE STRAP SETTINGS 
       ANI  PAGSTR    ;SET Z-FLAG 
       RET            ;RETURN 
 
;*******************************************
; CKPROT - CHECK PROTECT STATUS OF CURRENT *
;   CURSOR LOCATION                        *
;*******************************************
CKPROT EQU  $ 
       LDA  PROFLD    ;GET PROTECT FLAG 
       INR  A         ;SET Z-FLAG (-1 => PROTECTED
       RET            ;RETURN 
;*****************************************
; CKRMTE - CHECK FOR REMOTE MODE ENABLED *
;*****************************************
CKRMTE EQU  $ 
       LDA  CMFLGS    ;GET COMMON FLAGS 
       ANI  REMSET    ;MASK FOR REMOTE FLAG 
       RET            ;RET (NZ => YES; Z => NO) 
 
;*********************************************
; CLBLXF - CLEAR BLOCK TRANSFER PENDING FLAG *
;*********************************************
; 
;  ENTRY:  B = 377B-(FLAG TO CLEAR FROM MFLGS)
;          C = 377B-(FLAG TO CLEAR FROM MFLGS2) 
; 
;  EXIT :  H = BASEH
;          A,B,L DESTROYED
; 
;  CLEARS THE SPECIFIED TRANSFER PENDING FLAG 
;  FROM "MFLGS".  IF NO OTHER TRANSFER IS PENDING,
;  THEN THE KEYBOARD IS UNLOCKED.  OTHERWISE, 
;  THE NEXT TRANSFER PENDING IS SET UP. 
; 
CLBLXF EQU  $ 
       LHLD MFLGS2    ;GET TRANSFER PENDING FLAGS 
       MOV  A,B 
       ANA  H         ;CLEAR FLAG FROM "MFLGS"
       MOV  H,A 
       MOV  A,C 
       ANA  L         ;CLEAR FLAG FROM "MFLGS2" 
       MOV  L,A 
       SHLD MFLGS2    ;STORE NEW FLAG VALUES
       ANI  SBINRY+SDVREC 
       ORA  H         ;ANY MORE TRANSFER PENDING? 
       LXI  B,0         ;(SET FOR NULL FLAGS SET) 
       JNZ  SBLXF0    ;YES - SET UP NEXT BLOCK XFR
       CALL KBEN      ;NO - RE-ENABLE KEYBOARD
; 
;  CLRXON - CLEAR BLOCK TRANSFER TRIGGER
; 
CLRXON EQU  $ 
       MVI  A,CLRTRG  ;CLEAR BLOCK TRANSFER TRIGGE
       CALL DCMCTL    ;PERFORM DATACOM CONTROL
       STC            ;SET C-FLAG TRUE AND
       RET              ;RETURN 
 
;********************************************** 
; CLEARS - CLEAR DISPLAY FROM CURSOR POSITION * 
;********************************************** 
CLEARS EQU  $         ;CLEAR UNPROTECTED FIELDS 
       MVI  A,377Q-SDACOM  ;ONLY BY CLEARING DATA 
       CALL CLRDFL      ;COMM INPUT FLAG
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JNZ  CLS100    ;YES - CLEAR FIELDS ONLY
       CALL CLEARL    ;CLEAR LINE FROM CURSOR 
       RM             ;RETURN IF LINE NOT FOUND 
       LHLD LSTLIN    ;GET CURRENT LINE ADDRESS 
       MOV  A,M       ;GET THE LSB VALUE
       ORA  A         ;NEXT LINE EXIST (LSB # 0)? 
       RZ             ;NO - RETURN
       PUSH H         ;YES - ADD SUCCEEDING LINES 
       MVI  M,0         ;TO FREE BLOCKS LIST
       INX  H         ;SET NEXT LINE POINTER TO 
       MOV  D,M         ;INDICATE NO NEXT LINE
       MVI  M,EOP 
       MOV  E,A       ;SET D,E TO TOP NEXT LINE 
       LHLD FRBLKS    ;GET CURRENT FREE BLOCKS HEA
       XCHG           ;SET PREVIOUS LINE POINTER
       INX  H           ;IN FIRST SUCCEEDING LINE 
       INX  H           ;TO CURRENT FREE BLOCKS 
       INX  H           ;HEAD 
       MOV  M,E 
       INX  H 
       MOV  M,D 
       LHLD LLINE     ;SET FREE BLOCKS HEAD TO
       SHLD FRBLKS      ;CURRENT LAST LINE
       POP  H         ;SET LAST LINE ADDRESS TO 
       SHLD LLINE       ;CURRENT LINE 
;*******************
; MEMORY RELEASED  *
; CLEAR LOCK FLAGS *
;*******************
MLKOF  EQU $
       LDA  MDFLG1
       ANI  MEMLOK    ;MEMORY LOCK ENABLED? 
       RZ             ;NO - RETURN
       JMP  MLO010    ;YES - SET LED ON WO/BLINKIN
 
;***************************************
; FORMAT MODE CLEAR SCREEN FROM CURSOR *
;***************************************
CLS100 EQU  $ 
       CP   RCADR4    ;LOCATE CHAR IF FORMAT MODE 
       RM             ;RETURN IF NOT FOUND OR IN
;                       SOFT KEY DEFINE MODE
       JNZ  CLS110    ;PAST EOL - START AT NEXT FL
       INR  B         ;CURSOR IN UNPROTECTED FIELD
       JNZ  CLS130    ;YES - CLEAR REST OF FIELD
;******************************** 
; CURSOR IN PROTECTED FIELD     * 
; TAB TO NEXT UNPROTECTED FIELD * 
;******************************** 
CLS110 EQU $
       CALL FLDSR   ;SEARCH TO NEXT FIELD 
       RZ           ;NO MORE FIELDS - RETURN
       LDAX D       ;GET END PROTECT CHARACTER
CLS120 EQU  $ 
       STA  LSTFMT    ;SET LAST FORMAT CODE 
       DCX  D         ;SKIP OVER "ENDPR" CHAR 
;************************** 
; CLEAR UNPROTECTED FIELD * 
;************************** 
CLS130 EQU $
       CALL CLER01    ;CLEAR FIELD
       CPI EOP      ;TERMINATION AT END OF PAGE?
       RZ           ;YES - RETURN 
;************************************ 
; SEARCH FOR NEXT UNPROTECTED FIELD * 
;************************************ 
       DCX  D         ;ADJUST ADDRESS TO NEXT CHAR
CLS200 EQU  $ 
       INX  D         ;ADJUST ADDRESS TO PREV CHAR
CLS210 EQU  $ 
       CALL NXTCHR    ;GET NEXT CHARACTER 
       JNZ  CLS200    ;SKIP OVER EOL LINK 
       CPI  ENDPR     ;NEW FIELD? 
       JZ   CLS120    ;YES - CLEAR IT 
       CPI  EOP       ;END OF DISPLAY?
       RZ             ;YES - RETURN 
       CPI  STPFLG    ;NON-DISPLAYING TERMINATOR? 
       CZ   CHRDL2    ;YES - DELETE IT
       JMP  CLS210    ;CONTINUE SEARCH
 
;************************** 
; CLRALL - CLEAR ALL TABS * 
;************************** 
; 
;  ENTRY:  H = BASEH
; 
CLRALL EQU  $ 
       MVI  L,HTBTBL-BASE  ;SET ADDRESS AND NUMBER
       MVI  E,HTBLEN    ;OF BYTES TO BE CLEARED 
;***************************************
; CLRAL1 - SET A REGION OF RAM TO ZERO *
;***************************************
; 
;  ENTRY:  E = NUMBER OF BYTES IN REGION
;          H,L = LOW ADDRESS OF REGION
; 
;  EXIT :  A,E = 0
;          H,L = H,L(ENTRY) + E 
; 
CLRAL1 EQU  $ 
       XRA  A         ;SET A TO ZERO
CLA010 EQU  $ 
       MOV  M,A       ;SET BYTE TO ZERO 
       INX  H         ;ADVANCE TO NEXT BYTE 
       DCR  E         ;ALL BYTES DONE?
       JNZ  CLA010    ;NO - DO NEXT BYTE
       RET            ;YES - RETURN 
 
;**************************************** 
; CURPHD - HOME DOWN TO FIRST COLUMN OF * 
; FIRST LINE BEYOND END OF MEMORY       * 
;**************************************** 
CURPHD EQU  $ 
       CALL CHKSFK    ;DEFINE SOFT KEY MODE?
       RNZ            ;YES - IGNORE HOME DOWN 
       CALL CURPRT    ;NO - RETURN TO LEFT MARGIN 
;************************** 
; MOVE CURSOR TO NEXT ROW * 
;************************** 
HDC100 EQU  $ 
       LDA  LSTROW
       CPI  MAXROW    ;IS LAST ROW DONE AT BOTTOM?
       CZ   ROLLUP    ;YES - ROLL UP THE DISPLAY
       LHLD LSTLIN    ;GET CURRENT ROW ADDRESS
       MOV  A,M       ;GET LSB OF NEXT LINE POINTE
       ORA  A         ;IS THERE A NEXT ROW? 
       JZ   HDC200    ;NO - TERMINATE HOME DOWN 
       MOV  E,A       ;YES - SET E TO NEXT LINE 
       INR  E           ;POINTER OF NEXT LINE 
       CALL ROLUP2    ;SET "LSTLIN" AND "CURADR"
       LXI  H,LSTROW    ;TO NEXT LINE 
       INR  M         ;INCREMENT LAST ROW DONE
       JMP HDC100 
;****************** 
; LAST LINE FOUND * 
; SET ROW 
;****************** 
HDC200 EQU  $ 
       CALL NXTCH0    ;GET 1ST CHAR OF LAST ROW 
       CPI  EOL       ;LAST ROW EMPTY?
       LDA  LSTROW      ;(GET LAST ROW POSITION)
       JZ   HDC210    ;YES - SET CURRENT ROW = LAS
       INR  A         ;NO - SET TO NEXT ROW 
HDC210 EQU  $ 
       STA  CURROW    ;SET CURRENT ROW NUMBER 
       RET            ;RETURN 
 
;*******************************
; CURPOS - CURSOR POSITIONING  *
;          INITIAL ENTRY POINT *
;*******************************
CURPOS EQU $
       LDA  CURCOL    ;SET NEW COLUMN DEFAULT TO
       STA  NEWCOL      ;CURRENT COLUMN POSITION
       MVI  A,377Q-NWRWST 
       CALL CLRMF2    ;CLEAR NEW ROW SET FLAG 
       MVI  L,SCRNRW-BASE  ;PRESET RELATIVE ROW 
       MVI  M,-1        ;PARAMETER TO -1
       LXI  H,CRPTAB  ;SET RANGE TABLE FOR CURSOR 
       JMP  ESCAPA      ;POSITIONING
 
;*********************************
; NEW COLUMN POSITION IS DEFINED *
;*********************************
CURPO1 EQU  $ 
       MVI  C,MAXCOL  ;SET MAXIMUM VALUE AND
       LXI  D,NEWCOL    ;PARAMETER TO BE SET
       MVI  L,CURCOL-BASE    ;"CHKLIM"
       MOV B,M
       JMP CRP025   ;EVALUATE THE PARAMETER 
;***********************
; SCREEN ROW SPECIFIED *
;***********************
CURPO2 EQU  $ 
       MVI  C,MAXROW  ;SET MAXIMUM VALUE AND
       LXI  D,SCRNRW    ;PARAMETER TO BE SET
       MVI  L,CURROW-BASE    ;"CHKLIM"
       MOV B,M
       JMP CRP025   ;EVALUATE THE PARAMETER 
;****************************** 
; NEW ROW POSITION IS DEFINED * 
;****************************** 
CURPO3 EQU  $ 
       LDA  MLKROW    ;GET MEMORY LOCK ROW
       ORA  A         ;MEMORY LOCK ENABLED? 
       JNZ  CRP050    ;YES - IGNORE PARAMETER 
       MVI  A,NWRWST  ;NO - SET NEW ROW SET 
       CALL SETMF2      ;FLAG 
       MVI  C,255     ;SET MAXIMUM VALUE AND
       LXI  D,NEWROW    ;PARAMETER TO BE SET
       LDA  CURROW    ;COMPUTE CURRENT ABSOLUTE 
       MVI  L,TLINO     ;ROW ADDRESS
       ADD  M 
       MOV  B,A       ;PUT IT INTO B-REGISTER 
CRP025 EQU  $ 
       CALL CHKLI0    ;EVALUATE INPUT PARAMETER 
CRP050 EQU  $ 
       LDA  CHAR      ;RECALL THE INPUT CHARACTER 
       ANI  40Q       ;IS IT AN UPPER CASE CHAR?
       JNZ  ESCAPB    ;NO - CONTINUE ESC SEQUENCE 
;                     YES - POSITION CURSOR 
 
;*****************************
; EXECUTE COMPLETED SEQUENCE *
;*****************************
       LDA  SCRNRW  ;GET SCREEN ROW PARAMETER 
       ORA A        ;WAS SCREEN ROW ADDRESS SET?
       JM  CRP200   ;NO - SET ABSOLUTE ROW ADDR 
       STA  CURROW  ;YES - SET NEW SCREEN ROW 
;***************************
; SET ABSOLUTE ROW ADDRESS *
;***************************
CRP200 EQU  $ 
       CM   CRP500    ;FIND LOCATION OF NEW ROW 
; 
;  SET COLUMN ADDRESS 
; 
       LDA  NEWCOL  ;GET NEW COLUMN ADDRESS 
;****************************** 
; LOCATE ADDRESS OF CHARACTER * 
;****************************** 
CURPO4 EQU  $ 
       STA  CURCOL  ;STORE NEW COLUMN ADDRESS 
       CALL RCADDR  ;FIND CHARACTER 
       RZ           ;CHARACTER FOUND - RETURN 
;********************************** 
; CHARACTER NOT CURRENTLY STORED  * 
; BUILD LINE OVER TO NEW POSITION * 
;********************************** 
       MVI L,DCHAR  ;SET UP BLANK FOR NEW POS.
       MVI M,ABLNK
       JMP DISPL0   ;BUILD BLOCKS 
 
;***********************************
; LOCATE NEW ABSOLUTE ROW LOCATION *
;***********************************
CRP500 EQU  $ 
       LDA  MFLGS2    ;GET TERMINAL MODE FLAGS
       ANI  NWRWST    ;NEW ABSOLUTE ROW SET?
       RZ             ;NO - RETURN
       LDA  NEWROW  ;GET NEW ROW VALUE
       MVI L,TLINO  ;SUBTRACT ROW CORRESP.
       SUB M        ;TO TOP OF PAGE 
       MVI L,CURROW 
       JC  PRVPG1   ;LOCATE PREVIOUS ROW PAGE 
       CPI MAXROW+1 
       MOV M,A      ;SET NEW ROW
       RC           ;RETURN IF SAME PAGE
;****************************** 
; ROW IS AFTER BOTTOM OF PAGE * 
; ROLL DISPLAY UP             * 
;****************************** 
       MVI M,MAXROW ;SET ROW
       SUI  MAXROW    ;SET ROLL COUNT 
STR010 EQU  $ 
       CALL NXTPG1    ;ROLL DISPLAY UP
       MOV  A,M       ;GET NUMBER OF ROWS TO ROLL 
       SUB C        ;SUBTRACT ROWS ROLLED 
       RZ           ;RETURN IF ROLL COMPLETE
       MOV  M,A       ;SAVE NUMBER OF ROW TO ROLL 
       XRA  A           ;(SET TO FIND COLUMN 0) 
       CALL RCADR0    ;BUILD NEW ROWS 
       RNZ          ;RETURN IF OUT OF MEMORY
       LDA  NMROLL    ;GET # OF ROWS TO ROLL
       JMP  STR010    ;ROLL AGAIN 
;*********************************
; CURSEN - CURSOR POSITION SENSE *
;*********************************
; 
;  RLCRSN - SCREEN RELATIVE CURSOR SENSE
; 
RLCRSN EQU $
       MVI  A,RELSNS  ;SET RELATIVE SENSE FLAG
       CALL SETMF2
       JMP  CUR100    ;GO SET CURSOR SENSE FLAG 
; 
;  CURSEN - ABSOLUTE CURSOR SENSE 
; 
CURSEN EQU  $ 
       MVI  A,377Q-RELSNS 
       CALL CLRMF2    ;CLEAR RELATIVE SENSE FLAG
CUR100 EQU  $ 
       LXI  B,SCRSEN  ;SET UP BLOCK TRANSFER
       JMP  SBLXF0      ;FOR CURSOR SENSE PENDING 
 
CRSNGO EQU  $ 
       LXI  B,-1-SCRSEN  ;CLEAR CURSOR SENSE
       CALL CLBLXF      ;PENDING FLAG 
       MVI  B,AMPSND  ;SEND <ESC>-<&> 
       CALL ESCOUT
       MVI  A,SMALLA  ;TRANSMIT LOWER CASE A
       CALL XPUTDC
;***********************
; OUTPUT CURSOR COLUMN *
;***********************
       LXI  H,XPUTDC  ;SEND NUMBER TO DATA COMM 
       LDA  CURCOL    ;GET CURRENT CURSOR COLUMN
       CALL BN2DE1    ;CONVERT AND TRANSMIT VALUE 
       MVI  A,ALCC    ;TRANSMIT LOWER CASE C
       CALL XPUTDC
;******************** 
; OUTPUT CURSOR ROW * 
;******************** 
       LDA  MFLGS2    ;GET TERMINAL MODE FLAGS
       ANI  RELSNS    ;SCREEN RELATIVE SENSING? 
       LDA  CURROW      ;(GET CURSOR ROW NUMBER)
       MVI  B,Y         ;(SET DEFAULT PARAMETER)
       JNZ  CRS100    ;YES - OUTPUT SCREEN ADDRESS
       LXI  H,TLINO   ;NO - COMPUTE ABSOLUTE
       ADD  M           ;ROW NUMBER 
       MVI  B,R       ;SET ABSOLUTE PARAMETER CHAR
;*************************
; TRANSMIT ROW PARAMETER *
;*************************
; 
;  A = ROW VALUE
;  B = ROW PARAMETER LETTER 
; 
CRS100 EQU  $ 
       PUSH B         ;SAVE ROW PARAMETER LETTER
       CALL BN2DE2    ;CONVERT AND TRANSMIT VALUE 
       POP  PSW       ;RECALL ROW PARAMETER LETTER
       CALL XPUTDC    ;TRANSMIT ROW PARAMETER CHAR
;                     FALL INTO "SDTERM"
;************************************ 
; SDTERM - SEND BLOCK TERMINATOR *
; RS IF PAGE MODE, OTHERWISE CR(LF) * 
;************************************ 
SDTERM EQU  $ 
       CALL SDTRM1    ;SEND TERMINATOR
SDTER1 EQU  $ 
       CALL CLRXON    ;CLEAR BLOCK TERMINATOR 
       MVI  A,ENDBLK  ;TELL DATA COMM THAT LAST 
       JMP  DCMCTL      ;CHARACTER IN BLOCK IS OUT
 
; 
;  DC2GO - OUTPUT DC2 
; 
DC2GO  EQU $
       LXI  H,MFLGS 
       MOV  A,M       ;CLEAR DC2 PENDING FLAG 
       ANI  (-1-SDC2)/256 
       MOV  M,A 
       MVI  A,PROMPT  ;TELL DATA COMM ROUTINE TO
       JMP  DCMCTL      ;SEND PROMPT CODE 
;***************************************
; DCMINT - DATA COMM INTERRUPT ROUTINE *
;***************************************
; 
;  ENTRY:  PSW "PUSHED" 
;          A = INTERRUPT CODE 
; 
DCMINT EQU  $ 
       CALL INTVEC    ;CHECK ALTERNATE INTERRUPT
       POP  PSW       ;RESTORE PSW AND A-REGISTER 
       JMP  ZDCINT    ;EXECUTE NORMAL DATA COMM 
;                       INTERRUPT ROUTINE 
 
;********************************** 
; BRKDC - EXECUTE DATA COMM BREAK * 
;********************************** 
BRKDC  EQU  $ 
       MVI  A,PUTBRK  ;EXECUTE DATACOM BREAK
       JMP  DCMCTL      ;CONTROL
; 
;  DISMDM - DISCONNECT MODEM
; 
DISMDM EQU  $ 
       MVI  A,DISCNT  ;EXECUTE MODEM DISCONNECT 
;********************************************** 
; DCMCTL - PERFORM DATA COMM CONTROL FUNCTION * 
;********************************************** 
; 
;  ENTRY:  A = FUNCTION TYPE NUMBER 
; 
;  EXIT :  Z - FUNCTION PERFORMED 
;          NZ - FUNCTION NOT PERFORMED
; 
DCMCTL EQU  $ 
       PUSH PSW       ;SAVE A-REGISTER
       CALL CKRMTE    ;REMOTE MODE ENABLED? 
       JNZ  DCC010    ;YES - PERFORM FUNCTION 
       POP  PSW       ;NO - RESTORE A-REGISTER
       INR  A         ;FORCE NZ 
       RET            ;RETURN 
; 
DCC010 EQU  $ 
       POP  PSW       ;RESTORE A-REGISTER 
DCMCT1 EQU  $         ;ENTRY TO FORCE DATA COMM CT
       CALL ZDCCTL    ;EXECUTE FUNCTION 
       RNC            ;SUCCESSFUL - RETURN
DCERR  EQU  $         ;PROCESS DATA COMM ERROR
       JZ   ZBELL     ;NOT FATAL - SOUND BELL 
;*****************************
; DISPLAY TEST FAIL MESSAGES *
;*****************************
HANGU0 EQU  $ 
       CALL DSPMS0    ;DISPLAY THE ERROR MESSAGE
       MVI  A,FRCRST  ;SET TO FORCE FULL RESET
       CALL STCMFL      ;IF RESET KEY HIT 
; 
HNG010 EQU  $ 
       CALL DISLN4    ;RE-ENABLE RESET ONLY 
       JMP  HNG010    ;HANG TERMINAL
;                     ************************* 
;                     * RESET KEY MUST BE HIT * 
;                     * TO RESTORE TERMINAL   * 
;                     * OPERATION             * 
;                     ************************* 
 
;*******************************************
; DCNUM - ACCUMULATE PARAMETER FOR ESC SEQ *
;*******************************************
; 
;  EXIT :  Z TRUE 
; 
DCNUM  EQU  $ 
       LXI  H,IOCSGN  ;GET THE CURRENT SIGN 
       MOV  A,M         ;VALUE
       ORA  A         ;HAS ANY SIGN BEEN SET? 
       JNZ  DCN005    ;YES - DON'T CHANGE IT
       MVI  M,NOSIGN  ;NO - SET NO SIGN FLAG
DCN005 EQU  $ 
       LDA  CHAR      ;GET INPUT CHARACTER
       SUI  ZERO      ;EXTRACT BINARY VALUE 
       MOV  E,A       ;PUT VALUE IN E-REGISTER
       MVI  D,0       ;SET MSB TO ZERO
       LDA  RADIX     ;GET RADIX OF NUMBER
       LHLD IODATA    ;GET ACCUMULATOR
       XCHG           ;PUT ACCUMULATOR IN D,E 
; 
DCN010 EQU  $ 
       DAD  D         ;ACCUMULATE NEW VALUE 
       DCR  A         ;RADIX ADJUSTMENT COMPLETED?
       JNZ  DCN010    ;NO - CONTINUE ADDING 
       SHLD IODATA    ;YES - STORE NEW VALUE
       JMP  ESCAP1    ;CONTINUE ESCAPE SEQUENCE 
;******************************************** 
; DCPLUS - PLUS SIGN RECEIVED FOR PARAMETER * 
;******************************************** 
DCPLUS EQU  $ 
       MVI  B,1       ;SET B-REG TO SIGN VALUE
       JMP  DCM010    ;SET SIGN FLAG
;*********************************************
; DCMNUS - MINUS SIGN RECEIVED FOR PARAMETER *
;*********************************************
DCMNUS EQU  $ 
       MVI  B,-1
DCM010 EQU  $ 
       LXI  H,IOCSGN  ;GET CURRENT SIGN VALUE 
       MOV  A,M 
       ORA  A         ;SIGN SET ALREADY?
       JNZ  ESCEND    ;YES - ABORT ESCAPE SEQUENCE
       MOV  M,B       ;NO - SET SIGN VALUE
       JMP  ESCAP1    ;CONTINUE ESCAPE SEQUENCE 
 
;***************************************
; DCTEST - EXECUTE DATA COMM SELF-TEST *
;***************************************
DCTEST EQU  $ 
       CALL CKRMTE    ;REMOTE MODE ENABLED? 
       RZ             ;NO - DON'T DO SELF-TEST
       CALL ZDCTST    ;CALL DATA COMM SELF-TEST 
       JC   HANGU0    ;HANG TERMINAL IF FATAL ERRO
       JMP  DSPMS1    ;DISPLAY MESSAGE AND EXIT 
;                       IF SELF-TEST SUCCESSFUL 
;*****************************************
; DCXB2D - SEE IF SOURCE OF CHARACTER IS *
;   DATA COMM OR I/O BUFFER              *
;*****************************************
; 
;  EXIT :  Z - INPUT IS NOT FROM DATA COMM OR I/O 
;          NZ - INPUT IS FROM DATA COMM OR I/O
;          A DESTROYED
; 
DCXB2D EQU  $ 
       LDA  DFLGS     ;GET DATA TRANSFER FLAGS
       ANI  SDACOM+XBF2DS  ;SET Z-FLAG
       RET            ;RETURN 
 
;****************************** 
; DELAY0 - PAUSE FOR 1 SECOND * 
;****************************** 
DELAY0 EQU  $ 
       MVI  A,MAXROW+1  ;REMOVE CURSOR AND
       CALL DISLN2      ;RE-ENABLE RESET KEY
       MVI  L,100     ;DELAY FOR 1 SECOND 
;******************************** 
; DELAY - DELAY 10 MILLISECONDS * 
; TIMES COUNT IN L              * 
;******************************** 
DELAY  EQU  $ 
       MVI  A,SETROM
       OUT  PROCSR    ;RESET THE TIMER
       LDA  PRCCTL    ;RESTORE PROCESSOR STATE
       OUT  PROCSR
; 
DLY010 EQU  $ 
       XRA  A         ;CLEAR THE INTERRUPT FLAG 
       STA  INTFLG
DLY020 EQU  $ 
       HLT            ;SLEEP UNTIL INTERRUPTED
       LDA  INTFLG    ;GET INTERRUPT FLAG 
       CPI  TMRINT    ;TIMER INTERRUPT? 
       JNZ  DLY020    ;NO - CONTINUE WAITING
       DCR L        ;ENOUGH TIMER INTERRUPTS? 
       JNZ DLY010   ;NO - CONTINUE TIMING 
       RET            ;YES - RETURN 
 
;***************************
; <F> - SEND FUNCTION DATA *
;***************************
SNDCD2 EQU  $ 
       LDA  IODATA    ;GET ACCUMULATED VALUE
       MOV  B,A       ;PUT CODE INTO B-REGISTER 
       MVI  A,SNDFCT  ;SET DATA COMM CONTROL CODE 
       CALL DCMCTL    ;PERFORM FUNCTION 
       RNZ            ;EXIT IF FUNCTION NOT DONE
;                     OTHERWISE, SEND SCREEN DATA 
;***************
; DISPLAY SEND *
;***************
DPSEND EQU  $ 
       MVI  A,CKIOKY
       CALL ZKBCTL    ;I/O CONTROL KEY DOWN ALSO? 
       JNZ  DCTEST    ;YES - DO DATA COMM SELF-TES
       LDA  CMFLGS    ;GET COMMON FLAGS 
       ANI  REMSET    ;REMOTE ENABLED?
       LXI  D,(RCKYCD-ENTRCD)*2;(SET KEY INDEX) 
       JZ   IOKEYS    ;NO - PERFORM RECORD COMMAND
       LXI  B,SENTER  ;YES - SET XFR PENDING FLAG 
       LDA  MDFLG2    ;NO - GET TERMINAL MODE FLAG
       ANI  BLKMDE    ;BLOCK MODE ENABLED?
       JZ   DPS200    ;NO - DO CHARACTER MODE STAR
       CALL CHKSFK    ;SOFT KEY MODE? 
       JNZ  DPS220    ;YES - DON'T SET TERMINATOR 
       LDA  KBJMP2    ;YES - GET KEYBOARD JUMPERS 
       ANI  AUTTRM    ;AUTO TERMINATE ENABLED?
       JZ   DPS220    ;NO - DO DON'T MOVE CURSOR
       CALL STTERM    ;YES - SET NON-DISPLAYING 
;                       TERMINATOR
       RZ             ;EXIT IF NOT SUCCESSFUL 
;*****************************************
; FIRST TRANSMIT CHARACTER LOCATED - SET *
;   TRANSFER PENDING FLAG                *
;*****************************************
DPS100 EQU  $ 
       LXI  B,SENTER  ;SET B,C XFR PENDING FLAG 
       JMP  SBLXF1      ;FOR BLOCK MODE TRANSFER
 
;****************************************** 
; AUTO TERMINATOR JUMPER NOT REMOVED - DO * 
;   NORMAL DATA ENTRY FROM DISPLAY        * 
;****************************************** 
DPS200 EQU  $ 
       LDA  KBJMPR    ;GET KEYBOARD JUMPERS 1 
       ANI  HNDSHK+DC2SND 
       XRI  HNDSHK    ;HANDSHAKE ENABLED? 
       CNZ  CHKCT1    ;NO - SET BLOCK TRIGGER 
DPS210 EQU  $ 
       CALL SBLXFA    ;SET TRANSFER PENDING FLAG
DPS215 EQU  $ 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       RNZ            ;YES - DON'T MOVE CURSOR
       JMP  CRRET1    ;NO - PUT CURSOR AT BEGINNIN
;                       OF LINE (A = 0) 
; 
;  SET KEYBOARD BLOCK TRANSFER
; 
DPS220 EQU  $ 
       CALL SBLXF1    ;SET BLOCK MODE XFR PENDING 
       LDA  MFLGS     ;GET TRANSFER PENDING FLAGS 
       ANI  SDC2/256  ;DC2 TO BE SENT?
       RNZ            ;YES - DON'T MOVE CURSOR
       CALL CKLNMD    ;LINE MODE? 
       JZ   DPS215    ;YES - SET CURSOR IN LINE 
;**************************************** 
; DPSEN1 - HOME CURSOR FOR TRANSMISSION * 
;**************************************** 
DPSEN1 EQU  $ 
       CALL XMOHME    ;HOME CURSOR
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       RNZ            ;YES - RETURN 
       JMP  CRRET1    ;NO - SET CURSOR TO COLUMN 0
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  DPSGO - SEND DISPLAY TO DATACOM
; 
;      ENTRY:  CURCOL,CURROW SET TO STARTING
;                LOCATION 
; 
;      EXIT :  ALL REGISTERS DESTROYED
; 
DPSGO  EQU  $ 
       CALL INITDG    ;INIT DISPLAY GET ROUTINE 
       JNZ  DSG200    ;TERMINATE IF NO CHARACTERS 
       MVI  A,STPXFR  ;SET TERMINATOR FUNCTION TO 
       STA  TRMFCT      ;TERMINATE TRANSFER 
DSG010 EQU  $ 
       MVI  A,STCHST  ;SET CHARACTER SET FOR
       CALL ZKBCTL      ;FOREIGN TERMINALS? 
       CC   XPUTDC    ;YES - OUTPUT SI/SO 
; 
;  OUTPUT CHARACTERS FROM DISPLAY 
; 
DSG020 EQU  $ 
       CALL GETDSP    ;ANY CHARACTER? 
       JC   DSG100    ;NO - CHECK TERMINATION 
       CALL XPUTDC    ;YES - TRANSMIT THE CHARACTE
       JNC  DSG020    ;CONTINUE IF NO DATA COMM ER
       JMP  DSG230    ;ELSE, TERMINATE OUTPUT 
; 
;  NON-CHARACTER FOUND - CHECK TERMINATION
; 
DSG100 EQU  $ 
       JM   DSG200    ;END OF DISPLAY - TERMINATE 
       MOV  B,A       ;SAVE EXIT STATUS 
       CALL GTMODE    ;PAGE MODE ENABLED? 
       JZ   DSG210    ;NO - END WITH CR(LF) 
       CALL CHKFMT    ;FORMAT MODE? 
       JZ   DSG110    ;NO - SEND CR AND LF
       LDA  RECSEP    ;YES - END WITH RECORD
       CALL XPUTDC      ;SEPARATOR
       JMP  DSG010    ;CONTINUE THRU DISPLAY
 
; 
;  EOL FOR NON-FORMAT PAGE MODE - SEND CR AND LF
; 
DSG110 EQU  $ 
       MVI  A,CR      ;SEND RETURN
       CALL XPUTDC      ;AND
       CALL SDTRM3        ;LINE FEED
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       CZ   LNFEED    ;NO - DO LINE FEED
       CALL DISLN1    ;SET DISPLAY CURSOR ROW 
       JMP  DSG010    ;CONTINUE THRU DISPLAY
; 
;  END OF DISPLAY - SEND TERMINATOR 
; 
DSG200 EQU  $ 
       LDA  BLKTRM    ;SEND BLOCK TERMINATOR
       CALL XPUTDC      ;CHARACTER
       CALL GTMODE    ;PAGE MODE? 
       JZ   DSG220    ;NO - SEND CR(LF) 
       JMP  DSG225    ;YES - CLEAR XFR PENDING FLA
;****************************************** 
; NON-PAGE MODE TERMINATION - SEND CR(LF) * 
;****************************************** 
DSG210 EQU  $ 
       CALL CHKFMS    ;FORMAT/SOFT KEY MODE?
       JNZ  DSG220    ;YES - DON'T DO LINE FEED 
       LDA  MDFLG2    ;NO - GET SOFT MODE FLAGS 
       ANI  AUTOLF    ;AUTO LINE FEED ENABLED?
       CNZ  LNFEED    ;YES - DO LINE FEED 
;*************************
; SEND CR(LF) TERMINATOR *
;*************************
DSG220 EQU  $ 
       CALL SDTRM1    ;SEND CR(LF)
DSG225 EQU  $ 
       CALL SDTER1    ;MARK END OF OUTPUT BLOCK 
       XRA  A         ;RESET TERMINATOR FUNCTION
       STA  TRMFCT      ;TO DELETE TERMINATOR 
DSG230 EQU  $ 
       LXI  B,-1-SENTER 
       CALL CLBLXF    ;CLEAR ENTER PENDING FLAG 
       JMP  CRADV1    ;CLEAR CURSOR ADVANCE FLAG
;                       AND EXIT
 
;***************************************
; A2OUTB - PUT BYTE INTO OUTPUT BUFFER *
;***************************************
;  ENTRY:  A = BYTE TO BE OUTPUT
; 
;  EXIT :  H = BASEH
;          B2DEND = B2DEND + 1
;          D,E,L DESTROYED
; 
;  ECOUTB - OUTPUT <ESC>
; 
;      ENTRY:  B = SECOND CHARACTER IN ESCAPE SEQ 
; 
ECOUTB EQU  $ 
       MVI  A,ESC     ;SET A TO ESC 
       CALL A2OUTB    ;PUT ESC INTO OUTPUT BUFFER 
B2OUTB EQU  $ 
       MOV  A,B       ;PUT SECOND CHAR INTO A-REG 
;                     FALL INTO OUTPUT ROUTINE
; 
A2OUTB EQU  $ 
       LXI  H,B2DEND
       INR  M         ;INCREMENT TO NEXT POSITION 
       MOV  L,M       ;GET NEW ADDRESS
       MOV  M,A       ;STORE THE BYTE 
       RET            ;RETURN 
 
;**************************** 
; ENTLCL - ENTER LOCAL MODE * 
;**************************** 
ENTLCL EQU  $ 
       CALL CKEDIT    ;EDIT MODE ENABLED? 
       JZ   ENL100    ;NO - GO INTO LOCAL MODE
       MVI  A,REMOTE  ;YES - INHIBIT TRANSITION TO
       LXI  H,MDFLG2    ;LOCAL MODE 
       ORA  M         ;FORCE REMOTE FLAG ON 
       MOV  M,A 
       RET            ;RETURN 
; 
ENL100 EQU  $ 
       MVI  A,SETLCL  ;SET DATACOM FOR LOCAL
       CALL DCMCTL      ;OPERATION
       MVI  A,377Q-REMSET  ;CLEAR REMOTE MODE FLAG
;****************************** 
; CLCMFL - CLEAR COMMON FLAGS * 
;****************************** 
; 
;  ENTRY:  A = 377B-FLAG BIT TO BE CLEARED
; 
;  EXIT :  A,H,L DESTROYED
; 
CLCMFL EQU  $ 
       LXI  H,CMFLGS
       ANA  M         ;CLEAR THE FLAG BIT 
       MOV  M,A       ;STORE THE NEW SETTINGS 
       RET            ;RETURN 
 
; 
;  ENTREM - ENTER REMOTE MODE 
; 
ENTREM EQU  $ 
       CALL CKEDIT    ;EDIT MODE ENABLED? 
       JZ   ENR100    ;NO - GO INTO REMOTE MODE 
       MVI  A,377Q-REMOTE  ;YES - INHIBIT 
       LXI  H,MDFLG2    ;TRANSITION TO REMOTE MODE
       ANA  M         ;FORCE REMOTE FLAG OFF
       MOV  M,A 
       RET            ;RETURN 
; 
ENR100 EQU  $ 
       SUB  A         ;CLEAR THE DATA PENDING 
       STA  MFLGS       ;FLAGS
       MVI  A,377Q-SBINRY-SDVREC
       CALL CLRMF2    ;CLEAR BINARY RECORD PENDING
       MVI  A,SETREM  ;SET DATACOM FOR REMOTE 
       CALL DCMCT1      ;OPERATION
       MVI  A,REMSET  ;SET REMOTE MODE FLAG 
;**************************** 
; STCMFL - SET COMMON FLAGS * 
;**************************** 
; 
;  ENTRY:  A = FLAG BIT TO BE SET 
; 
;  EXIT :  A,H,L DESTROYED
; 
STCMFL EQU  $ 
       LXI  H,CMFLGS
       ORA  M         ;ADD BIT TO "CMFLGS"
       MOV  M,A       ;STORE NEW SETTINGS 
       RET            ;RETURN 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  FCTKEY - FUNCTION KEY PRESSED (F1-F8)
; 
;      ENTRY:  C = FUNCTION KEY CODE (360-367B) 
; 
;      EXIT :  DFLGS(FCTK2D) = 1, FUNCTION KEY
;                DATA TO BE USED AS NORMAL
;                KEYBOARD CHARACTERS
;              DFLGS(FCTK2D) = 0
;                MFLGS(SFCTKY) = 0, KEY WAS 
;                  INTERPRETED LOCALLY ONLY 
;                MFLGS(SFCTKY) = 1, DATA WAITING
;                  FOR BLOCK TRANSFER TRIGGER TO
;                  SEND TO CPU
;              ALL REGISTERS DESTROYED
; 
FCTKEY EQU  $ 
       MOV  A,C       ;COMPUTE NUMBER OF LINES TO 
       ADD  A           ;SEARCH:
       SUI  FCTADJ        ;2*(FUNCTION NUMBER) - 1
       LXI  H,SFTKYS
       CALL MLKSC1    ;LOCATE THE ATTRIBUTE LINE
; 
;  DEFINITION FOUND - PERFORM FUNCTION
; 
       MOV  A,L       ;COMPUTE LOCATION OF
       SUI  ATBLOC      ;ATTRIBUTE CODE 
       MOV  E,A 
       MOV  D,H 
       CALL CHAIN     ;GET ADDRESS OF DATA LINE 
       SHLD CURFKY    ;SAVE FIRST CHARACTER ADDRES
;                       TO FORCE SKIP OVER "ENDPR"
       LDAX D         ;GET ATTRIBUTE CODE 
       CPI  N         ;NORMAL MODE? 
       JC   FCT200    ;< - DO LOCAL ONLY
       MVI  A,FCTK2D    ;(SET DATA XFR FLAG)
       JZ   SETDFL    ;YES - SET NORMAL KEY XFR 
       CALL GTMODE    ;> - SET BLOCK TRANSFER 
       LXI  B,SFCTKY    ;FOR FUNCTION KEY 
       JZ   SBLXFA    ;SET FLAG FOR NOT PAGE MODE 
       JMP  SBLXF1      ;ELSE SET FOR PAGE XFR
 
;********************************** 
; PERFORM LOCAL ONLY KEY FUNCTION * 
;********************************** 
FCT200 EQU  $ 
       CALL GTFCTK    ;GET FUNCTION KEY DATA
       RZ             ;NONE LEFT - RETURN 
FCT210 EQU  $ 
       STA  CHARIN    ;SAVE FUNCTION KEY CHARACTER
       CALL CHINT     ;PROCESS DATA LOCALLY 
       LDA  CHARIN    ;RECALL FUNCTION CHARACTER
       CPI  CR        ;IS IT A RETURN?
       JNZ  FCT200    ;NO - DO THE NEXT BYTE
       LDA  MDFLG2    ;YES - GET HARD MODE FLAGS
       ANI  AUTOLF    ;AUTO LINE FEED ENABLED?
       JZ   FCT200    ;NO - DO NEXT FUNCTION BYTE 
       MVI  C,LF      ;YES - PERFORM LINE FEED
       JMP  FCT210      ;FUNCTION 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  FKEYGO - TRANSMIT FUNCTION KEY 
; 
;      ENTRY:  DON'T CARE 
; 
;      EXIT :  MFLGS1(SFCTKY) = 0 
;              ALL REGISTERS DESTROYED
; 
FKEYGO EQU  $ 
       LXI  B,-1-SFCTKY  ;CLEAR FUNCTION KEY
       CALL CLBLXF      ;PENDING FLAG 
       LDA  DFLGS     ;GET DATA TRANSFER FLAGS
       ANI  FCTK2D    ;OPERATE AS NORMAL KEY? 
       RNZ            ;YES - RETURN TO WAIT LOOP
; 
;  TRANSMIT FUNCTION KEY DATA 
; 
FKG010 EQU  $ 
       CALL GTFCTK    ;GET NEXT FUNCTION KEY CHAR 
       JZ   SDTERM    ;SEND TERMINATOR IF NO MORE 
;                       DATA
       LXI  H,BLKTRM
       CMP  M         ;BLOCK TERMINATOR CHARACTER?
       JZ   SDTERM    ;YES - OUTPUT TERMINATOR
       CALL XPUTDC    ;NORMAL DATA - TRANSMIT IT
       JMP  FKG010    ;DO NEXT CHARACTER
 
; 
;  MNMDON - MONITOR MODE ON 
; 
MNMDON EQU  $ 
       MVI  A,SETMON  ;SET DATACOM MONITOR
       CALL DCMCTL      ;MODE 
       RNZ            ;DON'T MONITOR IF NOT SET 
       MVI  B,377Q    ;SET TO BLINK LED 
       JMP  FDO100    ;SET FUNCTION TABLE 
;*****************************************
; FDISON - TURN ON FUNCTION DISABLE MODE *
;*****************************************
FDISON EQU $
       MVI  B,0       ;SET FOR NO BLINK 
FDO100 EQU  $ 
       MVI  A,DSPFNC  ;TURN ON DISPLAY FUNCTIONS
       CALL ZSTMD1      ;FLAG 
       LXI  H,FDISTB  ;SET H,L TO NEW RANGE TABLE 
       JMP  ESCEN1    ;SET RANGE TABLE AND EXIT 
;*************************************
; FDISOF - TURN OFF FUNCTION DISABLE *
;*************************************
FDISOF EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       JZ   FOF010    ;NO - DO NORMAL PROCESSING
       CALL DCXB2D    ;INPUT FROM KEYBOARD? 
       CNZ  SFKYOF    ;NO - RESTORE NORMAL DISPLAY
FOF010 EQU  $ 
       CALL FDESC1    ;DISPLAY INPUT CHARACTER
       LDA  LCHAR 
       CPI  ESC       ;WAS THE LAST CHAR <ESC>? 
       RNZ          ;NO - RETURN
;                     YES - TURN OFF DISPLAY FCTS 
DFCTOF EQU  $ 
       MVI  A,SETNRM  ;RESTORE DATACOM TO 
       CALL ZDCCTL      ;NORMAL MODE
       CALL ESCEND  ;YES - TURN OFF DISABLE MODE
       MVI  A,DSPFNC  ;TURN OFF DISPLAY FUNCTIONS 
       JMP  ZCLMD1      ;FLAG 
;************************** 
; FUNCTION DISABLE ESCAPE * 
;************************** 
FDESC  EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       JZ   FDESC1    ;NO - DO NORMAL PROCESSING
       CALL DCXB2D    ;INPUT FROM KEYBOARD? 
       CNZ  SFKYOF    ;NO - RESTORE NORMAL DISPLAY
FDESC1 EQU  $ 
       CALL DSPCHR    ;DISPLAY THE ESCAPE CODE
       JMP  CRADV1    ;RESET CURSOR ADVANCE FLAG T
;                       FORCE ANALYSIS OF NEXT
;                       INPUT CHARACTER FOR Z 
 
;******************************************** 
; FUNCTION TABLE FOR TERMINAL FUNCTION KEYS * 
;******************************************** 
FNCTAB EQU  $ 
       DW   DPSEND    ;230 - ENTER KEY
       DW   BRKDC     ;231 - BREAK KEY
       DW   DFCTOF    ;232 - DISPLAY FUNCTIONS OFF
       DW   IOKEYS    ;233 - I/O CONTROL KEY
       DW   IOKEYS    ;234 - READ KEY 
       DW   IOKEYS    ;235 - RECORD KEY 
       DW   IOKEYS    ;236 - SELECT KEY 
       DW   IOKEYS    ;237 - CONDITION TAPES
       DW   IOKEYS    ;240 - (CONTROL) READ KEY 
; 
ENTRCD EQU  230Q      ;ENTER KEY CODE 
RCKYCD EQU  235Q      ;RECORD KEY CODE
SLKYCD EQU  236Q      ;SELECT KEY CODE
CTRDKY EQU  240Q      ;CONTROL READ KEY CODE
FNCLWR EQU  230Q      ;FUNCTION CODE LOWER LIMIT
FNCLIM EQU  241Q      ;FUNCTION CODE UPPER LIMIT
; 
ESCSO  EQU  216Q      ;<ESC>-<SO> CODE
ESCLWD EQU  344Q      ;<ESC>-<LOWER CASE D> CODE
F1CODE EQU  360Q      ;F1 CODE
F8CODE EQU  367Q      ;F8 CODE
FCTAD1 EQU  F1CODE*2  ;FUNCTION CODE ADJUSTMENT 
FCTADJ EQU  -FCTAD1/256*256+FCTAD1-1  ;FACTOR 
STFOR2 EQU  375Q      ;SET FOREIGN MODE STEP 2
STFOR1 EQU  376Q      ;SET FOREIGN MODE STEP 1
ENHNCF EQU  377Q      ;ENHANCE DISPLAY FUNCTION 
;********************************** 
; FUNCTION ADDRESSES FOR I/O KEYS * 
;********************************** 
IOKYTB EQU  $ 
       DW   IOCKEY    ;I/O CONTROL KEY
       DW   REDKEY    ;READ KEY 
       DW   RECKEY    ;RECORD KEY 
       DW   SELKEY    ;SELECT KEY 
       DW   CONDTN    ;CONDITION TAPES
       DW   CTLRED    ;(CONTROL) READ KEY 
 
; 
;  DISPLAY STRINGS FOR SOFT KEY DISPLAY 
; 
ATBLIN EQU  $ 
       DB   EOL,ABLNK,ESC,ENDPR 
; 
       DB   EOL,STPR
ATB010 EQU  $ 
       DB   'T',SFKYAT,ENDPR,' '
       DB   NORMAL,'0',146Q,INVRS,0 
ATBLOC EQU  $-ATB010-1  ;ATTRIBUTE LOCATION IN BLK
ATBLEN EQU  $-ATBLIN-1  ;ATTRIBUTE LINE LENGTH
CHRLOC EQU  2         ;CHARACTER LOCATION IN STRIN
 
;********************************************** 
; FNDTAB - FIND TAB MASK                      * 
; EXIT: L,H = ADDR OF BYTE CONTAINING TAB BIT * 
;       A = MASK FOR TAB BIT                  * 
;********************************************** 
FNDTAB EQU $
       LDA  CURCOL  ;GET CURSOR COLUMN
       MOV B,A      ;SAVE IN B
FNDTB1 EQU $
       ANI 370Q     ;MASK OFF 3 LSB'S 
       RRC          ;RIGHT-ADJUST MSB'S 
       RRC
       RRC
       ADI HTBTBL   ;ADD BASE OF TAB TABLE
       MOV L,A      ;SAVE IN L
       MOV A,B      ;GET CURSOR COLUMN
       ANI 7        ;GET 3 LSB'S
       MOV B,A      ;SAVE IN B
       INR B        ;ADJUST BIT NUMBER
;*********************
; FNDTB2 - SET BIT N *
;*********************
; 
;  ENTRY:  B = BIT NUMBER TO BE SET 
; 
;  EXIT :  A = BYTE WITH BIT N SET
;          B = 0
; 
FNDTB2 EQU  $ 
       MVI A,200Q   ;SET BIT 7 OF A 
FTB100 EQU $
       RLC          ;SHIFT LEFT 1 POSITION
       DCR B        ;DECREMENT BIT COUNT
       JNZ FTB100   ;CONTINUE IF NOT DONE 
       RET          ;RETURN 
 
;*******************
; EXIT FORMAT MODE *
;*******************
FORMOF EQU $
       MVI  A,FORMAT  ;SET BIT TO BE CLEARED
       STA  PROFLD    ;SET PROTECT FLAG FOR UNPROT
       JMP  ZCLMD1    ;CLEAR FORMAT MODE FLAG 
 
;*********************************************
; FRECNT - CHECK THE NUMBER OF FREE BLOCKS   *
;                                            *
;          EXIT: Z=F, NOT ENOUGH FREE BLOCKS *
;                Z=T, ENOUGH FREE BLOCKS     *
;*********************************************
FRECNT EQU $
       MVI  B,25      ;SET DESIRED NUMBER OF BLOCK
       LXI  D,FRBLKS-2  ;SET TO FREE LIST HEAD
FRC010 EQU  $ 
       XCHG           ;SET H,L TO ADDRESS OF LSB
       INX  H           ;PART OF PREVIOUS LINE
       INX  H           ;POINTER
       MOV  A,M       ;GET LSB OF NEXT LINE LINK
       ORA  A         ;ANY MORE FREE BLOCKS?
       JZ   FRC100    ;NO - TRY TO GET MORE 
       DCR  B         ;ENOUGH FREE BLOCKS?
       RZ             ;YES - RETURN SUCCESSFUL
       CALL CHAIN     ;NO - GET NEXT LINE ADDRESS 
       MOV  D,H       ;SAVE NEXT LINE ADDRESS IN
       MOV  E,L         ;D,E
FRC050 EQU  $ 
       ANI  360Q      ;COMPUTE ADDRESS OF NEXT
       MOV  L,A         ;BLOCK LINK 
       MOV  A,M       ;GET THE LSB OF THE LINK
       CMA  ;A         IS IT AN EOL LINK (LOWER 
       ANI  BLKSM       ;FOUR BITS NOT ALL ONES)? 
       JNZ  FRC010    ;NO - GO TO THE NEXT LINE 
       DCR  B         ;ENOUGH FREE BLOCKS FOUND?
       RZ             ;YES - RETURN SUCCESSFUL
       CALL CHAIN     ;NO - GO TO THE NEXT BLOCK
       JMP  FRC050    ;CHECK FOR END OF LINE
;*******************************************
; NOT ENOUGH FREE BLOCKS - TRY TO GET MORE *
;*******************************************
FRC100 EQU  $ 
       CALL PTBLK     ;REMOVE A LINE FROM DISPLAY 
       JNZ  FRECNT    ;RECOUNT IF LINE FREED
       INR  A           ;(FORCE NZ) 
       RET            ;RETURN FAIL OTHERWISE
 
;********************************************** 
; FRNCT1 - FOREIGN MODE CONTROL 1 (<ESC>-"<") * 
;********************************************** 
FRNCT1 EQU  $ 
       MVI  A,FRNMD1  ;SET KEYBOARD FOREIGN MODE 1
       JMP  ZKBCTL
;********************************************** 
; FRNCT2 - FOREIGN MODE CONTROL 2 (<ESC>-">") * 
;********************************************** 
FRNCT2 EQU  $ 
       MVI  A,FRNMD2  ;SET KEYBOARD FOREIGN MODE 2
       JMP  ZKBCTL
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  GTFCTK - GET FUNCTION KEY
; 
;      ENTRY:  DON'T CARE 
; 
;      EXIT :  NZ - FUNCTION KEY CHAR AVAILABLE 
;                A = C = FUNCTION KEY CHARACTER 
;              Z - NO FUNCTION KEY CHAR AVAILABLE 
;                DFLGS(FCTK2D) = 0
;                A DESTROYED
;              D-L DESTROYED
; 
GTFCTK EQU  $ 
       LHLD CURFKY    ;GET LAST FUNCTION KEY
;                       CHARACTER ADDRESS 
       CALL NXTCH0    ;GET THE NEXT CHARACTER 
       JNZ  GTF010    ;EOL LINK - DO EOL EXIT 
       XCHG 
       SHLD CURFKY    ;STORE NEW ADDRESS
       CPI  ADEL+1    ;IS CHARACTER ASCII?
       MOV  C,A         ;(PUT DATA IN C-REGISTER) 
       RM             ;YES - RETURN 
; 
;  EOL FOUND - CLEAR FCTK2D FLAG
; 
GTF010 EQU  $ 
       MVI  A,377Q-FCTK2D 
              CMP  A         ;SET Z TRUE 
       RET            ;RETURN 
 
;***************************
; HTBSET - TAB SET ROUTINE *
;***************************
HTBSET EQU $
       CALL FNDTAB  ;GET TABLE ENTRY FOR COLUMN 
       ORA M        ;SET TAB
       MOV M,A
       RET          ;RETURN 
;*****************************
; HTBCLR - TAB CLEAR ROUTINE *
;*****************************
HTBCLR EQU $
       CALL FNDTAB  ;GET TABLE ENTRY FOR COLUMN 
       XRI 377Q     ;COMPLEMENT MASK
       ANA M        ;CLEAR TAB
       MOV M,A
       RET          ;RETURN 
 
;******************************************** 
; IOBNGO - FAST BINARY READ ESCAPE SEQUENCE * 
;******************************************** 
IOBNGO EQU  $ 
       LXI  H,CTDCDP  ;EXECUTE FAST BINARY READ 
       JMP  IORMGO      ;IF I/O ROM PRESENT 
;*****************************
; IOBSYC - WAIT FOR CTU IDLE *
;*****************************
IOBSYC EQU  $ 
       LXI  H,BSYCHK  ;GO TO CTU BUSY CHECK 
       CALL IORMGO      ;ROUTINE
       LDA  CMND      ;GET CURRENT CTU COMMAND
       ANI  RUN       ;TAPE STILL RUNNING?
       RZ             ;NO - RETURN
       STA  IOCERR    ;YES - CLEAR "IOCERR" 
       JMP  IOBSYC    ;CONTINUE WAITING 
;***************************************
; IOCTGO - I/O CONTROL ESCAPE SEQUENCE *
;***************************************
IOCTGO EQU  $ 
       LXI  H,IOCNTL  ;EXECUTE I/O CONTROL ESCAPE 
       JMP  IORMGO      ;SEQ IF I/O ROM PRESENT 
;***********************************
; IOCTMN - MONITOR CARTRIDGE TAPES *
;***********************************
IOCTMN EQU  $ 
       LXI  H,CTMON   ;GET MONITOR ADDRESS
       JMP  IORMGO    ;EXECUTE IF CODE PRESENT
;***********************
; IOKEYS - I/O KEY HIT *
;***********************
; 
;  ENTRY:  D,E = KEY INDEX
; 
IOKEYS EQU  $ 
       LXI  H,IOKYTB-6
       DAD  D         ;COMPUTE KEY FUNCTION ADDRES
       CALL CHAIN     ;EXECUTE KEY FUNCTION IF I/O
;                       ROM PRESENT 
 
;*******************************************
; IORMGO - PERFORM FUNCTION IF OPTION ROMS *
;   ARE PRESENT                            *
;*******************************************
; 
;  ENTRY:  H,L = VECTOR TO BE ENTERED 
; 
;  EXIT :  NC - FUNCTION EXECUTED 
;            REGISTERS SET ACCORDING TO FUNCTION
;          C - FUNCTION NOT EXECUTED
;            A DESTROYED
; 
IORMGO EQU  $ 
       PUSH H         ;PUT FUNCTION ADDR ON STACK 
       MVI  L,0       ;CHECK ROM START LOCATION 
       CALL IORMG1    ;DOES ROM EXIST?
       RZ             ;YES - EXECUTE FUNCTION 
       LXI  H,NODRVR  ;NO - SET ERROR MESSAGE TO
       SHLD MSGPT1      ;"NO DEVICE DRIVER" 
       POP  H         ;RESTORE STACK
       STC            ;RETURN FUNCTION NOT
       RET              ;EXECUTED (C-TRUE)
;******************************************** 
; IORMG1 - CHECK FOR PRESENCE OF OPTION ROM * 
;******************************************** 
; 
;  ENTRY:  H,L = ROM STARTING ADDRESS 
; 
;  EXIT :  Z => ROM EXIST 
;            H,L = H,L(ENTRY)+1 
;          NZ => ROM ABSENT 
;          A DESTROYED
;            H,L = H,L(ENTRY) => ROM ABSENT 
;            H,L = H,L(ENTRY)+1 => WRONG ROM
; 
IORMG1 EQU  $ 
       MOV  A,M       ;GET FIRST ROM BYTE 
       ANI  360Q      ;CHECK UPPER 4 BITS ONLY
       CPI  P         ;IS IT AN UPPER CASE P? 
       RNZ            ;NO - RETURN ROM ABSENT 
       INX  H         ;YES - CHECK SECOND BYTE
       MOV  A,M       ;SECOND BYTE OF ROM SHOULD
       CMP  H           ;EQUAL HIGH ORDER EIGHT 
       RET              ;BITS IN ITS PROPER ADDRES
;                       RANGE 
 
;************************************ 
; IOINTR - I/O INTERRUPT PROCESSING * 
;************************************ 
; 
;  ENTRY:  "PSW" AND H,L PUSHED 
;          A = INTERRUPT CODE 
; 
IOINTR EQU  $ 
       CALL INTVEC    ;CHECK ALTERNATE INTERRUPT
       LDA  PRCCTL    ;GET CURRENT PROCESSOR STATE
       ORI  POLL      ;POLL THE I/O BOARDS TO FIND
       OUT  PROCSR      ;OUT WHO INTERRUPTED
       LXI  H,IOCRCL  ;DO DUMMY I/O READ TO GET 
       MOV  L,M         ;POLL RESPONSE
       ANI  377Q-POLL 
       OUT  PROCSR    ;RESTORE PROCESSOR STATE
       LDA  DEVFLG    ;GET POLL DEVICE FLAG 
       ANA  L         ;DEVICE DRIVER PRESENT? 
       JM   CTINTR    ;CTU - DO CTU ROUTINE 
       ADD  A         ;ALTERNATE I/O INTERRUPT? 
       JM   ZINTAL    ;YES - GO CHECK INTERRUPT 
;****************************************** 
; INVALID DEVICE INTERRUPT - REPORT ERROR * 
;****************************************** 
       MOV  A,L       ;RECALL POLL RESPONSE 
       MVI  B,ATSIGN  ;COMPUTE ERROR CODE 
       ORA  A         ;ANY DEVICE INTERRUPTED?
       JZ   IOI020    ;NO - DON'T LOOK FOR BIT
;                     YES - DETERMINE DEVICE
IOI010 EQU  $ 
       INR  B         ;INCREMENT ERROR CODE 
       RLC            ;DEVICE TYPE FOUND? 
       JNC  IOI010    ;NO - CONTINUE LOOKING
IOI020 EQU  $         ;YES - SET ERROR CODE 
       MOV  A,B 
;                     FALL INTO ERROR REPORTER
 
;*********************************************
; INTERR - REPORT INVALID INTERRUPT OCCURRED *
;*********************************************
; 
;  ENTRY:  A = ERROR CODE (ASCII CHARACTER) 
; 
INTERR EQU  $ 
       LXI  H,IODATA  ;SET ERROR CODE FOR ERROR 
       SHLD MSGPT2      ;MESSAGE
       MOV  M,A 
       INX  H 
       MVI  M,EOP 
       LXI  H,INERMS  ;REPORT INTERRUPT ERROR 
       XRA  A         ;STOP ANY CTU MOTION
       STA  IOCTCO
       JMP  HANGU0      ;AND HANG TERMINAL
;*****************************************
; INTRPT - PROCESS UNEXPECTED INTERRUPTS *
;*****************************************
; 
;  ENTRY:  "PSW" PUSHED 
;          A = INTERRUPT CODE 
;          C-FLAG CLEARED 
; 
INTRPT EQU  $ 
       CALL INTVEC    ;ANY INTERRUPT HANDLER? 
       JNC  INTERR    ;NO - REPORT ERROR
       POP  PSW       ;YES - RESTORE PSW
       EI             ;RE-ENABLE INTERRUPTS 
       RET            ;RETURN TO INTERRUPTED CODE 
 
;************************************ 
; IOINTR - I/O INTERRUPT PROCESSING * 
;************************************ 
;****************** 
; KEYBOARD ENABLE * 
;****************** 
KBEN   EQU $
       LDA  DFLGS 
       ANI KBDLOK   ;KEYBOARD LOCKED BY ESC SEQ?
       RNZ          ;YES - DO NOT UNLOCK KEYBOARD 
; 
KBEN1  EQU $
       MVI  A,UNLKKB  ;UNLOCK THE KEYBOARD
       CALL ZKBCTL
       MVI  A,377Q-KBDLOK  ;CLEAR LOCKED FLAG 
; 
;  CLRDFL - CLEAR DATA TRANSFER FLAGS 
; 
;      ENTRY:  A = FLAGS TO BE CLEARED
; 
CLRDFL EQU  $ 
       LXI  H,DFLGS 
       ANA  M         ;MASK OUT FLAGS 
; 
;  STOREA - STORE VALUE N A-REG AND RETURN
; 
;      ENTRY:  A = VALUE TO BE STORED 
;              H,L = LOCATION TO BE STORED IN 
; 
STOREA EQU $
       MOV M,A      ;STORE UPDATED VALUE
       RET          ;RETURN 
;**************** 
; KEYBOARD LOCK * 
;**************** 
KBLOK0 EQU $
       MVI  A,KBDLOK  ;SET ESCAPE SEQUENCE LOCK 
       CALL SETDFL      ;FLAG 
; 
KBLOK  EQU $
       MVI  A,LOCKKB  ;LOCK THE KEYBOARD
       JMP  ZKBCTL
 
;*****************************
;      ESC & LOWER CASE B    *
;     BINARY LOADER          *
;  A  SET ADDRESS = DIGITS   *
;  C  COMPARE CHECKSUM       *
;  D   STORE BYTE            *
;      INCREMENT ADDRESS     *
;  E   CALL ADDRESS          *
;  DIGITS   1,2,3,4, OR 5    *
;*****************************
LOADR  EQU  $         ;INITIAL ENTRY
       MVI  A,MAXROW+1
       STA  CURROW    ;SET CURSOR OFF THE SCREEN
       LXI  H,LDRMSG
       CALL DSPMS0    ;DISPLAY THE LOADER MESSAGE 
LOADR1 EQU  $         ;ENTRY TO NOT DISPLAY MESSAG
       LXI  H,0       ;CLEAR CHECKSUM ACCUMULATOR 
       SHLD LCHKSM
       MVI  A,FRCRST  ;SET FORCE RESET FLAG 
       CALL STCMFL
LDR0   EQU $
       LDA  CHAR      ;RECALL INPUT CHARACTER 
       ANI  40Q       ;IS IT UPPER CASE?
       MVI  A,377Q-FRCRST 
       JZ   CLCMFL    ;YES - CLEAR FORCE RESET AND
;                       EXIT ESCAPE SEQUENCE
       LXI  H,LDRTAB  ;NO - SET LOADER FUNCTION 
       MVI  A,OCTRDX  ;SET FOR OCTAL RADIX
       JMP  ESCAP0
; 
;  <A> - ADDRESS PARAMETER - SET ADDRESS
; 
LDR3   EQU $
       LHLD LDATA  ;GET ACCUMULATED DATA
       SHLD LADDR  ;SET AS LOAD ADDRESS 
       XCHG           ;PUT VALUE INTO D,E 
LDR035 EQU $
       LHLD LCHKSM    ;ACCUMULATE CHECKSUM
       DAD  D 
       SHLD LCHKSM
       JMP LDR0     ;RETURN TO SYSTEM 
 
; 
;  <D> - DATA BYTE PARAMETER - STORE DATA BYTE
; 
LDR4   EQU $
       MVI  L,LDATA-BASE
       MOV  E,M       ;GET ACCUMULATED DATA 
       LHLD LADDR     ;GET LOAD ADDRESS 
       MOV M,E      ;STORE THE BYTE 
       MVI D,0      ;ZERO MSB FOR CHECKSUM
       INX  H         ;INCREMENT AND STORE NEW
       SHLD LADDR       ;LOAD ADDRESS 
       JMP  LDR035    ;ACCUMULATE CHECKSUM
;***********************************************
; <E> - EXECUTE ENTERED CODE, WAIT UNTIL CTU'S *
;   STOPPED BEFORE EXECUTING CODE              *
;***********************************************
LDR060 EQU  $ 
       CALL DISLN4    ;RE-ENABLE RESET KEY
       CALL ZGETDC    ;PURGE DATA COMM INPUT
       CC   DCERR     ;PROCESS ERROR IF ANY 
       LDA  CMND      ;GET CTU COMMAND
       ANI  RUN       ;CTU'S RUNNING? 
       JNZ  LDR060    ;YES - CONTINUE WAITING 
       MVI  A,CRTOFF  ;NO - TURN OFF THE DISPLAY
       STA  IOCRRW
       DI             ;DISABLE INTERRUPTS 
       LHLD LADDR     ;GET LOAD ADDRESS 
       PCHL           ;START EXECUTION THERE
; 
;  <C> - CHECKSUM ENTRY 
; 
LDR10  EQU $        ;CHECKSUM ENTRY 
       LXI  H,ERRFLG  ;DEFAULT TO GOOD CHECKSUM 
       MOV  A,M 
       ORI  LDRCHK
       MOV  M,A       ;SET ERROR FLAGS
       LHLD LDATA     ;GET USER SPECIFIED CHECKSUM
       XCHG 
       LXI  H,LCHKSM
       MOV  A,E       ;COMPARE TO CALCULATED
       XRA  M           ;CHECKSUM 
       MOV  C,A 
       INX  H 
       MOV  A,D 
       XRA  M 
       ORA  C         ;DO CHECKSUMS MATCH?
       JZ   LDR0      ;YES - RETURN NORMAL
       RST  RESET     ;NO - RESET TERMINAL
 
;****************************************** 
; PARAMETERIZED SEQUENCES INITIAL CONTROL * 
;****************************************** 
PRMSEQ EQU  $ 
       LXI  H,PRMTAB  ;SET RANGE TABLE FOR
       JMP  ESCAPA      ;PARAMETERIZED ESC SEQUENC
 
;**************** 
; START PROTECT * 
;**************** 
PRSTRT EQU $
       MVI  B,STPR    ;STORE START PROTECT CONTROL
       JMP  PRO100      ;FLAG 
;**************** 
; TRANSMIT-ONLY * 
;**************** 
STRXMO EQU  $ 
       MVI  A,XMONLY  ;STORE TRANSMIT-ONLY CONTROL
       JMP  PRO010      ;FLAG 
;************** 
; END PROTECT * 
;************** 
PREND  EQU $
       MVI  A,ENDPR   ;STORE END PROTECT CONTROL
; 
;  MAKE SURE PREVIOUS CHAR IS DEFINED PROTECTED 
; 
PRO010 EQU  $ 
       STA  PARM1     ;SAVE CONTROL FLAG
       LDA  CURCOL    ;GET THE CURRENT COLUMN 
       DCR  A         ;SET TO FIND PREVIOUS COLUMN
       CALL RCADR0    ;PREVIOUS COLUMN PRESENT? 
       JM   ZBELL     ;NO - SOUND BELL AND RETURN 
       LDA  LSTFMT    ;YES - RECALL LAST FORMAT CT
       CPI  STPR      ;WAS IT A START PROTECT?
       CNZ  PRSTRT    ;NO - ENTER STPR
       LDA  PARM1     ;RECALL FORMAT CONTROL FLAG 
       MOV  B,A         ;TO BE STORED 
; 
;  ENTER THE FORMAT CONTROL FLAG
; 
PRO100 EQU $
       CALL CHKFMS  ;FORMAT MODE? 
       RNZ          ;YES - TERMINATE
       MOV  A,B       ;NO - ADD CHAR TO DISPLAY 
       PUSH PSW       ;SAVE THE CONTROL CODE
       CALL DISPC1      ;(DISPC1 DESTROYS "LSTFMT"
       POP  PSW       ;RECALL CONTROL CODE
       STA  LSTFMT      ;NEW ENTRY
       RET
 
; 
;  ENTREN - ENABLE ENTER VIA ESCAPE SEQUENCE
; 
ENTREN EQU  $ 
       LXI  B,SENTER  ;SET DISPLAY SEND PENDING 
;                     FALL INTO "SBLXF0"
;********************************************** 
; SBLXF0 - SET BLOCK TRANSFER FLAG FOR ESCAPE * 
;   SEQUENCE INITIATED BLOCK TRANSFERS        * 
;********************************************** 
; 
;  ENTRY:  B = FLAG TO BE SET IN "MFLGS"
;          C = FLAG TO BE SET IN "MFLGS2" 
; 
;  EXIT :  ALL REGISTERS DESTROYED
;          X-ON AND DC2 PENDING FLAGS ARE SET 
;          ACCORDING TO THE SETTINGS OF G AND H 
; 
SBLXF0 EQU  $ 
       CALL CLRXON    ;CLEAR BLOCK TRANSFER TRIGGE
; 
;  SBLXFA - DETERMINE DC2 HANDSHAKE MODE FOR
;    NON-BLOCK MODE KEYBOARD INITIATED BLOCK
;    TRANSFERS
; 
SBLXFA EQU $
       LDA  KBJMPR    ;GET THE STRAP SETTINGS 
       ANI HNDSHK   ;DC2 ON ALL BLOCK TRANSFERS?
       JZ  SBL010   ;NO - DO NOT SET DC2 FLAG 
;                   YES - FALL INTO "SBLXF1"
 
;************************************************ 
; SBLXF1 - SET BLOCK TRANSFER FLAG FOR KEYBOARD * 
;   INITIATED BLOCK TRANSFERS                   * 
;************************************************ 
; 
;  ENTRY:  B = FLAG TO BE SET IN "MFLGS"
;          C = FLAG TO BE SET IN "MFLGS2" 
; 
SBLXF1 EQU  $ 
       LDA  KBJMPR    ;GET THE STRAP SETTINGS 
       ANI  DC2SND    ;INHIBIT DC2 HANDSHAKE? 
       MVI  A,SDC2/256  ;(SET DC2 PENDING FLAG) 
       JZ   SBL020    ;NO - SET DC2 PENDING FLAG
       CALL CHKCT1    ;YES - SET BLOCK TRANSFER 
;                       TRIGGER TO CAUSE IMMEDIATE
;                       TRANSMISSION OF DATA
SBL010 EQU $
       MOV A,B      ;PUT FLAG INTO A-REGISTER 
SBL020 EQU  $ 
       ORA  B         ;ADD IN OPTIONAL DC2 FLAG 
       MOV  B,A       ;SAVE FLAGS IN B-REGISTER 
       CALL CKRMTE    ;REMOTE MODE ENABLED? 
       RZ             ;NO - DON'T SET BLOCK XFR 
       LXI  H,MFLGS   ;YES - SET DATA PENDING 
       MOV  A,B         ;FLAGS
       ORA  M 
       MOV  M,A 
       DCX  H 
       MOV  A,C 
       ORA  M         ;SET FLAG IN "MFLGS2" 
       MOV  M,A 
       JMP  KBLOK     ;DISABLE THE KEYBOARD 
 
;*************************************
; SDTRM1 - SEND TERMINATOR CHARACTER *
;*************************************
; 
;  EXIT :  A DESTROYED
; 
SDTRM1 EQU  $ 
       CALL GTMODE    ;PAGE MODE? 
       LDA  BLKTRM      ;(GET BLOCK TERMINATOR) 
       JNZ  XPUTDC    ;YES - SEND BLOCK TERM ONLY 
SDTRM2 EQU  $         ;NO - SEND CR(LF) 
       MVI  A,CR
       CALL XPUTDC    ;TRANSMIT RETURN
       LDA  MDFLG2
       ANI  AUTOLF    ;AUTO LINE FEED ENABLED?
       RZ             ;NO - RETURN
SDTRM3 EQU  $ 
       MVI  A,LF      ;YES - TRANSMIT LINE FEED 
       JMP  XPUTDC
 
;********************************** 
; SETDFL - SET DATA TRANSFER FLAG * 
;********************************** 
; 
;  ENTRY:  A = FLAG BIT TO BE SET 
; 
;  EXIT :  H = BASEH
;          A,L DESTROYED
; 
SETDF0 EQU  $         ;SET DATA COMM INPUT FLAG 
       MVI  A,SDACOM  ;SET FLAG BIT TO BE SET 
SETDFL EQU  $ 
       LXI  H,DFLGS 
       ORA  M         ;MERGE FLAG BIT TO EXISTING 
       MOV  M,A         ;FLAGS
       RET            ;RETURN 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  SETLFT,SETRHT - SET LEFT AND RIGHT MARGINS 
; 
;      ENTRY:  H = BASEH
;              CURCOL = CURSOR COLUMN POSITION
; 
;      EXIT :  LFTMGN,RHTMGN SET APPROPRIATELY
; 
SETLFT EQU  $ 
       CALL CHKFMT    ;FORMAT MODE? 
       RNZ            ;YES - DON'T SET MARGIN 
       LDA  RHTMGN    ;NO - GET THE RIGHT MARGIN
       MVI  L,CURCOL-BASE 
       CMP  M         ;CURSOR AFTER RIGHT MARGIN? 
       JM   DSPCH1    ;YES - DON'T SET MARGIN 
       MOV  A,M       ;NO - SET NEW LEFT MARGIN 
       STA  LFTMGN
       RET            ;RETURN 
; 
SETRHT EQU  $ 
       CALL CHKFMT    ;FORMAT MODE? 
       RNZ            ;YES - DON' SET MARGIN
       LDA  CURCOL    ;GET CURRENT CURSOR COLUMN
       MVI  L,LFTMGN-BASE 
       CMP  M         ;BEFORE LEFT MARGIN?
       JM   DSPCH1    ;YES - DON'T SET MARGIN 
       DCX  H         ;NO - SET NEW RIGHT MARGIN
       MOV  M,A 
       RET            ;RETURN 
 
;********************************** 
; SETMF2 - SET FLAG BIT IN MFLGS2 * 
;********************************** 
; 
;  ENTRY:  A = FLAG BIT TO BE SET 
; 
;  EXIT :  A = UPDATED MFLGS2 VALUE 
;          H,L = MFLGS2 
; 
SETMF2 EQU  $ 
       LXI  H,MFLGS2
       ORA  M         ;ADD BIT TO MFLGS2
       MOV  M,A       ;STORE NEW SETTINGS 
       RET            ;RETURN 
 
;*****************************************
; SETTRM - SET NON-DISPLAYING TERMINATOR *
;*****************************************
SETTRM EQU  $ 
       MVI  A,IGNTRM  ;SET TO IGNORE NON-DISPLAYIN
       STA  TRMFCT      ;TERMINATORS
       MVI  A,STPFLG  ;ADD NON-DISPLAYING 
       CALL DISPC2      ;TERMINATOR TO DISPLAY
       JMP  FLDSRX    ;SET "LSTCOL" TO MAXCOL+1 
;                       TO FORCE LINE RE-SCAN TO
;                       INHIBIT DELETION OF NEW 
;                       NON-DISPLAYING TERMINATOR 
 
;**************************************** 
; SNDCDE - SEND ATTENTION/FUNCTION CODE * 
;**************************************** 
SNDCDE EQU  $ 
       LDA  DFLGS     ;GET DATA TRANSFER FLAGS
       ANI  SDACOM    ;COMMAND FROM DATA COMM?
       RNZ            ;YES - IGNORE IT
       LXI  H,SNDCTB  ;SET TO ACCUMULATE OCTAL
       MVI  A,OCTRDX    ;CODE CHARACTER 
       JMP  ESCAP0
;**************************** 
; <A> - SEND ATTENTION CODE * 
;**************************** 
SNDCD1 EQU  $ 
       LDA  IODATA    ;GET ACCUMULATED VALUE
       MOV  B,A       ;PUT CODE INTO B-REGISTER 
       MVI  A,SNDATN  ;SET DATA COMM CONTROL CODE 
       JMP  DCMCTL    ;PERFORM FUNCTION 
 
;***********************************************
; STRTBL - SET FIRST DISPLAY OUT CHARACTER FOR *
;   BLOCK STORE                                *
;***********************************************
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  CURCOL,CURROW = STARTING POSITION
; 
;  IF THE AUTO TERMINATOR STRAP (J) IS OUT, A 
;  TERMINATOR IS PLACED AHEAD OF THE CURRENT
;  CURSOR POSITION AND A REVERSE SCAN IS MADE 
;  FOR THE FIRST TERMINATOR BEFORE THE CURRENT
;  CURSOR POSITION.  OTHERWISE, THE CURSOR IS 
;  PLACED AT THE HOME POSITION
; 
STRTBL EQU  $ 
       CALL STRTB1    ;SET CURSOR START POSITION
       JMP  INITDG    ;SET UP DISPLAY GET ROUTINE 
; 
STRTB1 EQU  $ 
       LDA  KBJMP2    ;GET KEYBOARD JUMPERS 2 
       ANI  AUTTRM    ;AUTO TERMINATOR ENABLED? 
       JZ   XMOHME    ;NO - HOME THE CURSOR 
;*******************************
; STTERM - SET AUTO TERMINATOR *
;*******************************
; 
;  EXIT :  Z => AUTO TERMINATOR NOT SET 
;          NZ => AUTO TERMINATOR SET
; 
STTERM EQU  $ 
       CALL CHKMLK    ;MEMORY LOCK ENABLED? 
       JZ   STB010    ;YES - CHECK FOR FREE BLOCKS
       CALL CHKFMT    ;FORMAT MODE ENABLED? 
       JZ   STB050    ;NO - ADD TERMINATOR
STB010 EQU  $         ;YES - CHECK FOR FREE BLOCKS
       LDA  FRBLKS    ;GET LSB OF FREE BLOCKS PTR 
       ORA  A         ;ANY FREE BLOCKS? 
       JZ   MLOCK     ;NO - FORCE MEMORY LOCK ON
 
;****************************************** 
; SPACE AVAILABLE - STORE NON-DISPLAYING  * 
;   TERMINATOR AT CURRENT CURSOR POSITION * 
;****************************************** 
STB050 EQU  $ 
       CALL SETTRM    ;STORE TERMINATOR 
       LDA  BLKTRM    ;GET BLOCK TERMINATOR CHAR
       MOV  L,A       ;SET PARAMETERS FOR REVERSE 
       MVI  H,STPFLG    ;SEARCH FOR PREV TERMINATO
       CALL BACKT1    ;IS THER A PREV TERMINATOR? 
       JNZ  STB080    ;NO - HOME THE CURSOR 
       CALL RCADRA    ;DOES THE CHARACTER EXIST?
       CNZ  CRLF      ;NO - START AT NEXT LINE
STB060 EQU  $ 
       MVI  A,377Q-NOSEND 
       CALL CLRDFL    ;CLEAR NO DATA FLAG 
       ORI  SKPTRM    ;SET TO SKIP INITIAL BLOCK
       MOV  M,A         ;TERMINATOR CHARACTER 
       RET            ;RETURN NZ
 
;*******************************************
; NO PREVIOUS TERMINATOR - HOME THE CURSOR *
;*******************************************
STB080 EQU  $ 
       LHLD CURROW    ;SAVE THE CURRENT ROW AND 
       PUSH H           ;COLUMN VALUES
       CALL DPSEN1    ;HOME CURSOR FOR TRANSMISSIO
       LHLD CURROW    ;GET NEW ROW AND COLUMN 
       POP  B         ;RECALL OLD ROW AND COLUMN
       MOV  A,H       ;COMPARE TO HOME ROW AND
       SUB  B           ;COLUMN 
       MOV  B,A 
       MOV  A,L 
       SUB  C 
       ORA  B         ;DID CURSOR MOVE? 
       JNZ  STB060    ;YES - SET FOR DATA PRESENT 
       MVI  A,NOSEND  ;NO - SET FOR NO DATA 
       JMP  SETDFL    ;RETURN 
 
;****************************** 
; XPUTDC - TRANSMIT CHARACTER * 
;****************************** 
; 
;  ENTRY:  A = CHARACTER TO BE TRANSMITTED
; 
;  EXIT :  NC - TRANSMIT SUCCESSFUL 
;          C - TRANSMIT FAILED
;          A DESTROYED
; 
ESCOUT EQU  $         ;OUTPUT AN ESCAPE CODE
       MVI  A,ESC 
       CALL XPUTDC
       MOV  A,B       ;FOLLOWED BY CHAR IN B-REG
; 
XPUTDC EQU  $ 
       ORA  A         ;SET C-FLAG FALSE 
       PUSH PSW       ;SAVE THE FLAGS AND A-REG 
       CALL CKRMTE    ;REMOTE MODE ENABLED? 
       JZ   XPD005    ;NO - EXIT
XPD001 EQU  $ 
       POP  PSW       ;YES - RECALL THE CHARACTER 
       PUSH PSW       ;SAVE CONTENTS OF A AND FLAG
       CALL ZPUTDC    ;TRANSMIT THE CHAR IN A-REG 
       JC   XPD050    ;ERROR - REPORT IT
       JNZ  XPD010    ;WAIT - TRY AGAIN 
XPD005 EQU  $ 
       POP  PSW       ;DONE - RECALL FLAGS AND CHA
       RET            ;RETURN 
;                       TRANSFER TRIGGER (SETS
;                       FLAG TRUE)
;*************************************
; WAIT FOR DATACOM - RETRY OPERATION *
;*************************************
XPD010 EQU  $ 
       PUSH H         ;SAVE THE REGISTERS 
       PUSH D 
       PUSH B 
       CALL IOCTMN    ;MONITOR CARTRIDGE TAPES
       MVI  A,CKBRKY  ;LOOK FOR A BREAK KEY HIT 
       CALL ZKBCTL    ;BREAK KEY HIT? 
       POP  B           ;(RESTORE REGISTERS)
       POP  D 
       POP  H 
       JZ   XPD001    ;NO - TRY TO OUTPUT AGAIN 
       CALL BRKDC     ;YES - BREAK DATA COMM
;                     FALL INTO ERROR EXIT ROUTINE
 
;****************************************** 
; DATA COMM ERROR DETECTED - REPORT ERROR * 
;****************************************** 
XPD050 EQU  $ 
       INX  SP        ;RESTORE STACK LEVEL WITHOUT
       INX  SP          ;AFFECTING THE FLAGS
       JNZ  HANGU0    ;FATAL - HANG THE TERMINAL
       CALL ZBELL     ;NON-FATAL - SOUND BELL 
       STC            ;RETURN FAIL (C-FLAG = TRUE)
       RET
 
;****************************************** 
; XMOHME - HOME CURSOR INCLUDING TRANSMIT * 
;   ONLY FIELDS                           * 
;****************************************** 
XMOHME EQU  $ 
       CALL SETDF0    ;SET DATA COMM INPUT FLAG 
;                       TO ENABLE TRANSMIT ONLY 
;                       FIELDS
       JMP  CURPH1    ;HOME THE CURSOR
 
;************************** 
;  R O M   B R E A K   3  * 
;************************** 
       ORG  ZBRK2+4000Q 
ZBRK3  EQU  $ 
       DB   VERSN     ;ROM PRESENT FLAGS
       DB   ZBRK3/256 
 
;*************************************
; BACKT1 - LOCATE PREVIOUS CHARACTER *
;*************************************
; 
;  ENTRY:  IODATA = CHARS TO FIND (2 BYTES) 
;          CURCOL,CURROW = CURRENT CURSOR POSITION
; 
;  EXIT :  Z - CHARACTER FOUND
;            DISPLAY AND CURSOR SET TO CHARACTER
;              POSITION IN DISPLAY MEMORY - ALL 
;              DISPLAY PARAMETERS UPDATED 
;          NZ - CHARACTER NOT FOUND 
;            DISPLAY UNCHANGED
;          ALL REGISTERS DESTROYED
; 
BACKT0 EQU  $         ;LOOK FOR PREVIOUS FIELD
       LXI  H,ENDPR*256+ENDPR 
BACKT1 EQU  $ 
       SHLD LCHKSM    ;SAVE CHARACTERS TO BE FOUND
       XRA  A         ;CLEAR ROLL COUNT 
       STA  ROLLCT
       LHLD CURROW  ;SAVE THE CURRENT STATE OF
       SHLD LDATA     ;THE DISPLAY
       LHLD LSTLIN
       SHLD LADDR 
       MVI  A,IGNTRM  ;SET TO IGNORE NON-DISPLAYIN
       STA  TRMFCT      ;TERMINATOR 
       CALL RCADR1    ;DOES THE CURRENT LINE EXITS
       LDA  LDATA+1     ;(RECALL CURRENT COLUMN)
       JP   BKT230    ;YES - SEARCH FOR PREV FIELD
       LDA  CURROW    ;NO - LOCATE LAST LINE
       LXI  H,MLKROW  ;CURRENT ROW LESS THAN
       CMP  M           ;MEMORY LOCK ROW? 
       JP   BKT300    ;NO - LOOK FOR UNLOCKED LINE
BKT210 EQU  $         ;YES - START FROM LAST LINE 
       CALL CURPHD
       LDA  LSTROW    ;FORCE TO LAST ALLOCATED
       STA  CURROW      ;ROW
 
;************************************ 
; LOCATE THE LAST FIELD IN THE LINE * 
;************************************ 
BKT220 EQU  $ 
       MVI  A,MAXCOL  ;SET SEARCH LIMIT 
BKT230 EQU  $ 
       STA  TMPCOL  ;SAVE THE SEARCH LIMIT
       LHLD LSTLIN  ;GET SEARCH START ADDRESS 
       XCHG           ;PUT ADDRESS IN D,E 
       LHLD LCHKSM    ;RECALL CHARS TO BE FOUND 
       CALL FNDLST    ;ANY FIELDS IN LINE?
       JP   BKT400    ;YES - SET DISPLAY TO FIELD 
       LDA  MLKROW    ;NO - SEE IF TOP UNLOCKED 
       LXI  H,CURROW    ;LINE HAS BEEN REACHED
       CMP  M         ;REACHED MEMORY LOCK ROW? 
       JZ   BKT310    ;YES - CONTINUE ABOVE DISPLA
       LDA  ROLLCT
       ORA  M         ;ROLL COUNT AND ROW = ZERO? 
       JZ   BKT500    ;YES - NO PREVIOUS FIELD IN 
;                       LOCKED AREA, RESTORE DISPL
       DCR  M         ;NO - MOVE TO PREVIOUS ROW
       MVI  L,ROLLCT
       MOV  A,M       ;GET ROLL COUNT 
       ORA  A         ;SEARCHING ABOVE DISPLAY? 
       JZ   BKT240    ;NO - DON'T INCREMENT COUNT 
       INR  M         ;ROLL OVERFLOW? 
       JZ   BKT500    ;YES - RESTORE DISPLAY
BKT240 EQU  $         ;NO - LOOK TO PREVIOUS LINE 
       LHLD LSTLIN  ;RECALL CURRENT LINE ADDR 
BKT250 EQU  $ 
       INX  H         ;GET ADDRESS OF PREVIOUS
       INX  H           ;LINE 
       CALL CHAIN     ;GET PREVIOUS LINE ADDRESS
       ORA  A         ;DOES PREVIOUS LINE EXIST?
       JZ   BKT500    ;NO - RESTORE DISPLAY 
       SHLD LSTLIN    ;YES - SAVE ADDRESS OF LINE 
       JMP  BKT220    ;LOCATE LAST FIELD IN LINE
 
; 
;  ROW NOT FOUND AND CURSOR BELOW MEMORY LOCK 
;    LINE - LOCATE LAST LINE TO START 
; 
BKT300 EQU  $ 
       SUB  E           ;(E = # OF ROWS TO LAST LN
       CMP  M         ;LAST ROW BELOW LOCKED AREA?
       JP   BKT210    ;YES - START AT LAST LINE 
       MOV  A,M       ;NO - SEARCH ABOVE DISPLAY
       STA  CURROW    ;SET "CURROW" TO MEM LOCK RO
       LXI  H,CURROW  ;SET H,L -> "CURROW"
; 
;  NO PREVIOUS FIELDS ON DISPLAY - LOOK ABOVE DISP
; 
BKT310 EQU  $ 
       DCR  M         ;DECREMENT ROW NUMBER 
       MVI  L,ROLLCT-BASE 
       INR  M         ;INCREMENT ROLL COUNT 
       LHLD TOPLIN  ;GET TOP DISPLAY LINE ADDR
       JMP  BKT250    ;LOOK FOR PREVIOUS ROW
 
; 
;  FIELD FOUND - SET DISPLAY
; 
BKT400 EQU  $ 
       LHLD LADDR     ;RESTORE VALUE OF LSTLIN
       XCHG             ;AND SAVE ADDRESS OF
       LHLD LSTLIN      ;LINE WHERE FIELD IS
       SHLD LADDR 
       XCHG 
       SHLD LSTLIN
       LDA  TMPCOL  ;COMPUTE COLUMN LOCATION
       SUB  B 
       STA  CURCOL
       LDA  ROLLCT
       ORA  A         ;ROW ABOVE DISPLAY? 
       JZ   BKT450    ;NO - EXIT
; 
;  ROW ABOVE DISPLAY ROLL IT DOWN 
; 
BKT410 EQU  $ 
       MVI  A,-MAXROW-1  ;COMPUTE NUMBER OF LINES 
       LXI  H,MLKROW  ;TO ROLL FOR ONE PAGE 
       ADD  M 
       STA  ROLLCT  ;SAVE ROLL COUNT
BKT420 EQU  $ 
       CALL ROLLDN    ;ROLL DOWN ONE LINE 
       JZ   BKT430    ;ROLL FAIL - CHECK FOR FIELD
       LXI  H,CURROW
       INR  M         ;INCREMENT ROW NUMBER 
       MVI  L,ROLLCT
       INR  M         ;PAGE COMPLETED?
       JNZ  BKT420    ;NO - CONTINUE ROLLING
       LDA  CURROW
       MVI  L,MLKROW
       SUB  M         ;IS DESIRED ROW ON SCREEN?
       JM   BKT410    ;NO - ROLL DOWN ANOTHER PAGE
       JMP  BKT450    ;YES - EXIT 
; 
;  ROLL FAILED - CHECK FOR FIELD ON SCREEN
; 
BKT430 EQU  $ 
       LDA  CURROW  ;GET CURRENT ROW NUMBER 
       LXI  H,MLKROW  ;SUBTRACT MEMRY LOCK RWS
       SUB  M         ;IS FIELD ON SCREEN?
       JM   BKT510    ;NO - RESTORE DISPLAY, ROLL 
;                       DOWN FAILED BECAUSE OF NO 
;                       MEMORY TO FILL TO MEMORY
;                       LOCK LINE 
 
; 
;  FIELD ON SCREEN - SET SCREEN VALUES
; 
BKT450 EQU  $ 
       LDA  CURROW  ;SET LAST ROW VALUE TO
       STA  LSTROW    ;ROW FOUND
       XRA  A         ;SET LAST COL DONE TO ZERO
       STA  LSTCOL
       LHLD LADDR     ;SET ADDRESSES TO LOCATION
BACKT5 EQU  $ 
       SHLD LSTLIN      ;OF FIELD 
       DCX  H         ;SET CURADR TO CORRESPOND 
       SHLD CURADR
       RET            ;RETURN 
; 
;  FIELD NOT FOUND - RESTORE DISPLAY
; 
BKT500 EQU  $ 
       LHLD LADDR  ;RESTORE LAST LINE ADDRESS 
       SHLD LSTLIN
BKT510 EQU  $ 
       LHLD LDATA  ;RESTORE CURRENT ROW AND 
       SHLD CURROW   ;COLUMN
       ORI  377Q      ;SET Z FALSE
       RET            ;RETURN NOT FOUND (NZ)
 
;*********************
;  BKTAB - BACK TAB  *
;*********************
BKTAB  EQU  $ 
       CALL CHKFM0    ;FORMAT/SOFT KEY DEFINE MODE
       JNZ  BACKT0    ;YES - LOCATE PREVIOUS FIELD
       LDA  CURCOL    ;NO - FIND PREVIOUS SET TAB 
       DCR  A         ;START AT PREVIOUS COLUMN 
       MVI  L,LFTMGN-BASE 
       CMP  M         ;WHERE IS CURSOR? 
       JZ   CURPO4    ;AT MARGIN - SET DISPLAY
       JP   BKT100    ;AFTER MARGIN - FIND PREV TA
; 
;  CURSOR AT BEGINNING OF LINE - LOCATE TAB IN
;    PREVIOUS LINE
; 
       LDA  MLKROW  ;GET MEMORY LOCK ROW
       MVI  L,CURROW
       CMP  M         ;CURRENT ROW = LOCK ROW?
       JNZ  BKT010    ;NO - MOVE CURSOR UP ONE ROW
       CALL ROLLDN    ;YES - ROLL DOWN ONE LINE 
       RZ             ;CAN'T ROLL DOWN - EXIT 
       JMP  BKT050    ;GO LOCATE LAST TAB SET 
; 
;  CURSOR NOT AT TOP OF FREE AREA - MOVE UP 1 LINE
; 
BKT010 EQU  $ 
       MOV  A,M       ;GET CURRENT ROW NUMBER 
       ORA  A         ;ROW = 0
       RZ             ;YES - DON'T BACK TAB WHEN
;                       CURSOR IS LOCATED IN ROW
;                       ZERO AND DISPLAY LOCK ON
       DCR  M         ;NO - DECREMENT ROW NUMBER
 
; 
;  PREVIOUS ROW LOCATED - LOCATE LAST TAB SET 
; 
BKT050 EQU  $ 
       LDA  HTBTBL+9  ;GET LAST TAB ENTRY 
       ANI  200Q      ;LAST TAB SET?
       MVI  A,MAXCOL    ;(SET FOR LAST COLUMN-1)
       JZ   BKT060    ;NO - LOCATE LAST TAB 
       INR  A         ;YES - SET FOR LAST COLUMN #
       MOV  C,A 
       MVI  L,RHTMGN-BASE 
       CMP  M         ;RIGHT MARGIN = LAST COLUMN?
       JZ   CURPO4    ;YES - SET CURSOR TO LAST CO
BKT060 EQU  $         ;NO - SET TO MAXCOL-1 AND 
       DCR  A           ;LOCATE PREVIOUS TAB
; 
;  LOCATE PREVIOUS TAB (A = CURRENT COLUMN - 1) 
; 
BKT100 EQU  $ 
       INR  A         ;RESTORE CURRENT COLUMN 
       MOV  B,A       ;SAVE IT
       ORI  7Q        ;SET TO COLUMN CORRESPOINDIN
;                       TO LAST BIT OF TAB BYTE 
       MVI  L,LFTMGN-BASE 
       SUB  M         ;COMPUTE NUMBER OF CHARS
       MOV  C,A         ;TO SEARCH
       MOV  A,B       ;RECALL CURRENT COLUMN
       CALL FNDTB1    ;GET BYTE MASK AND
;                       CORRESPONDING TABLE BYTE
       DCR  A         ;SET FOR MASK TO MASK OFF 
       ANA  M           ;SUCCEEDING TABS
; 
;  LOCATE PREVIOUS TAB SETTING
; 
BKT110 EQU  $ 
       MVI  B,8       ;INITIALIZE BIT COUNT 
BKT120 EQU  $ 
       RLC            ;TAB SET? 
       JNC  BKT150    ;NO - BACK UP ANOTHER COLUMN
; 
;  TAB LOCATED - SET CURSOR (C = TAB COLUMN)
; 
BKT130 EQU  $ 
       MOV  E,A       ;SAVE A-REGISTER
       MOV  A,C       ;PUT COLUMN NUMBER IN A-REG 
       PUSH H         ;SAVE H AND L 
       LHLD RHTMGN    ;GET MARGIN SETTINGS
       ADD  H         ;COMPUTE TAB COLUMN LOCATION
       INR  L         ;IS TAB LOCATION BEYOND LEFT
       CMP  L           ;MARGIN?
       POP  H           ;(RESTORE H AND L)
       JM   CURPO4    ;NO - LOCATE TAB AND RETURN 
       MOV  A,E       ;YES - RECALL A-REGISTER
 
;****************************** 
; CONTINUE SCANNING BACKWARDS * 
;****************************** 
BKT150 EQU  $ 
       DCR  C         ;COLUMN ZERO REACHED? 
       JZ   BKT130    ;YES - SET CURSOR COLUMN
       DCR  B         ;BYTE DONE? 
       JNZ  BKT120    ;NO - CONTINUE TO NEXT COLUM
       DCX  H         ;YES - GET NEXT BYTE
       MOV  A,M 
       JMP  BKT110    ;CHECK BYTE FOR TAB SET 
 
;*****************************************
; CHAIN - SET H,L TO POINTER FROM MEMORY *
;*****************************************
; 
;  ENTRY:  H,L = ADDRESS OF POINTER 
; 
;  EXIT :  A = LSB OF POINTER 
;          H,L = POINTER VALUE
; 
CHAIN0 EQU  $ 
       XCHG           ;PUT ADDRESS INTO H,L 
CHAIN1 EQU  $ 
       MOV  A,L       ;COMPUTE LOCATION OF NEXT 
       ANI  377Q-BLKSM  ;BLOCK POINTER IN BLOCK 
       MOV  L,A       ;GET THE NEXT BLOCK ADDRESS 
CHAIN  EQU  $ 
       MOV  A,M       ;GET LSB OF POINTER 
       INX  H 
       MOV  H,M       ;PUT MSB INTO H-REGISTER
       MOV  L,A       ;PUT LSB INTO L-REGISTER
NOFNCT EQU  $           ;(NON-FUNCTION FOR ESC SEQ
       RET            ;RETURN 
 
;*************************************************
; CHKFMS - CHECK FORMAT AND SOFT KEY DEFINE MODE *
;*************************************************
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  Z - NEITHER MODE ENABLED 
;            A = 0
;          NZ - MODE ENABLED
;            A = -1, SOFT KEY MODE ENABLED
;            A >  0, FORMAT MODE ONLY ENABLED 
; 
CHKFM0 EQU  $ 
       MVI  L,SPOWL   ;TURN OF SPOW LATCH FIRST 
       MVI  M,SPOWOF
CHKFMS EQU $
       LDA  DSPTYP    ;GET DISPLAY TYPE FLAG
       ORA  A         ;SOFT KEY DISPLAY ON? 
       RNZ            ;YES - RETURN 
CHKFMT EQU  $ 
       LDA  MDFLG1    ;NO - GET MODE FLAGS
       ANI  FORMAT    ;MASK FOR FORMAT FLAG AND 
       RET              ;RETURN 
 
;*****************************************
; CHKMLK - CHECK FOR MEMORY LOCK ENABLED *
;*****************************************
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  Z => MEMORY LOCK ENABLED 
;          NZ => MEMORY LOCK NOT ENABLED
;          A,H,L DESTROYED
; 
CHKMLK EQU  $ 
       LDA  MDFLG1    ;GET SOFT MODE FLAGS
       CMA            ;MEMORY LOCK ENABLED FOR FUL
       ANI  MEMLOK      ;LOCKOUT IF MEMORY LOCK SE
       LXI  H,MLKROW    ;AND MEMORY LOCK ROW = 0
       ORA  M 
       RET            ;RETURN 
;***********************************
; CHKSFK - CHECK FOR SOFT KEY MODE *
;***********************************
; 
;  EXIT :  Z - NORMAL MODE
;            A = 0
;          NZ - SOFT KEY DEFINE MODE
;            A DESTROYED
; 
CHKSFK EQU  $ 
       LDA  DSPTYP    ;GET DISPLAY TYPE FLAG
       ORA  A         ;SET Z FALSE IF SOFT KEY
       RET              ;ON AND RETURN
 
;************************ 
; CD - CHARACTER DELETE * 
;************************ 
DELWRP EQU  $         ;DELETE WITH WRAP AROUND
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       MVI  A,WRPDEL    ;(PUT WRAP FLAG IN A-REG) 
       CZ   SETMF2    ;NO - SET WRAP AROUND FLAG
; 
CHRDEL EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       JZ   CHD010    ;NO - DO DELETE 
       LDA  CURROW    ;YES - GET CURSOR ROW 
       RRC            ;IN DATA LINE?
       RNC            ;NO - RETURN
CHD010 EQU  $         ;YES - DO DELETE
       XRA  A         ;ZERO SAVE AREA 
       STA  CHSAV 
       CALL CHD000    ;DELETE A CHARACTER 
       LDA  CHSAV     ;RECALL THE DELETED CHARACTE
       ORA  A         ;WAS IT A DISPLAY CONTROL?
       JM   CHRDEL    ;YES - CONTINUE DELETING
;******************************************** 
; ADJUST FOR CHARACTERS BEYOND RIGHT MARGIN * 
;******************************************** 
       LXI  H,CURCOL
       LDA  RHTMGN
       CMP  M         ;CURSOR BEYOND RIGHT MARGIN?
       RC             ;YES - DON'T CHECK WRAP 
       MOV  B,M       ;NO - SAVE CURRENT COLUMN 
       MOV  M,A       ;SET COLUMN TO RIGHT MARGIN 
       MOV  D,A       ;SAVE RIGHT MARGIN VALUE
       MVI  L,MDFLG1-BASE 
       MOV  C,M       ;SAVE SOFT MODE FLAGS STATE 
       PUSH B           ;AND CURRENT COLUMN 
       MOV  A,C       ;FORCE THE INSERT CHARACTER 
       ANI  377Q-INSCHR  ;MODE OFF
       MOV  M,A 
 
;*******************************************
; DELETE PERFORMED - CHECK FOR WRAP AROUND *
;*******************************************
       LXI  H,MFLGS2  ;GET TERMINAL MODE FLAGS
       MOV  A,M       ;MASK OUT DELETE WRAP FLAG
       ANI  377Q-WRPDEL 
       CMP  M         ;DELETE WRAP AROUND ENABLED?
       JZ   CHD050    ;NO - EXIT
       MOV  M,A       ;YES - UPDATE MODE FLAGS
;******************************************** 
; TRANSFER A CHRACTER UP FROM THE NEXT LINE * 
;******************************************** 
CHD020 EQU  $ 
       MVI  A,ABLNK   ;PRESET DELETED CHARACTER 
       STA  CHSAV       ;TO A BLANK 
       LXI  H,CURROW  ;SET TO DELETE FIRST
       INR  M           ;CHARACTER AT LEFT MARGIN 
       INX  H           ;FROM NEXT ROW
       LDA  LFTMGN
       MOV  M,A 
       CALL RCADR4    ;CHARACTER EXIST? 
       CZ   CHRDL1    ;YES - DELETE IT
       LXI  H,CURROW  ;RESTORE ROW NUMBER AND SET 
       DCR  M           ;COLUMN TO RIGHT MARGIN 
       INX  H 
       LDA  RHTMGN
       MOV  M,A 
       LDA  CHSAV     ;GET THE DELETED CHARACTER
       CPI  ABLNK     ;BLANK CHARACTER DELETED? 
       JZ   CHD050    ;YES - EXIT 
       MVI  B,0       ;NO - SET TO FORCE ENHANCE
       CALL DISPC2    ;DISPLAY THE CHARACTER
       LDA  CHSAV     ;RECALL THE DELETED CHARACTE
       ORA  A         ;WAS IT ASCII?
       JM   CHD020    ;NO - TRANSFER ANOTHER BYTE 
;******************************************** 
; EXIT - RESTORE CURSOR COLUMN AND "MDFLG1" * 
;******************************************** 
CHD050 EQU  $ 
       POP  B         ;RECALL ORIGINAL VALUES 
       LXI  H,CURCOL
       MOV  M,B       ;RESTORE CURSOR COLUMN
       MVI  L,MDFLG1-BASE 
       MOV  M,C       ;RESTORE "MDFLG1" 
       RET            ;RETURN 
 
CHD000 EQU $
       CALL RCADR4    ;DOES CHARACTER EXIST?
       RNZ            ;NO - RETURN
       CALL CHD500    ;SKIP OVER SINGLE DISPLAY 
;                       ENHANCEMENT CODE
       CALL CHKFMT    ;FORMAT MODE? 
       JZ   CHD100    ;NO - DELETE THE CHARACTER
       INR  B         ;CURSOR IN PROTECTED FIELD? 
       RZ             ;YES - RETURN 
;******************************** 
; CHRDL1 - DELETE ONE CHARACTER * 
;******************************** 
; 
;  ENTRY:  C = CHARACTER COLUMN POSITION
;          D,E = ADDRESS OF CHAR TO BE DELETED
; 
;  EXIT :  ALL REGISTERS DESTROYED
;          CHSAV = CHARACTER DELETED (UNCHANGED 
;            IF A CHARACTER HAS NOT BEEN DELETED) 
; 
CHRDL1 EQU  $ 
CHD100 EQU  $ 
       LDAX D         ;GET CHARACTER TO BE DELETED
       CPI EOL      ;IS IT EOL? 
       RZ           ;YES - RETURN 
       STA  CHSAV     ;SAVE THE DELETED CHARACTER 
       MOV  H,D       ;H,L = ADDR OF CHAR TO FILL 
       MOV  L,E       ;D,E = ADDR OF CHAR TO MOVE 
;******************************************** 
; MOVE CHARACTERS DOWN TO PREVIOUS POSITION * 
;******************************************** 
CHD110 EQU  $ 
       CALL NXTCHR    ;GET THE NEXT CHARACTER 
       JNZ  CHD210    ;EOL LINK - TERMINATE DELETE
       MOV  B,A       ;SAVE CHARACTER IN B-REGISTE
       CPI  ENHLIM+1  ;ASCII OR ENHANCEMENT CODE? 
       JC   CHD120    ;YES - SEE IF PAST MARGIN 
;*********************************************
; FORMAT CONTROL CODE FOUND - CHECK FUNCTION *
;*********************************************
       CPI  EOL       ;END OF LINE? 
       JZ   CHD250    ;YES - TERMINATE DELETE 
       CPI  FILL      ;END OF LINE FILL?
       JZ   CHD200    ;YES - TERMINATE DELETE 
       CALL CHD400    ;FORMAT MODE & DELETE ASCII?
       JZ   CHD120    ;NO - MOVE NEW CHARACTER
       MOV  A,B       ;YES - GET CHAR TO BE MOVED 
       CPI  STPR      ;IS IT START PROTECT? 
       JZ   CLER02    ;YES - CLEAR REST OF FIELD
;                       AND TERMINATE DELETE
       CPI  ALPHA     ;TYPE DEFINITION? 
       JP   CHD110    ;YES - SKIP OVER CHARACTER
 
;***************************************
; CHARACTER TO BE MOVED - CHECK MARGIN *
;***************************************
CHD120 EQU  $ 
       LDA  RHTMGN
       CMP  C         ;CHAR FROM BEYOND MARGIN? 
       JNZ  CHD130    ;NO - CONTINUE DELETE 
       LDA  CHSAV     ;YES - GET DELETED CHARACTER
       ORA  A         ;IS IT ASCII? 
       MVI  M,ABLNK     ;(SET BLANK BY DEFAULT) 
       RP             ;YES - TERMINATE DELETE 
;                     NO - PUT CHAR INTO PREV CHAR
;*************************************************
; MOVE CHARACTER INTO PREVIOUS CHARACTER POSITON *
;*************************************************
CHD130 EQU  $ 
       MOV  M,B       ;REPLACE PREVIOUS CHARACTER 
       MOV  A,B 
       ORA  A         ;IS CHARACTER ASCII?
       JM   CHD140    ;NO - ADVANCE TO NEXT CHAR
       INR  C         ;YES - INCREMENT COLUMN # 
CHD140 EQU  $ 
       CALL NXTCH0    ;GET THE NEXT CHARACTER 
       CPI  ALPHA     ;TYPE DEFINITION? 
       JC   CHD150    ;NO - CONTINUE MOVING CHARS 
       CALL CHD400    ;FORMAT MODE & DELETE ASCII?
       CNZ  NXTCHR    ;YES - ADVANCE TO NEXT CHAR 
CHD150 EQU  $ 
       XCHG           ;RESTORE REGISTER POSITIONS 
       JMP  CHD110    ;MOVE NEXT CHARACTER
 
;***********************************************
; END OF LINE FILL CHARACTER FOUND - CLEAR THE *
;   REST OF THE LINE                           *
;***********************************************
CHD200 EQU  $ 
       CALL CHAIN0    ;GET END OF LINE LINK IN H,L
       XCHG           ;EXCHANGE H,L AND D,E 
;*********************************************
; END OF LINE LINK FOUND - CLEAR THE REST OF *
;   THE LINE                                 *
;*********************************************
CHD210 EQU  $ 
       CALL CHD400    ;FORMAT MODE & DELETE ASCII?
       XCHG             ;(SET D,E TO LAST CHAR ADD
       DCX  H            ;H,L TO LSB OF NEXT LINE 
;                        LINK)
       JNZ  CHD260    ;YES - CLEAR REST OF FIELD
;                       TO LSB OF NEXT LINE LINK
       LDA  CHSAV     ;RECALL DELETED CHARACTER 
       ORA  A         ;WAS IT ASCII?
       JP   CHD260    ;YES - END LINE WITH EOL
       MVI  A,FILL    ;NO - END LINE WITH FILL
       JMP  CLERL1    ;CLEAR REST OF LINE 
 
;*****************************************
; EOL FOUND - CLEAR THE REST OF THE LINE *
;*****************************************
CHD250 EQU  $ 
       CALL CHAIN0    ;GET EOL LINK IN H,L
       DCX  H         ;SET TO LSB OF NEXT LINE LIN
CHD260 EQU  $         ;CLEAR THE REST OF THE LINE 
       MVI  A,EOL       ;TERMINATING WITH AN EOL
       JMP  CLERL1
;*********************************************
; CHD400 - CHECK FOR FORMAT MODE ENABLED AND *
;   DISPLAYABLE ASCII CHARACTER DELETED      *
;*********************************************
; 
;  EXIT :  NZ - FORMAT MODE AND DELETE ASCII
;          Z - NOT FORMAT MODE OR NON-DISPLAY 
;            CODE DELETED 
; 
CHD400 EQU  $ 
       LDA  CHSAV     ;GET CHARACTER DELETED
       ORA  A         ;IS IT DISPAYABLE ASCII 
       JP   CHKFMT    ;YES - CHECK FOR FORMAT MODE
       XRA  A         ;NO - RETURN Z
       RET
 
;***********************************************
; CHD500 - CHECK FOR DISPLAY EHANCEMENT DELETE *
;***********************************************
; 
;  ENTRY:  D,E = CHARACTER TO BE DELETED
; 
;  EXIT :  D,E = ACTUAL CHARACTER TO DELETE 
;          A,L DESTROYED
; 
CHD500 EQU  $ 
       LDAX D         ;GET CHARACTER TO BE DELETED
       ADD  A         ;DISPLAY ENHANCEMENT CODE?
       RNC            ;ASCII - LET IT BE DELETED
       RM             ;FORMAT CONTROL - DELETE IT 
       MVI  L,2       ;YES - LOOK FOR POSSIBLE
       PUSH D           ;DOUBLE EHANCEMENT CODE 
CHD510 EQU  $ 
       CALL NXTCHR    ;GET THE NEXT CHARACTER 
       JNZ  CHD515    ;EXIT IF EOL LINK 
       ADD  A         ;ENHANCEMENT CODE?
       JNC  CHD520    ;ASCII - CHECK FOR SCAN DONE
       JM   CHD510    ;FORMAT CONTROL - CONTINUE
CHD515 EQU  $ 
       POP  D         ;YES - DELETE ENHANCEMENT 
       RET
;********************************************** 
; ASCII CHARACTER FOUND - CHECK FOR SCAN DONE * 
;********************************************** 
CHD520 EQU  $ 
       DCR  L         ;NEXT ASCII CHARACTER FOUND?
       JNZ  CHD510    ;NO - CONTINUE SCAN 
;*******************************************
; NEXT ASCII CHARACTER OR EOL LINK FOUND - *
;   DON'T DELETE DISPLAY ENHANCEMENT CODE  *
;*******************************************
       POP  D         ;RECALL ORIGINAL ADDRESS
       JMP  NXTCHR    ;SET TO DELETE NEXT CHAR
 
;******************************************** 
; CHRDL2 - DELETE CHARACTER W/REGISTER SAVE * 
;******************************************** 
; 
;  ENTRY:  C = CHARACTER COLUMN POSITION
;          D,E = ADDRESS OF CHAR TO BE DELETED
; 
;  EXIT :  B,C = B,C(ENTRY) 
;          D,E = D,E(ENTRY) + 1 
;          A,H,L DESTROYED
; 
CHRDL2 EQU  $ 
       PUSH B         ;SAVE REGISTERS B,C 
       PUSH D           ;AND D,E
       CALL CHRDL1    ;DELETE THE CHARACTER 
       POP  D         ;RESTORE REGISTER D,E 
       POP  B           ;AND B,C
       INX  D         ;INCREMENT D,E
       RET            ;RETURN 
 
;**************************** 
; CHRINS - INSERT CHARACTER * 
;**************************** 
; 
;  ENTRY:  A = CHARACTER TO BE INSERTED 
;          CURROW,CURCOL = DISPLAY POSITION WHERE 
;            INSERT IS TO BE DONE 
; 
;  EXIT :  A = 0, INSERT NOT DONE 
;          A # 0, INSERT PERFORMED
;          DCHAR DESTROYED
;          B-L DESTROYED
; 
;  CHARACTER IS INSERTED IMMEDIATELY AHEAD OF THE 
;  CHARACTERS LOCATED AT THE SPECIFIED ROW AND
;  COLUMN POSITIONS 
; 
CHRINS EQU  $ 
       STA  DCHAR     ;SAVE CHAR TO BE INSERTED 
       MVI  A,377Q    ;INHIBIT LINE EXTENSION 
       STA  BLKFIL
       CALL RCADR4    ;DOES DISPLAY POSITION EXIST
       JNZ  DISPLA    ;NO - TRY TO EXTEND LINE
;                     YES - INSERT THE CHARACTER
 
;***********************************************
; CRI100 - ENTRY TO STORE CHARACTER FOR INSERT *
;   CHARACTER MODE                             *
;***********************************************
; 
;  ENTRY:  C = COLUMN NUMBER
;          D,E = ADDR WHERE INSERT IS TO BE MADE
;          H = BASEH
; 
CRI100 EQU  $ 
       CALL CKPROT    ;CURSOR IN PROTECTED FIELD? 
       JZ   DIS092    ;YES - TAB TO NEXT FIELD
CRI104 EQU $
       MVI  L,DCHAR-BASE
       MOV  B,M       ;GET CHAR TO BE INSERTED
       XCHG           ;PUT CHAR ADDRESS INTO H,L
CRI110 EQU $
       MOV A,B      ;IS THIS CONTROL CODE?
       ORA A
       JM   CRI120    ;YES - DON'T COUNT COLUMN 
       INR C        ;INCREMENT COLUMN 
CRI120 EQU $
       MOV A,M      ;GET CHAR IN CURRENT ADDR 
       MOV M,B      ;STORE NEW CHAR 
       MOV B,A      ;SAVE OLD CHAR IN B 
       DCX  H         ;MOVE TO NEXT CHARACTER 
       MVI  A,MAXCOL+1
       CMP  C         ;STORE DONE AT END OF LINE? 
       JZ   CRI305    ;YES - TERMINATE INSERT 
       LDA  RHTMGN    ;GET RIGHT MARGIN COLUMN
       INR  A         ;WAS THE LAST STORE DONE
       CMP  C           ;AT THE RIGHT MARGIN? 
       JZ   CRI300    ;YES - TERMINATE INSERT 
 
;********************************** 
; PROCESS NEXT CHARACTER OF BLOCK * 
;********************************** 
CRI140 EQU  $ 
       MOV  A,M       ;GET THE NEXT CHARACTER 
       CPI  ENHLIM+1  ;ASCII OR DISPLAY CONTROL?
       JC   CRI110    ;YES - MOVE THE BYTE
       CPI  LNKLIM    ;IS IT A LINK BYTE? 
       JNC CRI200   ;YES - MOVE TO NEXT BLOCK 
       CPI EOL      ;IS IT END OF LINE? 
       JZ   CRI158    ;YES - ADD LAST CHAR TO LINE
       CPI  FILL      ;END OF LINE FILL CHARACTER?
       JZ   CRI159    ;YES - ADD BYTE TO END
       LDA  DCHAR     ;NO - FIELD CHECK CHARACTER 
       ORA  A         ;IS ADDED CHARACTER ASCII?
       JM   CRI110    ;NO - CONTINUE INSERT MOVE
       CALL CHKFMS    ;FORMAT MODE ENABLED? 
       JZ   CRI110    ;NO - CONTINUE INSERT 
       MOV  A,M       ;YES - RECALL THE BYTE
       CPI  STPR      ;IS CHARACTER A START PROT? 
       JZ   CRI150    ;YES - CHECK INSERT TYPE
       CPI  ALPHA     ;FIELD TYPE DEFINITION? 
       JM   CRI110    ;NO - CONTINUE INSERT 
       DCX  H         ;YES - ADVANCE TO NEXT BYTE 
       JMP  CRI140    ;LOOK TO NEXT CHARACTER 
 
;*************************************
; END OF FIELD - ASCII CODE INSERTED *
;*************************************
CRI150 EQU  $ 
       MOV  A,B       ;GET CHAR WHICH ROLLED OFF
       ORA  A         ;IS IT ASCII? 
       JP   CRI154    ;YES - DELETE PREV CONTROLS 
CRI152 EQU  $         ;NO - BACK UP ANOTHER CHAR
       CALL CRI500    ;IS PREVIOUS CHARACTER ASCII
       JM   CRI152    ;NO - CONTINUE BACKING UP 
       MVI  M,200Q    ;YES - TEMPORARILY REPLACE
;                       ASCII WITH DUMMY CONTROL
CRI154 EQU  $ 
       CALL CRI500    ;PREVIOUS CHARACTER ASCII?
       JM   CRI154    ;N0 - CONTINUE BACKING UP 
       DCX  H         ;MOVE TO NEXT CHARACTER 
       JMP  CLER02    ;CLEAR REST OF FIELD
 
;*****************************
; EOL FOUND                  *
; ADD LAST CHARACTER TO LINE *
;*****************************
CRI158 EQU $
       MOV A,B      ;GET CHARACTER
       ORA A        ;IS THIS CONTROL CHAR?
       JM  CRI160   ;YES - ADD CHAR 
       MOV A,C      ;NO - CHAR IS ASCII 
       CPI MAXCOL   ;IS THIS MAX COLUMN?
       JNZ CRI170   ;NO - ADD CHAR
CRI159 EQU $
       MOV  M,B       ;ASCII CHARACTER INSERTED TO
       ORA  A           ;MAXIMUM COLUMN - OVERLAY 
       RET              ;EOL AND RETURN NZ
;************************** 
; EOL CANNOT BE OVERLAYED * 
; ADD NEW CHAR TO LINE    * 
;************************** 
CRI160 EQU $
       DCR C
CRI170 EQU $
       XCHG           ;PUT H,L INTO D,E 
CRI180 EQU $
       LXI  H,DCHAR   ;SAVE CHARACTER TO BE ADDED 
       MOV  M,B 
       MVI  L,CURCOL-BASE 
       MOV  B,M       ;GET CURRENT CURSOR COLUMN
       PUSH B           ;AND SAVE IT
       MOV  M,C       ;SET "CURCOL" TO INSERT COL 
       MVI  C,0       ;SET # OF CHARS NEEDED TO 1 
;                       (VALUE IN C IS ONE LESS)
       CALL DISPL1    ;BUILD NECESSARY BLOCKS 
       POP  B         ;RESTORE ORIGINAL CURSOR
       LXI  H,CURCOL    ;COLUMN NUMBER
       MOV  M,B 
       RET          ;RETURN (A=MEMORY LOCK STATE) 
 
;********************************** 
; LINK FOUND - MOVE TO NEXT BLOCK * 
;********************************** 
CRI200 EQU  $ 
       SHLD LNKSAV    ;SAVE CURRENT BLOCK ADDRESS 
       DCX  H         ;GET THE LSB OF THE LINK
       MOV  A,M 
       CMA            ;IS IT AN EOL LINK (LOWER 
       ANI  BLKSM       ;FOUR BITS NOT ALL ONES)? 
       JNZ  CRI240    ;YES - EXTEND THE LINE
       CALL CHAIN     ;NO - GET NEXT BLOCK ADDRESS
       JMP  CRI140    ;CONTINUE INSERT CHARACTER
;*********************
; NEW BLOCK REQUIRED *
;*********************
CRI240 EQU $
       MOV  A,B       ;SAVE CHARACTER BEING MOVED 
       STA  TEMP
       INX  H         ;GET THE LAST CHARACTER OF
       INX  H           ;THE CURRENT BLOCK TO BE
       MOV  B,M         ;STORED AGAIN IN THE SAME 
       XCHG             ;LOCATION BY "DISPL1" 
       DCR  C         ;GET COLUMN # OF PREV CHAR
       CALL CRI180  ;ADD BLOCK
       ORA A        ;IS MEMORY LOCKED?
       JZ  CRI260   ;YES - BLOCK NOT ADDED
       LDA  TEMP      ;NO - RECALL CHAR TO BE ADDE
       STAX D         ;PUT CHARACTER IN NEW BLOCK 
;                       (OVERWRITE EOL) 
       RET            ;RETURN 
;*********************************
; BLOCK NOT AVAILABLE            *
; WRITE EOL AT END OF LAST BLOCK *
;*********************************
CRI260 EQU $
       LHLD EOLADR  ;GET ADR OF CHR BEFORE LNK
       MVI M,EOL    ;WRITE EOL
       RET          ;RETURN 
 
;*******************************************
; RIGHT MARGIN OR END OF LINE REACHED -    *
; TERMINATE AND OPTIONALLY PUSH CHARACTERS *
; TO THE NEXT LINE (WRAP AROUND)           *
;*******************************************
CRI300 EQU  $ 
       LDA  DCHAR     ;GET THE INSERTED CHARACTER 
       ORA  A         ;IS IT ASCII? 
       JM   CRI140    ;NO - CONTINUE INSERTING
       MOV  A,C       ;YES - RECALL ENDING COLUMN 
CRI305 EQU  $ 
       STA  PARM5     ;SAVE ENDING COLUMN NUMBER
       SHLD LNKSAV    ;SAVE ENDING CHARACTER ADDR 
       XCHG           ;PUT ENDING ADDRESS IN D,E
       CALL INITD1    ;INIT CHAR BUFFER POINTERS
       INX  D         ;GET ADDRESS OF NEXT EXCESS 
       CALL NXTCHR      ;CHARACTER
       XCHG 
       SHLD PARM6     ;ARE WE AT AN EOL LINK? 
       MOV  A,B         ;(PUT 1ST EXCESS CHAR IN A
       JZ   CRI320    ;NO - ACCUMULATE EXCESS 
       CALL A2OUTB    ;YES - SAVE FIRST EXCESS CHA
       ORA  A         ;IS IT ASCII? 
       JP   CRI330    ;YES - CHECK FOR INSERT WRAP
       RET            ;NO - RETURN
; 
; ACCUMULATE THE EXCESS CHARACTERS
; 
CRI310 EQU  $ 
       LHLD PARM6     ;RECALL EXCESS CHAR ADDRESS 
       XCHG           ;PUT ADDRESS INTO D,E 
       MVI  A,-1      ;SET DELETED CHAR TO -1 
       STA  CHSAV 
       MVI  C,MAXCOL+1  ;FORCE DELETE PAST MARGIN 
       CALL CHRDL1    ;DELETE ONE EXCESS CHARACTER
       LDA  CHSAV     ;RECALL THE DELETED CHARACTE
       MOV  B,A       ;SAVE THE CHARACTER IN B-REG
       INR  B         ;ANY CHARACTER DELETED? 
       RZ             ;NO - RETURN (A#0)
CRI320 EQU  $         ;YES - ACCUMULATE EXCESS
       CALL A2OUTB    ;PUT DELETED CHAR INTO BUFFE
       ORA  A         ;WAS DELETED CHARACTER ASCII
       JM   CRI310    ;NO - CONTINUE ACCUMULATING 
       LDA  PARM5     ;RECALL ENDING COLUMN NUMBER
       CPI  MAXCOL+1  ;TERMINATE ON LAST COLUMN?
       LHLD LNKSAV      ;(RECALL ENDING CHAR ADDR)
       XCHG 
       MVI  A,FILL      ;(SET FOR FILL PAD) 
       CZ   CLERL0    ;YES - CLEAR REST OF LINE 
 
; 
; EXCESS CHARACTERS ACCUMULATED - CHECK FOR WRAP
; 
CRI330 EQU  $ 
       LDA  CMFLGS    ;GET THE COMMON FLAGS 
       CMA            ;COMPLEMENT FLAGS 
       ANI  INSWRP    ;WRAP AROUND ENABLED? 
       RNZ            ;NO - RETURN (A#0)
       LDA  CURCOL    ;YES - GET THE CURRENT COLUM
       MOV  B,A       ;SAVE VALUE IN B-REGISTER 
       LDA  RHTMGN
       CMP  B         ;CURSOR BEYOND RIGHT MARGIN?
       RC             ;YES - RETURN 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       RNZ            ;YES - RETURN 
       PUSH B         ;NO - SAVE CURRENT COLUMN AN
       LXI  H,CURROW  ;INCREMENT TO NEXT ROW
       INR  M 
       LHLD LSTLIN    ;CHECK TO SEE IF NEXT LINE
       MOV  E,M         ;IS FULL (I.E., NO "EOL"
       INX  H           ;BEFORE RIGHT MARGIN) 
       MOV  D,M 
       INR  E         ;DOES NEXT LINE EXIST?
       DCR  E           ;(LSB # 0)? 
       JZ   CRI400    ;NO - ADD CHAR TO NEW LINE
       INX  D         ;YES - START FROM BEGINNING 
       LDA  RHTMGN      ;OF LINE TO RIGHT MARGIN
       CALL FNDLS0    ;NEXT LINE FULL?
       JP   CRI400    ;NO - ADD OVERFLOW CHARACTER
;                       TO NEXT LINE
       CALL LININS    ;YES - INSERT A LINE
       JZ   CRI450    ;EXIT IF MEMORY LOCKED
 
; 
;  INSERT CHARACTERS INTO NEXT LINE 
; 
CRI400 EQU  $ 
       LXI  H,B2DEND  ;GET BUFFER POINTER 
       MOV  A,M 
       CPI  B2DBFL-1  ;ALL BYTES DONE?
       JZ   CRI450    ;YES - EXIT 
       DCR  M         ;NO - UPDATE BUFFER POINTER 
       MOV  L,A       ;PUT LSB INTO L 
       LDA  LFTMGN    ;SET TO INSERT CHARACTER AT 
       STA  CURCOL      ;LEFT MARGIN
       MOV  A,M       ;GET CHARACTER TO INSERT
       CALL CHRINS    ;INSERT CHARACTER 
       ORA  A         ;INSERT SUCCESSFUL? 
       JNZ  CRI400    ;YES - DO NEXT BYTE 
; 
;  ALL CHARACTERS INSERTED - EXIT 
; 
CRI450 EQU  $ 
       LXI  H,CURROW
       DCR  M         ;RESTORE THE ROW NUMBER 
       POP  PSW       ;RECALL THE COLUMN NUMBER 
       INX  H 
       MOV  M,A       ;RESTORE COLUMN NUMBER
       INR  A         ;FORCE A # 0
       RET            ;RETURN 
 
;********************************** 
; CRI500 - GET PREVIOUS CHARACTER * 
;********************************** 
; 
;  ENTRY:  H,L = CURRENT CHARACTER ADDRESS
;          LNKSAV = ADDRESS OF MSB PART OF NEXT 
;            BLOCK LINK IN PREVIOUS BLOCK 
; 
;  EXIT :  A = PREVIOUS CHARACTER 
;          H,L = ADDRESS OF PREVIOUS CHARACTER
;          P - CHARACTER IS ASCII 
;          M - CHARACTER IS NON-DISPLAY CONTROL 
; 
CRI500 EQU  $ 
       INX  H         ;MOVE TO PREVIOUS CHARACTER 
       MOV  A,L         ;IN BLOCK 
       ANI  BLKSM     ;PREVIOUS CHARACTER IN BLOCK
       JNZ  CRI510    ;YES - GET IT 
       LHLD LNKSAV    ;NO - GET PREV BLOCK ADDRESS
       INX  H         ;SET TO LAST CHARACTER ADDR 
CRI510 EQU  $ 
       MOV  A,M       ;GET THE PREVIOUS CHARACTER 
       ORA  A         ;SET FLAGS FOR ASCII OR NOT 
       RET              ;ASCII AND RETURN 
 
;********************** 
; CLEARL - CLEAR LINE * 
;********************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  A = -1, ROW NOT FOUND
;            =  0, CHARACTER FOUND AND CLEAR DONE 
;            >  0, COLUMN PAST EOL, CLEAR NOT DONE
; 
CLEARL EQU  $ 
       CALL RCADR4    ;DOES ROW EXIST?
       RNZ            ;NO - RETURN
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JZ   CLERLA    ;NO - DO NORMAL CLEAR LINE
       JP   CLL400    ;FORMAT MODE - CLEAR FIELD
;********************************************** 
; SOFT KEY DEFINE MODE - CLEAR DATA ROWS ONLY * 
;********************************************** 
       LDA  CURROW    ;GET CURSOR ROW 
       RRC            ;IN DATA LINE (ODD ROW #)?
       RNC            ;NO - INHIBIT CLEAR 
       LDAX D         ;GET FIRST CHARACTER
       CPI  ENDPR     ;END PROTECT? 
       CZ   NXTCHR    ;YES - SKIP TO 1ST ASCII CHA
CLERLA EQU  $ 
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       MVI  A,SETFRN    ;(SET CONTROL CODE) 
       CZ   ZKBCTL    ;NO - UPDATE FOREIGN MODE 
       MVI  A,EOL     ;CLEAR LINE WITH "EOL" ENDIN
 
;****************************** 
; CLERL0 - CLEAR REST OF LINE * 
;****************************** 
; 
;  ENTRY:  A = TERMINATOR CHARACTER 
;          D,E = CLEAR STARTING ADDRESS 
; 
;  EXIT :  SEE "CLEARL" 
; 
CLERL0 EQU  $ 
       LHLD LSTLIN    ;GET CURRENT LINE ADDRESS 
CLERL1 EQU  $ 
       STA  FILCHR    ;SAVE TERMINATOR CHARACTER
       MOV  B,H       ;SET B,C TO ADDRESS OF NEXT 
       MOV  C,L         ;LINE POINTER'S LSB 
       MOV  A,E       ;SET H,L TO ADDRESS OF NEXT 
       ANI  377Q-BLKSM  ;BLOCK LINK IN CURRENT
       MOV  L,A         ;BLOCK
       MOV H,D
       MOV A,M      ;GET NEXT BLOCK 
       INX  B         ;SET B,C TO MSB OF NEXT LINE
       MOV  M,C         ;POINTER
       INX  H 
       MOV  C,M 
       MOV  M,B 
       MOV  B,L       ;SAVE LSB OF LINK'S MSB ADDR
       MOV  H,C 
       MOV  L,A 
       PUSH H         ;SAVE ADDRESS OF NEXT BLOCK 
 
;*****************************************
; INSERT FILL CHARS BETWEEN LINK AND EOL *
;*****************************************
       MOV A,E      ;COMPUTE NO. OF FILLS 
       ANI BLKSM
       SUI 2        ;LESS THAN 2? 
       JM  CLL160   ;YES - RELEASE THE BLOCK
       MOV  E,B       ;SET H,L TO ADDRESS OF MSB
       XCHG             ;PART OF NEXT BLOCK POINTE
CLL120 EQU $
       INX  H         ;ADVANCE TO NEXT BYTE 
       MVI  M,FILL    ;STORE FILL CHARACTER 
       DCR  A         ;ALL BYTES DONE?
       JP   CLL120    ;NO - CONTINUE FILLING
       LDA  FILCHR    ;YES - GET AND STORE FINAL
       MOV  M,A         ;FILL CHARACTER 
;******************************** 
; RELEASE EXCESS DISPLAY BLOCKS * 
;******************************** 
CLL160 EQU  $ 
       POP  D         ;RECALL ADDRESS OF NEXT BLOC
       MOV  A,E 
       CMA            ;IS THE LINK AN EOL LINK
       ANI  BLKSM       ;(LOW 4 BITS NOT ALL ONES)
       JNZ  CLL310    ;YES - EXIT 
       DCX  D         ;NO - ADD BLOCKS TO FREE LIS
       DCX  D         ;SET ADDRESS TO LSB OF NEXT 
       DCX  D           ;LINE FIELD IN FIRST BLOCK
       CALL PUTLIN    ;ADD BLOCKS TO FREE LIST
CLL310 EQU $
       XRA A        ;SET ZERO FLAG FOR CLEARS 
       RET          ;RETURN 
 
;************************************** 
; CLEAR LINE FUNCTION FOR FORMAT MODE * 
;************************************** 
CLL400 EQU  $ 
       INR  B         ;CURSOR IN PROTECTED FIELD? 
       RZ             ;YES - RETURN, DON'T DO CLEA
;*********************************************
; CLEAR UNPROTECTED FIELD                    *
; D,E = ADDRESS OF FIRST ASCII CHAR IN FIELD *
;*********************************************
CLER01 EQU $
       XCHG 
CLER02 EQU  $ 
       XCHG           ;PUT CHARACTER ADDR INTO D,E
       INX  D         ;SET TO PREVIOUS CHARACTER
CLL510 EQU  $ 
       CALL NXTCHR    ;GET THE NEXT CHARACTER 
       JNZ  CLL580    ;CHECK EXIT IF EOL LINK 
       ADD A        ;ASCII? 
       JC  CLL540   ;NO - CONTINUE
       MVI  A,ABLNK   ;YES - STORE BLANK
       STAX D 
       INR C        ;INCREMENT COLUMN 
       JMP  CLL510    ;TRY NEXT CHARACTER 
;********************** 
; NON-ASCII CHARACTER * 
;********************** 
CLL540 EQU $
       JM  CLL550   ;NOT DSPLY CNTRL - CHECK MORE 
;********************************** 
; DELETE DISPLAY ENHANCEMENT CHAR * 
;********************************** 
CLL544 EQU  $ 
       CALL CHRDL2    ;DELETE ENHANCEMENT CODE
       JMP  CLL510    ;CONTINUE CLEARING
 
;*******************************
; NOT ASCII OR DISPLAY CONTROL *
;*******************************
CLL550 EQU  $ 
       RAR            ;RESTORE CHARACTER
       CPI  FILL      ;END OF LINE FILL?
       JZ   CLL510    ;YES - GO TO NEXT CHARACTER 
       CPI  STPR      ;START PROTECT? 
       RZ             ;YES - TERMINATE CLEAR
       CPI  STPFLG+1  ;FORMAT CONTROL CODE? 
       JC   CLL544    ;YES - DELETE IT
       JMP  CLL510    ;NO - GO TO NEXT CHARACTER
;*********************
; LINK FOUND         *
; MOVE TO NEXT BLOCK *
;*********************
CLL580 EQU  $ 
       LDAX D         ;GET NEXT LINE LINK'S MSB 
       CPI  EOP       ;END OF DISPLAY LIST? 
       RZ             ;YES - RETURN 
       CALL FLDSR2    ;CONTINUATION FIELD?
       JZ   CLL510    ;YES - CONTINUE CLEAR 
       XRA  A         ;NO - TERMINATE CLEAR AND 
       RET              ;RETURN END ON END OF FIEL
 
;***************************
; DSPMSG - DISPLAY MESSAGE *
;***************************
; 
;  ENTRY:  NC - ADD MESSAGE TO NORMAL DISPLAY 
;          C - REPLACE DISPLAY WITH MESSAGE 
;          MSGPT1-MSGPT8 = POINTERS TO MESSAGE
;            SECTIONS 
; 
;  EXIT :  ALL REGISTERS DESTROYED
; 
DSPMS0 EQU  $         ;SET C-FLAG TO FORCE DISPLAY
       STC              ;REPLACEMENT BY MESSAGE 
DSPMS1 EQU  $ 
       SHLD MSGPT1    ;SET MESSAGE POINTER 1
DSPMSG EQU  $ 
       JNC  DSM500    ;ADD MESSAGE TO DISPLAY 
       LXI  B,DSPSTR  ;SET DESTINATION POINTER
       LXI  H,MSGPT1+1  ;SET INITIAL TABLE POINTER
; 
;  TRANSFER MESSAGE TO MESSAGE BUFFER 
; 
DSM010 EQU  $ 
       MOV  D,M       ;GET POINTER TO MESSAGE 
       DCX  H 
       MOV  E,M 
       DCX  H         ;SET TO NEXT POINTER
       XCHG           ;PUT POINTER INTO H,L 
       CALL MOVCHR    ;XFR MESSAGE PART TO BUFFER 
       XCHG           ;PUT POINTER TO TABLE IN H,L
       JZ   DSM010    ;DO NEXT PART IF NOT EOP END
       LXI  H,DSPSTR  ;SET DISPLAY POINTER TO 
       SHLD DISPST      ;MESSAGE AREA 
       MVI  A,MAXROW+1  ;REMOVE CURSOR FROM DISPLA
       STA  IOCRRW
       RET            ;RETURN 
 
; 
;  ADD MESSAGE TO NORMAL DISPLAY
; 
DSM500 EQU  $ 
       CALL SFKYOF    ;FORCE NORMAL DISPLAY ON
       LXI  H,MSGPT1+1  ;SET INITIAL TABLE POINTER
DSM510 EQU  $ 
       MOV  D,M       ;GET POINTER TO MESSAGE 
       DCX  H 
       MOV  E,M 
       DCX  H         ;SET TO NEXT POINTER
       PUSH H         ;SAVE TABLE POINTER 
       XCHG           ;PUT MESSAGE POINTER IN H,L 
       CALL XMS2DS    ;XFR MESSAGE TO THE DISPLAY 
       POP  H         ;RECALL TABLE POINTER 
       JZ   DSM510    ;DO NEXT PART IF NOT EOP END
;                     FALL INTO "RSTDSP" TO 
;                       FORCE DISPLAY ON
;********************************** 
; RSTDSP - RESTORE NORMAL DISPLAY * 
;********************************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  PROCESSOR FLAGS UNCHANGED
;          H,L DESTROYED
; 
RSTDSP EQU  $ 
       LHLD TOPLIN    ;GET TOP LINE ADDRESS 
       DCX  H         ;SET TO FIRST CHAR ADDRESS
       SHLD DISPST    ;SET DISPLAY START POINTER
       JMP  DISLN1    ;SET THE DISPLAY CURSOR 
 
;*****************************
; FORMON - ENTER FORMAT MODE *
;*****************************
FORMON EQU  $ 
       CALL CKEDIT    ;EDIT MODE? 
       RNZ            ;YES - INHIBIT FORMAT MODE
       LXI  H,MAXCOL  ;NO - SET MARGINS TO ENDS OF
       SHLD RHTMGN      ;DISPLAY
       MVI  A,FORMAT  ;TURN ON FORMAT MODE FLAG 
       CALL ZSTMD1
;                   SET CURSOR TO FIRST 
;                     UNPROTECTED FIELD 
; 
;***********************************
; CURPH - CURSOR POINTER HOME (UP) *
;***********************************
CURPH  EQU $
       MVI  A,377Q-SDACOM  ;CLEAR DATACOM INPUT 
       CALL CLRDFL      ;FLAG TO DISABLE TRANSMIT-
;                       ONLY FIELDS 
; 
CURPH1 EQU  $ 
       CALL CURPRT    ;SET CURSOR TO LEFT MARGIN
       CALL CHKSFK    ;SOFT KEY MODE? 
       JNZ  HUP060    ;YES - SET CURSOR ONLY
       STA  TLINO     ;NO - SET TOP LINE # TO ZERO
       DCR  A         ;RESET SPOW LATCH 
       STA  SPOWL 
       CALL MLKSCH    ;DISPLAY AREA LOCKED? 
       JZ   HUP100    ;NO - HOME TO FIRST LINE
; 
;  DISPLAY LOCK ON - CHANGE ONLY UNLOCKED LINES 
; 
       MOV  D,H       ;SAVE ADDRESS OF LSB PART OF
       MOV  E,L         ;NEXT LINE POINTER IN FIRS
       INX  H           ;UNLOCKED LINE
       INX  H         ;GET ADDRESS OF LAST LOCKED 
       MOV  C,M         ;ROW
       INX  H 
       MOV  B,M 
       LHLD TOPLIN    ;GET PTR TO TOP DSPLY LINE
       INX  H         ;GET ADDRESS OF FIRST LINE
       INX  H           ;ABOVE TOP DISPLAY LINE 
       MOV  A,M 
       ORA  A         ;ANY LINES ABOVE DISPLAY? 
       JZ   HUP050    ;NO - POSITION CURSOR ONLY
 
; 
;  LINK SPLIT PARTS TOGETHER
; 
       MVI  M,0       ;ZERO PREV LINE PTR OF TOP L
       INX  H 
       MOV  H,M       ;SET H,L TO FIRST LINE ABOVE
       MOV  L,A         ;DISPLAY
       DCX  D         ;SET ITS NEXT LINE POINTER T
       MOV  M,E         ;FIRST CHARACTER OF FIRST 
       INX  H         ;UNLOCKED LINE
       MOV  M,D 
       XCHG           ;SET PREVIOUS LINE POINTER O
       INX  H           ;FIRST UNLOCKED LINE TO 
       INX  H           ;FIRST LINE ABOVE DISPLAY 
       INX  H 
       MOV  M,A 
       INX  H 
       MOV  M,D 
       LHLD FLINE     ;REPLACE CONTENTS OF FLINE
       XCHG             ;WITH VALUES FROM TOPLIN
       LHLD TOPLIN
       SHLD FLINE 
       MOV  H,D       ;SET PREVIOUS LINE POINTER O
       MOV  L,E         ;CURRENT TOP LINE TO POINT
       INX  H           ;TO LAST LOCKED ROW 
       INX  H 
       MOV  M,C 
       INX  H 
       MOV  M,B 
       MOV  H,B       ;SET H,L TO MSB PART OF NEXT
       MOV  L,C         ;LINE POINTER IN LAST 
       INX  H           ;LOCKED ROW 
       MOV  B,D       ;SET NEXT LINE POINTER TO 
       MOV  C,E         ;POINT TO FIRST CHARACTER 
       DCX  B           ;OF LINE POINTED BY FLINE 
       CALL DISLNK
; 
;  DISPLAY SET FOR DISPLAY LOCK HOME - SET CURSOR 
; 
HUP050 EQU  $ 
       CALL ROLUP3    ;SET "LSTLIN" AND "CURADR"
       CALL CHKFMT    ;FORAMT MODE? 
       XRI  FORMAT      ;(REVERSE RESULT OF TEST) 
       JZ   HUP110    ;YES - LOCATE FIRST FIELD 
;                       STARTING IN LOCKED REGION 
;                       (A = 0) 
       LDA  MLKROW    ;NO - SET CURSOR TO FIRST 
       STA  CURROW      ;UNLOCKED ROW 
       STA  LSTROW
       RET            ;RETURN 
 
; 
;  DEFINE SOFT KEYS HOME UP 
; 
HUP060 EQU  $ 
       XRA  A         ;SET CURSOR ROW TO ZERO 
       STA  CURROW
       STA  LSTROW
       LHLD SFTKYS    ;SET "CURADR" AND "LSTLIN"
       INX  H           ;TO FIRST SOFT KEY LINE 
       CALL ROLUPC
       JMP  FLDSR1    ;LOCATE FIRST FIELD 
; 
;  DISPLAY NOT LOCKED - SET TOPLIN TO FLINE 
; 
HUP100 EQU  $ 
       LDA  MLKROW    ;SET CURSOR TO 1ST UNLK RW
HUP110 EQU  $ 
       STA  CURROW    ;SET NEW CURRENT ROW
       XRA  A 
       STA  LSTROW    ;SET LAST ROW DONE TO ZERO
       MOV  D,A       ;SET D=0 TO FLAG TLINO UPDAT
       LXI  H,FLINE 
       MOV  A,M       ;SET TOP LINE POINTER TO
       CALL ROLUP1      ;FIRST DISPLAY LINE 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       RZ             ;NO - RETURN
;                     YES - FALL INTO "FLDSR1" TO 
;                       FIND FIRST UNPROTECTED
;                       FIELD 
 
;******************************************** 
; FLDSR - LOCATE THE NEXT UNPROTECTED FIELD * 
;******************************************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  NZ - FIELD FOUND 
;            D,E = ADDRESS OF "ENDPR" 
;            CURADR,CURCOL,CURROW,LSTLIN,LSTCOL 
;              LSTROW UPDATE TO CORRESPOND TO 
;              FIELD FOUND
;          Z - FIELD NOT FOUND
;            ALL REGISTERS DESTROYED
; 
FLDSR1 EQU  $         ;LOOK FOR NEXT UNPROTECT
       LXI  H,NEWROW ;INITIALIZE ROW COUNT
       MVI  M,0         ;TO ZERO
       MVI  L,CURCOL-BASE  ;GET CURRENT COLUMN
       MOV  C,M              ;POSITION
       JMP FSR100 
FLDSR  EQU $
       XRA  A         ;ZERO NUMBER OF ROWS ROLLED 
       STA  NEWROW
       CALL RCADRB    ;DOES CURSOR ROW EXIST? 
       JM   ZRETRN    ;NO - RETURN ZERO 
       MOV  C,A       ;YES - SAVE LAST COLUMN FOUN
       CALL CKPROT    ;CURSOR IN PROTECTED FIELD? 
       JZ   FSR100    ;YES - LOOK FOR NEXT UNPROTC
;*******************************************
; CURSOR IS IN UNPROTECTED FIELD           *
; SEARCH FOR START OF NEXT PROTECTED FIELD *
;*******************************************
FSR080 EQU $
       LXI  H,STPR*256+STPR 
       CALL FNDCU1    ;ANY MORE FIELDS IN LINE? 
       JZ   FSR120    ;NO - GO TO NEXT LINE 
;*********************************************
; ADVANCE CURSOR TO START OF PROTECTED FIELD *
;*********************************************
       MVI A,MAXCOL+1 ;COMPUTE NEW COLUMN 
       SUB C
       MOV C,A      ;SAVE COLUMN IN C 
;************************************ 
; CURSOR IS IN PROTECTED FIELD      * 
; SEARCH FOR NEXT UNPROTECTED FIELD * 
; IN THIS LINE                      * 
;************************************ 
FSR100 EQU $
       CALL FNDCHU    ;ANY MORE FIELDS IN LINE? 
       JNZ  FSR200    ;YES - SET CURSOR AND DISPLA
 
;*************************
; NO MORE FIELDS IN LINE *
; MOVE TO NEXT LINE      *
;*************************
FSR120 EQU $
       CPI  STPFLG    ;NON-DISPLAYING TERMINATOR? 
       JZ   FSR140    ;YES - RETURN FAIL
       MOV  C,H       ;NO - SAVE TERMINATOR CHAR
       CALL CHAIN0    ;GET NEXT BLOCK LINK
       MOV  A,M       ;GET NEXT LINE LINK'S MSB 
       DCX  H 
       MOV  L,M       ;PUT LSB INTO L-REGISTER
       CPI  EOP       ;END OF DISPLAY FOUND?
       JZ   FSR140    ;YES - EXIT FIELD NOT FOUND 
       MOV  H,A       ;NO - SAVE ADDRESS OF NEW 
       SHLD LNKSAV      ;LINE 
       XCHG 
       LXI  H,NEWROW  ;INCREMENT ROW NUMBER 
       INR  M 
       XRA A
       STA  LSTDCD  ;CLEAR LAST DISPLAY CODE
       STA  TEMP
       MOV A,C      ;GET LAST TERMINATOR CHAR 
       MVI C,0      ;SET COLUMN TO ZERO 
       CPI  STPR      ;LOOKING FOR START PROTECT? 
       JNZ  FSR100    ;NO - CONTINUE UNPROTECT FIN
;                     YES - SEE IF CONTINUE UNPROT
;**************************************** 
; SEARCH FOR PROTECTED FIELD            * 
; CHECK FOR CONTINUED UNPROTECTED FIELD * 
;**************************************** 
       CALL FLDSR2    ;FIRST CHAR AN "ENDPR"
       LDA  TEMP        ;(SET NEW LSTDCD VALUE) 
       STA  LSTDCD
       JZ   FSR080    ;YES - LOOK FOR START PROTEC
       JMP  FSR100    ;NO - LOOK FOR NEXT UNPROTEC
;******************************** 
; SET LSTCOL PAST END OF LINE   * 
; TO CAUSE LINE TO BE RESCANNED * 
;******************************** 
FLDSRX EQU  $ 
FSR140 EQU  $         ;(Z TRUE) 
       LXI  H,LSTCOL
       MVI  M,MAXCOL+1
       RET            ;RETURN 
 
;************************** 
; UNPROTECTED FIELD FOUND * 
; SET NEW CURSOR POSITION * 
;************************** 
FSR200 EQU $
       MVI A,MAXCOL+1 ;COMPUTE NEW COLUMN 
       SUB C
       CALL CRRET1    ;SET CURRENT CURSOR LOCATION
       STA  LSTCOL      ;AND LAST CURSOR VALUE
       XCHG           ;STORE NEW CURRENT ADDRESS
       SHLD CURADR
       SHLD LADDR     ;SAVE FIELD ADDRESS IN
;                       CASE ROLL UP NEEDED 
       XCHG           ;RESTORE D,E AND H,L
;*************************
; COMPUTE NEW CURSOR ROW *
;*************************
       LDA  NEWROW    ;GET NEW ABSOLUTE ROW NUMBER
       ORA A        ;HAS ROW CHANGED? 
       JZ   FSR360    ;NO - RETURN
       LXI  H,CURROW  ;YES - CALCULATE NEW
       ADD  M           ;ROW NUMBER 
FSR240 EQU $
       MVI C,MAXROW+1 ;IS NEW ROW ON CURRENT PAGE?
       CMP C
       JC  FSR340   ;YES
 
;***************************************
; NEW CURSOR ROW IS ON NEW PAGE        *
; ROLL DISPLAY UP TO GET ROW ON SCREEN *
;***************************************
       SUB  C         ;DECREMENT ROLL COUNT BY ONE
       LXI  H,MLKROW  ;PAGE 
       ADD  M         ;ADJUST FOR LOCKED DISPLAY
       MOV  D,A       ;SAVE RESULT FOR STORAGE
       MOV  A,C       ;COMPUTE NUMBER OF LINES TO 
       SUB  M           ;ROLL FOR ONE PAGE
       MOV  E,A       ;SAVE THE VALUE FOR STORAGE 
       XCHG           ;PUT VALUES INTO H,L
       SHLD ROLLCT  ;STORE ROLL PARAMETERS
; 
;  ROLL UP ONE PAGE OF LINES
; 
FSR300 EQU  $ 
       CALL ROLLUP    ;ROLLUP ONE LINE
       LXI  H,ROLLCT
       DCR  M         ;PAGE ROLLED UP?
       JNZ  FSR300    ;NO - DO ANOTHER LINE 
       INX  H         ;YES - GET NUMBER OF ROWS 
       MOV  A,M         ;TO UNPROTECTED FIELD AND 
       JMP  FSR240      ;CHECK TO SEE IF ON SCREEN
;*************
; UPDATE ROW *
;*************
FSR340 EQU  $ 
       STA  CURROW    ;SET NEW ROW NUMBER 
       LHLD CURROW    ;SET LAST ROW AND COLUMN DON
       SHLD LSTROW      ;CURRENT ROW AND COLUMN 
       LHLD LNKSAV    ;SET "LSTLIN" TO CURRENT ROW
       INX  H           ;ADDRESS
       SHLD LSTLIN
       LHLD LADDR     ;SET "CURADR" TO ADDRESS OF 
       SHLD CURADR      ;FIRST CHAR IN NEW FIELD
       XCHG           ;PUT CURRENT ADDRESS INTO D,
FSR360 EQU  $ 
       CPI  D         ;SET Z-FALSE (D >= 320) 
       JMP  DISLN1    ;GO SET DISPLAY CURSOR ROW
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  FLDSR2 - DETERMINE PROTECT SENSE OF NEXT 
;    CHARACTER
; 
;      ENTRY:  D,E = NEXT CHARACTER ADDRESS 
; 
;      EXIT :  Z - CONTINUATION OF FORMAT FIELD 
;              NZ - NOT A CONTINUATION
;              D,E = ADDRESS OF CHARACTER 
;              H = BASEH
;              TEMP = NEW ENHANCEMENT CODE IF ANY 
;              A,L DESTROYED
; 
FS2000 EQU  $ 
       STA  TEMP  ;STORE NEW DISPLAY CONTROL
FLDSRB EQU  $ 
FS2005 EQU  $ 
       DCX  D         ;SET ADDRESS TO NEXT CHAR 
FLDSR2 EQU $
       INX  D         ;SET ADDRESS TO PREV CHAR 
       CALL NXTCHR  ;GET NEXT CHARACTER 
       JNZ FLDSR2   ;SKIP OVER LINKS
       ADD  A         ;ASCII OR DISPLAY CONTROL?
       JNC  NZEXIT    ;ASCII - RETURN NOT CONTINUE
       RAR              ;(RESTORE DATA BYTE)
       JP   FS2000    ;DISPLAY CONTROL - IGNORE IT
       CPI  STPFLG    ;TERMINATOR OR TYPE DEFINE? 
       JP   FS2005    ;YES - SKIP TO NEXT CHARACTE
       LXI  H,LSTFMT  ;COMPARE AGAINST LAST FORMAT
       CMP  M           ;CONTROL AND RETURN 
       RET
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  FNDCH - SEE IF NEXT CHAR IS FORMAT CONTROL BYTE
; 
;      ENTRY:  TERMINAL IS IN FORMAT MODE 
;              D,E = START ADDRESS
;              H,L = CHARACTERS TO LOOK FOR 
; 
;      EXIT :  Z - CHARACTER NOT FOUND
;              NZ - CHARACTER FOUND 
;              D,E = ADDRESS OF ENDING CHARACTER
;              A,B,C,L,TEMP DESTROYED 
; 
;  FNDCH0 - SEE IF NEXT CHARACTER IS PROTECTED
; 
FNDCH0 EQU  $ 
       LXI  H,STPR*256+STPR  ;SET COMPARE CHARS 
FNDCH  EQU  $ 
       MVI  A,IGNTRM  ;SET TO IGNORE NON-DISPLAYIN
       STA  TRMFCT      ;TERMINATOR 
       LDA  PROFLD    ;SAVE PROTECTED FIELD 
       PUSH PSW         ;STATUS 
       MVI  C,0       ;SET FOR NEXT CHARACTER ONLY
       CALL FCR400    ;LOCATE THE NEXT CHARACTER
       MVI  A,DELTRM  ;RESTORE FLAG TO DELETE NON-
       STA  TRMFCT      ;DISPLAYING TERMINATOR
       POP  B         ;RESET PROTECT STATUS TO BE 
       MOV  A,B         ;CONSISTENT WITH CHARACTER
       STA  PROFLD      ;POINTED TO BY "CURADR" 
       RET            ;RETURN 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  FNDCHU - LOCATE NEXT UNPROTECTED FIELD 
;    CONTROL BYTE IN CURRENT LINE 
; 
;      ENTRY:  TERMINAL IS IN FORMAT MODE 
;              B = DON'T CARE 
;              C = CURRENT COLUMN NUM8ER
;              D,E = START ADDRESS
; 
;      EXIT :  Z - CHARACTER NOT FOUND
;              NZ - CHARACTER FOUND 
;              C = NUMBER OF CHARS TO END OF LINE 
;              D,E = ADDRESS OF ENDING CHARACTER
;              PROFLD SET AS DEFINED
;              A,B,L DESTROYED
; 
FNDCHU EQU  $ 
       CALL DCXB2D    ;DATA COMM OR I/O BUFF INPUT
       LXI  H,ENDPR*256+ENDPR  ;(SET "ENDPR" ONLY)
       JZ   FNDCU1    ;NO - SKIP XMIT ONLY FIELDS 
       MVI  L,XMONLY  ;YES - LOOK FOR "XMONLY" ALS
; 
;  LOCATE THE FORMAT CONTROL CHARACTER
; 
FNDCU1 EQU  $ 
       MVI A,MAXCOL ;COMPUTE NO. OF CHARS 
       SUB C        ;TO SEARCH
       MOV C,A
FCR400 EQU $
       CALL FNDCHR    ;LOOK FOR SPECIFIED CHARS 
       RZ             ;RETURN IF EOL ENCOUNTERED
       XRA  A         ;OTHERWISE, SET FLAG TO 
       ORA  C           ;SHOW IF CHARACTER FOUND
       RET
 
;************************************** 
; FNDCHR - LOCATE SPECIFIED CHARACTER * 
;************************************** 
; 
;  ENTRY:  C = NUMBER OF COLUMNS TO SEARCH
;          D,E = STARTING ADDRESS 
;          H,L = CHARACTERS TO LOOK FOR 
;            (VALID FOR FORMAT MODE ONLY) 
; 
;  EXIT :  Z - CHARACTER NOT FOUND
;          NZ - CHARACTER FOUND 
;          C = NUMBER OF CHARACTERS LEFT
;            (= 0, IF CHARACTER FOUND)
;          D,E = ADDRESS OF TERMINATING CHARACTER 
;          "EOLMV" SET TO ZERO
;          "PROFLD" SET IF IN FORMAT MODE 
;          "LSTFMT" UPDATED IF A FORMAT CONTROL 
;            CHARACTER IS ENCOUNTERED 
; 
FNDCHR EQU  $ 
       XRA  A 
       STA  EOLMV 
       INX  D         ;SET TO PREV CHAR ADDRESS 
       INR  C         ;ADJUST CHARACTER COUNT 
       INR  C 
FCR005 EQU  $ 
       DCR  C         ;COLUMN FOUND?
       JZ   NZEXIT    ;YES - RETURN CHARACTER FOUN
; 
;  SEARCH DISPLAY LIST
; 
FCR010 EQU  $ 
       CALL NXTCHR    ;GET THE NEXT CHARACTER 
       JNZ  FCR260    ;EOL LINK - EXIT NOT FOUND
       ADD  A         ;IS IT ASCII? 
       JNC  FCR005    ;YES - DECREMENT COLUMN COUN
;************************************************ 
; NON-ASCII CHARACTER - DETERMINE CHAR FUNCTION * 
;************************************************ 
       RAR            ;RESTORE CHARACTER
       JM   FCR100    ;NOT DISPLAY CTL - CHECK MOR
       STA  LSTDCD    ;UPDATE CURRENT DISPLAY CODE
       JMP  FCR010    ;CONTINUE SEARCHING 
 
; 
;  FORMAT CONTROL CHARACTER - CHECK FOR ENDING
; 
FCR100 EQU  $ 
       CPI  EOL       ;END OF LINE? 
       RZ             ;YES - RETURN 
       CPI  EOP       ;END OF DISPLAY?
       RZ             ;YES - RETURN 
       CPI  STPFLG    ;NON-DISPLAYING TERMINATOR? 
       JZ   FCR200    ;YES - DETERMINE ITS FUNCTIO
       CPI  ALPHA     ;TYPE DEFINITION? 
       JP   FCR150    ;YES - SET CHECK FUNCTION 
       CPI  XMONLY+1  ;FORMAT CONTROL?
       JP   FCR010    ;NO - CONTINUE SEARCHING
       PUSH H         ;YES - RESET CHECK ROUTINE
       LXI  H,ZRETRN    ;ADDRESS
       SHLD CHKRTN
       POP  H         ;RESTORE CHECK CHARACTERS 
       STA  LSTFMT    ;SET CURRENT FORMAT CONTROL 
       MOV  B,A       ;SAVE CONTROL CHARACTER 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JZ   FCR010    ;NO - CONTINUE SEARCHING
       MOV  A,B       ;RECALL CHARACTER 
       SBI  STPR+1    ;COMPUTE "PROFLD" VALUE 
       STA  PROFLD      ;(= -1 FOR PROTECTED) 
       MOV  A,B       ;RECALL CHARACTER 
       CMP  H         ;TERMINATOR FOUND?
       JZ   FCR110    ;YES - EXIT 
       CMP  L 
       JNZ  FCR010    ;NO - CONTINUE SEARCHING
FCR110 EQU  $ 
       ORA  A         ;SET Z FALSE
       RET            ;RETURN 
; 
;  TYPE DEFINITION FOUND - SET CHECK ROUTINE
; 
FCR150 EQU  $ 
       PUSH H         ;SAVE TERMINATOR CHARACTERS 
       LXI  H,ZALPCK  ;SET H,L FOR ALPHA CHECK
       JZ   FCR160    ;SET ALPHA CHECK IF ALPHA 
       LXI  H,ZNUMCK  ;SET H,L FOR NUMERIC CHECK
       SUI  NUMBER+1  ;NUMERIC FIELD? 
       JM   FCR160    ;YES - SET CHECK ROUTINE ADD
       LXI  H,ZRETRN  ;NO - SET H,L FOR ALPHANUM
       JZ   FCR160    ;SET ROUTINE ADDR IF = ZERO 
       LXI  H,SFKCHK    ;ELSE, SET FOR SOFT KEYS
FCR160 EQU  $ 
       SHLD CHKRTN    ;SET CHECK ROUTINE ADDRESS
       POP  H         ;RECALL TERMINATOR CHARACTER
       JMP  FCR010    ;CONTINUE SEARCHING 
 
;********************************************** 
; NON-DISPLAYING TERMINATOR FOUND - DETERMINE * 
;   AND PERFORM ITS FUNCTION                  * 
;********************************************** 
FCR200 EQU  $ 
       LDA  TRMFCT    ;GET THE FUNCTION FLAG
       ORA  A         ;WHAT FUNCTION? 
       JM   FCR250    ;-1 - TERMINATE TRANSFER
       JNZ  FCR010    ;+1 - IGNORE IT 
       CALL CHRDL2     ;0 - DELETE IT 
       JMP  FCR010    ;CONTINUE CHARACTER SEARCH
; 
;  TERMINATE TRANSFER 
; 
FCR250 EQU  $ 
       LDAX D         ;PUT CHARACTER BACK IN A-REG
FCR260 EQU  $ 
       CMP  A         ;SET Z-FLAG TRUE
       RET            ;RETURN CHARACTER NOT FOUND 
 
;***********************************************
; FNDLST - LOCATE LAST CHARACTER TYPE AHEAD OF *
;   CURRENT CHARACTER                          *
;***********************************************
; 
;  ENTRY:  A = NUMBER OF COLUMNS TO SEARCH
;          D,E = ADDRESS OF CHARACTER BEFORE
;            BEFORE FIRST CHARACTER TO LOOK AT
;          H,L = CHARACTERS TO BE FOUND 
; 
;  EXIT :  P - CHARACTER FOUND
;            B = NUMBER OF CHARACTERS FROM CURRENT
;              CHARACTER
;          M - CHARACTER NOT FOUND
;            B DESTROYED
;          A,C,D,E DESTROYED
; 
FNDLS0 EQU  $ 
       INR  A         ;ADJUST SEARCH COUNT
       LXI  H,EOL*256+EOL  ;SET TO LOOK FOR "EOL" 
; 
FNDLST EQU  $ 
       MOV  C,A       ;PUT SEARCH COUNT IN C-REG
       MVI  B,377Q    ;PRESET B FOR FAIL RETURN 
       DCR  A         ;ANY COLUMNS TO SEARCH? 
       RM             ;NO - RETURN NONE FOUND 
FLS010 EQU  $ 
       CALL NXTCHR    ;GET THE NEXT CHARACTER 
       CMP  H         ;DOES IT MATCH DESIRED CHARS
       JZ   FLS020    ;YES - SAVE LOCATION OF CHAR
       CMP  L 
       JNZ  FLS030    ;NO - GO TO NEXT CHARACTER
FLS020 EQU  $ 
       MOV  B,C       ;SAVE LOCATION OF CHAR IN B 
FLS030 EQU  $ 
       ORA  A         ;IS CURRENT CHAR ASCII? 
       JM   FLS050    ;NO - CHECK FOR TERMINATION 
       DCR  C         ;SEARCH COMPLETE? 
FLS035 EQU  $ 
       JNZ  FLS010    ;NO - CHECK NEXT CHARACTER
FLS040 EQU  $ 
       XRA  A         ;CLEAR A-REGISTER 
       ORA  B         ;SET FLAGS FOR RETURN 
       RET            ;RETURN 
;********************************************** 
; NON-ASCII CHARACTER - CHECK FOR TERMINATION * 
;********************************************** 
FLS050 EQU  $ 
       CPI  EOL       ;IS IT AN EOL?
       JZ   FLS040    ;YES - EXIT 
       CPI  EOP       ;IS IT AN EOP?
       JMP  FLS035    ;GO CHECK RESULT
 
;***********************************
; HTAB - SKIP TO NEXT TAB POSITION *
;***********************************
HTAB   EQU  $ 
       CALL CHKFM0    ;FORMAT/SOFT KEY DEFINE MODE
       JNZ  HTB200    ;YES - LOCATE NEXT FIELD
       MVI  L,CURCOL-BASE  ;NO - LOCATE NEXT TAB
       MOV  B,M         ;SET POSITION 
       INR  B         ;START FROM NEXT COLUMN 
       MVI  A,MAXCOL  ;COMPUTE NUMBER OF COLUMNS
       SUB  B           ;TO END OF LINE 
       JM   CRLF      ;GO TO START OF NEXT LINE IF
;                       ALREADY AT END OF LINE
       ORI 7        ;MOVE TO COL CORRESP. TO
;                     START OF BYTE 
       MOV C,A      ;SAVE IN C
       MOV A,B
       CALL FNDTB1  ;GET TABLE ENTRY FOR COLUMN 
       DCR  A         ;MASK OFF BITS FOR
       CMA              ;PREVIOUS COLUMNS 
       ANA M
;******************************** 
; CHECK NEXT COLUMN FOR SET TAB * 
;******************************** 
HTB100 EQU $
       MVI B,8      ;GET BIT COUNT
       JZ  HTB140   ;NO BITS SET IN BYTE
HTB120 EQU  $ 
       RRC            ;TAB BIT SET? 
       JNC  HTB130    ;NO - TRY NEXT COLUMN 
;*****************************
; TAB IS SET - UPDATE CURCOL *
;*****************************
HTB160 EQU  $ 
       MOV  E,A       ;SAVE A-REGISTER
       MVI  A,MAXCOL+7  ;COMPUTE COLUMN OF LOCATIO
       SUB  C             ;OF TAB 
       SUB B
       SHLD LNKSAV    ;SAVE CURRENT TABLE ADDRESS 
       LHLD RHTMGN    ;GET RIGHT AND LEFT MARGINS 
       CMP  L         ;TAB BEYOND RIGHT MARGIN? 
       JP   CRLF      ;YES - DO CR, LF
       INR  A         ;NO - ADJUST TO PROPER VALUE
       CMP  H         ;TAB BEYOND LEFT MARGIN?
       JNC  CURPO4    ;YES - LOCATE TAB LOCATION
       MOV  A,E       ;NO - RESTORE A-REGISTER
       LHLD LNKSAV    ;RECALL TAB TABLE ADDRESS 
;                     LOOK FOR ANOTHER TAB
 
;************************************ 
; TAB NOT FOUND - CHECK NEXT COLUMN * 
;************************************ 
HTB130 EQU  $         ;NO - TRY NEXT COLUMN 
       DCR  B         ;ALL BITS EXAMINED? 
       JNZ  HTB120    ;NO - LOOK TO NEXT BIT
;**************************** 
; BYTE EXHAUSTED            * 
; MOVE TO NEXT TABTBL ENTRY * 
;**************************** 
HTB140 EQU $
       MOV A,C      ;GET COLUMN COUNT 
       SUI 8        ;DECREMENT
       JM   CRLF      ;DO CR,LF IF REACHED END
       MOV C,A
       INX  H         ;GET NEXT BYTE FROM TABLE 
       MOV A,M
       ORA A        ;SET FLAGS
       JMP HTB100 
 
;****************** 
; FORMAT MODE TAB * 
;****************** 
HTB200 EQU $
       CALL FLDSR   ;SEARCH FOR NEXT FIELD
       RNZ          ;RETURN IF FOUND
       JMP  CURPH1    ;HOME TO FIRST UNPROT. FIELD
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  ICHON,ICHOFF - INSERT CHARACTER ON/OFF 
; 
ICHON  EQU  $ 
       MVI  B,0       ;SET FOR NO BLINK 
ICH010 EQU  $ 
       MVI  A,INSCHR  ;TURN ON INSERT CHARACTER 
       JMP  ZSTMD1      ;LED AND EXIT 
; 
ICHOFF EQU  $ 
       MVI  A,377Q-INSWRP 
       CALL CLCMFL    ;CLEAR WRAP AROUND FLAG 
       MVI  A,INSCHR  ;TURN OFF INSERT CHARACTER
       JMP  ZCLMD1
;*************************************
; IWRPON - INSERT WITH WRAPAROUND ON *
;*************************************
IWRPON EQU  $ 
       MVI  A,INSWRP
       CALL STCMFL    ;SET WRAP AROUND FLAG 
       MVI  B,377Q    ;SET TO BLINK LED 
       JMP  ICH010    ;SET INSERT CHARACTER LED ON
 
;******************************************** 
; BCKSPC - BACKSPACE ONE CHARACTER POSITION * 
;******************************************** 
BCKSPC EQU  $ 
       MVI  L,CURCOL-BASE 
       DCR  M         ;DECREMENT CURRENT COLUMN 
       RP             ;RETURN IF NOT AT COLUMN ZER
       INR  M         ;ELSE, RESTORE TO ZERO AND
       RET            ;RETURN 
 
;************************** 
;  R O M   B R E A K   4  * 
;************************** 
       ORG  ZBRK3+4000Q 
ZBRK4  EQU  $ 
       DB   VERSN     ;ROM PRESENT FLAGS
       DB   ZBRK4/256 
 
;***********************************
; CURADV - CURSOR ADVANCE ROUTINE  *
; ADVANCES CURSOR TO NEXT POSITION *
; ON DISPLAY                       *
;***********************************
CURAD2 EQU  $         ;ADVANCE CURSOR TWICE 
       CALL CURADV    ;DO FIRST CURSOR ADVANCE
;                       THEN FALL IN TO DO NEXT 
CURADV EQU $
       CALL CRADV   ;ADVANCE CURSOR 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       RZ             ;NO - RETURN
;*****************************************
; FORMAT MODE                            *
; CHECK FOR ADVANCE INTO PROTECTED FIELD *
;*****************************************
       LDA  CURCOL    ;GET NEW CURRENT COLUMN 
       ORA  A         ;DID CURSOR WRAP AROUND?
       JNZ  CRA040    ;NO - CHECK FOR PROTECTED FL
;********************************** 
; CURSOR WRAPPED AROUND           * 
; SEE IF NEW LINE IS CONTINUATION * 
; OF UNPROTECTED FIELD            * 
;********************************** 
       LHLD LSTLIN
       XCHG           ;GET CURRENT LINE ADDR IN D,
       LDA  FMTCTL    ;RESET "LSTFMT" TO LAST 
       STA  LSTFMT      ;FORMAT CONTROL IN LINE 
       CALL FLDSRB    ;CONTINUATION FIELD?
       JNZ  CRA060    ;NO - TAB TO NEXT FIELD 
;******************** 
; RESET CURADV FLAG * 
;******************** 
CRADV1 EQU $
       XRA  A 
       STA  CRAFLG
       RET
 
;*****************************
; CURSOR DID NOT WRAP AROUND *
; SEE IF CURSOR ENTERED      *
;  PROTECTED FIELD           *
;*****************************
CRA040 EQU  $ 
       LHLD CURADR  ;GET THE CURRENT CHAR ADDR
       XCHG           ;PUT IT INTO H,L
       DCX  D         ;SET POINTER TO NEXT CHAR 
       LHLD CHKRTN    ;SAVE THE CURRENT CHECK 
       PUSH H           ;ROUTINE ADDRESS
       CALL FNDCH0    ;NEXT CHARACTER PROTECTED?
       POP  H           ;(RESTORE CHECK ROUTINE 
       SHLD CHKRTN         ;ROUTINE ADDRESS)
       RZ             ;NO - RETURN
CRA060 EQU $
       CALL CRADV1  ;RESET CURADV FLAG
       CALL DCXB2D    ;DATA COMM OR I/O BUFF CHAR?
       LXI  H,ENDPR*256+XMONLY  ;(SET DEFAULT)
       JNZ  CRA070    ;YES - DON'T SOUND BELL 
       CALL ZBELL     ;NO - SOUND BELL
       MOV  L,H       ;LOOK FOR "ENDPR" ONLY
CRA070 EQU  $ 
       CALL FNDCH     ;NEXT CHARACTER UNPROTECTED 
       CZ   FLDSR       ;OR ANOTHER FIELD EXIST?
       RNZ            ;YES - RETURN 
       CALL DCXB2D    ;DATA FROM DATA COMM OR CTU?
       RZ             ;NO, FROM KEYBOARD - RETURN 
       JMP  CURPH1    ;YES - HOME THE CURSOR
 
;*************************
; CRADV - ADVANCE CURSOR *
;*************************
CRADV  EQU $
       LDA  RHTMGN    ;GET RIGHT MARGIN SETTING 
       LXI  H,CURCOL
CRA010 EQU  $ 
       CMP  M         ;CURSOR AT RIGHT MARGIN?
       JZ   CRA100    ;YES - CHECK FOR WRAP AROUND
       MVI  A,MAXCOL    ;(SET FOR LAST COL CHECK) 
       JM   CRA010    ;AFTER MARGIN - CHECK EOL 
       INR  M         ;ADVANCE CURSOR 
       CMP  M         ;MOVED INTO RIGHT MARGIN OR 
       CNZ  CKPROT      ;INTO PROTECTED FIELD?
       RZ             ;YES - DON'T SET CURADV FLAG
       LDA  MDFLG1    ;GET TERMINAL MODE FLAGS
       ANI  INSCHR    ;IN CHARACTER INSERT MODE?
       RNZ            ;YES - DON'T SET FLAG 
       MVI  L,CRAFLG-BASE  ;NO - SET CURADV FLAG
       MVI M,1
       RET
;***********************************
; CURSOR IS IN LAST COLUMN OF LINE *
;***********************************
CRA100 EQU  $ 
       LDA  LSTFMT    ;SAVE LAST FORMAT CONTROL 
       STA  FMTCTL      ;IN CURRENT LINE
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE OR
       CZ   CKDSPF      ;DISPLAY FUNCTIONS ENABLED
       JNZ  CRLF      ;YES - DON'T CLEAR WRAP FLAG
       LDA  KBJMPR    ;NO - GET KEYBOARD JUMPERS 1
       ANI  LINWRP    ;WRAP AROUND ENABLED? 
       RNZ            ;NO - RETURN
       LDA  DFLGS     ;YES - GET DATA TRANSFER FLG
       ANI  XBF2DS    ;I/O BUFFER TO DISPLAY? 
       MVI  A,377Q-WRPFLG  ;(SET CLEAR MASK)
       CNZ  CLRMF2    ;YES - CLEAR LINE WRAP FLAG 
;****************************************** 
; CURSOR SHOULD BE WRAPPED INTO NEXT LINE * 
; GENERATE CR,LF                          * 
;****************************************** 
CRLF   EQU $
       CALL CRRET   ;CARRIAGE RETURN
       JMP LNFEED   ;LINE FEED
 
;*******************************
; CURPR - CURSOR POINTER RIGHT *
;*******************************
CURPR  EQU $
       MVI A,1      ;GET INCREMENT RIGHT
       JMP CURPL1 
;****************************** 
; CURPL - CURSOR POINTER LEFT * 
;****************************** 
CURPL  EQU $
       MVI A,-1     ;GET INCREMENT LEFT 
CURPL1 EQU $
       MVI L,CURCOL ;GET CURSOR COLUMN
       ADD M        ;ADD INCREMENT
       MOV M,A      ;STORE NEW COLUMN ADDRESS 
       JM  CURPL2   ;WRAPAROUND TO LEFT 
       SUI MAXCOL+1 ;WRAPAROUND TO RIGHT? 
       RNZ          ;NO - RETURN
       MOV M,A      ;YES - SET TO COLUMN ZERO 
;****************************** 
; CURPD - CURSOR POINTER DOWN * 
;****************************** 
CURPD  EQU $
       MVI A,1
       JMP CURPU1 
;********************************** 
; CURSOR MOVED OFF LEFT OF SCREEN * 
; WRAPAROUND TO RIGHT AND UP      * 
;********************************** 
CURPL2 EQU $
       MVI M,MAXCOL ;PUT CURSOR AT LAST COLUMN
;**************************** 
; CURPU - CURSOR POINTER UP * 
;**************************** 
CURPU  EQU $
       MVI A,MAXROW 
CURPU1 EQU $
       MVI L,CURROW ;GET CURSOR ROW 
       ADD M        ;ADD DISPLACEMENT 
       MOV M,A      ;STORE NEW ROW ADDRESS
       SUI MAXROW+1 ;ROW LIMIT EXCEEDED?
       RM           ;NO - RETURN
       MOV M,A      ;YES - STORE ADJUSTED ROW 
       RET          ;RETURN 
 
;**************************** 
; DFSFKY - DEFINE SOFT KEYS * 
;**************************** 
DFSFKY EQU  $ 
       MVI  L,SCRNRW  ;CLEAR SOFT KEY PARAMETERS
       MVI  E,3         ;TO ZERO
       CALL CLRAL1
       LXI  H,DFSTAB  ;SET RANGE TABLE FOR SOFT KE
       JMP  ESCAPA      ;DEFINITION ESCAPE SEQUENC
; 
;  A - DEFINE ATTRIBUTE CODE
; 
;    0 = NORMAL 
;    1 = LOCAL ONLY 
;    2 = TRANSMIT ONLY
; 
DFS100 EQU  $ 
       MVI  C,2       ;SET MAXIMUM VALUE AND
       LXI  D,PARM2     ;PARAMETER TO BE SET
       JMP  DFS220    ;SET PARAMETER AND EXIT 
; 
;  K - KEY NUMBER TO BE DEFINED 
; 
DFS110 EQU  $ 
       MVI  C,NMFCTK-1  ;SET MAXIMUM VALUE AND
       LXI  D,PARM3     ;PARAMETER TO BE SET
       JMP  DFS200    ;SET PARAMETER AND EXIT 
; 
;  L - SET LENGTH OF INPUT
; 
DFS120 EQU  $ 
       MVI  C,MAXCOL  ;SET MAXIMUM VALUE AND
       LXI  D,PARM1 
;                     FALL INTO EVALUATION ROUTINE
 
; 
;  EVALUATE AND SET PARAMETER 
; 
;    D = MAXIMUM ALLOWABLE VALUE
;    E = LSB OF PARAMETER TO BE SET (MSB = BASEH) 
; 
DFS200 EQU  $         ;ENTRY FOR MIN VALUE = 1
       LHLD IODATA    ;GET INPUT PARAMETER
       DCX  H         ;ADJUST PARAMETER TO ONE LES
       MOV  A,H       ;CHECK FOR ZERO PARAMETER 
       CMP  L         ;DOES MSB=LSB?
       JNZ  DFS210    ;NO - STORE ADJUST VALUE
       INR  A         ;IS ADJUST VALUE -1 
       JZ   DFS220    ;YES - DON'T STORE NEW VALUE
DFS210 EQU  $         ;NO - STORE ADJUSTED VALUE
       SHLD IODATA
DFS220 EQU  $ 
       CALL CHKLI0    ;EVALUATE AND SET PARAMETERS
       LDA  CHAR      ;RECALL INPUT CHARACTER 
       ANI  40Q       ;IS IT UPPER CASE?
       JNZ  ESCAPB    ;NO - CONTINUE ESCAPE SEQ 
;                     YES - SET NEW DEFINITION
 
;*************************************************
; UPPER CASE CHARACTER INPUT - EVALUATE SEQUENCE *
;*************************************************
       CALL CHKSFK    ;SOFT KEY DEFINE MODE?
       CZ   SWAP      ;NO - SET TO SOFT KEY DISPLA
       LDA  PARM3     ;COMPUTE DESIRED KEY DATA RO
       ADD  A 
       INR  A           ;= 2*(KEY NUMBER) + 1 
       STA  CURROW
       LXI  H,SFTKYS  ;LOCATE THE START OF THE
       CALL MLKSC1      ;DATA ROW 
       MVI  A,MAXCOL+1
       CALL FNDLS0    ;LOCATE THE END OF THE DATA 
       MVI  A,MAXCOL+2  ;ROW + 1
       SUB  B 
       STA  PARM3     ;SAVE END COLUMN NUMBER 
       LDA  PARM1     ;TRY TO EXTEND LINE TO
       STA  CURCOL      ;END OF NEW DATA LINE 
       CALL DSPASC    ;TRY TO ALLOCATE LINE NEEDED
       ORA  A         ;COLUMN POSITION ALLOCATED? 
       JZ   DFS250    ;NO - DON'T SET NEW VALUE 
       LHLD CURADR    ;YES - GET ADDRESS OF 
       CALL NXTCH0      ;END OF NEW DATA LINE 
       LDA  CURCOL    ;GET NUMBER OF DATA CHARS 
       CPI  MAXCOL    ;FULL LINE USED?
       CNZ  CLERLA    ;NO - CLEAR EXCESS CHARACTER
       CALL CURPRT    ;SET CURRENT COLUMN TO ZERO 
       LXI  H,CURROW  ;SET FOR ATTRIBUTE ROW
       DCR  M 
       LDA  PARM2     ;GET ATTRIBUTE PARAMETER
       DCR  A         ;WHICH ATTRIBUTE TO SET?
       MVI  A,N         ;(N = NORMAL) 
       JM   DFS230    ;0 - SET AS NORMAL KEY
       MVI  A,L         ;(L = LOCAL ONLY) 
       JZ   DFS230    ;1 - SET FOR LOCAL ONLY 
       MVI  A,T       ;2 - SET FOR TRANSMIT ONLY
DFS230 EQU  $ 
       CALL DSPTST    ;STORE ATTRIBUTE LETTER 
       CALL SWAP0     ;RESTORE ACTIVE DISPLAY 
       LXI  H,DFSTB2  ;SET RANGE TABLE FOR SOFT 
       JMP  ESCAPA      ;KEY DATA ACCUMULATION
 
;************************************************ 
; NOT ENOUGH BLOCKS AVAILABLE FOR SOFT KEY DATA * 
;   RESTORE OLD STATE AND IGNORE DEFINITION     * 
;************************************************ 
DFS250 EQU  $ 
       LDA  PARM3     ;RECALL END OF DATA LINE
       STA  CURCOL
       CALL CLEARL    ;CLEAR ANY ADDED CHARACTERS 
;********************************************** 
; SWAP - SWAP DISPLAY PARAMETERS BETWEEN SOFT * 
;   KEY AND NORMAL DISPLAY                    * 
;********************************************** 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  DISPLAY PARAMTERS EXCHANGED
;          ALL REGISTERS DESTROYED
; 
SWAP0  EQU  $ 
       LDA  CMFLGS    ;GET COMMON FLAGS 
       ANI  DEFSKY    ;DEFINE SOFT KEY MODE?
       RNZ            ;NO - DON'T DO SWAP 
; 
SWAP   EQU  $ 
       LXI  H,DSPTYP  ;SET DISPLAY TYPE FLAG
       MOV  A,M         ;TO VALUE FOR DISPLAY TO
       CMA              ;MADE ACTIVE
       MOV  M,A 
SWAP1  EQU  $ 
       MVI  C,NUMSWP  ;SET SWAP COUNT 
       LXI  D,SWPSTR  ;SET ADDRESS OF LOCATIONS 
       LXI  H,RHTMGN    ;TO BE EXCHANGED
; 
;  EXCHANGE DISPLAY PARAMETERS
; 
SWP010 EQU  $ 
       MOV  B,M       ;GET CURRENT SETTING
       LDAX D         ;GET STORED SETTING 
       XCHG           ;EXCHANGE ADDRESSES 
       MOV  M,B       ;STORE NEW SAVE VALUE 
       STAX D         ;STORE NEW CURRENT VALUE
       XCHG           ;RESTORE ADDRESSES
       INX  D         ;INCREMENT TO NEXT VALUE
       INX  H 
       DCR  C         ;ALL VALUES EXCHANGED?
       JNZ  SWP010    ;NO - MOVE NEXT VALUE 
       RET            ;YES - RETURN 
 
;******************** 
; SET SOFT KEY DATA * 
;******************** 
DFS300 EQU  $ 
       CALL CHKSFK    ;SOFT KEY ALREADY ENABLED?
       CZ   SWAP      ;NO - SET SOFT KEY DISPLAY O
       LXI  H,MDFLG1  ;GET SOFT MODE FLAGS
       MOV  A,M 
       PUSH PSW       ;SAVE SOFT MODE FLAGS 
       MVI  M,0       ;FORCE INSERT CHARACTER OFF 
       CALL FDESC1    ;ADD INPUT TO DEFINITION
       POP  PSW       ;RECALL SOFT MODE FLAGS 
       STA  MDFLG1    ;RESTORE ORIGINAL VALUES
       CALL SWAP0     ;RESTORE ACTIVE DISPLAY 
       CALL GETDC1    ;SET DISPLAY CURSOR 
       LXI  H,NEWCOL
       DCR  M         ;ALL CHARACTERS DONE? 
       JP   ESCAP1    ;NO - CONTINUE ESC SEQUENCE 
       LXI  H,DFSTB3  ;YES - SET TO WAIT FOR ANY
       JMP  ESCAPA      ;CHAR EXCEPT CR, LF, OR DC
;******************************************** 
; WAIT FOR CHARACTER TO RESTORE NORMAL MODE * 
;******************************************** 
DFS350 EQU  $         ;LINE FEED CODE 
       CALL DCXB2D    ;DATA FROM KEYBOARD?
       JZ   LNFEED    ;YES - DO LINE FEED 
       RET            ;NO - RETURN TO RE-ENABLE AL
;                       CODES BY CALL TO "ESCEND" 
;                       IN "CHINT" CLEAN-UP 
; 
DFS360 EQU  $         ;RETURN CODE
       CALL DCXB2D    ;DATA FROM KEYBOARD 
       JNZ  ESCAP1    ;NO - CONTINUE WAITING
;                     YES - DO RETURN OPERATION 
;************************************ 
; CRRET - SET CURSOR TO LEFT MARGIN * 
;************************************ 
; 
;  ENTRY:  DON'T CARE 
; 
;  EXIT :  A,CURCOL = LEFT MARGIN SETTING 
;          IF SPOW NOT DISABLED, SPOW SET 
; 
CRRET  EQU  $ 
       LDA  KBJMPR    ;GET STRAP SETTINGS 
       ANI  SPLDIS    ;SPOW DISABLED? 
       JZ   CURPRT    ;YES - RETURN CURSOR ONLY 
       LXI  H,SPOWL   ;NO - SET SPOW LATCH
       MVI  M,SPOWON
CURPRT EQU  $ 
       LDA  LFTMGN    ;SET CURSOR TO LEFT MARGIN
CRRET1 EQU  $ 
       STA  CURCOL    ;UPDATE CURRENT COLUMN NUMBE
       STA  IOCRCL      ;AND SET DISPLAY CURSOR 
       RET            ;RETURN 
 
;********************** 
; DISPLAY ENHANCEMENT * 
;********************** 
DISPEN EQU  $ 
       CALL CHKSFK    ;DEFINE SOFT KEY MODE?
       RNZ            ;YES - NO DISPLAY ENHANCEMEN
       LXI  H,DENTAB  ;SET FOR DISPLAY ENHANCEMENT
       JMP ESCAP0 
;****************************************** 
; DISPLC - ENTER DISPLAY ENHANCEMENT CHAR * 
;****************************************** 
DISPLC EQU $
       LDA  DCHAR     ;GET DISPLAY CHARACTER
       ANI  17Q       ;EXTRACT ENHANCEMENT BITS 
DISPC0 EQU  $ 
       MVI  B,60Q     ;SET MASK TO SAVE ALT CHAR
;***********************************************
; DISPC1 - ENTER ENHANCEMENT OR FLAG CHARACTER *
;***********************************************
; 
;  ENTRY:  A = CHARACTER TO BE STORED 
;          B = MASK TO SAVE UNCHANGED PART (USED
;            ONLY FOR ENHANCEMENT CHARACTERS) 
; 
;  EXIT :  SEE "DISPLA" 
; 
DISPC1 EQU  $ 
       ORI  200Q      ;ADD BIT FOR REFRESH LOGIC
DISPC2 EQU  $ 
       STA  DCHAR     ;STORE NEW ENHANCEMENT CODE 
       MOV  A,B       ;STORE MASK FOR ENHANCEMENT 
       STA  CDSPEN      ;BITS NOT TO BE ALTERED 
;                     FALL INTO DISPLAY ROUTINE 
 
;************************************ 
; DISPLA - ADD CHARACTER TO DISPLAY * 
;************************************ 
; 
;  ENTRY:  CURCOL,CURROW = SCREEN POSITION WHERE
;            CHARACTER IS TO BE INSERTED
;          DCHAR = CHARACTER TO BE DISPLAYED
;          CDSPEN = MASK TO MASK OUT COMMON BITS
;            IF DCHAR IS A DISPLAY CONTROL BYTE 
; 
;  EXIT :  A = 0, NO PLACE FOR CHARACTER
;          A # 0, CHARACTER PROCESSED 
;            B = CHARACTER REPLACED IF ADDITION 
;              DONE BY INSERT 
;              D,E = ADDRESS OF CHAR IN DISPLAY 
; 
DISPLA EQU $
       LDA  DCHAR  ;GET CHAR TO BE STORED 
       ORA A        ;IS THIS ASCII CHAR?
       JP  DIS060   ;YES - CONTINUE 
;************************************ 
; CONTROL CODE TO BE ENTERED INTO   * 
; DATA STREAM - FIND CHAR PRECEDING * 
; THIS COLUMN                       * 
;************************************ 
       LDA  CURCOL    ;GET CURRENT COLUMN NUMBER
       DCR  A         ;SET FOR PREVIOUS COLUMN
       CALL RCADR0    ;DOES LINE EXIST? 
       JM   MLOCK1    ;NO - SOUND BELL AND EXIT 
;                       WITH A-REGISTER = 0 
       JNZ  DIS100    ;COL BEYOND EOL - EXTEND LIN
;************************ 
; PREVIOUS COLUMN FOUND * 
;************************ 
       MOV C,A      ;SAVE COLUMN IN C 
       INR  C         ;SET C TO NEXT COLUMN NUMBER
       CALL CKPROT    ;PREVIOUS CHAR PROTECTED? 
       JNZ  DIS030    ;NO - CONTINUE
DIS020 EQU  $ 
       DCX  D         ;YES - SET PTR TO NEXT CHAR 
       LXI  H,ENDPR*256+XMONLY
       CALL FNDCH     ;IS NEXT CHARACTER PROTECTED
       JZ   DIS092    ;YES - LOOK FOR NEXT FIELD
       LXI  H,CURCOL  ;YES - RECALL COLUMN VALUE
       MOV  C,M 
 
;*********************************
; SEARCH FOR PLACE FOR CHARACTER *
;*********************************
DIS030 EQU $
       CALL NXTCHR  ;GET NEXT CHAR
       MOV  B,A       ;SAVE EXISTING CHAR IN B-REG
       LXI  H,DCHAR 
       CPI  STPFLG    ;NON-DISPLAYING TERMINATOR? 
       JZ   DIS035    ;YES - DELETE IT
       CPI  EOL       ;EXISTING CHARACTER AN EOL? 
       MOV  A,M         ;(GET CHAR TO BE DISPLAYED
       JZ   DIS050    ;YES - ADD CHARACTER TO LINE
       CPI  STPFLG    ;NON-DISPLAYING TERMINATOR? 
       JZ   CRI104    ;YES - INSERT TERMINATOR
       MOV  A,B       ;NO - RECALL EXISTING CHAR
       ADD  A         ;EXISTING CHARACTER ASCII?
       MOV  A,M         ;(GET CHAR TO BE DISPLAYED
       JNC  DIS050    ;YES - INSERT NEW CHARACTER 
       JM   DIS040    ;FLAG CHAR - ADD FLAG TO DIS
       ADD  A         ;NEW CHAR DISPLAY CONTROL?
       JM   DIS030    ;NO - GO TO NEXT CHARACTER
;***********************************
; MERGE NEW DISPLAY ENHANCEMENT    *
; WITH CODE ALREADY IN THIS COLUMN *
;***********************************
       LDA  CDSPEN    ;GET ENHANCEMENT MASK 
       ANA B        ;EXTRACT BITS TO BE SAVED 
       ORA  M         ;COMBINE WITH NEW ENHANCEMEN
       JMP  DIS044    ;STORE THE NEW DISPLAY CODE 
;********************************************** 
; NON-DISPLAYING TERMINATOR FOUND - DELETE IT * 
;********************************************** 
DIS035 EQU  $ 
       CMP  M         ;IS NEW CHAR TERMINATOR ALSO
       RZ             ;YES - RETURN 
       CALL CHRDL2    ;NO - DELETE THE CHARACTER
       JMP  DIS030    ;CONTINUE SCAN
 
;****************** 
; FLAG CHAR FOUND * 
;****************** 
DIS040 EQU $
       CMP B        ;IS THIS SAME FLAG CHAR?
       RZ             ;YES - RETURN (A # 0) 
       ADD  A         ;NEW CHARACTER DISPLAY CNTL?
       RAR              ;(RESTORE CHARACTER)
       JP   DIS045    ;YES - CHECK PROTECTED FIELD
       CPI  ALPHA     ;IS NEW CHAR TYPE DEFINITION
       MOV  A,B         ;(RECALL OLD FLAG CHAR) 
       JM   DIS042    ;NO - ADD FIELD DEFINITION
       CPI  ALPHA     ;IS OLD CHAR TYPE DEFINITION
       JP   DIS043    ;YES - REPLACE THE CHARACTER
       JMP  DIS030    ;NO - GO TO NEXT CHARACTER
;***********************************************
; FIELD DEFINITION CHARACTER TO BE ADDED - PUT *
;   AHEAD OF TYPE DEFINITION OR AFTER "STPR"   *
;***********************************************
DIS042 EQU  $ 
       CPI  ALPHA     ;IS OLD CHAR TYPE DEFINITION
       JP   CRI104    ;YES - INSERT FIELD DEF 
       MVI  A,STPR    ;NO - STORE NEW FIELD DEF 
       CMP  B         ;OLD CHAR = START PROTECT?
       JZ   DIS030    ;YES - LOOK TO NEXT CHAR
       CMP  M         ;IS NEW CHAR A STPR?
       JZ   CRI104    ;YES - INSERT BEFORE UNPROTC
;*************************************
; REPLACE EXISTING DISPLAY CHARACTER *
;*************************************
DIS043 EQU  $ 
       LDAX D         ;PUT EXISTING CHARACTER INTO
       MOV  B,A         ;B-REG FOR SOFT KEY CHECK 
       LDA  DCHAR     ;GET CHAR TO BE DISPLAYED 
       LXI  H,SPOWL   ;CHECK AGAINST SPOW LATCH 
       CMP  M         ;INPUT = SPACE AND SPOW SET?
       RZ             ;YES - RETURN (A # 0) 
DIS044 EQU  $ 
       STAX D         ;STORE THE NEW CHARACTER
       INR  A         ;FORCE A # 0
       RET            ;RETURN 
 
;****************************** 
; FLAG CHAR FOUND AND         * 
; DISPLAY CONTROL TO BE ADDED * 
;****************************** 
DIS045 EQU  $ 
       MOV  A,B       ;RECALL EXISTING CHARACTER
       CPI  STPR      ;BEGINNING A PROTECTED FIELD
       JNZ  DIS030    ;NO - MOVE TO NEXT CHAR 
       CALL CHKFMS    ;FORMAT MODE? 
       JZ   DIS030    ;NO - ADD CHAR TO DISPLAY 
       JMP  DIS020    ;YES - LOOK FOR NEXT FIELD
;*****************************************
; ASCII OR EOL FOUND                     *
; MERGE NEW DISPLAY CONTROL IF NECESSARY *
;*****************************************
DIS050 EQU  $ 
       ADD  A         ;NEW CHAR DISPLAY CONTROL?
       JM   DIS054    ;NO - ADD CHAR TO DISPLAY 
       LDA  CDSPEN    ;YES - GET MASK 
       MVI  L,LSTDCD-BASE  ;GET LAST ENHANCEMENT
       ANA M        ;EXTRACT BITS TO BE SAVED 
       MVI  L,DCHAR-BASE
       ORA  M         ;COMBINE WITH NEW ENHANCEMEN
       MOV M,A      ;STORE
DIS054 EQU $
       MOV A,B      ;WAS CHAR ASCII?
       ORA A
       JP  CRI104   ;YES - DO INSERT
       MVI C,0      ;NO - ADD SINGLE CHAR 
       JMP DIS110 
 
;*****************************************
; ENTER ASCII CHARACTER INTO DATA STREAM *
;*****************************************
DSPASC EQU  $ 
DIS060 EQU $
       CALL RCADDR  ;GET MEMORY ADDRESS 
       JZ  DIS080   ;CHAR FOUND BY RCADDR 
DISPL0 EQU $
       JM  DIS070   ;RETURN IF LINE NOT BUILT 
       DCR C
       JNZ DIS100   ;MORE THAN ONE CHAR NEEDED
;******************************** 
; SINGLE CHARACTER REQUIRED     * 
; CHECK FOR LAST COLUMN OF LINE * 
;******************************** 
       CPI MAXCOL   ;COMPARE WITH MAX COLUMN
       JNZ DIS110   ;NOT MAXIMUM COLUMN 
       JMP DIS090 
;******************************** 
; LINE NOT BUILT                * 
; PERFORM HOMEUP IF FORMAT MODE * 
;******************************** 
DIS070 EQU  $ 
       CALL CHKFMS    ;FORMAT MODE? 
       RZ             ;NO - RETURN (A = 0)
       CALL ZBELL     ;YES - SOUND BELL 
       JMP  DIS093    ;HOME UP AND TRY AGAIN
 
;************************ 
; CHARACTER REPLACEMENT * 
;************************ 
DIS080 EQU $
       MOV C,A      ;SAVE COLUMN IN C 
       LDA  MDFLG1    ;GET TERMINAL MODE FLAGS
       ANI  INSCHR    ;IN CHARACTER INSERT MODE?
       JZ   DIS090    ;NO - ADD CHARACTER TO DISPL
       LDA  EOLMV     ;YES - GET EOL SHIFTED FLAG 
       ORA  A         ;HAS LINE BEEN EXTENDED?
       JZ   CRI100    ;NO - PERFORM INSERT CHAR 
DIS090 EQU  $ 
       CALL CKPROT    ;CURSOR IN PROTECTED FIELD? 
       JNZ  DIS043    ;NO - STORE THE CHARACTER 
DIS092 EQU  $ 
       CALL DCXB2D    ;DATA COMM OR I/O BUFF CHAR?
       CZ   ZBELL     ;NO - SOUND THE BELL
       LDA  DCHAR     ;GET CHAR TO BE DISPLAYED 
       ORA  A         ;IS IT A CONTROL CHARACTER? 
       RM             ;YES - DON'T TAB (RETURN A#0
       CALL FLDSR   ;NO - TAB TO NEXT FIELD 
       JNZ DISPLA   ;JUMP IF FIELD FOUND
DIS093 EQU  $ 
       CALL CURPH1    ;ANY FIELDS IN DISPLAY? 
       JNZ  DISPLA    ;YES - ADD CHARACTER TO FIEL
       RET            ;NO - RETURN (A # 0)
 
;*************************************************
; LINE MUST BE EXTENDED TO ACCOMODATE CHARACTER  *
;   - EXTEND TO ONE COLUMN BEFORE DESIRED COLUMN *
;*************************************************
; 
;  ENTRY:  C = NUMBER OF CHARACTERS REQUIRED
; 
DIS100 EQU  $ 
       DCR  C         ;MORE THAN ONE CHAR TO ADD? 
       JNZ  DIS110    ;NO - ADD MULTIPLE CHARACTER
       CALL CKPROT    ;CURSOR IN PROTECTED FIELD? 
       JZ   DIS092    ;YES - TAB TO NEXT FIELD
       LXI  H,NCHAR   ;NO - SET "NCHAR" TO STORE
       MVI  M,1         ;BLANK OVER EOL (I.E.,
;                       MAKE DISPLAY ROUTINE
;                       THINK MORE THAN ONE 
;                       CHARACTER BEING ADDED)
       CALL DISPL2    ;EXTEND LINE BY ONE CHARACTE
       JMP  DIS114    ;CHECK MEMORY LOCKED
; 
DIS110 EQU  $ 
       CALL CKPROT    ;CURSOR IN PROTECTED FIELD? 
       JZ   DIS092    ;YES - TAB TO NEXT FIELD
       CALL DISPL1    ;NO - EXTEND LINE 
DIS114 EQU  $ 
       ORA  A         ;MEMORY LOCKED? 
       RZ             ;YES - RETURN FAIL (A = 0)
       LDA  NCHAR     ;GET # OF CHARACTERS ADDED
       DCR  A         ;SINGLE CHARACTER ADDED?
       JP   DISPLA    ;NO - TRY TO STORE AGAIN
       RET            ;YES - STORE DONE BY DISPLAY
;                       (A # 0) 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  DSPTST - DISPLAY TEST PATTERN
; 
;      ENTRY:  A = CHARACTER TO BE DISPLAYED
; 
;      EXIT :  A,B,C,D,E,L DESTROYED
; 
DSPTST EQU $
       STA  DCHAR  ;PUT CHAR IN DISPLAY BUFFER
       CALL SETDF0    ;SET DATA COMM INPUT FLAG TO
;                       INHIBIT BELL ON FIELD SKIP
; 
;  DSPCHR - DISPLAY CHARACTER IN DCHAR
; 
DSPCHR EQU  $ 
       LXI  H,CURADV  ;SET NORMAL EXIT ROUTINE
DSPCH0 EQU  $ 
       PUSH H         ;SAVE NORMAL EXIT ROUTINE 
       CALL DSPASC    ;ADD ASCII CHAR TO DISPLAY
       ORA  A         ;CHARACTER DISPLAYED? 
       JZ   DCH100    ;NO - DON'T MOVE CURSOR 
;                     FALL INTO DISPLAY ROUTINE 
 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       RZ             ;NO - DO NORMAL EXIT
       CALL DCXB2D    ;DATA COMM OR I/O BUFF CHAR?
       RNZ            ;NO - DO NORMAL EXIT
       LDA  DCHAR     ;GET CHARACTER DISPLAYED
       LHLD CHKRTN    ;NO - GET CHECK ROUTINE ADDR
       RST  RSTJMP    ;IS IT A VALID CHARACTER? 
       RZ             ;YES - DO NORMAL EXIT 
       POP  PSW       ;NO - POP OFF NORMAL EXIT AD
; 
;  FIELD CHECK ERROR - LOCK UP UNTIL BACKSPACE HIT
; 
       XRA  A         ;CLEAR OUT INPUT CHARACTER
       STA  CHARIN      ;TO KILL FUNCTION KEYS
DCH010 EQU  $ 
       CALL ZBELL     ;SOUND BELL 
DCH020 EQU  $ 
       CALL IOCTMN    ;MONITOR THE TAPE DRIVES
       CALL ZGETKY    ;ANY KEY HIT? 
       JNZ  DCH020    ;NO - CONTINUE WAITING
       CPI  CR        ;IS IT THE RETURN KEY?
       JNZ  DCH010    ;NO - SOUND BELL, TRY AGAIN 
       MVI  A,STPRPT  ;YES - STOP RETURN KEY
       JMP  ZKBCTL      ;FROM REPEATING AND EXIT
;****************************************** 
; CHARACTER NOT DISPLAYED - SOUND BELL IF * 
;   CHARACTER FROM KEYBOARD               * 
;****************************************** 
DCH100 EQU  $ 
       POP  H         ;POP OFF NORMAL EXIT ROUTINE
DSPCH1 EQU  $ 
       CALL DCXB2D    ;INPUT FROM KEYBOARD
       JZ   ZBELL     ;YES - SOUND BELL AND EXIT
       RET            ;NO - RETURN ONLY 
 
;******************************************** 
; EXPAND - EXPAND DISPLAY CONTROL TO ESCAPE * 
;   SEQUENCE                                * 
;******************************************** 
; 
;  ENTRY:  A,C = DISPLAY CONTROL BYTE 
; 
;  EXIT :  H = BASEH
;          A,B,L DESTROYED
; 
EXPAND EQU  $ 
       CALL INITD1    ;INITIALIZE CHAR BUFFER PTRS
       ADD  A         ;IS CHAR DISPLAY CONTROL? 
       RAR              ;(RESTORE CHARACTER)
       JM   EXP100    ;NO - EXPAND FORMAT CONTROL 
       LXI  H,ENHOUT  ;YES - COMPARE TO PREVIOUS
       XRA  M         ;ANY CHANGES? 
       RZ           ;NO - RETURN IMMEDIATELY
       ANI 17Q      ;CHANGE IN ENHANCEMENT? 
       JZ   EXP010    ;NO - CHECK NEW CHARACTER SE
       MVI  B,AMPSND  ;YES - OUTPUT ENHANCEMENT 
       CALL ECOUTB      ;ESCAPE SEQUENCE: 
       MVI  A,SMALLD    ;<ESC>-<&>-<LOWER CASE D> 
       CALL A2OUTB
       MOV  A,C       ;COMPUTE ENHANCEMENT
       ANI  17Q         ;PARAMETER (@-O)
       ORI  100Q      ;ADJUST TO ASCII LETTER 
       CALL A2OUTB    ;PUT IT INTO OUTPUT BUFFER
       MVI  L,ENHOUT-BASE  ;CHECK CHARACTER SET 
 
; 
;  CHECK FOR CHARACTER SET CHANGE 
; 
EXP010 EQU $
       MOV A,C      ;RECALL CURRENT SETTING 
       XRA M        ;COMPARE TO PREVIOUS VALUE
       ANI 60Q      ;ANY CHANGE IN CHAR SET?
       MOV M,C      ;(SAVE NEW SETTING) 
       RZ           ;NO - RETURN
       MOV A,C      ;YES - RECALL NEW SETTING 
       ANI 60Q      ;RETURN TO BASE SET?
       JZ  EXP030   ;YES - SEND SHIFT IN (SI) 
       MVI  L,CALTST-BASE  ;IS IT THE SAME
       CMP  M                ;ALTERNATE CHAR SET? 
       JZ  EXP020   ;YES - SEND SHIFT OUT ONLY
       MOV M,A      ;NO - SAVE NEW ALTERNATE
; 
;  GENERATE ESCAPE SEQUENCE FOR ALTERNATE 
;    CHARACTER SET SPECIFIER
; 
       MVI  B,ARPARN  ;OUTPUT <ESC> 
       CALL ECOUTB      ;<RIGHT PARENTHESIS>
       MOV  A,C 
       ANI 60Q      ;COMPUTE ALTERNATE CHARACTER
       RRC          ;SET PARAMETER
       RRC
       RRC
       RRC
       ADI 100Q 
       CALL A2OUTB    ;SEND IT
; 
EXP020 EQU $
       MVI A,SO     ;SEND SHIFT OUT (SO)
       JMP  A2OUTB      ;AND RETURN 
; 
EXP030 EQU $
       MVI A,SI     ;SEND SHIFT IN
       JMP  A2OUTB      ;AND RETURN 
 
; 
;  EXPAND ON FORMAT CONTROL 
; 
EXP100 EQU  $ 
       CPI  XMONLY    ;TRANSMIT ONLY CONTROL? 
       MVI  B,LFTBRC    ;(SET FOR LEFT BRACE) 
       JZ   ECOUTB    ;YES - OUTPUT AND EXIT
       JP   EXP110    ;TYPE DEF - OUTPUT NUMBER 
       CPI  ENDPR     ;END PROTECT? 
       MVI  B,LFTBKT    ;(SET FOR LEFT BRACKET - [
       JZ   ECOUTB    ;YES - OUTPUT AND EXIT
       INR  B         ;NO - ALTER CHAR TO  RIGHT
       INR  B           ;BRACKET AND OUTPUT IT
       JMP  ECOUTB
; 
;  TYPE DEFINITION - OUTPUT NUMERIC TERMINATOR
; 
EXP110 EQU  $ 
       CPI  SFKYAT    ;IS CODE VALID? 
       MVI  B,ADEL      ;(SET DEL CHAR FOR INVALID
       JP   B2OUTB    ;NO - RETURN DEL CHARACTER
       CPI  FILL      ;FILL CODE? 
       JZ   B2OUTB    ;YES - RETURN DEL CHARACTER 
       SUI  ALPHA-6-ZERO  ;COMPUTE ASCII DIGIT
       MOV  B,A       ;PUT CHARACTER INTO B-REG 
       JMP  ECOUTB    ;OUTPUT THE ESCAPE SEQUENCE 
 
; 
;  GET DISPLAY DATA 
; 
GDS010 EQU  $ 
       CALL CHKSFK    ;SOFT KEY MODE? 
       JZ   GDS050    ;NO - DO NORMAL PROCEDURE 
       LDA  CURROW    ;YES - GET CURSOR ROW 
       CPI  SFTEND    ;BEYOND SOFT KEY DATA?
       JP   GDS160    ;YES - RETURN END OF DISPLAY
       RRC            ;IN ATTRIBUTE ROW?
       JC   GDS030    ;NO - OUTPUT DISPLAY DATA 
       MVI  B,AMPSND  ;YES - START ESCAPE SEQUENCE
       CALL INITD1    ;INIT OUTPUT BUFFER POINTERS
       CALL ECOUTB    ;SEND <ESC>-<&> 
       MVI  A,SMALLF    ;<LOWER CASE F> 
       CALL A2OUTB
       LDA  CURROW
       RRC              ;<KEY NUMBER> 
       INR  A 
       ORI  ZERO
       CALL A2OUTB
       MVI  A,SMALLK    ;<LOWER CASE K> 
       CALL A2OUTB
       LHLD LSTLIN    ;GET ADDRESS OF CURRENT 
       MOV  A,L         ;LINE 
       SUI  ATBLOC    ;COMPUTE LOCATION OF
       MOV  L,A         ;ATTRIBUTE CODE 
       MOV  A,M       ;GET ATTRIBUTE CODE 
       MVI  B,ZERO    ;COMPUTE ATTRIBUTE CODE:
       CPI  N 
       JZ   GDS020      ;0 = NORMAL 
       INR  B           ;1 = LOCAL ONLY 
       CPI  L           ;2 = TRANSMIT ONLY
       JZ   GDS020
       INR  B 
GDS020 EQU  $ 
       CALL B2OUTB    ;OUTPUT ATTRIBUTE CODE
       MVI  A,SMALLA
       CALL A2OUTB    ;OUTPUT <LOWER CASE A>
       MVI  A,FRSOUT  ;SET FLAG TO INDICATE FIRST 
       CALL SETMF2      ;SOFT KEY DATA OUT
       CALL FLDSR     ;LOCATE THE DATA FIELD
       XCHG 
       SHLD GETADR    ;SAVE FIRST CHAR ADDRESS
;                     RESTART "GETDSP" TO OUTPUT
;                       FIRST SOFT KEY CHAR 
 
; 
; * * * * * * * * * * * * * * * * * * * * * * * * 
; 
;  GETDSP - GET A CHARACTER FROM DISPLAY
; 
;      ENTRY:  CURADR = ADDR OF DISPLAY BYTE
;              CURCOL = COLUMN OF NEXT BYTE 
; 
;      EXIT :  NC - CHARACTER FOUND 
;                A = CHARACTER
;                GETADR,CURCOL UPDATED
;              C - NO CHARACTER 
;                M - END OF DISPLAY 
;                Z - END OF FIELD 
;                P,NZ - END OF LINE 
;              B-L DESTROYED
; 
GETDSP EQU  $ 
       LXI  H,B2DPTR  ;GET EXPANSION BUFFER 
       MOV  A,M         ;POINTER
       DCX  H         ;SET ADDRESS TO END POINTER 
       CMP  M         ;BUFFER EMPTY?
       JZ   GDS010    ;YES - GET BYTE FROM DISPLAY
       INR  L         ;NO - INCREMENT POINTER AND 
       INR  A           ;STORE IT 
       MOV  M,A 
       MOV  L,A       ;SET BUFFER ADDRESS 
       MOV  A,M       ;GET THE DATA BYTE
       ORA  A         ;SET C = FALSE
       RET            ;RETURN CHARACTER FOUND 
 
; 
;  GET SOFT KEY DATA
; 
GDS030 EQU  $ 
       LXI  H,MFLGS2  ;GET MODE FLAGS 
       MOV  A,M       ;MASK OUT FIRST OUTPUT FLAG 
       ANI  377Q-FRSOUT 
       CMP  M         ;FIRST DATA?
       JZ   GDS050    ;NO - GET NEXT DATA 
       MOV  M,A       ;YES - UPDATE FLAG
       CALL INITD1    ;INITIALIZE CHAR BUFFER PTRS
       LHLD GETADR    ;LOCATE END OF LINE 
       XCHG           ;PUT START ADDRESS IN D,E 
       MVI  A,MAXCOL  ;SEARCH TO END OF LINE
       CALL FNDLS0    ;ANY "EOL" IN DATA LINE?
       MVI  A,MAXCOL+1  ;(SET FOR NO EOL LENGTH=80
       JM   GDS040    ;NO - OUTPUT VALUE MAXCOL+1 
       SUB  B         ;YES -  COMPUTE EOL LOCATION
GDS040 EQU  $ 
       PUSH PSW       ;SAVE DATA LENGTH 
       LXI  H,A2OUTB  ;SET OUTPUT ROUTINE ADDRESS 
       CALL BN2DE1    ;CONVERT AND STORE IN BUFFER
       MVI  A,L       ;OUTPUT UPPER CASE L
       CALL A2OUTB
       POP  PSW       ;RECALL DATA LENGTH 
       DCR  A         ;DOES DATA EXIST? 
       MVI  A,ABLNK     ;(SET TO ADD BLANK) 
       CM   A2OUTB    ;NO - ADD A BLANK TO OUTPUT 
       JMP  GETDSP    ;OUTPUT LENGTH PARAMETER
 
; 
;  GET NEXT BYTE FROM DISPLAY 
; 
GDS045 EQU  $         ;ENTRY TO SKIP TERMINATOR 
       MOV  M,A       ;UPDATE "DFLGS" TO CLEAR
;                       SKIP TERMINATOR FLAG
GDS050 EQU  $ 
       LHLD GETADR  ;GET CURRENT ADDRESS
       XRA  A 
       ORA  L         ;END OF DISPLAY?
       JZ   GDS150    ;YES - TERMINATE
GDS060 EQU  $ 
       MOV  A,M 
       DCX  H         ;DECREMENT TO NEXT BYTE 
       SHLD GETADR    ;UPDATE "GETADR"
       ORA  A         ;IS BYTE ASCII? 
       JP   GDS100    ;YES - RETURN CHARACTER 
       CPI  LNKLIM    ;IS IT A LINK?
       JC   GDS200    ;NO - PROCESS DISPLAY CONTRO
       MOV  L,M       ;YES - SET NEW ADDRESS
       MOV  H,A 
       MOV  A,L       ;PUT LSB INTO A-REGISTER
       CMA
       ANI  BLKSM     ;IS IT AN END OF LINE LINK? 
       JZ   GDS060    ;NO - CONTINUE THRU CHAIN 
       JMP  GDS320    ;YES - CHECK TERMINATON 
 
; 
;  ASCII BYTE FOUND - RETURN CHARACTER FOUND
; 
GDS100 EQU  $ 
       MOV  B,A       ;SAVE THE CHARACTER 
       LXI  D,CURCOL
       LDAX D         ;INCREMENT CURSOR COLUMN
       INR  A           ;POSITION 
       STAX D 
       STA  IOCRCL    ;UPDATE DISPLAY CURSOR
       LDA  BLKTRM    ;GET BLOCK TERMINATOR CHAR
       CMP  B         ;IS CHAR = BLOCK TERMINATOR?
       MVI  A,377Q-SKPTRM  ;(SET CLEAR FLAG)
       JZ   GDS110    ;YES - RETURN TERMINATION 
       CALL CLRDFL    ;NO - CLEAR SKIP FLAG 
       MOV  A,B       ;RECALL DISPLAY CHARACTER 
       RET            ;RETURN (NC FROM "CLRDFL")
;******************************************** 
; BLOCK TERMINATOR - CHECK FOR END OF LINE, * 
;   RETURN END OF DISPLAY                   * 
;******************************************** 
GDS110 EQU  $ 
       LXI  H,DFLGS   ;CLEAR SKIP TERMINATOR FLAG 
       ANA  M 
       CMP  M         ;WAS SKIP FLAG SET? 
       JNZ  GDS045    ;YES - IGNORE TERMINATOR
       LDAX D         ;NO - TERMINATE TRANSMISSION
       CPI  MAXCOL+1  ;WAS RS IN LAST COLUMN? 
       CZ   CRLF      ;YES - DO CR,LF 
; 
;  RETURN END OF DISPLAY
; 
GDS150 EQU  $ 
       CALL FLDSRX    ;SET "LSTCOL" TO MAXCOL+1 TO
;                       FORCE LINE RE-SCAN
GDS160 EQU  $ 
       XRA  A         ;SET A TO -1
       DCR  A 
       STC            ;SET C-FLAG TRUE
       RET            ;RETURN 
 
; 
;  NON-ASCII BYTE PROCESSING
; 
GDS200 EQU  $ 
       CPI  EOP       ;END OF DISPLAY?
       JZ   GDS150    ;YES - RETURN END OF DISPLAY
       CPI  STPFLG    ;NON-DISPLAYING TERMINATOR? 
       JZ   GDS230    ;YES - RETURN END OF DISPLAY
       CPI  EOL       ;END OF LINE? 
       JZ   GDS300    ;YES - RETURN END OF LINE 
       CPI  FILL      ;FILL BYTE? 
       JZ   GDS060    ;YES - GET NEXT BYTE
       MOV  C,A       ;NO - SAVE THE BYTE 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JNZ  GDS210    ;YES - LOOK FOR START PROTEC
       LDA  IOFLG2    ;NO - GET I/O FLAGS 2 
       ANI  XDS2BF    ;DISPLAY TO I/O BUFFER? 
       MOV  A,C         ;(RECALL DATA BYTE) 
       RNZ            ;YES - RETURN UNEXPANDED BYT
       CALL EXPAND    ;NO - EXPAND DISPLAY CONTROL
       JMP  GETDSP    ;RETURN 1ST EXPANDED CHAR 
; 
;  FORMAT MODE - IGNORE ALL DISPLAY CONTROL EXCEPT
;    FOR START PROTECT
; 
GDS210 EQU  $ 
       MOV  A,C       ;RECALL THE DATA BYTE 
       CPI  STPR      ;IS IT START PROTECT? 
       JNZ  GDS060    ;NO - IGNORE THE BYTE 
       XCHG           ;YES - PUT GETADR INTO D,E
       LHLD CURROW    ;SAVE ENDING ROW AND
       LDA  TLINO       ;COLUMN+1 FOR FIELD 
       ADD  L 
       MOV  L,A       ;SAVE ABSOLUTE ROW NUMBER 
       SHLD ENDROW
GDS220 EQU  $ 
       CALL GTMOD1    ;PAGE MODE/DISPLAY -> BUFFER
       JZ   GDS225    ;NO - RETURN END OF FIELD 
       CALL FLDSR1    ;ANY MORE FIELDS? 
       JZ   GDS150    ;NO - EXIT END OF DISPLAY 
       XCHG           ;YES - STORE NEW GETADR 
       SHLD GETADR
GDS225 EQU  $ 
       XRA  A         ;RETURN END OF FIELD
       STC              ;(C = TRUE, A = 0)
       RET
 
;********************************************** 
; NON-DISPLAYING TERMINATOR FOUND - CHECK FOR * 
;   AUTO CLEAR OPTION                         * 
;********************************************** 
GDS230 EQU  $ 
       LDA  KBJMP2    ;GET JUMPERS SET 2
       ANI  CLRTRM    ;CLEAR TERMINATOR?
       LDA  CURCOL      ;(SET CURRENT COLUMN) 
       MOV  C,A 
       LHLD GETADR      ;(SET LOCATION OF 
       INX  H              ;TERMINATOR) 
       XCHG             ;(PUT ADDRESS INTO D,E) 
       CNZ  CHRDL2    ;YES - CLEAR THE BYTE 
       XCHG 
       DCX  H         ;SET LAST CHARACTER ADDRESS 
       JMP  GDS150    ;RETURN END OF DISPLAY
 
; 
;  END OF LINE - PAD OUT LINE IF FORMAT MODE
; 
GDS300 EQU  $ 
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JZ   GDS310    ;NO - ADVANCE TO NEXT LINE
       JM   GDS310    ;SOFT KEY - SKIP TO NEXT LIN
       LXI  D,CURCOL  ;FORMAT - BLANK FILL
       LDAX D         ;GET CURRENT CURSOR COLUMN
       CPI  MAXCOL+1  ;LINE COMPLETED?
       JZ   GDS310    ;YES - ADVANCE TO NEXT LINE 
       INR  A         ;NO - INCREMENT COLUMN
       STAX D           ;NUMBER 
       STA  IOCRCL    ;UPDATE DISPLAY CURSOR
       INX  H         ;RESTORE "GETADR" TO LOCATIO
       SHLD GETADR      ;OF "EOL" 
       MVI  A,ABLNK   ;RETURN BLANK 
       ORA  A         ;CLEAR C-FLAG 
       RET            ;RETURN 
; 
GDS310 EQU  $ 
       CALL CHAIN1    ;GET ADDR OF NEXT LINE LINK 
 
; 
;  EOL LINK FOUND - DETERMINE TERMINATION TYPE
; 
GDS320 EQU  $ 
       MOV  A,M       ;GET POINTER TO NEXT LINE 
       DCX  H 
       MOV  L,M 
       MOV  H,A 
       SHLD GETADR    ;PUT IT INTO "GETADR" 
       XRA  A         ;PUT CURSOR IN COLUMN ZERO
       STA  ENHOUT    ;CLEAR LAST ENHANCE OUT FLAG
       CALL CRRET1
       CALL CHKFMS    ;FORMAT/SOFT KEY DEFINE MODE
       JZ   GDS360    ;NEITHER - SEND END OF LINE 
       JM   GDS350    ;SOFT KEY - FIND NEXT FIELD 
       LHLD CURROW    ;FORMAT - SAVE ENDING ROW AN
       LDA  TLINO       ;COLUMN+1 FOR FIELD 
       ADD  L 
       MOV  L,A       ;SAVE ABSOLUTE ROW NUMBER 
       SHLD ENDROW
       CALL LNFEED    ;YES - DO LINE FEED 
       CALL DISLN1    ;SET DISPLAY CURSOR ROW 
       LHLD GETADR    ;RECALL POINTER TO NEXT LINE
       MOV  A,L       ;GET LSB VALUE
       ORA  A         ;END OF DISPLAY (LSB = 0)?
       JZ   GDS160    ;YES - RETURN END OF DISPLAY
; 
;  FORMAT EOL - CHECK FOR CONTINUATION FIELD
; 
       XCHG           ;PUT CURRENT ADDR IN D,E
       CALL FLDSR2    ;NEXT LINE CONTINUES FIELD? 
       JNZ  GDS220    ;NO - RETURN END OF FIELD 
       XCHG           ;YES - CONTINUE PROCESSING
       LDA  IOFLG2    ;GET I/O FLAGS 2
       ANI  XDS2BF    ;DISPLAY TO I/O BUFFER? 
       JZ   GDS060    ;YES - CONTINUE FIELD 
       SHLD GETADR    ;NO - STORE NEW "GETADR"
       STC            ;RETURN END OF LINE 
       RET            ;RETURN NZ, C 
 
;***********************************************
; END OF LINE FOR NON-FORMAT MODE - RETURN END *
;   OF LINE CODE (C, P, NZ)                    *
;***********************************************
GDS350 EQU  $         ;SOFT KEY END OF LINE 
       CALL LNFEED    ;LOCATE THE ATTRIBUTE OF THE
       CALL FLDSR       ;NEXT DEFINITION
GDS360 EQU  $         ;NON-FORMAT/SOFT KEY EOL
       XRA  A         ;SET NZ,P 
       INR  A 
       STC            ;SET C-TRUE 
       RET            ;RETURN END OF LINE 
 
;************************************** 
; INITDG - INITIALIZE FOR DISPLAY GET * 
;************************************** 
; 
;  EXIT :  Z - CHARACTER FOUND
;            GETADR = ADDRESS OF FIRST CHARACTER
;          NZ - NO CHARACTER FOUND
;            GETADR UNCHANGED 
;          ALL REGISTERS DESTROYED
; 
;  DISPLAY GET ROUTINE IS SET TO START
;  AT CURRENT CURSOR LOCATION 
; 
INITD0 EQU  $         ;ENTRY FOR DISPLAY TO I/O 
       CALL CHKFMT    ;FORMAT MODE ENABLED? 
       JNZ  INITDG    ;YES - DON'T MOVE CURSOR
       STA  CURCOL    ;NO - BEGIN AT LINE START 
INITDG EQU  $ 
       CALL SETDF0    ;SET DATA COMM INPUT FLAG TO
;                       ENABLE TRANSMIT ONLY DATA 
       ANI  377Q-NOSEND  ;CLEAR NO DATA FLAG
       CMP  M         ;WAS IT SET BEFORE? 
       MOV  M,A         ;(SET NEW VALUE)
       RNZ            ;YES - RETURN NO DATA 
       MVI  L,IOFLG2-BASE  ;CLEAR DISPLAY BOUNDARY
       MOV  A,M         ;FLAGS
       ANI  377Q-ENDDSP-DSPBTM
       MOV  M,A 
 
; 
;  LOCATE FIRST CHARACTER 
; 
       CALL CHKSFK    ;SOFT KEY MODE? 
       JZ   IDG055    ;NO - LOCATE THE FIRST CHAR 
       LXI  H,CURROW  ;YES - CHECK CURSOR POSITION
       MVI  A,SFTEND
       CMP  M         ;CURSOR BELOW DATA AREA?
       RM             ;YES - RETURN NO CHARACTER
       MVI  A,376Q    ;NO - SET CURSOR ROW TO 
       ANA  M           ;ATTRIBUTE ROW
       MOV  M,A 
       XRA  A         ;SET CURSOR COLUMN TO 
       INX  H           ;BEGINNING OF ROW 
       MOV  M,A 
;                     LOCATE ATTRIBUTE
; 
IDG055 EQU  $ 
       MVI  A,IGNTRM  ;SET TO IGNORE NON-DISPLAYIN
       STA  TRMFCT      ;TERMINATORS
       CALL RCADR4    ;DISPLAY PRESENT? 
       RM             ;NO - RETURN NO CHARACTER 
       JZ   IDG060    ;CHARACTER - CHECK PROTECTED
       CALL CHKFMT    ;EOL - FORMAT MODE? 
       JZ   IDG100    ;NO - EXIT WITH EOL 
       JMP  IDG070    ;YES - CHECK PROTECTED
; 
IDG060 EQU  $ 
       LXI  H,PROFLD  ;SET PROTECT STATUS 
       MOV  M,B 
IDG070 EQU  $ 
       CALL CKPROT    ;CURSOR IN PROTECTED FIELD? 
       JNZ  IDG090    ;NO - RETURN CHARACTER FOUND
       MVI  A,STPXFR  ;SET TERMINATOR FUNCTION TO 
       STA  TRMFCT      ;TERMINATE TRANSFER 
       CALL FLDSR1    ;ANY MORE FIELDS? 
       JZ   NZEXIT    ;NO - RETURN NO CHARACTER 
IDG090 EQU  $ 
       LXI  H,377Q    ;INITIALIZE PREVIOUS FIELD'S
       SHLD ENDROW      ;ROW AND COLUMN TO ZERO 
 
; 
;  CHARACTER FOUND - RETURN CHARACTER FOUND 
; 
IDG100 EQU  $ 
       LDAX D         ;GET FIRST CHARACTER
       CPI  STPFLG    ;NON-DISPLAYING TERMINATOR? 
       CZ   NXTCHR    ;YES - GET THE NEXT CHARACTE
       XCHG           ;SAVE ADDRESS OF BYTE 
       SHLD GETADR
       LDA  ALTOUT    ;SET CURRENT ALTERNATE CHAR 
       STA  CALTST      ;SET TO DEFAULT VALUE 
       LDA  LSTDCD    ;SET LAST ENHANCEMENT OUT 
       STA  ENHOUT      ;WORD 
       CMP  A         ;SET Z-FLAG TRUE
INITD1 EQU  $         ;INITIALIZE CHARACTER BUFFER
       LXI  H,(B2DBFL-1)*256+B2DBFL-1;POINTERS
       SHLD B2DEND
       RET            ;RETURN 
 
;*************************************************
; STAT2 - SEND SECONDARY TERMINAL STATUS REQUEST *
;*************************************************
STAT2  EQU  $ 
       LXI  B,SSTAT2  ;SET SECONDARY STATUS PENDIN
       JMP  SBLXF0      ;FLAG 
;********************************************** 
; STA2GO - TRANSMIT SECONDARY TERMINAL STATUS * 
;********************************************** 
STA2GO EQU  $ 
       LXI  B,-1-SSTAT2 
       CALL CLBLXF    ;CLEAR STATUS 2 PENDING FLAG
       MVI  B,VRTBAR  ;SEND <ESC>-<VERTICAL BAR>
       CALL ESCOUT
       LXI  H,XPUTDC  ;SET OUTPUT ROUTINE ADDRESS 
       CALL STA2G1    ;OUTPUT SECONDARY STATUS BIT
       JMP  SDTERM    ;SEND TERMINATOR AND RETURN 
 
;**************************************** 
; STA2G1 - OUTPUT SECONDARY STATUS BITS * 
;**************************************** 
; 
;  ENTRY:  H,L = ADDRESS OF OUTPUT ROUTINE
; 
;  EXIT :  ALL REGISTER DESTROYED 
;          CNTFAD DESTROYED 
; 
STA2G1 EQU  $ 
       SHLD CNTFAD    ;SET OUTPUT ROUTINE ADDRESS 
STA2G2 EQU  $ 
; 
;  SEND NON-DISPLAY RAM SIZE (K)
; 
       MVI  A,(BFSPCE+1)/256
       LXI  H,BUFBGN+1  ;COMPUTE NON-DISPLAY RAM
       SUB  M           ;SIZE 
       CALL PAROT2    ;SEND NON-DISPLAY RAM SIZE
; 
;  OUTPUT TERMINAL TYPE 
; 
       LDA  TRMTYP    ;GET THE TERMINAL TYPE NUMBE
       CALL PAROUT    ;SEND ONLY LOWER FOUR BITS
; 
;  OUTPUT REMAINING KYBD INTFACE STRAPS 
; 
       LHLD KBJMP3    ;GET JUMPERS J-Z
       MOV  A,H       ;SEND STRAPS J-K-L-M
       CALL PAROUT
       MOV  A,H       ;SEND STRAPS N-P-Q-R
       CALL PAROT4
       MOV  A,L       ;SEND STRAPS S-T-U-V
       CALL PAROUT
       MOV  A,L       ;SEND STRAPS W-X-Y-Z
       CALL PAROT4
; 
;  OUTPUT MEMORY LOCK STATUS
; 
       LDA  MLKFLG    ;GET MEMORY LOCK FLAG 
       LXI  H,MDFLG1  ;COMBINE WITH MODE FLAG 
       ANA  M         ;EXTRACT MEMORY LOCK STATE
       ANI  MEMLOK
       JMP  PAROUT    ;OUTPUT MEMORY LOCK STATE 
;                       AND RETURN
 
;************************************************ 
; SOFT KEY DATA DONE TABLE - IGNORE DC3,CR,& LF * 
;************************************************ 
DFSTB3 EQU  $-3 
       DB   12Q,12Q   ;LINE FEED
       DW   DFS350+B15  ;CHECK FOR IGNORE 
       DB   15Q,15Q   ;RETURN 
       DW   DFS360+B15  ;CHECK FOR IGNORE 
       DB   23Q,23Q   ;DC3
       DW   ESCAP1+B15  ;IGNORE IT
;************************************ 
; SOFT KEY MODE ENABLED RANGE TABLE * 
;************************************ 
DFSTB0 EQU  $-3 
       DB   40Q,177Q  ;DISPLAYABLE CHARACTER
       DW   SFKYDS+B15  ;DISPLAY IN PROPER DISPLAY
;********************************** 
; NORMAL CHARACTER SET ATTRIBUTES * 
;********************************** 
RTABLE EQU  $-3 
       DB   40Q,177Q  ;ALPHANUMERICS
       DW   DSPCHR+B15  ;DISPLAYABLE CHARACTERS 
       DB   7Q,17Q    ;BELL,BS,HT,LF,VT,FF,CR,SO,S
       DW   RTB010    ;USE FUNCTION TABLE 
       DB  33Q,33Q  ;ESCAPE 
       DW   ESCAPE+B15  ;USE <ESC> RANGE TABLE
; 
       DB   0Q,177Q   ;ALL OTHER CODES
       DW   CHKCTL+B15  ;CHECK FOR BLOCK XFR CHARS
; 
;  <BELL> THROUGH <SHIFT IN>
; 
RTB010 EQU  $ 
       DW   ZBELL     ;BELL - SOUND KEYBOARD BELL 
RTB020 EQU  $         ;<BS> THROUGH <SHIFT IN>
       DW   BCKSPC    ;BS - BACKSPACE CURSOR
       DW   HTAB    ;HORIZONTAL TAB 
       DW   LNFEED  ;LINE FEED
       DW   NOFNCT    ;VT - NO FUNCTION 
       DW   NOFNCT    ;FF - NO FUNCTION 
       DW   CRRET   ;CARRIAGE RETURN
       DW   SHFTOT  ;SHIFT OUT
       DW   SHFTIN  ;SHIFT IN 
 
;******************************************** 
; ESCAPE CHARACTER ATTRIBUTES FOR SOFT KEYS * 
;******************************************** 
SESCTB EQU  $-3 
       DB   51Q,76Q    ;<)> TO (>)
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
       DB   114Q,117Q  ;<L> TO <O>
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
       DB   123Q,130Q  ;<S> TO <W>
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
;            *** LOWER CASE CHARACTERS ***
       DB   154Q,155Q  ;<L> TO <M>
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
       DB   171Q,173Q  ;<Y> TO <[>
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
;*************************************
; NORMAL ESCAPE CHARACTER ATTRIBUTES *
;*************************************
ESCTAB EQU  $-3 
       DB   46Q,46Q   ;<&> - AMPERSAND
       DW   PRMSEQ+B15  ;PARAMETERIZED SEQUENCE 
; 
       DB   51Q,51Q  ;) - SPECIFY ALT CHAR SET
       DW   SCHRST+B15
       DB   61Q,65Q   ;<1> TO <5> 
       DW   EI1 
       DB   66Q,70Q   ;<6> TO <8> 
       DW   TYPSET+B15  ;DEFINE FIELD TYPE
; 
       DB   74Q,76Q   ;(<) TO (>) 
       DW   EI1A        ;USE INDEX TABLE
; 
       DB   100Q,155Q  ;<@> TO <LOWER CASE M> 
       DW   EI2         ;USE INDEX TABLE
;             *** LOWER CASE RANGE ***
       DB   170Q,173Q  ;<X> TO <LEFT BRACE> 
       DW   EI3         ;USE INDEX TABLE
; 
       DB   176Q,176Q  ;<^> (TILDE) 
       DW   STAT2+B15   ;TERMINAL STATUS 2
; 
       DB   0Q,177Q   ;ALL OTHER CODES
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
 
;************************************ 
; INDEX TABLES FOR ESCAPE SEQUENCES * 
;************************************ 
EI1    EQU  $ 
       DW   HTBSET    ;1 - HORIZONTAL TAB SET 
       DW   HTBCLR    ;2 - HORIZONTAL TAB CLEAR 
       DW   CLRALL    ;3 - CLEAR ALL TABS 
       DW   SETLFT    ;4 - SET LEFT MARGIN
       DW   SETRHT    ;5 - SET RIGHT MARGIN 
; 
EI1A   EQU  $ 
       DW   FRNCT1    ;< - SET FOREIGN MODE 1 
       DW   ESCEND    ;= - INVALID, ABORT SEQUENCE
       DW   FRNCT2    ;> - SET FOREIGN MODE 2 
; 
EI2    EQU  $ 
       DW   DELAY0    ;@ - PAUSE FOR 1 SECOND 
       DW   CURPU     ;A - CURSOR POINTER UP
       DW   CURPD   ;CURSOR POINTER DOWN
       DW   CURPR   ;CURSOR POINTER RIGHT 
       DW   CURPL     ;D - CURSOR LEFT
       DW   CLEAR     ;E - FULL TERMINAL RESET
       DW   CURPHD    ;F - HOME DOWN
       DW   CURPRT    ;G - CURSOR RETURN
       DW   XMOHME    ;H - HOME TO TRANSMIT-ONLY
       DW   HTAB    ;CURSOR POINTER TAB 
       DW   CLEARS  ;CLEAR DISPLAY
       DW   CLEARL  ;CLEAR LINE 
       DW   LININS  ;LINE INSERT
       DW   LINDEL    ;M - LINE DELETE
       DW   IWRPON    ;N - INSERT W/WRAP AROUND ON
       DW   DELWRP    ;O - DELETE CHAR W/WRAPAROUN
       DW   CHRDEL    ;P - DELETE CHARACTER 
       DW   ICHON     ;Q - INSERT CHARACTER ON
       DW   ICHOFF    ;R - INSERT CHARACTER OFF 
       DW   ROLLUP    ;S - ROLL UP
       DW   ROLLDN  ;ROLL DOWN
       DW   NEXTPG  ;NEXT PAGE
       DW   PREVPG  ;PREVIOUS PAGE
       DW   FORMON  ;FORMAT MODE ON 
       DW   FORMOF    ;X - FORMAT MODE OFF
       DW   FDISON    ;Y - DISPLAY FUNCTIONS ON 
       DW   ESCEND  ;INVALID
       DW   PREND   ;END PROTECT
       DW   ESCEND  ;INVALID
       DW   PRSTRT  ;START PROTECT
       DW   STATUS    ;^ - SEND TERMINAL STATUS 
       DW   SETTRM    ;_ - STORE NON-DISPLAYING 
;                           TERMINATOR CODE 
 
; 
;  LOWER CASE RANGE FOR 2 CHARACTER ESC SEQUENCES 
; 
       DW   RLCRSN  ;@ - SCREEN RELATIVE SENSE
       DW   CURSEN  ;A - ABSOLUTE CURSOR SENSE
       DW   KBEN1   ;B - ENABLE KEYBOARD
       DW   KBLOK0    ;C - DISABLE (LOCK) KEYBOARD
       DW   ENTREN    ;D - SEND DISPLAY TO CPU
       DW   IOBNGO    ;E - FAST BINARY READ 
       DW   DISMDM    ;F - DISCONNECT MODEM 
       DW   SFTRST    ;G - SOFT RESET 
       DW   CURPH     ;H - HOME TO UNPROTECTED
       DW   BKTAB     ;I - BACK TAB 
       DW   SFKYON    ;J - TURN ON SOFT KEY MENU
       DW   SFKYOF    ;K - RESTORE NORMAL DISPLAY 
       DW   MLKON     ;L - MEMORY LOCK ON 
       DW   MLKOFF    ;M - MEMORY LOCK OFF
; 
EI3    EQU  $         ;LOWER CASE <X> TO <[>
       DW   DCTEST    ;X - DATA COMM SELF-TEST
       DW   MNMDON    ;Y - MONITOR MODE ON
       DW   TEST      ;Z - SELF-TEST
       DW   STRXMO    ;[ - START TRANSMIT-ONLY
 
;***********************************************
; PRMTAB - TABLE FOR SEQUENCES WITH PARAMETERS *
;***********************************************
PRMTAB EQU  $-3 
       DB   141Q,147Q  ;LOWER CASE <A> TO <G> 
       DW   PRM010      ;USE INDEX TABLE
; 
       DB   153Q,153Q  ;LOWER CASE <K>
       DW   ZSTLKY+B15  ;GO TO SET KEYS ROUTINE 
; 
       DB   160Q,160Q  ;LOWER CASE <P>
       DW   IOCTGO+B15  ;GO TO I/O CONTROL ROUTINE
; 
       DB   163Q,163Q  ;LOWER CASE <S>
       DW   ZSTJPR+B15  ;GO TO SET JUMPERS ROUTINE
       DB   0Q,177Q   ;ALL OTHER CODES
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
; 
PRM010 EQU  $         ;LOWER CASE <A> TO <F>
       DW   CURPOS    ;A - CURSOR POSITIONING 
       DW   LOADR     ;B - BINARY LOADER
       DW   LOADR1    ;C - LOADER SANS MESSAGE
       DW   DISPEN    ;D - DISPLAY ENHANCEMENT
       DW   ESCEND    ;E - INVALID, ABORT SEQUENCE
       DW   DFSFKY    ;F - DEFINE FUNCTION KEYS 
       DW   SNDCDE    ;G - SEND ATTENTION/FUNCTION
;                       CODE
 
;******************************************** 
; DENTAB - DISPLAY ENHANCEMENT ESCAPE TABLE * 
;******************************************** 
DENTAB EQU  $-3 
       DB   100Q,117Q  ;<@>-<O> 
       DW   DISPLC+B15  ;TURN ON ENHANCEMENT
;*****************************************
; CHRSTB - ALTERNATE CHARACTER SET TABLE *
;*****************************************
CHRSTB EQU  $-3 
       DB   100Q,103Q  ;<@> - <C> 
       DW   SCHST1+B15  ;SET ALTERNATE CHAR SET 
; 
       DB   0Q,177Q   ;ALL OTHER CODES
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
;*******************************************
; CRPTAB - CURSOR POSITIONING ESCAPE TABLE *
;*******************************************
CRPTAB EQU  $-3 
       DB   53Q,53Q   ;<+> - PLUS SIGN
       DW   DCPLUS+B15 ;SET SIGN FLAG TO +1 
       DB  55Q,55Q  ;NEGATIVE REL. POSITIONING
       DW   DCMNUS+B15 ;SET SIGN FLAG TO -1 
       DB  60Q,71Q  ;VALID PARAMETER DIGITS 
       DW   DCNUM+B15 ;ACCUMULATE NUMERICAL VALUE 
; 
       DB   103Q,103Q  ;<C> 
       DW   CURPO1+B15  ;SET COLUMN PARAMETER 
; 
       DB   122Q,122Q  ;<R> 
       DW   CURPO3+B15  ;SET ROW PARAMETER
; 
       DB   131Q,131Q  ;<Y> 
       DW   CURPO2+B15  ;SET SCREEN ROW PARAMETER 
; 
       DB   143Q,143Q  ;<LOWER CASE C>
       DW   CURPO1+B15  ;SET COLUMN PARAMETER 
; 
       DB   162Q,162Q  ;<LOWER CASE R>
       DW   CURPO3+B15  ;SET ROW PARAMTER 
; 
       DB   171Q,171Q  ;<LOWER CASE Y>
       DW   CURPO2+B15  ;SET SCREEN ROW PARAMETER 
; 
       DB  40Q,40Q  ;SPACE - IGNORE 
       DW   ESCAP1+B15
       DB  0,177Q   ;INVALID
       DW   ESCEND+B15
 
;****************************** 
; FUNCTION DISABLE ATTRIBUTES * 
;****************************** 
FDISTB EQU  $-3 
       DB   15Q,15Q   ;RETURN CODE
       DW   CARRET+B15
       DB  33Q,33Q  ;ESCAPE 
       DW   FDESC+B15 
       DB  132Q,132Q
       DW   FDISOF+B15
       DB   0,177Q    ;ALL OTHER CODES
       DW   SFKYDS+B15  ;ADD CHARACTER TO DISPLAY 
 
;*************************************
; BINARY LOADER CHARACTER ATTRIBUTES *
;*************************************
LDRTAB EQU  $-3 
       DB   101Q,106Q  ;<A> - <F> 
       DW   LI1         ;USE INDEX TABLE
; 
       DB  141Q,144Q ;LOADER COMMAND
       DW   LI1         ;USE INDEX TABLE
; 
       DB   12Q,12Q   ;LINE FEED
       DW   ESCAP1+B15
       DB  15Q,15Q  ;CR 
       DW   ESCAP1+B15
       DB  23Q,23Q  ;DC3
       DW   ESCAP1+B15  ;IGNORE 
;********************************************** 
; SNDCTB - ACCUMULATE ATTENTION/FUNCTION CODE * 
;********************************************** 
SNDCTB EQU  $-3 
       DB   60Q,67Q   ;OCTAL DIGITS 
       DW   DCNUM+B15  ;ACCUMULATE VALUE
; 
       DB   101Q,101Q  ;<A> 
       DW   SNDCD1+B15  ;SEND ATTENTION CODE
; 
       DB   106Q,106Q  ;<F> 
       DW   SNDCD2+B15  ;SEND FUNCTION CODE 
; 
       DB   40Q,40Q   ;SPACE
       DW   ESCAP1+B15
       DB  0,177Q   ;OTHER CHARACTERS 
       DW   B15         ;TERMINATE AND RESET
; 
LI1    EQU  $ 
       DW   LDR3      ;A - ADDRESS
       DW   LDR0    ;B - IGNORE 
       DW   LDR10   ;CHECKSUM 
       DW   LDR4    ;DATA 
       DW   LDR060    ;E - EXECUTE LOADED CODE
       DW   BEGIN     ;F - TERMINATE AND RESET
 
;********************************** 
; DFSTAB - DEFINE SOFT KEYS TABLE * 
;********************************** 
DFSTAB EQU  $-3 
       DB   40Q,40Q   ;SPACE
       DW   ESCAP1+B15  ;IGNORE 
       DB   60Q,71Q   ;DIGITS <0>-<9> 
       DW   DCNUM+B15  ;ACCUMULATE NUMERICAL VALUE
       DB   101Q,101Q  ;<A> - ATTRIBUTE PARAMETER 
       DW   DFS100+B15  ;STORE DEFINED ATTRIBUTE
       DB   113Q,114Q  ;<K> - <L> 
       DW   DFT010      ;USE INDEX TABLE
; 
;  LOWER CASE RANGE 
; 
       DB   141Q,141Q  ;<A> - ATTRIBUTE PARAMETER 
       DW   DFS100+B15  ;STORE DEFINED ATTRIBUTE
       DB   153Q,154Q  ;<K> - <L> 
       DW   DFT010      ;USE INDEX TABLE
       DB   0Q,177Q   ;ALL OTHER CODES
       DW   ESCEND+B15  ;ABORT ESCAPE SEQUENCE
; 
DFT010 EQU  $ 
       DW   DFS110    ;DEFINE KEY NUMBER
       DW   DFS120    ;DEFINE LENGTH OF INPUT DATA
;*********************************
; ACCUMULATE SOFT KEY DATA TABLE *
;*********************************
DFSTB2 EQU  $-3 
       DB   0Q,177Q   ;ALL CODES
       DW   DFS300+B15  ;ADD TO DATA LINE 
 
       END
