home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
TERM
/
REMSCR.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-06-30
|
21KB
|
617 lines
;REMSCRN.ASM
;
;WRITTEN 2/28/86 BY JOHN GOTSCHALL
;
;
;
;
; GENERIC SCREEN CONTROL STRING FILTER
; REPLACES OUTBOUND SCREEN COMMAND STRINGS WITH
; STRINGS THAT PERFORM IDENTICLE FUNCTIONS ON A
; REMOTE CONSOLE, THIS PROGRAM WAS DEVELOPED FOR
; USE IN AN APPLICATION WHERE A BUSINESS HAD A CP/M
; MACHINE RUNNING DBASE II, THEY DID NOT WANT TO
; GET A MULTI-USER MACHINE, BUT THEY DID WANT
; SIMULTANEOUS I/O TO A REMOTE HAZELTINE 1500, SO
; THAT WHEN ONE TERMINAL WAS NOT IN USE THE OTHER COULD
; BE USED, VERY SIMILAR IN FUNCTION TO A BYE PROGRAM,
; WITH THE EXCEPTION THAT THERE WAS NO MODEM INVOLVED.
; THE REMOTE IN THIS CASE HAD A DIFFERENT SET OF SCREEN COMMAND
; SEQUENCES THAN THE LOCAL, NECESSITATING CONVERSION
; OF THE LOCAL'S NATIVE COMMAND STRINGS INTO THE REMOTES
; NATIVE TONGUE. THIS MODULE PERFORMS THAT FUNCTION,
; RATHER NICELY.
;
; I WROTE THIS LITTLE THING, AND AS IT IS MY VERY FIRST
; 100% SUCCESSFUL ASSEMBLY PROGRAM WITH PRACTICAL APPLICATION,
; I HAVE MADE IT AVAILABLE TO THE GENERAL PUBLIC AND THUS
; MAY BE USED BY ANY PERSON FOR NON-PROFIT USE. IF YOU
; DO USE IT FOR PROFIT, YOU OWE ME ONE U.S. DOLLAR FOR
; EVERY PERSON THAT USES IT. (PRETTY CHEAP HUH?, THAT'S NOT
; ASKING A HECK OF A LOT.)
;
; IF YOU OWE ME A BUCK SEND IT TO:
;
; JOHN GOTSCHALL
; PO BOX 2475
; SEATTLE WA 98111
;
; ANYWAY, IMPLEMENTATION OF THIS CODE SHOULD BE PRETTY
; OBVIOUS, JUST PATCH THE FIRST TABLE WITH THE VALUES
; FOR YOUR LOCAL TERMINAL, THEN PLACE THE APPROPRIATE
; REPLACEMENT VALUES INTO THE SECOND TABLE, WHEN OUTPUTTING
; TO THE REMOTE, IF THE STRING THAT APPEARS IN THE FIRST
; FOUR BYTES OF THE FIRST TABLE GETS SENT TO THE LOCAL,
; THE CONTENTS OF THE FIRST FOUR BYTES OF THE SECOND
; TABLE WILL BE SENT TO THE REMOTE IN PLACE OF WHAT WAS SENT
; TO THE LOCAL. IF YOU ARE USING A BYE PROGRAM, ALL YOU
; NEED TO DO IS ADD THIS CODE TO YOUR BYE PROGRAM SOURCE
; CODE (MAKING SURE TO FIX ANY DUPLICATED LABELS), THEN HAVE
; YOUR BBS PROGRAM POKE THE VALUES FOR THE REMOTE'S
; COMMAND STRINGS INTO THE SECOND TABLE, THEN YOUR BYE
; MERGED WITH THIS PROGRAM WILL TAKE CARE OF MAKING
; SURE THE REMOTE GETS SCREEN CONTROL SEQUENCES THAT IT CAN
; UNDERSTAND, YET YOUR BBS PROGRAM NEED NOT DO ANYMORE
; THAN PRETEND THAT YOUR LOCAL AND THE REMOTE HAVE THE
; SAME SCREEN COMMAND SET. WORKS PERFECT WITH THE
; BUILT IN COMMANDS LIKE IN DBASE II AND TURBO PASCAL,
; IT EVEN WORKED PERFECT WITH WORDSTAR IN MY APPLICATION.
; WELL, IF YOU HAVE READ ALL OF THIS, I CERTAINLY HOPE YOU
; CAN MAKE USE OF THIS PROGRAM, AS YOU ALREADY HAVE SOME
; TIME INTO IT.
;
; BE FORWARNED, WHILE THIS CODE NEVER USES A STACK,
; IT WILL, WITHOUT A DOUBT DESTROY THE CONTENTS OF
; THE CPU REGISTERS, SO SAVE ANYTHING YOU WANT TO KEEP
; BEFORE CALLING THIS SUBROUTINE!!!!!
;
; DELIVER OUTBOUND CHARACTERS TO THIS ROUTINE IN BOTH
; THE A AND C REGISTERS !!
;
;
;=======================================================
;The following section of code filters the output to the remote,
;checking for the presence of screen command sequences, and when
;encountered, replaces the strings that are native to the local
;with strings that are native to the remote. This is done
;through the use of two look-up tables. The first of the two
;tables contains all of the sequences that are expected to be
;sent out, and are in code that is native to the local screen.
;the second table is where we patch in the corresponding strings,
;but there they are the strings that the remote will recognize
;as they are native to the remote.
;=======================================================
;
;******************************************************
;There are many calls to a routine labeled 'REMOUT',
;you will not find remout in this listing, whenever this
;code calls remout, it thinks that it is delivering a
;single character to the remote... all waiting for status
;for the remote must take place in remout, your version
;of bye should already have a routine to output characters
;to the remote..... THAT routine is the one that this code
;refers to when it calls remout. The character to be sent to the
;renote from this code will be found in the C register whenever remout
;is called.
;********************************************************
;
;
;THE FOLLOWING TWO TABLES ARE 60 BYTES LONG, THEY ARE
;ORGANIZED SO THERE ARE 15 STRINGS OF 4 BYTES. THE FIRST
;TABLE IS SCANNED PRIOR TO ANY OUTPUT TO THE REMOTE, IF
;THE CURRENT OUTBOUND CHARACTER MATCHES ANY OF THE CHARACTERS
;IN THE FIRST POSITIONS OF THE FIRST TABLE, THE CHARACTER IS
;BUFFERED, WHEN THE NEXT CHARACTER COMES THROUGH, A TEST IS
;MADE TO FIND ANY WHOLE MATCHING STRINGS, IF THERE IS A
;POSSIBILITY OF A MATCH ON THE THIRD CHARACTER, THE SECOND
;CHARACTER IS BUFFERED, AND THE ROUTINE WAITS UNTIL THE
;THIRD CHARACTER COMES THROUGH, IT THEN TESTS TO SEE IF
;THERE IS A POSSIBILITY OF A COMPLETE MATCH. ON CHARACTERS
;2, AND 3, CHECKS ARE MADE FOR BOTH PENDING MATCHES, AND
;COMPLETE MATCHES, ANY COMPLETE MATCHES WIN AND ARE IMMEDIATLY
;CONVERTED TO THE REMOTE'S COMMAND SET, AND ARE IMMEDIATLY SENT OUT
;TO THE REMOTE.
;
;IF THERE IS A MATCH IN ANY OF THE STRINGS IN THE FIRST TABLE
;THE STRING IS REPLACED WITH THE CONTENTS OF THE SAME POSITIONS
;IN THE SECOND TABLE... ANY STRINGS MAY BE PUT IN ANY LOCATIONS,
;WITH THE EXCEPTION THAT THE LAST STRING OF 4 IN EACH TABLE IS
;RESERVED FOR THE CURSOR POSITIONING LEAD IN STRINGS, THE
;FOLLOWING THREE BYTES ARE FOR THE X AND Y COORDINATES AND
;THERE IS A FLAG THAT DENOTES WHICH COORDINATE COMES FIRST.
;
;THE MAXIMUM LENGTH FOR ANY COMMAND STRING IS FOUR BYTES!
;
INSTNG EQU $+OFFSET
DB 01BH,045H,01BH,048H ;CLEAR AND HOME CURSOR
DB 01BH,05AH,0,0 ;CLEAR TO EOL
DB 01BH,04AH,0,0 ;CLEAR TO EOS
DB 27,69,0,0 ;ANOTHER STRING THAT IS CL & HME
DB 01BH,048H,01BH,045H ;YET ANOTHER CL & HOME STRING
DB 01BH,'K',0,0 ;IF LESS THAN 4 BYTES LONG,
DB 0,0,0,0 ;LEAVE 0'S TO FILL THE EXTRAS,
DB 0,0,0,0 ;THE ZEROS WON'T BE SENT OUT
DB 0,0,0,0
DB 0,0,0,0
DB 0,0,0,0
DB 0,0,0,0
DB 0,0,0,0
DB 0,0,0,0
DB 27,70,0,0 ;**LEAD-IN** CHARACTERS FOR THE
;LOCAL CONSOLE'S CURSOR POSITIONING
;STRING, IF LESS THAN 4 BYTES LONG,
;LEAVE A '0' TO FILL THE EXTRAS
;
ICCC EQU $+OFFSET
DB 2 ;WHICH COORDINATE CARRIES THE COLUMN DATA?
;THE FIRST OR THE SECOND
;
ICCO EQU $+OFFSET
DB 32 ;VALUE OF COLUMN OFFSET FOR LOCAL
;
ICRO EQU $+OFFSET
DB 32 ;VALUE OF ROW OFFSET FOR LOCAL
;
;
OUTSTNG EQU $+OFFSET
DB 07EH,01CH,0A0H,0 ;REPLACEMENT COMMAND STRINGS
DB 07EH,0FH,0,0 ;THAT ARE TO BE INSERTED IN THE
DB 07EH,018H,0,0 ;DATA FLOW TO THE REMOTE IN
DB 07EH,01CH,0A0H,0 ;IN PLACE OF THE COMMAND STRINGS
DB 07EH,01CH,0A0H,0 ;FOUND IN THE ABOVE TABLE. THE
DB 07EH,0FH,0,0 ;STRINGS IN THE TABLE ABOVE MUST
DB 0,0,0,0 ;MATCH THE STRINGS THAT WILL BE
DB 0,0,0,0 ;SENT TO THE LOCAL CONSOLE, WHILE
DB 0,0,0,0 ;THESE MUST CARRY THE STRINGS FOR
DB 0,0,0,0 ;THE SAME FUNCTIONS, BUT IN THE
DB 0,0,0,0 ;REMOTE'S NATIVE TONGUE.
DB 0,0,0,0 ;IF LESS THAN 4 BYTES LONG,
DB 0,0,0,0 ;LEAVE 0'S TO FILL THE EXTRAS,
DB 0,0,0,0 ;THE ZEROS WON'T BE SENT OUT
DB 07EH,011H,0,0 ;**LEAD-IN** CHARACTERS FOR THE
;REMOTE CONSOLE'S CURSOR POSITIONING
;STRING, IF LESS THAN 4 BYTES LONG,
;LEAVE 0'S TO FILL THE EXTRAS,
; ;THE ZEROS WON'T BE SENT OUT
;
OCCC EQU $+OFFSET
DB 1 ;POSITION IN CURSOR POSITIONING
;STRING THAT CARRIES THE COLUMN
;FOR REMOTE
;
OCCO EQU $+OFFSET
DB 0 ;VALUE OF COLUMN OFFSET FOR REMOTE
;
OCRO EQU $+OFFSET
DB 0 ;VALUE OF ROW OFFSET FOR REMOTE
;
;
;MOVE (HL) TO (DE) LENGTH IN (B)
;
;THE FOLLOWING IS COMMENTED OUT, THIS ROUTINE IS DUPLICATED EXACTLY
;IN MY VERSION OF BYE.COM, SO I DON'T NEED THIS AGAIN, BUT IF YOUR
;VERSION OF BYE.COM DOES NOT HAVE THIS ROUTINE IN IT, USE THIS ONE
;OR IF YOU MAKE AN OVERLAY OF THIS FILE YOU WILL NEED IT
;
;
;MOVE EQU $+OFFSET
; MOV A,M ;GET A BYTE
; STAX D ;PUT IT IN NEW HOME
; INX D ;BUMP POINTERS
; INX H
; DCR B ;DEC BYTE COUNT
; JNZ MOVE ;IF MORE, DO IT
; RET ;IF NOT, RETURN
;
;**************************************************
;**************************************************
;* MAIN PROGRAM SECTION, THIS IS THE PART THAT *
;* DOES ALL THE FILTERING OF CURSOR COMMAND *
;* SEQUENCES....... *
;**************************************************
;
;
;the call to vconout below calls the routine that is already
;in my version of bye. I replaced the call for vconout in
;my version of bye with a call for 'OUTPUT' below, so that the
;program comes here just prior to outputing to the local.
;
OUTPUT EQU $+OFFSET
CALL STRT ;STORE CHAR IN FIRST EMPTY BUFFER LOC
CALL VCONOUT ;SEND IT TO THE LOCAL
;
MT1 EQU $+OFFSET
LDA CLCF ;POINT TO CURSOR LOCATION COMMAND FLG
CPI 1 ;ARE WE AWAITING A CURSOR COMMAND?
JZ CPF ;YES, GOTO CURSOR POS.FILTER
MT2 EQU $+OFFSET
LDA MTSTR ;POINT TO MATCHSTRING
CPI 01H ;IS IT A 1?
JZ MMF ;THERE WAS A PRIVIOUS MATCH, AND NOT A CURSOR
;COMMAND, SO
;LETS TAKE THIS CHAR TO THE MAIN
;MATCH FINDER
MT3 EQU $+OFFSET
JMP QCHK ;NOTHING MATCHED LAST TIME
;WE OUTPUTTED, AND WER'E NOT LOOKIN
;FOR A CURSOR COORDINATE, SO LET'S JUST
;QUICKLY SCAN FOR A FIRST
;CHAR MATCH
;
QCHK EQU $+OFFSET
LXI H,BUFLOC ;GET THE ADDRESS OF THE BUFFER
SHLD BUFPTR ;PUT IT IN THE BUFFERPOINTER
LXI H,INSTNG ;GET THE ADDRESS OF INSTING
SHLD INSPTR ;PUT IT IN THE POINTER
MOV B,C ;SAVE THE CHAR IN B
MVI A,0
STA COUNT
STA COUNT1
LXI H,INSTNG ;POINT TO THE BEGINNING OF THE INSTING
QCHCK1 EQU $+OFFSET
MOV A,M ;GET THE CONTENTS
CMP C ;IS IT THE SAME AS OUR CHAR?
JZ ST1MT ;IT'S A MATCH
QCHK2 EQU $+OFFSET
INX H ;BUMP
INX H ;UP TO THE
INX H ;BEGINNING OF THE NEXT
INX H ;STRING OF FOUR BYTES
LDA COUNT
INR A
STA COUNT ;KEEP TRACK OF WHICH GROUP OF FOUR WERE' ON
CPI 0FH ;PAST 15 YET?, IF SO, THEN THERE IS NO POSSIBLE
JZ DONE ;MATCH SO GO DUMP THE CHARACTER FROM THE BUFFER
JMP QCHCK1
ST1MT EQU $+OFFSET
LXI H,MTSTR ;THERE IS A MATCH IN ONE OF THE FIRST
MVI A,1 ;POSITIONS OF THE INSTRING LINES
MOV M,A ;LEAVE NOTE OF THIS IN THE MTSTR GROUP.
RET ;TO CP/M, WE'LL SEND OUT THIS CHAR LATER..
;
;
;###########################
;
; MMF (MAIN MATCH FINDER,
; ROUTINE CHECKS ENTIRE INSTRING, COMPARES TO THE CONTENTS OF THE
; BUFFER TO THE INSTNG TABLE, MAKES NOTATION TO SHOW POSSIBLE
; PENDING MATCHES, OR PARTIAL BUT IMPOSSIBLE MATCHES, AND MAKES
; THE FINAL DECISION ON WHETHER OR NOT THERE IS A MATCH OF
; AN ENTIRE STRING.
;
;
;
MMF EQU $+OFFSET
LXI H,INSTNG ;GET ADDRESS OF INSTNG INTO (D,E)
SHLD INSPTR ;RESET POINTER
LXI H,BUFLOC ;POINT TO FIRST BUFFER POSITION
SHLD BUFPTR ;RESET BUFPTR
MVI A,0 ;GET A 0
STA POSMTCH ;RESET POSSIBLE MATCH FLAG
STA COUNT ;RESET COUNT FLAG
STA COUNT1
ENT EQU $+OFFSET
LDA COUNT1 ;REACHED END OF INSTNG?
CPI 15
JZ ANT1 ;YEP...GO AND CHECK FOR A PENDING MATCH...
;IT MAY BE THAT WE NEED TO WAIT FOR MORE
;CHARACTERS TO COME THROUGH...
LHLD BUFPTR ;POINT TO THE CURRENT BUFFER ADDRESS
;
;COME INTO ENT1 WITH THE CURRENT BUFFER ADDR IN HL
;
ENT1 EQU $+OFFSET
MOV A,M ;GET VALUE OF CHAR AT BUFFER
LHLD INSPTR ;POINT TO TABLE
CMP M ;DOES BUFFER CHAR MATCH TABLE CHAR?
JNZ ENT7 ;NOPE...
ENT2 EQU $+OFFSET
LDA COUNT ;IF WE ARE AT THE FIRST OF 4,
CPI 0 ;COUNT WILL BE 0
JNZ ENT6 ;NOPE...
ENT3 EQU $+OFFSET
MVI A,1 ;SINCE THERE IS A MATCH IN THE
STA POSMTCH ;FIRST OF 4 IN THE TABLE, MAKE
;A NOTE OF IT
ENT4 EQU $+OFFSET
LXI H,MTSTR ;POINT TO MATCHSTRING
LDA COUNT ;ALSO MAKE NOTE IN THE MATCHSTRING
MOV B,A ;ADD COUNT TO MATCHSTR LOCATION
ENT4A EQU $+OFFSET
MOV A,B ;MAKE SURE WE STILL HAVE IT
CPI 0 ;MATCHING LOCATIONS YET?
JZ ENT4B ;YEP
INX H ;BUMP POINTER
DCR B ;COUNTDOWN
JMP ENT4A
ENT4B EQU $+OFFSET
MVI A,1 ;GET A ONE
MOV M,A ;PUT THE FLAG INTO THE MATCHSTRING
ENT5 EQU $+OFFSET
LDA COUNT ;CECK TO SEE IF THIS IS THE
CPI 3 ;4TH CHAR IN THE STRING
JNZ ENT8 ;NOPE, GO DO SOME MORE....
JMP WHM ;WE HAVE A FULL MATCH FOR A WHOLE
;STRING OF FOUR !!!!!!!
ENT6 EQU $+OFFSET
LDA POSMTCH ;IS THERE A POSSIBLE MATCH?
CPI 1 ;
JZ ENT4
JMP ENT8
ENT7 EQU $+OFFSET
LXI H,POSMTCH ;POINT TO POSMTCH
MVI A,0 ;GET A 0
MOV M,A ;RESET POSMTCH
ENT8 EQU $+OFFSET
LHLD BUFPTR ;GET THE ADDRESS IN THE BUFFER POINTER
INX H ;INCREMENT IT
SHLD BUFPTR ;PUT IT BACK
LHLD INSPTR ;GET THE ADDRESS IN THE INSTRING POINTER
INX H ;INCREMENT IT
SHLD INSPTR ;PUT IT BACK
LDA COUNT ;GET THE COUNT
INR A ;INCREMENT IT
STA COUNT ;PUT IT BACK
ENT9 EQU $+OFFSET
LDA COUNT ;MAKE SURE WE HAVE THE COUNT
CPI 4 ;PAST THE 4TH CHAR YET?
JNZ ENT ;NOPE , GO DO MORE
ENT10 EQU $+OFFSET
MVI A,0 ;WE'RE AT HE 4TH, SO
STA COUNT ;RESET COUNT
LDA COUNT1 ;WERE LOOKING AT THE NEXT
INR A ;STRING IN THE TABLE, SO
STA COUNT1 ;MAKE NOTE OF THAT
LXI H,BUFLOC ;ALSO, ON THE NEXT PASS,
SHLD BUFPTR ;WE WANT TO POINT TO
;THE FIRST CHAR IN THE BUFFER
JMP ENT
;################################################
;
;END OF MATCH FINDER, IF THERE WAS NO EXACT MATCH,
;WE MAY JUST NOT HAVE ALL THE CHARACTERS YET, SO NOW WE CHECK TO
;SEE IF ANY PARTIAL MATCH IS A POSSIBLE MATCH
;
ANT1 EQU $+OFFSET
LXI H,MTSTR ;POINT TO THE FIRST POS OF MTSTR
MOV A,M ;GET THE CONTENTS
CPI 1 ;IS IT A ONE?
JNZ DONE ;NOPE, GO EMPTY BUFFER TO REMOTE,
;THERE IS NO CHANCE OF A MATCH..
ANT2 EQU $+OFFSET
INX H ;POINT TO NEXT LOCATION IN MTSTR
MOV A,M ;IS IT A ONE?
CPI 1 ;NOPE,
JNZ BZ ;GO CHECK BUFFER STRING
ANT3 EQU $+OFFSET
INX H ;POINT TO NEXT LOCATION
MOV A,M ;GET CONTENTS
CPI 1
JNZ BZ1 ;GO CHECK BUFFER STRING
JMP BZ2
BZ EQU $+OFFSET
LXI H,BUFLOC ;POINT TO BUFFER
INX H ;POINT TO 2ND CHAR
MOV A,M ;GET THE CHAR
CPI 0 ;IS THE POSITION IN THE BUFFER EMPTY?
RZ ;YES, THEN RETURN TO CP/M, LEAVE ALL AS IT
;IS, THERE MAY BE MORE CHARACTERS NEEDE TO
;MAKE A MATCHING STRING
JMP DONE ;THERE IS NO POSSIBILITY OF A MATCH,
;SO GO DUMP THE BUFFER
BZ1 EQU $+OFFSET
LXI H,BUFLOC ;POINT TO THE
INX H ;3RD CHAR IN BUFFER
INX H ;THERE WE ARE.....
MOV A,M ;GET THE CHAR, IS IT EMPTY?
CPI 0
RZ ;YEP, SAME AS IN BZ....
JMP DONE
BZ2 EQU $+OFFSET
LXI H,BUFLOC ;SAME AS BZ & BZ1,
INX H
INX H
INX H ;BUT CHECK THE LAST CHAR IN BUFFER
MOV A,M ;GET THE CHAR..
CPI 0 ;IS THE POSITION EMPTY?
RZ ;STILL EMPTY,GO TO CP/M AND TO IT AGIN,
JMP DONE ;BUFFER IS FULL AND NO MATCHES, SO GO EMPTY
;THE BUFFER.
;*****************************************
;END OF MAIN MATCH FINDER.....
;****************************************
;
;
;
;****************************************
;THIS IS WHERE WE GO WHEN WE HAVE A MATCH
;WE NEED TO SEND OUT THE STRING THAT CORRESPONDS TO
;THE STRING THAT MATCHED IN THE TABLE, IF IT WAS THE
;CURSOR POSITIONING STRING, WE WILL HAVE TO HANDLE THAT HERE ALSO.
;
WHM EQU $+OFFSET
LXI H,BUFLOC ;POINT TO BUFFER
XCHG ;MOVE TO DE
WHM1 EQU $+OFFSET
LXI H,COUNT1
MOV B,M ;PUT THE VALUE INTO B:
LXI H,OUTSTNG ;GET THE ADDRESS OF THE TABLE
WHM2 EQU $+OFFSET
MOV A,B ;PUT B INTO A
CPI 0 ;POINTING TO THE CORRECT SUBSTRING?
JZ WHM3 ;YEP
INX H ;MOVE POINTER UP
INX H ;BYE FOUR, THUS
INX H ;POINTING AT
INX H ;THE NEXT SUBSTRING IN THE OUTSTNG
DCR B ;BUMP B DOWN
JMP WHM2 ;LOOP SOME MORE
WHM3 EQU $+OFFSET
MVI B,4 ;4 BYTES TO MOVE
CALL MOVE ;MOVE THE CONTENTS TO THE BUFFER
;******************************
;DONE MOVING THE NEW STRING INTO THE BUFFER, NOW LET'S
;SEE IF IT IS A CURSOR POSITIONING STRING....
;
LDA COUNT1 ;GET THE TABLE STRING POINTER
CPI 14 ;IS IT A CURSOR COMMAND?
JNZ DONE ;NOPE, SO GO EMPTY BUFFER & RESET ALL
MVI A,1 ;GET A 1
STA CLCF ;SET CURSOR COMMAND FLAG TO TRUE
JMP DONE ;GO EMPTY THE BUFFER TO THE REMOTE....
;********************************
;SINCE WE JUST SET THE CLCF, WE WILL COME HERE ON
;THE NEXT 2 CONSOLE OUTPUT CALLS....
;OUR VALUE IS IN THE BUFFER, BUT IF THE SECOND BUFFER POSITION
;IS EMPTY, THEN WE NEED ONE MORE CHARACTER...
;ALSO, SINCE ONE OR BOTH OF OUR CURSOR AND ROW VALUES
;MAY BE A 0, WE'LL DUMP THE BUFFER HERE INSTEAD OF USING
;THE 'DONE ' ROUTINE....
;WE ARE COUNTING ON GETTING AN OFFSET OF >0 FROM THE LOCAL
;FOR THE FIRST POSITION...
CPF EQU $+OFFSET
LXI H,BUFLOC ;POINT TO THE BUFFER'S
INX H ;SECOND POSITION
MOV A,M ;GET THE CHAR
CPI 0 ;IS THERE A CHAR THERE?
RZ ;NOPE, GOTO CP/M AND AWAIT ANOTHER
CPF1 EQU $+OFFSET ;NOW WE HAVE THE TWO CHARACTERS WE WANT
LXI H,OCCC ;POINT TO THE FIRST BUFFER LOCATION
MOV B,M ;GET THE VALUE INTO B
LDA ICCC ;GET THE OTHER ONE
CMP B ;DO THEY MATCH?
JZ CPF2 ;YEP,DON'T NEED TO REVERSE THE BUFFER CONTENTS
LDA BUFLOC ;GET THE FIRST CHAR
MOV B,A ;SAVE IT IN B
LDA BUFLOC+1 ;GET THE NEXT ONE
STA BUFLOC ;PUT IT WHERE THE FIRST ONE WAS
MOV A,B ;GET THE ONE THAT WAS THE FIRST
STA BUFLOC+1 ;AND PUT IT IN THE SECOND POSITION
;
;NOW MODIFY THE X,Y COORDINATE VALUES
;BY STRIPPING THEM OF THEIR ORIGINAL OFFSET(S)
;
CPF2 EQU $+OFFSET
LXI H,ICCO ;POINT TO VAL OF LOCAL OFFSET
LDA BUFLOC ;GET THE FIRST CHAR
SUB M ;SUBTRACT THE OFFSET
STA BUFLOC ;PUT IT BACK
LXI H,ICRO ;POINT TO VAL OF 2ND LOCAL OFFSET
LDA BUFLOC+1 ;GET 2ND VAL FROM BUFFER
SUB M ;SUBTRACT THE OFFSET
STA BUFLOC +1 ;PUT IT BACK
;
;NOW ADD THE NEW OFFSETS TO THEM
;
CPF3 EQU $+OFFSET
LXI H,OCCO ;POINT TO THE OUTSTNG VALUE
LDA BUFLOC ;GET THE VALUE OF THE 1ST CHAR
ADD M ;ADD THE NEW OFFSET
STA BUFLOC
LXI H,OCRO ;POINT TO THE OTHER ONE
LDA BUFLOC+1 ;GET THE SECOND VAL FROM BUFFER
ADD M ;ADD THE NEW OFFSET
STA BUFLOC+1 ;PUT IT BACK
LDA BUFLOC ;GET 1ST CHAR
MOV C,A ;PUT IT IN C
CALL REMOUT ;SEND IT OUT
LDA BUFLOC+1 ;GET SECOND
MOV C,A ;PUT IT IN C
CALL REMOUT ;SEND IT OUT
MVI A,0 ;NOW KILL THE CHARS IN THE BUFFER
STA BUFLOC
STA BUFLOC+1
CALL DONE2 ;USE DONE'S ROUTINES TO CLEAR THINGS
INIT9 EQU $+OFFSET
LXI H,CLCF ;POINT TO THE FIRST OF THE FLAGS AND BUFFERS
LXI B,BUFPTR-CLCF ;# OF VARIABLES TO CLEAR
MVI A,0 ;GET A ZERO
INIT10 EQU $+OFFSET
MOV M,A ;PUT IT IN THE VAR OR FLAG
DCX B ;BUMP COUNTER
MOV B,A
CPI 0
RZ ;ALLDONE, BACK TO CP/M
INX H ;POINT TO NEXT BYTE
MVI A,0 ;GET THE ZERO BACK
JMP INIT10
;********************************************
;DONE OUTPUTTING ANYTHING THAT COMES ALONG, CONVERTED AS NECESSARY
;******************************************
;
;COME HERE WITH A NEW CHARACTER, BEFORE OUTPUTING IT TO
;THE LOCAL
;
STRT EQU $+OFFSET
MVI A,0
STA COUNT ;ZERO THE COUNTER
LXI H,BUFLOC ;POINT TO THE BUFFER
STRT1 EQU $+OFFSET
MOV A,M ;GET THE CONTENTS
CPI 0 ;IS THERE A 0 THERE?
JZ STRT2 ;YES, BUFFER IS EMPTY
LDA COUNT ;NO? THEN HOW MANY CHAR IN IT?
INR A ;LETS LOOK AT THEM AND COUNT
STA COUNT ;THE CHARACTERS
CPI 6 ;BETTER NOT BE MORE THAN 6
JZ ERRXIT ;OOPS, GOT A PROBLEM
INX H ;POINT TO NEXT POSITION
JMP STRT1 ;MORE CHARS TO CHECK
STRT2 EQU $+OFFSET
MOV M,C ;PUT OUTBOUND CHAR INTO BUFFER
RET
;**************************************
;
;DONE... THIS IS WERE WE END UP WHEN WE WANT TO DUMP THE BUFFER TO
; THE REMOTE.....
;
DONE EQU $+OFFSET
MVI B,0 ;SET COUNT TO 0
LXI H,BUFLOC ;POINT TO THE BUFFER
DONE1 EQU $+OFFSET
MOV A,M ;GET THE CHAR
CPI 0 ;IS IT A 0?
JZ DONE2 ;RETURN IF 0
MOV C,M ;NOT A 0 SO GET THE CHAR
CALL REMOUT ;GO OUTPUT IT
MVI A,0
MOV M,A ;KILL THE BUFFER CHAR
INX H ;POINT TO NEXT CHAR
JMP DONE1
DONE2 EQU $+OFFSET
LXI H,POSMTCH ;POINT TO POSMTCH FLAG
MOV M,A ;PUT A ZERO THERE
LXI H,MTSTR ;POINT TO MATCH STR
MVI B,5 ;SET COUNT
DONE3 EQU $+OFFSET
MOV M,A ;ZERO THE MTSTR ALSO
DCR B
CMP B ;IS B A 0 YET?
JZ DONE4 ;ALL DONE
INX H ;POINT TO NEXT
MVI A,0 ;GET A 0
JMP DONE3 ;
DONE4 EQU $+OFFSET
RET
;
CLCF EQU $+OFFSET
DB 0
POSMTCH EQU $+OFFSET
DB 0
OSPTR EQU $+OFFSET
DB 0,0
INSPTR EQU $+OFFSET
DB 0,0
MTSTR EQU $+OFFSET
DB 0,0,0,0,0,0
COUNT EQU $+OFFSET
DB 0
COUNT1 EQU $+OFFSET
DB 0
BUFLOC EQU $+OFFSET ;LOCATION OF OUTBOUND BUFFERED STRING
DB 0,0,0,0,0,0,0
BUFPTR EQU $+OFFSET
DB 0,0
;==========================================================
;END OF SCREEN COMMAND STRING FILTER SECTION.
;==========================================================