Category : Assembly Language Source Code
Archive   : AT110.ZIP
Filename : SCRMGR.ASM

 
Output of file : SCRMGR.ASM contained in archive : AT110.ZIP

PAGE 86,132 ;PAGE WIDTH, LENGTH
TITLE SCREEN INPUT/OUTPUT MANAGER
; *********************************************************************
; * *
; * AUTHOR: JIM BRACKING *
; * MODULE NAME: SCRMGR *
; * VERSION: 1:0 *
; * DECRIPTION: THIS MODULE IS CALLED BY OTHER PROGRAMS TO *
; * PERFORM THE FOLLOWING FUNCTION: *
; * *
; * 1: SCREEN WRITES. *
; * 2: SCREEN INPUT AND EDITING. *
; * *
; * ALL SCREEN WRITES ARE DIRECT TO THE VIDEO *
; * RAM. *
; * *
; * PARAMETERS: AH = FUNCTION CODE *
; * *
; * 00 = SCREEN WRITE *
; * 01 = SCREEN INPUT *
; * 02 = SET BORDER COLOR *
; * AL = BORDER COLOR *
; * 03 = CLEAR THE SCREEN *
; * AL = ATTRIBUTE *
; * BH = STARTING ROW *
; * BL = STARTING COLUMN *
; * CH = ENDING ROW *
; * CL = ENDING COLUMN *
; * 04 = SCROLL SCREEN UP 1 LINE *
; * AL = ATTRIBUTE *
; * BH = STARTING ROW *
; * BL = STARTING COLUMN *
; * CH = ENDING ROW *
; * CL = ENDING COLUMN *
; * 05 = WRITE CHARACTER *
; * AL = ATTRIBUTE *
; * BH = ROW *
; * BL = COLUMN *
; * CH = CHARACTER *
; * CL = COUNT *
; * *
; * *
; * ES:BX = POINTER TO PARAMETER LIST USED FOR *
; * SCREEN INPUT/OUTPUT *
; * *
; * OUTPUTS: AH = CURSOR POSITION IN CURRENT ENTRY *
; * AL = RETURN CODE *
; * FF = ERROR *
; * NN = EXTENDED KEY CODE *
; * BX = OFFSET OF CURRENT ENTRY *
; * *
; *********************************************************************
;
; *********************************************************************
; * LET THE OTHERS KNOW ABOUT US *
; *********************************************************************
PUBLIC SCRMGR
;
IF1
INCLUDE SCRNWORK.MAC
ENDIF
;
;
CSEG SEGMENT PUBLIC 'CODE'
ASSUME CS:CSEG
SCRMGR PROC NEAR
PUSH AX ;SAVE AX
PUSH BX ;SAVE BX
PUSH CX ;SAVE CX
PUSH DX ;SAVE DX
PUSH DI ;SAVE DI
PUSH SI ;SAVE SI
PUSH DS ;SAVE DS
PUSH ES ;SAVE ES
PUSH BP ;SAVE BP
PUSH AX ;SAVE AX
PUSH CS ;ESTABLISH
POP DS ; DATA
ASSUME DS:CSEG ; SEGMENT
JMP BY_INFO ;JMP AROUND COPYRIGHT
DB 'COPYRIGHT (C) ATI 1984 '
DB 'PROGRAM - SCRMGR '
DB ' VERSION 1.10 11/20/84'
;
INCLUDE SCRNWORK.ASM
;
; *********************************************************************
; * *
; * GENERAL WORK AREAS *
; * *
; *********************************************************************
WORK_IN LABEL BYTE ;WORK AREA
ROW DB 0 ;CURRENT ROW
COL DB 0 ;CURRENT COLUMN
ENTSEG DW 0 ;SEGMENT OF PARM ENTRY
ENTOFF DW 0 ;OFFSET OF PARM ENTRY
PARMSEG DW 0 ;PARM SEGMENT
PARMOFF DW 0 ;PARM OFFSET
SW1 DB 0 ;SWITCH1 INDICATORS
CAPS EQU 080H ;CAPS ON
INS EQU 040H ;INSERT ACTIVE
COLOR EQU 020H ;COLOR MONITOR
MONO EQU 010H ;MONOCHROME MONITOR
XLIST EQU 008H ;LIST REQUEST
ADV EQU 004H ;ENHANCED GRAFICS ADAPTER
NORM_CUR DW 0 ;NORMAL CURSOR
WIDE_CUR DW 0 ;WIDE CURSOR
SW2 DB 0 ;SPECIAL CHARACTER SWITCH
DP EQU 080H ;DECIMAL POINT
MS EQU 040H ;MINUS SIGN
RETURN DB 0 ;RETURN CODE
CURPOS DB 0 ;CURSOR POSITION FOR THIS ENTRY
;
; **********************************************************************
; * *
; * EXTENDED KEY TABLE *
; * *
; **********************************************************************
EX_KEY LABEL BYTE
DB 132 DUP(0)
ORG $-132
ORG EX_KEY+15
DB TL_INDEX ;TAB LEFT
ORG EX_KEY+59
DB 0FFH,0FFH,0FFH,0FFH,0FFH ;FUNCTION KEYS 1 TO 5
DB 0FFH,0FFH,0FFH,0FFH,0FFH ;FUNCTION KEYS 6 TO 10
ORG EX_KEY+71
DB HO_INDEX ;HOME KEY
ORG EX_KEY+72
DB CU_INDEX ;CURSOR UP
ORG EX_KEY+73
DB 0FFH ;PAGE UP
ORG EX_KEY+75
DB CL_INDEX ;CURSOR LEFT
ORG EX_KEY+77
DB CR_INDEX ;CURSOR RIGHT
ORG EX_KEY+79
DB 0FFH ;END
ORG EX_KEY+80
DB CD_INDEX ;CURSOR DOWN
ORG EX_KEY+81
DB 0FFH ;PAGE DOWN
ORG EX_KEY+82
DB IN_INDEX ;INSERT
ORG EX_KEY+83
DB DE_INDEX ;DELETE
ORG EX_KEY+84
DB 0FFH,0FFH,0FFH,0FFH,0FFH ;FUNCTION KEYS 11 TO 15
DB 0FFH,0FFH,0FFH,0FFH,0FFH ;FUNCTION KEYS 16 TO 20
ORG EX_KEY+94
DB 0FFH,0FFH,0FFH,0FFH,0FFH ;FUNCTION KEYS 21 TO 25
DB 0FFH,0FFH,0FFH,0FFH,0FFH ;FUNCTION KEYS 26 TO 30
ORG EX_KEY+104
DB 0FFH,0FFH,0FFH,0FFH,0FFH ;FUNCTION KEYS 31 TO 35
DB 0FFH,0FFH,0FFH,0FFH,0FFH ;FUNCTION KEYS 36 TO 40
ORG EX_KEY+132
; **********************************************************************
; * *
; * TRANSLATE TABLE FOR GET_INPUT ROUTINE *
; * *
; **********************************************************************
TRANTBL LABEL BYTE
DB 128 DUP(0)
ORG $-128
DB 0FFH,0FFH,0FFH
DB CB_INDEX ;CONTROL BREAK
DB 0FFH,0FFH,0FFH,0FFH
DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
ORG TRANTBL+08
DB BS_INDEX ;BACKSPACE
ORG TRANTBL+09
DB TR_INDEX ;TAB RIGHT
ORG TRANTBL+13
DB EN_INDEX ;ENTER
ORG TRANTBL+27
DB ES_INDEX ;ESC KEY
ORG TRANTBL+126
DB 0FFH,0FFH
; *********************************************************************
; * *
; * *
; * *
; *********************************************************************
BY_INFO:
CMP CS:VI_BASE,0 ;INIT COMPLETE??
JE INIT ;NO
JMP INIT_20 ;YES
INIT:
XOR AH,AH ;SET B&W
MOV AL,2 ; 80 COLUMN
INT 10H ;DO IT
MOV AH,05H ;SET ACTIVE
XOR AL,AL ; PAGE TO ZERO
INT 10H ;DO IT
INT 11H ;GET CONFIGURATION
AND AL,30H ;ONLY INTERESTED IN VIDEO SWITCHES
PUSH CX ;SAVE CX
MOV CL,4 ;SHIFT COUNT
SHR AL,CL ;ALIGN IT
POP CX ;RESTORE CX
CMP AL,00H ;ENHANCED ADAPTER??
JNE INIT_00A ;NO
MOV CS:VI_BASE,0B800H ;ENHANCED ADAPTER
MOV AL,CS:SW1 ;INDICATE
OR AL,ADV ;ENHANCED ADAPTER
MOV CS:SW1,AL
MOV AX,000BH ;WIDE CURSOR
MOV CS:WIDE_CUR,AX ;AND SAVE IT
MOV AX,0B0CH ;NORMAL CURSOR
MOV CS:NORM_CUR,AX ;AND SAVE IT
JMP INIT_10 ;CONTINUE
INIT_00A:
CMP AL,03H ;MONOCHROME??
JNE INIT_05 ;NO - MUST BE COLOR
MOV CS:VI_BASE,0B000H ;MONOCHROME BASE ADDRESS
MOV AL,CS:SW1 ;INDICATE
OR AL,MONO ;MONOCHROME MONITOR
MOV CS:SW1,AL
INIT_00:
MOV AX,000BH ;WIDE CURSOR
MOV CS:WIDE_CUR,AX ;AND SAVE IT
MOV AX,0B0CH ;NORMAL CURSOR
MOV CS:NORM_CUR,AX ;AND SAVE IT
JMP INIT_10 ;CONTINUE
INIT_05:
MOV CS:VI_BASE,0B800H ;COLOR BASE ADDRESS
MOV AL,CS:SW1 ;INDICATE
OR AL,COLOR ;COLOR MONITOR
MOV CS:SW1,AL
MOV AX,0007H ;WIDE CURSOR
MOV CS:WIDE_CUR,AX ;AND SAVE IT
MOV AX,0707H ;NORMAL CURSOR
MOV CS:NORM_CUR,AX ;AND SAVE IT
INIT_10:
POP AX ;RESTORE AX
PUSH AX ;SAVE AX
INIT_20:
MOV CS:ENTOFF,BX ;SAVE FIRST ENTRY
MOV CS:RETCODE,0 ;ZERO RETURN CODE
MOV AL,AH ;FUNCTION CODE
XOR AH,AH ;CLEAR AH
CMP AX,CS:TBL_LIMIT ;BAD CALL??
JAE ERROR_RET ;YES
SHL AL,1 ;ESTABLISH
MOV SI,AX ; INDEX
POP AX ;RESTORE AX
JMP WORD PTR CS:[SI+OFFSET FUNCTION_TABLE]
ERROR_RET:
POP AX ;RESTORE AX
MOV CS:RETCODE,0FFH ;INDICATE ERROR
JMP EXIT ;AND EXIT
;
FUNCTION_TABLE LABEL WORD
DW SCREEN_OUTPUT
DW SCREEN_INPUT
DW SET_BORDER
DW CLR_SCREEN
DW SCROLL_UP
DW WRITE_CHAR
TBL_LIMIT EQU ($-FUNCTION_TABLE)/2
SCRMGR ENDP
; *********************************************************************
; * *
; * BLANK THE SCREEN *
; * *
; *********************************************************************
CLR_SCREEN PROC
MOV DX,CX ;ENDING ROW + COLUMN
MOV CH,BH ;STARTING ROW
MOV CL,BL ;STARTING COLUMN
MOV BH,AL ;SET ATTRIBUTE CHARACTER
XOR AL,AL ;NUMBER OF LINES TO SCROLL
XOR BL,BL ;CLEAR BL
MOV AH,7 ;SCROLL ACTIVE PAGE DOWN
INT 10H ;CLEAR THE SCREEN
JMP EXIT ;AND EXIT
CLR_SCREEN ENDP
; *********************************************************************
; * *
; * SCROLL UP ONE LINE *
; * *
; *********************************************************************
SCROLL_UP PROC
MOV DX,CX ;ENDING ROW + COLUMN
MOV CH,BH ;STARTING ROW
MOV CL,BL ;STARTING COLUMN
MOV BH,AL ;SET ATTRIBUTE CHARACTER
MOV AL,1 ;NUMBER OF LINES TO SCROLL
XOR BL,BL ;CLEAR BL
MOV AH,6 ;SCROLL ACTIVE PAGE UP
INT 10H ;SCROLL THE SCREEN
JMP EXIT ;AND EXIT
SCROLL_UP ENDP
; *********************************************************************
; * *
; * WRITE CHARACTER ROUTINE *
; * *
; *********************************************************************
WRITE_CHAR PROC
PUSH ES ;SAVE ES
PUSH AX ;SAVE AX
PUSH BX ;SAVE BX
PUSH CX ;SAVE CX
PUSH DX ;SAVE DX
PUSH SI ;SAVE SI
PUSH DI ;SAVE DI
PUSH AX ;SAVE AX
MOV AX,CS:VI_BASE ;ESTABLISH
MOV ES,AX ; VIDEO BASE
XOR AX,AX ;CLEAR AX
MOV AL,BH ;CALCULATE
MUL CS:LINE_LEN ; OFFSET TO LINE
ADD AL,BL ;INCLUDE COLUMN
JNC WC_00 ;IF NO CARRY
ADD AH,1 ;OTHERWISE ADDJUST
WC_00:
SHL AX,1 ;ALLOW FOR ATTRIBUTE
MOV DI,AX ;ESTABLISH OFFSET
POP AX ;RESTORE AX
MOV AH,AL ;ATTRIBUTE
MOV AL,CH ;CHARACTER
WC_10:
XOR CH,CH ;CLEAR CH
CLD ;SET DIRECTION
WC_12:
PUSH AX ;SAVE AX
TEST CS:SW1,MONO ;MONOCHROME DISPLAY??
JNZ WC_18 ;YES - SKIP STUFF FOR COLOR
MOV DX,03DAH ;VIDEO STAT REGISTER
STI ;ENABLE INTERRUPTS
WC_15:
IN AL,DX ;READ STAT REGISTER
TEST AL,01H ;VIDEO RAM AVAILABLE??
JNZ WC_15 ;YES - WAIT FOR NEXT CYCLE
WC_16:
IN AL,DX ;READ STAT REGISTER
TEST AL,01H ;VIDEO RAM AVAILABLE??
JZ WC_16 ;NO - WAIT FOR IT
WC_18:
POP AX ;RESTORE AX
CLI ;DISABLE INTERRUPTS
WC_20:
STOSW ;WRITE THE CHARACTER AND ATTRIBUTE
LOOP WC_20 ;LOOP UNTILL DONE
STI ;ENABLE INTERRUPTS
WC_EXIT:
POP DI ;RESTORE DI
POP SI ;RESTORE SI
POP DX ;RESTORE DX
POP CX ;RESTORE CX
POP BX ;RESTORE BX
POP AX ;RESTORE AX
POP ES ;RESTORE ES
JMP EXIT ;RETURN
WRITE_CHAR ENDP
; *********************************************************************
; * *
; * SET THE BORDER COLOR *
; * *
; *********************************************************************
SET_BORDER PROC
PUSH DX ;SAVE DX
MOV DX,03D9H ;REGISTER FOR BORDER COLOR
AND AL,0FH ;CLEAN IT UP
OUT DX,AL ;SET BORDER COLOR
POP DX ;RESTORE DX
JMP EXIT ;A HARD DAYS WORK
SET_BORDER ENDP
; *********************************************************************
; * *
; * SCREEN OUTPUT MANAGER *
; * *
; *********************************************************************
SCREEN_OUTPUT PROC
MOV CS:PARMSEG,ES ;SAVE SEGMENT
MOV CS:PARMOFF,BX ; AND OFFSET
PUSH ES ;ESTABLISH INPUT
POP DS ; SEGMENT
CALL SET_FIELDS ;INIT ALL FIELDS
SCREEN_O_00:
OR CS:SW1,XLIST ;LIST REQUEST
CALL WRITE_DATA ;WRITE THIS LIST
MOV CS:RETCODE,0 ;SET RETURN CODE
JMP EXIT ;YES - RETURN
SCREEN_OUTPUT ENDP
; *********************************************************************
; * *
; * SCREEN INPUT MANAGER *
; * *
; *********************************************************************
SCREEN_INPUT PROC
MOV CS:PARMSEG,ES ;SAVE SEGMENT
MOV CS:PARMOFF,BX ; AND OFFSET
PUSH ES ;ESTABLISH INPUT
POP DS ; SEGMENT
TEST CS:SW1,INS ;INSENSERT MODE??
JZ SCREEN_I_A0 ;NO
PUSH AX ;SAVE AX
PUSH CX ;SAVE CX
MOV CX,CS:WIDE_CUR ;WIDE CURSOR
MOV AH,1 ;FUNCTION
INT 10H ;CALL BIOS
POP CX ;RESTORE CX
POP AX ;RESTORE AX
SCREEN_I_A0:
TEST [BX].S_OPT,@LABEL ;A DATA INPUT FIELD??
JZ SCREEN_I_X0 ;YES
CALL GET_NEXT_OUTPUT ;GET NEXT ENTRY
CMP BX,CS:PARMOFF ;ALL DONE??
JNE SCREEN_I_A0 ;NO
MOV CS:RETCODE,0FFH ;ERROR RETURN CODE
JMP EXIT ;AND EXIT
SCREEN_I_X0:
CALL SET_FIELDS ;INIT ALL FIELDS
SCREEN_I_00:
MOV DX,0 ;RELATIVE CURSOR OFFSET
CALL UPDATE_CURSOR ;UPDATE CURSOR POSITION
SCREEN_I_05:
CALL GET_INPUT ;GET SOMETHING FROM THE KEYBOARD
PUSH BX ;SAVE BX
MOV BL,AH ;RESULT INDEX
XOR BH,BH ;CLEAR BH
SHL BL,1 ;TRUE INDEX
MOV SI,BX ;BRANCH INDEX
POP BX ;RESTORE BX
JMP WORD PTR CS:[SI + OFFSET FUNC_TABLE]
;
FUNC_TABLE LABEL WORD
DW DATA ;DATA RETURNED
D_INDEX EQU ($-FUNC_TABLE)/2-1
DW ENTER ;ENTER KEY
EN_INDEX EQU ($-FUNC_TABLE)/2-1
DW ESC_KEY ;ESC KEY
ES_INDEX EQU ($-FUNC_TABLE)/2-1
DW CTRL_BK ;CONTROL BREAK
CB_INDEX EQU ($-FUNC_TABLE)/2-1
DW CURSRT ;CURSOR RIGHT
CR_INDEX EQU ($-FUNC_TABLE)/2-1
DW CURSLF ;CURSOR LEFT
CL_INDEX EQU ($-FUNC_TABLE)/2-1
DW CURSDN ;CURSOR DOWN
CD_INDEX EQU ($-FUNC_TABLE)/2-1
DW CURSUP ;CURSOR UP
CU_INDEX EQU ($-FUNC_TABLE)/2-1
DW TABRT ;TAB RIGHT
TR_INDEX EQU ($-FUNC_TABLE)/2-1
DW TABLF ;TAB LEFT
TL_INDEX EQU ($-FUNC_TABLE)/2-1
DW INS_KEY ;INSERT KEY
IN_INDEX EQU ($-FUNC_TABLE)/2-1
DW DEL_KEY ;DELETE KEY
DE_INDEX EQU ($-FUNC_TABLE)/2-1
DW HOME_KEY ;DELETE KEY
HO_INDEX EQU ($-FUNC_TABLE)/2-1
DW BACKSPACE ;DELETE KEY
BS_INDEX EQU ($-FUNC_TABLE)/2-1
DW EXTENDED_KEY ;PGUP,PGDN,FUNCTION KEYS
EX_INDEX EQU ($-FUNC_TABLE)/2-1 ;EXTENDED KEY INDEX
; *********************************************************************
; * *
; * PROCESS THE DATA BYTE JUST READ *
; * *
; *********************************************************************
DATA:
CMP DL,[BX].S_LEN ;EXCEEDED MAX COLUMN??
JAE DATA_ERR ;YES
TEST [BX].S_OPT,@NUM ;NUMERIC ONLY??
JZ DATA_05 ;NO
CALL CHK_NUMERIC ;VALIDATE IT
JC DATA_ERR ;FAILED
DATA_05:
TEST [BX].S_OPT,@ALPHA ;ALPHA ONLY??
JZ DATA_10 ;NO
CALL CHK_ALPHA ;VALIDATE IT
JC DATA_ERR ;FAILED
DATA_10:
TEST [BX].S_OPT,@YN ;YES OR NO??
JZ DATA_15 ;NO
CALL CHK_YN ;VALIDATE IT
JC DATA_ERR ;FAILED
DATA_15:
TEST [BX].S_OPT,@UC ;CONVERT TO UPPER CASE??
JZ DATA_20 ;NO
CMP AL,060H ;ALPHA??
JBE DATA_20 ;NO
CMP AL,07BH ;ALPHA??
JAE DATA_20 ;NO
AND AL,0FFH-020H ;CONVERT TO UPPER CASE
JMP DATA_20 ;CONTINUE
;
DATA_ERR:
CALL BEEP ;RING THE BELL
JMP SCREEN_I_05 ;TRY AGAIN
;
DATA_20:
TEST CS:SW1,INS ;INSERT MODE??
JNZ DATA_30 ;YES
CLD ;FORWARD DIRECTION
LEA DI,[BX].S_DATA ;DATA OFFSET
ADD DI,DX ;CURRENT COLUMN
STOSB ;STORE BYTE IN DATA FIELD
; OR [BX].S_OPT,@CHG ;FIELD CHANGED
MOV AH,[BX].S_LEN ;FETCH MAX LENGTH
DEC AH ;MAX COLUMN
CMP DL,AH ;MAX COLUMN??
JE DATA_28 ;YES - NO CURSOR UPDATE
; INC DX ;UPDATE CURSOR OFFSET
DATA_28:
JMP DATA_50 ;GO DISPLAY IT
DATA_30:
CALL FIND_LEN ;GET DATA LENGTH
CMP CL,[BX].S_LEN ;ROOM FOR INSERT??
JAE DATA_ERR ;NO
CMP CL,DL ;NEED TO SHIFT DATA??
JE DATA_32 ;NO
CMP CL,DL ;NEED TO SHIFT DATA??
JAE DATA_33 ;YES
DATA_32:
LEA DI,[BX].S_DATA ;DATA OFFSET
ADD DI,DX ;ADD OFFSET
STOSB ;STORE THE DATA
; OR [BX].S_OPT,@CHG ;FIELD CHANGED
JMP DATA_50 ;CONTINUE
DATA_33:
LEA DI,[BX].S_DATA ;DATA OFFSET
ADD DI,CX ;DESTINATION
MOV SI,DI ;SOURCE
DEC SI ; OFFSET
SUB CL,DL ;COMPUTE LENGTH
STD ;REVERSE DIRECTION
DATA_35:
MOVSB ;MOVE A BYTE
LOOP DATA_35 ;NEXT BYTE
STOSB ;INSERT DATA BYTE
; OR [BX].S_OPT,@CHG ;FIELD CHANGED
DATA_50:
INC DX ;UPDATE CURSOR OFFSET
CALL WRITE_DATA ;DISPLAY IT ON THE SCREEN
CMP DL,[BX].S_LEN ;MAX COLUMN??
JNE DATA_52 ;NO
TEST CS:SW1,INS ;IN INSERT MODE??
JNZ DATA_52 ;YES - STAY HERE
TEST [BX].S_OPT,@NFULL ;NEXT LINE WHEN FULL??
JZ DATA_52 ;NO
JMP TABRT ;MOVE THE CURSOR
DATA_52:
CALL UPDATE_CURSOR ;POSITION THE CURSOR
JMP SCREEN_I_05 ;NEXT
; *********************************************************************
; * *
; * PROCESS THE ENTER KEY *
; * *
; *********************************************************************
ENTER:
TEST [BX].S_OPT,@EX ;EXTENDED KEY ONLY??
JZ ENTER_05 ;NO
JMP CURSDN ;CURSOR DOWN
ENTER_05:
CALL TREQ ;REQUIRED??
JNC ENTER_10 ;PASSED
JMP SCREEN_I_00 ;DATA REQUIRED IN THIS FIELD
ENTER_10:
MOV CS:RETCODE,0DH ;SET KEY CODE FOR ENTER KEY
JMP EXIT ;AND EXIT
; *********************************************************************
; * *
; * PROCESS THE ESC KEY *

; * *
; *********************************************************************
ESC_KEY:
MOV CS:RETCODE,AL ;SET KEY CODE FOR ESC KEY
JMP EXIT ;AND EXIT
; *********************************************************************
; * *
; * PROCESS CONTROL BREAK *
; * *
; *********************************************************************
CTRL_BK:
MOV CS:RETCODE,114 ;SET KEY CODE FOR ESC KEY
JMP EXIT ;AND EXIT
; *********************************************************************
; * *
; * PROCESS THE CURSOR LEFT KEY *
; * *
; *********************************************************************
CURSLF:
OR DX,DX ;AT ZERO??
JNZ CURSLF_00 ;NO
CALL GET_PREV_INPUT ;GET THE PREV ENTRY
JMP SCREEN_I_00 ;CONTINUE
CURSLF_00:
DEC DX ;ONE LESS
CALL UPDATE_CURSOR ;UPDATE CURSOR POSITION
JMP SCREEN_I_05 ;CONTINUE
; *********************************************************************
; * *
; * PROCESS THE CURSOR RIGHT KEY *
; * *
; *********************************************************************
CURSRT:
CMP [BX].S_LEN,01H ;ONE BYTE FIELD??
JNE CURSRT_02 ;NO
OR DL,DL ;FIRST COLUMN??
JZ CURSRT_04 ;YES
CURSRT_02:
MOV AH,[BX].S_LEN ;FETCH MAX LENGTH
DEC AH ;MAX COLUMN
CMP DL,AH ;MAX COLUMN??
JNE CURSRT_10 ;NO
CURSRT_04:
TEST [BX].S_OPT,@NFULL ;NEXT LINE WHEN FULL??
JZ CURSRT_05 ;NO
CALL GET_NEXT_INPUT ;GET THE NEXT ENTRY
JMP SCREEN_I_00 ;CONTINUE
CURSRT_05:
CALL BEEP ;RING THE BELL
JMP SCREEN_I_05 ;NEXT
CURSRT_10:
INC DX ;PLUS ONE
CALL UPDATE_CURSOR ;UPDATE CURSOR POSITION
JMP SCREEN_I_05 ;CONTINUE
; *********************************************************************
; * *
; * PROCESS THE CURSOR UP KEY *
; * *
; *********************************************************************
CURSUP:
CALL GET_PREV_INPUT ;GET THE PREVIOUS ENTRY
JMP SCREEN_I_00 ;CONTINUE
; *********************************************************************
; * *
; * PROCESS THE CURSOR DOWN KEY *
; * *
; *********************************************************************
CURSDN:
CALL GET_NEXT_INPUT ;GET THE NEXT ENTRY
JMP SCREEN_I_00 ;CONTINUE
; *********************************************************************
; * *
; * PROCESS THE TAB RIGHT KEY *
; * *
; *********************************************************************
TABRT:
CALL GET_NEXT_INPUT ;GET THE NEXT ENTRY
JMP SCREEN_I_00 ;CONTINUE
; *********************************************************************
; * *
; * PROCESS THE TAB LEFT KEY *
; * *
; *********************************************************************
TABLF:
CALL GET_PREV_INPUT ;GET THE PREVIOUS ENTRY
JMP SCREEN_I_00 ;CONTINUE
; *********************************************************************
; * *
; * PROCESS THE INS KEY *
; * *
; *********************************************************************
INS_KEY:
TEST CS:SW1,INS ;INSERT MODE ACTIVE??
JNZ INS_KEY_10 ;YES - TOGGLE IT
OR CS:SW1,INS ;INSERT MODE NOW ACTIVE
PUSH AX ;SAVE AX
PUSH CX ;SAVE CX
MOV CX,CS:WIDE_CUR ;WIDE CURSOR
MOV AH,1 ;FUNCTION
INT 10H ;CALL BIOS
POP CX ;RESTORE CX
POP AX ;RESTORE AX
JMP SCREEN_I_05 ;CONTINUE
INS_KEY_10:
AND CS:SW1,0FFH-INS ;RESET INSERT MODE
PUSH AX ;SAVE AX
PUSH CX ;SAVE CX
MOV CX,CS:NORM_CUR ;NORMAL CURSOR
MOV AH,1 ;FUNCTION
INT 10H ;CALL BIOS
POP CX ;RESTORE CX
POP AX ;RESTORE AX
JMP SCREEN_I_05 ;CONTINUE
; *********************************************************************
; * *
; * PROCESS THE DEL KEY *
; * *
; *********************************************************************
DEL_KEY:
MOV AH,[BX].S_LEN ;FETCH MAX LENGTH
DEC AH ;MAX COLUMN
CMP DL,AH ;MAX COLUMN??
JNE DEL_KEY_00 ;NO
LEA DI,[BX].S_DATA ;GET DATA
ADD DI,DX ; OFFSET
JMP DEL_KEY_20 ;CONTINUE
DEL_KEY_00:
LEA DI,[BX].S_DATA ;DATA OFFSET
ADD DI,DX ;DESTINATION
MOV SI,DI ;SOURCE
INC SI ; OFFSET
CLD ;SET DIRECTION
XOR CX,CX ;CLEAR CX
MOV CL,[BX].S_LEN ;GET FIELD LENGTH
SUB CX,DX ;LENGTH
DEC CX
DEL_KEY_10:
MOVSB ;MOVE A BYTE
LOOP DEL_KEY_10 ;NEXT BYTE
DEL_KEY_20:
MOV BYTE PTR [DI],BLANK ;BLANK EXTRA CHARACTER
CALL WRITE_DATA ;DISPLAY IT ON THE SCREEN
JMP SCREEN_I_05 ;NEXT
; *********************************************************************
; * *
; * PROCESS THE BACKSPACE KEY *
; * *
; *********************************************************************
BACKSPACE:
OR DX,DX ;AT COLUMN ZER0??
JNZ BS_00 ;NO
CALL BEEP ;RING THE BELL
JMP SCREEN_I_05 ;CONTINUE
BS_00:
DEC DX ;COLUMN -1
LEA DI,[BX].S_DATA ;DATA OFFSET
ADD DI,DX ;CURRENT COLUMN
MOV BYTE PTR [DI],BLANK ;STORE A BLANK
CALL WRITE_DATA ;WRITE IT
CALL UPDATE_CURSOR ;UPDATE CURSOR POSITION
JMP SCREEN_I_05 ;NEXT
; *********************************************************************
; * *
; * PROCESS THE HOME KEY *
; * *
; *********************************************************************
HOME_KEY:
MOV BX,CS:PARMOFF ;FIRST ENTRY
MOV CS:ENTOFF,BX ;CURRENT ENTRY
JMP SCREEN_I_X0 ;CONTINUE
; *********************************************************************
; * *
; * PROCESS EXTENDED KEYS *
; * PGUP,PGDN,FUNCTION KEYS *
; * *
; *********************************************************************
EXTENDED_KEY:
MOV CS:RETCODE,AL ;SAVE KEY CODE
JMP EXIT ;EXIT
SCREEN_INPUT ENDP
; *********************************************************************
; * *
; * GET INPUT FROM THE KEYBOARD *
; * *
; * OUTPUTS: AH = TABLE INDEX *
; * AL = DATA BYTE OR FUNCTION *
; * KEY TABLE INDEX *
; *********************************************************************
GET_INPUT PROC
MOV AH,07H ;DOS FUNCTION CODE
INT 21H ;GET A CHARACTER
OR AL,AL ;EXTENDED CODE??
JZ GET_INPUT_10 ;YES
PUSH BX ;SAVE BX
MOV BX,OFFSET CS:TRANTBL ;TABLE OFFSET
XOR AH,AH ;CLEAR AH
ADD BX,AX ;INDEX
MOV AH,CS:[BX] ;GET TABLE VALUE
POP BX ;RESTORE BX
CMP AH,0FFH ;VALID CHARACTER??
JNE GET_INPUT_05 ;YES
GET_INPUT_00:
CALL BEEP ;RING THE BELL
JMP GET_INPUT ;TRY AGAIN
GET_INPUT_05:
RET ;RETURN
GET_INPUT_10:
MOV AH,07H ;DOS FUNCTION CODE
INT 21H ;GET A CHARACTER
PUSH BX ;SAVE BX
MOV BX,OFFSET CS:EX_KEY ;TABLE OFFSET
XOR AH,AH ;CLEAR AH
ADD BX,AX ;INDEX
MOV AH,CS:[BX] ;GET TABLE VALUE
POP BX ;RESTORE BX
CMP AH,00H ;VALID CHARACTER??
JNE GET_INPUT_15 ;YES
CALL BEEP ;RING THE BELL
JMP GET_INPUT ;TRY AGAIN
GET_INPUT_15:
CMP AH,EX_INDEX ;PASS IT TO THE PROGRAM??
JBE GET_INPUT_20 ;NO
MOV AH,EX_INDEX ;RETURN CODE
RET ;AND RETURN
GET_INPUT_20:
RET ;RETURN
GET_INPUT ENDP
; *********************************************************************
; * *
; * FIND DATA LENGTH *
; * OUTPUT: CX = DATA LENGTH *
; * *
; *********************************************************************
FIND_LEN PROC
PUSH AX ;SAVE AX
PUSH SI ;SAVE SI
LEA SI,[BX].S_DATA ;DATA OFFSET
XOR CX,CX ;CLEAR CX
MOV CL,[BX].S_LEN ;MAX LENGTH
ADD SI,CX ;POINT TO LAST
DEC SI ; BYTE
STD ;REVERSE DIRECTION
FL_00:
LODSB ;FETCH A BYTE
CMP AL,BLANK ;IS IT A BLANK??
JNE FL_EXIT ;NO
LOOP FL_00 ;KEEP TRYING
FL_EXIT:
POP SI ;RESTORE SI
POP AX ;RESTORE AX
RET ;AND RETURN
FIND_LEN ENDP
SET_FIELDS PROC
PUSH AX ;SAVE AX
MOV CS:ENTOFF,BX ;CURRENT ENTRY OFFSET
MOV SI,BX ;INPUT OFFSET
MOV AL,[BX].S_ROW ;CURRENT
MOV CS:ROW,AL ; ROW
MOV AL,[BX].S_COL ;CURRENT
MOV CS:COL,AL ; COLUMN
POP AX ;RESTORE AX
RET ;AND RETURN
SET_FIELDS ENDP
; *********************************************************************
; * *
; * GET THE NEXT INPUT ENTRY *
; * *
; *********************************************************************
GET_NEXT_INPUT PROC
MOV BX,[BX].S_NEXT ;GET THE NEXT ENTRY
TEST [BX].S_OPT,@LABEL ;LABEL ENTRY??
JNZ GET_NEXT_INPUT ;YES - SKIP THIS ONE
GET_NEXT_I_10:
CALL SET_FIELDS ;INIT FIELDS
RET ;AND RETURN
GET_NEXT_INPUT ENDP
; *********************************************************************
; * *
; * GET THE PREV INPUT ENTRY *
; * *
; *********************************************************************
GET_PREV_INPUT PROC

PUSH DX ;SAVE DX
PUSH SI ;SAVE SI
MOV SI,[BX].S_NEXT ;FETCH NEXT ENTRY
MOV DX,BX ;SET PREV ENTRY
GET_PREV_I_00:
TEST [SI].S_OPT,@LABEL ;LABEL ENTRY??
JZ GET_PREV_I_10 ;NO - PROCESS IT
GET_PREV_I_05:
MOV SI,[SI].S_NEXT ;NEXT ENTRY
CMP SI,BX ;LAST ENTRY??
JE GET_PREV_I_20 ;YES
JMP GET_PREV_I_00 ;NEXT
GET_PREV_I_10:
MOV DX,SI ;PREVIOUS ENTRY
JMP GET_PREV_I_05 ;CONTINUE
GET_PREV_I_20:
MOV BX,DX ;PREVIOUS ENTRY
CALL SET_FIELDS ;INIT ALL FIELDS
POP SI ;RESTORE SI
POP DX ;RESTORE DX
RET ;AND RETURN
GET_PREV_INPUT ENDP
; *********************************************************************
; * *
; * GET THE NEXT OUTPUT ENTRY *
; * *
; *********************************************************************
GET_NEXT_OUTPUT PROC
MOV BX,[BX].S_NEXT ;GET THE NEXT ENTRY
GET_NEXT_O_10:
CALL SET_FIELDS ;INIT FIELDS
RET ;AND RETURN
GET_NEXT_OUTPUT ENDP
; *********************************************************************
; * *
; * SCREEN WRITE ROUTINE *
; * *
; *********************************************************************
WRITE_DATA PROC
PUSH ES ;SAVE ES
PUSH AX ;SAVE AX
PUSH BX ;SAVE BX
PUSH CX ;SAVE CX
PUSH SI ;SAVE SI
PUSH DI ;SAVE DI
MOV AX,CS:VI_BASE ;ESTABLISH
MOV ES,AX ; VIDEO BASE
PUSH BX ;SAVE FIRST ENTRY OFFSET
WE_00:
CALL CALC_OFFSET ;RETURN VIDEO RAM OFFSET IN AX
MOV DI,AX ;ESTABLISH OFFSET
WE_10:
XOR CH,CH ;CLEAR CH
MOV CL,[BX].S_LEN ;FIELD SIZE
LEA SI,[BX].S_DATA ;INPUT OFFSET
CLD ;SET DIRECTION
WE_12:
PUSH DX ;SAVE DX
TEST CS:SW1,MONO ;MONOCHROME DISPLAY??
JNZ WE_18 ;YES - SKIP STUFF FOR COLOR
MOV DX,03DAH ;VIDEO STAT REGISTER
STI ;ENABLE INTERRUPTS
WE_15:
IN AL,DX ;READ STAT REGISTER
TEST AL,01H ;VIDEO RAM AVAILABLE??
JNZ WC_15 ;YES - WAIT FOR NEXT CYCLE
WE_16:
IN AL,DX ;READ STAT REGISTER
TEST AL,01H ;VIDEO RAM AVAILABLE??
JZ WC_16 ;NO - WAIT FOR IT
WE_18:
POP DX ;RESTORE DX
CLI ;DISABLE INTERRUPTS
WE_20:
LODSB ;FETCH OUTPUT BYTE
MOV AH,AL ;PUT IT IN AH
MOV AL,[BX].S_ATTR ;ATTRIBUTE BYTE
XCHG AL,AH ;MAKE IT RIGHT
WE_30:
STOSW ;WRITE THE CHARACTER AND ATTRIBUTE
LOOP WE_20 ;LOOP UNTILL DONE
STI ;ENABLE INTERRUPTS
WE_40:
POP AX ;RESTORE FIRST ENTRY OFFSET
TEST CS:SW1,XLIST ;LIST FUNCTION??
JZ WE_EXIT ;NO - WERE ALL DONE
CALL GET_NEXT_OUTPUT ;GET THE NEXT ENTRY
CMP AX,BX ;ALL DONE??
JE WE_EXIT ;YES
PUSH AX ;SAVE FIRST ENTRY OFFSET
JMP WE_00 ;CONTINUE
WE_EXIT:
AND CS:SW1,0FFH-XLIST ;RESET SWITCHE
POP DI ;RESTORE DI
POP SI ;RESTORE SI
POP CX ;RESTORE CX
POP BX ;RESTORE BX
POP AX ;RESTORE AX
POP ES ;RESTORE ES
RET ;RETURN
WRITE_DATA ENDP
; *********************************************************************
; * *
; * SOUND THE MUSIC *
; * *
; *********************************************************************
BEEP PROC
BEEP_00:
PUSH AX ;SAVE AX
PUSH BX ;SAVE BX
PUSH CX ;SAVE CX
CLI ;DISABLE INTERRUPTS
IN AL,61H ;GET KEYBOARD/SPEAKER CTL DATA
PUSH AX ;AND SAVE IT
MOV BX,300 ;DURATION OF TONE
BEEP_05:
AND AL,0FCH ;TURN OFF TIMER GATE AND SPEAKER
OUT 61H,AL ;WRITE NEW CTL DATA
MOV CX,48H ;HALF CYCLE TIME FOR TONE
BEEP_10:
LOOP BEEP_10 ;SPEAKER OFF
OR AL,02H ;TURN ON
OUT 61H,AL ; SPEAKER
MOV CX,48H ;HALF CYCLE TIME FOR TONE
BEEP_20:
LOOP BEEP_20 ;LET US HEAR THE MUSIC
DEC BX ;TIMES GROWING SHORTER
JNZ BEEP_05 ;DO IT AGAIN
POP AX ;RESTORE AX
OUT 61H,AL ;RESTORE KEYBOARD/SPEAKER CTL DATA
STI ;ENABLE INTERRUPTS
POP CX ;RESTORE CX
POP BX ;RESTORE BX
POP AX ;RESTORE AX
RET ;AND RETURN
BEEP ENDP
; *********************************************************************
; * *
; * TEST FOR REQUIRED PARAMETER *
; * CY = 1 IF PARMAMETER REQUIRED *
; * BUT NOT PRESENT *
; * *
; *********************************************************************
TREQ PROC
PUSH DX ;SAVE DX
MOV DX,BX ;SAVE FIRST ENTRY
TREQ_00:
TEST [BX].S_OPT,@REQ ;PARAMETER REQUIRED??
JZ TREQ_NEXT ;NO
CALL FIND_LEN ;GET DATA LENGTH
CLC ;CLEAR CARRY
OR CX,CX ;ANY DATA??
JNZ TREQ_NEXT ;YES
CALL BEEP ;RING THE BELL
STC ;INDICATE DATA REQUIRED
JMP TREQ_EXIT ;AND RETURN
TREQ_NEXT:
CALL GET_NEXT_INPUT ;NEXT ENTRY
CMP BX,DX ;LAST ENTRY??
JNE TREQ_00 ;NO - PROCESS THIS ONE
CLC ;SUCESSFULL
TREQ_EXIT:
POP DX ;RESTORE DX
RET ;AND RETURN
TREQ ENDP
; *********************************************************************
; * *
; * VALIDATE AL FOR AN ALPHA CHARACTER *
; * *
; *********************************************************************
CHK_ALPHA PROC
CMP AL,20H ;BLANK??
JE ALPHA_00 ;YES
CMP AL,040H ;LESS THAN "A"??
JBE ALPHA_ERR ;YES
CMP AL,'Z' ;EQUAL TO OR LESS THAN A "Z"
JBE ALPHA_00 ;YES
CMP AL,060H ;LESS THAN "a"??
JBE ALPHA_ERR ;YES
CMP AL,07BH ;GREATER THAN "z"??
JAE ALPHA_ERR ;YES
ALPHA_00:
CLC ;VALID CHARACTER
RET ;RETURN
ALPHA_ERR:
STC ;E R R O R
RET ;RETURN
CHK_ALPHA ENDP
; *********************************************************************
; * *
; * VALIDATE AL FOR AN Y OR N CHARACTER *
; * *
; *********************************************************************
CHK_YN PROC
CMP AL,'n' ;LOWER CASE N??
JE YN_00 ;YES
CMP AL,'N' ;UPPER CASE N??
JE YN_00 ;YES
CMP AL,'y' ;LOWER CASE Y??
JE YN_00 ;YES
CMP AL,'Y' ;UPPER CASE Y??
JE YN_00 ;YES
YN_ERR:
STC ;E R R O R
RET ;RETURN
YN_00:
CLC ;VALID CHARACTER
RET ;RETURN
CHK_YN ENDP
; *********************************************************************
; * *
; * VALIDATE AL FOR NUMERIC *
; * *
; *********************************************************************
CHK_NUMERIC PROC
CMP AL,'.' ;DECIMAL POINT??
JE NUMERIC_00 ;YES
CMP AL,'-' ;MINUS SIGN??
JE NUMERIC_00 ;YES
CMP AL,' ' ;BLANK??
JE NUMERIC_00 ;YES
CMP AL,02FH ;LESS THAN "0"??
JBE NUMERIC_ERR ;YES
CMP AL,'9' ;EQUAL TO OR LESS THAN "9"
JBE NUMERIC_00 ;YES
NUMERIC_ERR:
STC ;E R R O R
RET ;RETURN
NUMERIC_00:
CLC ;GOOD NUMBER
RET ;RETURN
CHK_NUMERIC ENDP
; *********************************************************************
; * *
; * COMPUTE VIDEO RAM OFFSET *
; * *
; *********************************************************************
CALC_OFFSET PROC
PUSH DX ;SAVE DX
PUSH BX ;SAVE BX
SUB AX,AX ;CLEAR AX
MOV AL,CS:ROW ;CALCULATE
MUL CS:LINE_LEN ; OFFSET TO LINE
MOV DL,CS:COL ;GET COLUMN
ADD AL,DL ;INCLUDE COLUMN
JNC CALC_OFFSET_00 ;IF NO CARRY
ADD AH,1 ;OTHERWISE ADDJUST
CALC_OFFSET_00: ;RETURN
SHL AX,1 ;ALLOW FOR ATTRIBUTE
POP BX ;RESTORE BX
POP DX ;RESTORE DX
RET ;RETURN
CALC_OFFSET ENDP
; *********************************************************************
; * *
; * UPDATE CURSOR POSITION *
; * *
; *********************************************************************
UPDATE_CURSOR PROC
PUSH AX ;SAVE AX
PUSH BX ;SAVE BX
PUSH DX ;SAVE DX
MOV AH,CS:ROW ;CURSOR ROW
MOV AL,CS:COL ;CURSOR
ADD AL,DL ; COLUMN
MOV DX,AX
MOV AH,02H ;SET CURSOR POSITION
XOR BX,BX ;PAGE 0
INT 10H ;CALL VIDEO SERVICE ROUTINE
POP DX ;RESTORE DX
POP BX ;RESTORE BX
POP AX ;RESTORE AX
RET
UPDATE_CURSOR ENDP
; *********************************************************************
; * *
; * EXIT *
; * *
; *********************************************************************
EXIT PROC
MOV CS:CURPOS,DL ;SAVE CURSOR POSITION
MOV CX,CS:NORM_CUR ;NORMAL CURSOR
MOV AH,1 ;FUNCTION
INT 10H ;CALL BIOS
POP BP ;RESTORE BP
POP ES ;RESTORE ES
POP DS ;RESTORE DS
POP SI ;RESTORE SI
POP DI ;RESTORE DI
POP DX ;RESTORE DX
POP CX ;RESTORE CX
POP BX ;RESTORE BX
POP AX ;RESTORE AX
MOV AL,CS:RETCODE ;SET RETURN CODE
MOV AH,CS:CURPOS ;RESTORE CURSOR POSITION
MOV BX,CS:ENTOFF ;CURRENT ENTRY OFFSET
RET ;AND RETURN
EXIT ENDP
CSEG ENDS
END SCRMGR