PGM 8086 MONITOR TTL MONITOR2 REL * * This version allows Tripos to start at absolute * location #500 * * BEGIN EQU $ * * * CLKCTL EQU #B6 SET UP TIMER 2 AS CLOCK TIMCTL EQU #D6 ADD OF TIMER CONTROL TIM2 EQU #D4 ADD OF TIMER 2 CNCTL EQU #DA ADD OF ONBOARD USART MODE EQU #4E USART AS VDU CMD EQU #27 SET USART OFF INT3 EQU #CC INT3 COMMAND * * UIO0 EQU #B0 BUFFER OF USART 0 UST0 EQU #B1 STATUS OF USART 0 UIO1 EQU #B2 UST1 EQU #B3 UIO2 EQU #B4 UST2 EQU #B5 UIO3 EQU #B6 UST3 EQU #B7 * * * * * TABLE OF VARIOUS BAUD RATES * * RATET EQU $ B38400 DW 2 B19200 DW 4 B9600 DW 8 B4800 DW 16 B2400 DW 32 B1200 DW 64 B600 DW 128 B300 DW 256 B150 DW 512 B110 DW 698 B75 DW 1024 NRATES EQU $-RATET NUMBER OF RATES IN TABLE * * * * * * *SET UP SOME CHARACTERS * * * CR EQU #D LF EQU #A ESC EQU #1B BRCHR EQU #1B * * * * CONST EQU #DE ADD OF CONSOLE STATUS CONDR EQU #DC ADD OF INPUT-OUTPUT OF CONSOLE TRDY EQU 1 DATA FOR CONSOLE RBR EQU 2 CONSOLE READ READY * * * *CONSTANT DEFINITIONS * * * PRTY0 EQU #7F MASK TO BLANK OFF PARITY *RSAV EQU -- START ADD OF SAVED REGS-DEFINED LATER *TABLE EQU -- START OF RECOGNISED SYMBOLS-LATER *CTAB EQU -- START OF RECOGNISED COMMANDS *NCMDS EQU -- NO OF RECOGNISED COMMANDS *CADR EQU -- START OF COMMAND ADDRESSES *LSGNON EQU -- LENGTH OF SIGN ON MESSAGE-DEFINED LATER MSEG EQU #40 MONITOR DATA SEGMENT AT #400 *MSEG EQU #500 FOR TESTS AT 4000 LMSEG DW MSEG START OF MONITOR TABLES-DS,SS&ES MSTAK EQU #80 START OF MONITOR STACK TOPINTLOC EQU #400 MCSEG EQU #FF80 START OF CODE SEG- TOP OF MEM-ROM (#FF800) *MCSEG EQU #400 TEMP FOR TESTS * EJT RTAB DB "SPSSCSIPFSESDSDISIBPDXCXBXAXCOSTS1S2#1#2ID" LTAB EQU $-RTAB * * * SPSAV EQU 0 SSSAV EQU 2 CSSAV EQU 4 IPSAV EQU 6 FSSAV EQU 8 ESSAV EQU 10 DSSAV EQU 12 DISAV EQU 14 SISAV EQU 16 BPSAV EQU 18 DXSAV EQU 20 CXSAV EQU 22 BXSAV EQU 24 AXSAV EQU 26 SSCNTR EQU 28 NUMBER OF CALLS BEFORE DISPLAYS SSTEP EQU 30 S1 EQU 32 S2 EQU 34 STEPCNT EQU 36 STEPCOUNTER TO BE USED INTPRES EQU 38 WE ARE IN MONITOR FOLLOWING AN INT INTDIS EQU 40 IF INTERRUPTS ARE TO BE DISABLED BEFORE RETURN CONSPD EQU 42 CURRENT VALUE FROM SPEED TABLE TABLE EQU 44 TOP OF RECOGNISED SYMBOLS * * COMMBASE EQU #B0 CONIN EQU CONDR DELAYTIME EQU 2 * * * * * CTAB DB "!" DB "R" DB "M" DB "I" DB "G" DB "D" DB "L" DB "E" DB "X" DB "C" DB "F" DB "V" NCMDS EQU $-CTAB NO OF RECOGNISED COMMANDS * * * CADR DW SCMD TTY SPEED COMMAND-CALLED BY B DW RCMD RCMD-RETURN TO USER PROG DW MCMD MCMD DW ERROR ICMD DW GCMD GO COMMAND DW DCMD DCMD DW LOAD LCMD DW RVIEW REG DISPLAY COMMAND DW XCMD REGISTER DISPLAY AND CHANGE DW CCMD MEMORY DISPLAY AND CHANGE DW FCMD FAST CONNECTION TO 1270 DW VCMD SET UP 1270 CONNECTION THEN AS FCMD * * * * SGNON DB 14,CR,LF,"RL8086 MON",CR,LF IPMES DB 6,"IP/CS=" AXMES DB 4,",AX=" BPMES DB 4,",BP=" SPMES DB 4,",SP=" FSMES DB 4,",FS=" SIMES DB 4,",SI=" BXMES DB 4,",BX=" DIMES DB 4,",DI=" LSGNON EQU $-SGNON LENGTH OF SIGN ON MESSAGE * MACRO DEFINITIONS * * **************************************************************** * * * * PUT MAC :@ MOV AL,!:1 CALL ECHO OUTPUT THE CH EMP * * SRET MAC :@ STC SET CARRY FOR SUCCESS RET EMP * * * FRET MAC :@ CLC CLEAR FOR FAILURE RET EMP * * * WRITE MAC :@ MOV SI,!:1 CALL WRITES EMP * * EJT ORG BEGIN+#100 * * * ************************************************************** * * START JMPS START1-BEGIN,MCSEG SET UP CORRECT IP&CS START1 MOV DX,!MSEG NOTE THAT DX CANNOT BE SEEN AFTER RESET MOV DS,DX RELOAD MONITOR DATA SEGMENT MOV AXSAV,AX SAVE ALL THE REGISTERS MOV BXSAV,BX FOLLOWING MOV CXSAV,CX A RESTART MOV BPSAV,BP MOV SISAV,SI INCLUDE STACK MOV DISAV,DI MOV SPSAV,SP MOV FSSAV,!0 CLEAR THE USERS FLAGS MOV DSSAV,DX SET UP SEGMENTS MOV ESSAV,DX TO POINT TO MONITOR SEGEMENTS MOV CX,!7 CLEAR THE REST OF THE FLAGS MOV SI,!SSCNTR IN THE MONITOR TABLE START3 MOV (SI),!0 CLEAR ADD SI,!2 TO TOP OF TABLE LOOP START3 * MOV AX,!0 SET UP THE INTERRUPT MOV DS,AX LOCATIONS IN THE BOTTOM MOV SI,AX OF MEMORY MOV BX,!INTENT THIS IS THE DEFAULT TRPA LOCATION MOV AX,!MCSEG AND THIS IS MONITOR CODE SEGMENT START2 MOV (SI),BX MOV 2(SI),AX ADD SI,!4 CMP SI,!TOPINTLOC JL START2 * OUT COMMBASE+#F RESET 4 CHANNEL EXPANSION BOARD * MOV AX,!MSEG START OTHER SEGS AT FF800 MOV SS,AX MOV AX,!MCSEG MOV DS,AX MOV ES,AX MOV SP,!MSTAK START MONITOR STACK HERE CLI TEMP TURN OFF INTS * * * MOV BX,B4800 MOV CONSPD,BX[SS] CALL TTYON SET UP CONSOLE * * MSGL WRITE SGNON * * * * * **************************************************************** * * ***************************************************************** * * * COMMAND RECOGNISING ROUTINE * * **************************************************************** *FUNCTION: GETCM *INPUTS : NONE *OUTPUTS : NONE *CALLS : GETCH,ECHO,EEROR *DESTROYS : A,C,DI,SI,FFS *DESCRIPTION:GETM RECIEVES AN INPUT CH FROM THE USER AND TRIES TO LOCATE * THIS CH IN THE COMMAND CHARACTER TABLE . IF SUCCESSFUL, * THE ROUTINE CORRESPONDING TO THIS CH IS SELECTED FROM * A TABLE OF COMMAND ROUTINE ADDRESSES, AND CONTROL IS * TRANSFERRED . IF NO MATCH THEN ERROR. * * * GETCM MOV SP,!MSTAK ALWAYS WANT TO RESET SP TO MONITOR MOV AX,!MSEG MOV SS,AX MOV AX,!MCSEG NB SCAW USES ES MOV DS,AX MOV ES,AX PUT "." PROMPT CH TO TTY CALL GETCH COMMAND CH TO A CALL ECHO BACK TO USER CMP AL,!ESC JNE GCM20 MOV AX,INTPRES[SS] IF INTERRUPT PRESENT CMP AX,!0 AND ESC HIT JE GCM20 THEN RETURN TO USER JMP INTRES ELSE IGNORE GCM20 MOV CX,!NCMDS DI GETS LOOP & INDEX COUNT MOV DI,!CTAB DI POINTS INTO COMM TABLE CLD MAKE SURE INCREMENTS REP LOOP THRO CX COMMANDS SCAB DOES IT MATCH JE GCM10 OK FOUND IT JMP ERROR COMM IS ILLEGAL GCM10 MOV SI,!NCMDS-1 SUB SI,CX SHL SI EACH BIT IS 2 BYTES LONG CALLI CADR(SI) NEXT INSTR COMES FROM COMM ROUTINE JMP GETCM BACK FOR NEXT COMMAND * * * * *********************************************************************** * * ROUTINE : DUMP * INPUTS : NONE * OUTPUTS : NONE * DESTROYS : A,BP,SI,CX * DESCRIPTION : READS TWO HEX NUMBERS AND DUMPS THE MEMORY OFFSET * BY S1 (USUALLY DEFAULTED TO USERS DI ).HALTS IF * ON 16TH LINE BOUNDARY TO DISPLAY THE PAGE-CR CAUSES * RETURN TO MONITOR ANY OTHER CH GIVES NEXT PAGE. * * * DCMD PUSH ES USED AS DUMP SEGMENT REG PUSH DS MOV AX,!MSEG MOV DS,AX MOV CL,!2 GET TWO NUMBERS CALL GETNM JCC DCM15 FAILED TO GET CORRECT ANS POP BP END ADD POP SI START ADD SAR SI MAKE SI EVEN SHL SI AND LOWER MOV ES,S1 LOAD SEG REG DCM05 CALL CROUT NEWLINE MOV AX,SI CALL PUT4H TYPE THE ADDRESS DCM10 PUT " " TYPE SPACER MOV AX,(SI)[ES] PICK UP CONTENTS XCHG AL,AH MAKE BYTES APPEAR CORRECT WAY ROUND CALL PUT4H TYPE THEM PUT " " TYPE SPACER ADD SI,!2 NEXT WORD CMP SI,BP FINISHED JA DCM15 SO END TEST SI,!#FF PAGE TYPED JNZ DCM12 NO PUT "?" QUERY AND CAUSES WAIT FOR CH CALL GETCH HOLDS PAGE UP CMP AL,!CR IF CR THEN BACK TO MON JE DCM15 QUIT DCM12 TEST SI,!#F AT END OF LINE JZ DCM05 ANOTHER LINE JMP DCM10 ANOTHER CONTENTS DCM15 CALL CROUT ENDING POP DS REPLACE SAVED SEGMENTS POP ES RET * * * * * * *********************************************************************** * * FUNCTION : GO * DESCRIPTION : GETS SEG,INSTR POINTER AND GOES THERE * * * GCMD MOV CL,!2 GET 2 NUMBERS CALL GHXNM FROM INPUT JCC GCMDERR TWAS IN ERROR POP BX POP AX MOV CSSAV,BX[SS] SET UP USERS BLOCK MOV IPSAV,AX[SS] FOR A RETURN RCMD JMP INTRES AND RETURN GCMDERR JMP ERROR AS ALWAYS * * * *********************************************************************** * * ROUTINE : MOVE * INPUTS NOTHING *OUTPUTS NOTHING * DESTROYS A,C,SI,DI,BP,FFS * DESCRIPTION MOVES THE MEMORY POINTED TO BY S1/IST NO UPTO (INC) * S1/2ND NO INTO S2/3RD NO. NB S1&S2 USUALLY DEFAULTED TO * THE USERS DS. * * * MCMD MOV CL,!3 GET THREE NUMBERS CALL GETNM START-UPTO-DEST JCC MERROR ERROR IN READ ROUTINE POP DI DEST ADD POP BP LAST SOURCE ADD POP SI START SOURCE ADD PUSH ES USED AS SOURCE SEG PUSH DS USED AS DEST ADD MOV AX,!MSEG MOV DS,AX MOV ES,S1 SET UP SEGS MOV AX,S2 MOV DS,AX MCM10 MOV AL,(SI)[ES] GET SOURCE BYTE MOV (DI),AL PUT IT AWAY INC SI NEXT LOC INC DI CMP SI,BP ALL DONE JBE MCM10 NO SO AGAIN POP DS POP ES CALL CROUT RET MERROR JMP ERROR * * * * ****************************************************************** * * ROUTINE : RCMD * DESCRIP : RETURNS TO USER PROG * * * * * * ***************************************************************** * * * SCMD : SETS UP TTY AT DESIRED SPEED * * SCMD XOR BP,BP COUNTER FOR NUMBER OF RATES TRIED S05 CMP BP,!NRATES ALL DONE JGE SCMD HAVEN'T FOUND SO TRY COMMAND AGAIN MOV SI,!RATET POINTER TO START OF TABLE ADD SI,BP MOV BX,(SI) GET THE RATE XOR DI,DI NUMBER OF SUCCESSFUL TRIES ADD BP,!2 POINT TO THE NEXT RATE CALL TTYSP SET UP THE CONSOLE S10 CALL GETCH TRY TO READ A CH CALL GETCH DO ANOTHER IN CASE THE FIRST WAS RUBBISH CMP AL,!#5 IS IT CONTROL E? JNE S05 NO SO ONTO NEXT INC DI ANOTHER SUCCESS CMP DI,!4 JL S10 NOT SECOND SO CHECK MOV BP,(SI) MOV CONSPD,BP[SS] RET SUCCESS * * * * EJT * * * ********************************************************** * * * * UTILITY ROUTINES * ************************************************************************** * * FUNCTION:BREAK * INPUTS:NONE * OUTPUTS: CARRY - 1 IF ESCAPE CHAR * - 0 IF ANY OTHER CHAR OR NO CHAR PENDING * CALLS:NOTHING * DESTROYS: AL,F/F'S * DESCRIPTION: BREAK IS USED TO SENSE AN ESCAPE CHAR FROM * THE PENDING USER. IF NO CHAR IS PENDING OR IF * THE PENDING CHAR IS NOT ESCAPE THEN A FAILURE * RETURN (CARRY=0) IS TAKEN. IN THIS CASE THE * PENDING CHAR(IF ANY) IS LOST. IF THE PENDING CHAR * IS AN ESCAPE CHAR THEN BREAK TAKES A SUCSSESFUL RETURN * CARRY=1 * BREAK IN CONST GET CONSOLE STATUS TEST AL,!RBR SEE IF CHAR IS PENDING JZ BREF NO TAKE FAILURE RETURN IN CONDR YES PICK UP CHAR AND AL,!PRTY0 STRIP OFF PARITY BIT CMP AL,!BRCHR IS IT ESCAPE CHAR JNE BREF FAILURE RET SRET SUCCESS RET BREF FRET FAILURE RET * * ************************************************************************** * * * FUNCTION: WRITES * INPUTS: SI - ADRESS OF STRING (IN BCPL FORMAT) I.E LENGTH,STRING * OUTPUTS: STRING TO CONSOLE * DESTROYS - SI IN MACRO FORM * DESCRIPTION : WRITE OUT A CHRACTER STRING * WRITES PUSH AX PUSH CX XOR CX,CX CLEAR CX MOV CL,(SI) MOV COUNT INTO LOWER BYTE OF CX INC SI POINT AT FIRST CHARACTER WLOOP MOV AL,(SI) NEXT CHARACTER => AL CALL CO OUTPUT IT INC SI BUMP CHARACTER POINTER LOOP WLOOP FOR CX CHARACTERS POP CX POP AX RET * * ************************************************************************ * * FUNCTION:CI * INPUTS : NONE * OUTPUTS A CHAR FROM THE CONSOLE * CALLS: NOTHING * DESTROYS: AL, F/F'S * DESCRIPTION: * CI WAITS UNTIL A CHAR IS READY FROM THE CONSOLE AND RETURNS * WITH THE CH IN AL * THIS ROUTINE IS CALLED BY THE USER VIA A JMP TABLE IN RAM * CI IN CONST GET STATUS OF THE CONSOLE AND AL,!RBR CHECK FOR RECEIVE BUFFER READY JZ CI NOT YET -- WAIT IN CONDR READY SO GET CHAR RET NB HAVENT GOT RID OF PARITY BIT * * ************************************************************************ * * FUNCTION: CNVBN * INPUTS: AL --ASCII CHAR '0'-'9' OR 'A'-'F' * OUTPUTS AL -- 0 - F HEX * CALLS : NOTHING *DESTROYS : AL,FFS * DESCRIPTION: CONVERTS CHAR TO HEX DOES NOT CHECK INPUT * CNVBN SUB AL,!"0" SUB CODE FOR ZERO CMP AL,!9 TEST FOR 0-9 JLE CNV05 OK SO RET SUB AL,!7 THIS IS RIGHT FOR ASCII ONLY CNV05 RET * * ************************************************************************ * * FUNCTION: CO * INPUTS: AL -- CHAR TO OUTPUT TO CONSOLE * OUTPUTS : AL TO CONS * CALLS : NOTHING * DESTROYS F/F'S *DESCRIPTION: * CO WAITS TILL CONSOLE IS READY THEN WRITES CHAR * CO PUSH AX CO05 IN CONST GET STATUS OF CONSOLE TEST AL,!TRDY IS IT READY TO GO JZ CO05 NO THEN WAIT POP AX REPLACE THE CH OUT CONDR SEND TO CONSOLE RET * ************************************************************************ * * FUNCTION : CROUT * INPUTS : NONE * OUTPUTS: NONE * CALLS:ECHO * DESTROYS :F/F'S * DESCRIPTION: * CROUT SENDS A CR ( AND HENCE A LF) TO CONSOLE * CROUT PUT CR RET * ************************************************************************ * * FUNCTION : ECHO * INPUTS: AL - CHAR TO ECHO TO TERMINAL * OUTPUTS: NONE * DESTROYS :F/F'S * DESCRIPTION: * ECHO SENDS A SINGLE CHAR AS INPUT AND VIA THE MONTOR SENDS THAT CHAR * TO THE USERS TERMINAL. A CR IS ECHOED AS CR + LF AND ESCAPE AS $ * * ECHO PUSH AX SAVE ARG CMP AL,!ESC JNZ ECH05 NO BRANCH MOV AL,!"$" ECH05 CALL CO DO OUTPUT THRU MONITOR CMP AL,!CR JNE ECH10 NO NEED FOR SPECIAL ACTION MOV AL,!LF YES ECHO LF ASWELL CALL CO ECH10 POP AX RESTORE ARG RET * ************************************************************************ * * FUNCTION :ERROR * INPUTS : NONE * OUTPUTS: NONE * CALLS: ECHO, CROUT, GETCM * DESTROYS: F/F'S * DESCRIPTION: * ERROR PRINTS THE ERROR CHAR (CURRENTLY AN ASTERISK) * FOLLOWED BY CR + LF * AND THE RETURNS CONTROL TO THE COMMAND REGOGNISER * ERROR PUT "*" SEND * TO CONSOLE CALL CROUT NEWLINE JMP GETCM TRY FOR ANOTHER COMMAND * ************************************************************************ * * FUNCTION : GETCH * INPUTS: NONE * OUTPUTS: AL -- CHAR FROM INPUT STREAM * CALLS : CI * * DESTROYS AL,F/F * DESCRIPTION: * GETCH GETS NEXT CHAR FROM THE INPUT * GETCH CALL CI GET CHAR AND AL,!PRTY0 TURN OFF PARITY BIT RET * * * ************************************************************************ * * FUNCTION GETHX * INPUTS: NONE * OUTPUTS : BP -- 16 BIT INTEGER * AL - CHAR TERMINATING THE INTEGER * AH - FF IF FIRST CH DELIMETER * CARRY - 1 IF SUCCESS * 0 IF FAILURE * CALLS: ECHO,GETCH,VALDL,VALDG,CNVBN,ERROR * DESTROYS: AX,BP,F/F'S * DESCRIPTION: * GETHX ACCEPTS A STREAM OF HEX DIGITS AS A 16 BIT INTEGER.IF MORE THAN * 4 HEX DIGITS ARE ENTERED ONLY THE LAST 4 ARE USED. THE NUMBER ENDS * WHEN A VALID DELEIMETER IS FOUND.THE DELIMETER IS ALSO RETURNED AS AN * OUTPUT OF THE FUNCTION. ILLEGAL CHARS ( NOT HEX OR DELIMETERS) CAUSE * AN FLAG. IF THE FIRST VALID CHAR IN INPUT IS NOT DELIMETER * AH SET TO 0 * GETHX PUSH CX SAVE CX MOV CL,!#FF FLAG FOR FIRST DIGIT XOR BP,BP INIT ANS TO 0 GHX05 CALL GETCH GET A CHAR GHX06 CALL ECHO ECHO IT CALL VALDL SEE IF DELIMETER JCS GHX15 YES SO END CALL VALDG IF NOT DELIM WAS IT A DIGIT JCC GHX20 NO SO INVALID DIGIT CALL CNVBN CONVERT TO BINARY MOV CX,!4 ROTATE ANS BY 1 DIGIT GHX10 SHL BP,CX MOV AH,!0 ADD IN THIS DIGIT ADD BP,AX B GHX05 GHX15 MOV AH,CL SET UP FIRST DIGIT FLAG STC FLAG TO SAY NO ERROR GHX20 POP CX RESTORE RET * * * ************************************************************************ * * FUNCTION: GETNM * INPUTS: CL- COUNT OF NUMBER TO BE FOUND IN INPUT STREAM * OUTPUTS: TOP OF STACK: NUMBERS TO BE FOUND IN REVERSE ORDER * CALLS: GETHX,HILO,ERROR * DESTROYS : AX,BP,SI,DI,CX,FFS * DESCRIPTION: * GETNM FINDS A CNT OF NUMBERS BETWEEN 1 AND 3 INCLUSIVE IN THE * INPUT STREAM AND RETURNS THEIR VALUES ON THE STACK * IF 2 OR MORE ARE REQUIRED THEN THE FIRST MUST BE LESS THAN OR EQUAL * TO 2ND OR 1ST IS SET EQ TO 2ND. THE LAST NUMBER MUST BE TERMINATED * BY CR OR AN ERROR IS GIVEN-C IS SET * REGS ARE STACKED IN REVERSE ORDER TO THAT READ IN * GETNM MOV SI,SP SAVE CORRECT SP IF ROUTINE FAILS AND CL,!3 FORCE TO MAX OF 3 JZ GNM30 IF 0 DONT BOTHER MOV CH,CL SAVE NUMBER OF NUMBERS GNM05 CALL GETHX GET A NUMBER FROM THE INPUT STREAM JCC GNM30 ERROR IF NOT THERE TOO FEW NUMBERS PUSH BP ELSE SAVE NUMBER ON STACK DEC CL DECR ARG CNT JZ GNM10 NO MORE NUMBERS WANTED CMP AL,!CR WAS IT CR JZ GNM30 ERROR IF SO TOO FEW JMP GNM05 ELSE PROCESS NEXT NUMBER GNM10 CMP AL,!CR WHEN CNT 0 CHECK LAST TERM JNE GNM30 ERROR IF NOT CR MOV BP,!#FFFF BP GETS LARGEST NUMBER MOV AL,!3 MAKE SURE HAVE STACKED THREE NUMBERS SUB AL,CH GNM15 JZ GNM20 IF YES 3 NUMBERS WERE INPUT PUSH BP IF NOT FILL OUT REST WITH FFFF DEC AL B GNM15 LOOP TILL DONE GNM20 POP SI POP BP GET THE 3 ARGS OUT POP AX CMP AX,BP SEE IF 1ST >= 2ND JBE GNM25 NO -- BRANCH JMP IF OK MOV AX,BP FORCE THEM = GNM25 POP DI REMOVE RETURN ADDRESS PUSH AX PUSH BP PUSH SI 3RD PUSH DI PUT RET ADDRESS ON STACK NEG CH ADD CH,!3 FIND NO OF EXTRA REGS STACKED GNM26 JZ GNM28 WHEN 0 FINISH POP DI POP BP TAKE EXTRA FROM UNDER RET ADD PUSH DI DEC CH B GNM26 LOOP GNM28 SRET SUCCESS GNM30 MOV SP,SI REPLACE CORRECT SP FRET FAILURE RET * * * ****************************************************************** * * GHXNM SAME AS GETNM BUT NO SWAPPING OF NUMBERS * * * GHXNM MOV SI,SP SAVE CORRECT SP IF ROUTINE FAILS AND CL,!3 FORCE TO MAX OF 3 JZ GXM30 IF 0 DONT BOTHER MOV CH,CL SAVE NUMBER OF NUMBERS GXM05 CALL GETHX GET A NUMBER FROM THE INPUT STREAM JCC GXM30 ERROR IF NOT THERE TOO FEW NUMBERS PUSH BP ELSE SAVE NUMBER ON STACK DEC CL DECR ARG CNT JZ GXM10 NO MORE NUMBERS WANTED CMP AL,!CR WAS IT CR JZ GXM30 ERROR IF SO TOO FEW JMP GXM05 ELSE PROCESS NEXT NUMBER GXM10 CMP AL,!CR WHEN CNT 0 CHECK LAST TERM JNE GXM30 ERROR IF NOT CR MOV BP,!#FFFF BP GETS LARGEST NUMBER MOV AL,!3 MAKE SURE HAVE STACKED THREE NUMBERS SUB AL,CH GXM15 JZ GXM20 IF YES 3 NUMBERS WERE INPUT PUSH BP IF NOT FILL OUT REST WITH FFFF DEC AL B GXM15 LOOP TILL DONE GXM20 POP SI POP BP GET THE 3 ARGS OUT POP AX GXM25 POP DI REMOVE RETURN ADDRESS PUSH AX PUSH BP PUSH SI 3RD PUSH DI PUT RET ADDRESS ON STACK NEG CH ADD CH,!3 FIND NO OF EXTRA REGS STACKED GXM26 JZ GXM28 WHEN 0 FINISH POP DI POP BP TAKE EXTRA FROM UNDER RET ADD PUSH DI DEC CH B GXM26 LOOP GXM28 SRET SUCCESS GXM30 MOV SP,SI REPLACE CORRECT SP FRET FAILURE RET * * * * ************************************************************************ * * FUNCTION NMOUT * INPUTS: AL - 8 BIT INTEGER * OUTPUTS: NONE * CALLS : ECHO,PRVAL * DESTROYS: F/F'S * DESCRIPTION: * NMOUT CONVERTS THE 8 BIT INTEGER INTO 2 ASCII CHARS AND PRINTS THEM * NMOUT PUSH AX SAVE AX DESTROYED HERE SHR AL SHR AL SHR AL SHR AL CALL PRVAL CONVERT TO ASCII CALL ECHO TYPE POP AX RESTORE PUSH AX AND SAVE IT AGAIN AND AL,!#F BOTTOM 4 BITS ONLY CALL PRVAL CALL ECHO POP AX RESTORE AX RET * *********************************************************************** * * FUNCTION : PRVAL * INPUTS : AL - INTEGER 0-F * * OUTPUTS: AL -ASCII CHAR * CALLS: NOTHING *DESCRIPTION: * CONVERTS TO ASCII WITHOUT CHECK ON VALUE * PRVAL ADD AL,!"0" CONVERT TO ASCII CMP AL,!"9" JLE PRV05 IF <10 OK ADD AL,!7 WORKS ONLY FOR ASCII PRV05 RET * ************************************************************************ * * FUNCTION: PUT4H * INPUT : AX 16 BIT INTEGER * OUTPUT : TYPES 4 HEX DIGITS * DESTROYS : NOTHING ? * DESCRIPTION : TYPES 4 HEX DIGITS * * PUT4H PUSH AX SAVE THE ARG XCHG AL,AH TYPE TOP BITS FIRST CALL NMOUT POP AX PUSH AX MAKE SURE ITS UNCHANGED CALL NMOUT TYPE BOTTTOM BITS POP AX RET **************************************************************** * * * FUNCTION : TTYON * DESCRIP : SETS TTY SPEED TO BX * * * TTYSP IN CONST TEST AX,!1 OK TO PROCEED JZ TTYSP PUSH BX MOV BX,!1 CALL DELAY POP BX MOV AL,!#40 SET CMD WORD BACK TO INSTRUCTION MODE OUT CNCTL TTYON MOV AL,!CLKCTL OUT TIMCTL PUSH AX POP AX MOV AX,BX PUT IN SPEED READY FOR OUT OUT TIM2 MOV AL,AH OUT TIM2 MOV AL,!MODE OUT CNCTL PUSH AX POP AX WASTE TIME FOR USART TO SET UP MOV AL,!CMD OUT CNCTL START IT OFF PUSH AX POP AX RET * * * ***************************************************************** * * * FUNCTION : VALDG * INPUTS: AL-- ASCII CHAR * OUTPUTS: CARRY = 1 IF REPRESENTS A HEX DIGIT * = 0 IF NOT * *CALLS : NOTHING * DESTROYS: F/FS * DESCRIPTION : * CHECK FOR A VALID HEX DIGIT '0'-'9' AND 'A' TO 'F' * VALDG CMP AL,!"0" AGAINST "0" JB VDGF IF LOWER CANT BE VALID CMP AL,!"9" WAS IT 0-9 JBE VDGS BETWEEN 0 AND 9 CMP AL,!"A" WAS IT A TO F JB VDGF NO CMP AL,!"F" JA VDGF NO VDGS SRET WAS A TO F INCLUSIVE VDGF FRET FAILURE RET * ************************************************************************ * * FUNCTION : VALDL * INPUTS : AL-- CHARACTER * OUTPUTS: CARRY = 1 VALID DELIMETER * =0 INVALID DELIMETER * CALLS :NOTHING * DESTROYS F/FS * DESCRIPTION: * VALID IF ( SPACE ,COMMA,CR) FAILURE IF NOT * VALDL CMP AL,!"," COMMA JZ VDLS SUCCESS CMP AL,!"." ALSO PERIOD JZ VDLS CMP AL,!"/" ALSO A STOKE JZ VDLS IS GOOD CMP AL,!CR CARRIAGE RETURN JZ VDLS SUCCESS CMP AL,!" " SPACE JZ VDLS FRET ALL ELSE INVALID VDLS SRET SUCCESS RET * ************************************************************************ * * * FUNCTION: CCMD * INPUTS: NONE * OUTPUTS: NONE * DESTROYS: PROBABLY EVERYTHING * DESCRIPTION: ALOWWS THE USER TO LOOK AND MODIFY MEMORY * CCMD CALL GETHX WHAT IS THE LOCATION JCC CERR MOV SI,BP FOR THE BYTE POINTER CMP AL,!"/" WAS DELIMETER SLASH JNE CC1 IF SO WE OVERRIDE SEGMENT CALL GETHX WITH A VALUE AFTER THE SLASH JCC CERR THIS REPLACES S1 MOV S1,BP[SS] CHANGE CC1 MOV ES,S1[SS] ES IS USED TO ACCES MEMORY * CC0 CALL CROUT FRESH LINE MOV AX,SI NOW OUTPUT THE LOCATION CALL PUT4H PUT "-" SEPERATE PUT " " MOV AL,(SI)[ES] THIS IS CALL NMOUT THE BYTE PUT " " PUT "-" DO WE WANT TO CHANGE CALL GETHX IF SO JCC CC2 MUST BE SUCCESS CMP AH,!#FF AND 1ST CHAR NOT DELIMETER JE CC2 BEFORE WE DO MOV BX,BP MOV (SI),BL[ES] CHANGE IT CC2 CMP AL,!CR IF RETURN JNE CC3 TIME TO GO HOME RET CC3 CMP AL,!"^" IF "^" THEN JNE CC4 MOVE BACK DEC SI JMP CC0 CC4 CMP AL,!"." IF "." THEN STAY JNE CC5 AS YOU WERE JMP CC0 CC5 INC SI IN ALL OTHER CASES JMP CC0 GO TO NEXT * CERR JMP ERROR * ****************************************************** * * * FUNCTION : XCMD * INPUT & OUTPUT : NONE * DESTROYS : ALL * DESCRIPTION: DISPLAYS USERS REGISTERS AND ALLOWS YOU TO CHANGE * XCMD PUT "-" THIS ALLOWS PUT " " THE USER CALL GETCH TO SET CALL ECHO EVERYTHING IN THE USER BLOCK XCHG AH,AL CALL GETCH CALL ECHO GET 2 CHAR IDENTIFIER XCHG AH,AL * MOV CX,!LTAB/2 NOW SCAN THE TABLE MOV DI,!RTAB FOR A MATCH CLD RIGHT DIRECTION REP SCAW JNZ XERR DID NOT FIND MATCH MOV SI,!LTAB/2 BYTE ADDRESSING SUB SI,CX DEC SI ADD SI,SI COMPLICATED PUT " " MOV AX,SPSAV(SI)[SS] THIS SHOULD GET IT CALL PUT4H DISPLAY IT PUT " " PUT "-" CALL GETHX DO WE NEED A CHANGE JCC XC1 CMP AH,!#FF JE XC1 MOV SPSAV(SI),BP[SS] CHANGE IT XC1 CMP AL,!CR IF DELIMETER RETURN JNE XC2 WE HAVE FINISHED RET XC2 CALL CROUT NEWLINE PUT " " NEW LOOK PUT " " JMP XCMD * XERR JMP ERROR * * ********************************************************************* * * * FUNCTION: RVIEW * INPUT & OUTPUT :NONE * DESTROYS : ALL * DESCRIPTION : DISPLAYS IP/CX,AX,SP,BP,SI,FLAGS * RVIEW CALL CROUT FRESH LINE WRITE IPMES MOV AX,IPSAV[SS] NOTE THAT CALL PUT4H AS USUAL WE USE PUT "/" WE USE MONITOR MOV AX,CSSAV[SS] TO ACCESS THE CALL PUT4H USERS WRITE SPMES REGISTER BLOCK MOV AX,SPSAV[SS] VIA STACK SEGMENT CALL PUT4H WRITE AXMES MOV AX,AXSAV[SS] CALL PUT4H WRITE BXMES MOV AX,BXSAV[SS] CALL PUT4H WRITE BPMES MOV AX,BPSAV[SS] CALL PUT4H WRITE SIMES MOV AX,SISAV[SS] CALL PUT4H WRITE DIMES MOV AX,DISAV[SS] CALL PUT4H WRITE FSMES MOV AX,FSSAV[SS] CALL PUT4H CALL CROUT RET * * * ************************************************************************* * * * * INTENT :::: FOR ALL UNDEFINED AND INTERRUPT 3 * IF SSTEP IS SET THEN IT WILL CALL RVIEW EVERY SSCNTR TIMES * SSCNTR-1 IN FACT * IT COMPLETELY SAVES THE USERS ENVIROMENT INCLUDE HIS CORRECT STACK * POSITION * IT IS A LITTLE TRICKY AS IT MUST USE THE USERS STACK INITIALLY * IT THEN COMPLETELY SWAPS TO THE MONITORS ENVIRONMENT * * INTENT PUSH DS WE MUST USE PUSH AX THE USERS STACK INITIALLY MOV AX,!MSEG NOW THE MONITORS MOV DS,AX DATA SEGMENT CMP SSTEP,!1 IF THE SINGLE STEP JNE INT2 FLAG IS UNSET OR COUNTER IS 0 CMP STEPCNT,!0 THEN WE DIPLAY AND GO JE INT2 THIS IS OK DEC STEPCNT MAYBE OK NEXT TIME JMP INTEXIT BUT OFF FOR NOW INT2 MOV AX,SSCNTR NOW RELOAD COUNT MOV STEPCNT,AX IT MAY WELL BE ZERO * POP AX AX RESTORED MOV AXSAV,AX NOW WE CAN MOV BXSAV,BX SAVE ALL THE MOV CXSAV,CX THE USERS MOV DXSAV,DX REGISTERS MOV BPSAV,BP THAT ARE STRAIGHT MOV SISAV,SI FORWARD MOV DISAV,DI MOV ESSAV,ES MOV SSSAV,SS * POP AX THIS WAS THE USERS MOV DSSAV,AX DATA SEGMENT POP AX IP USER POP BX CS -- USER POP CX FLAGS -- USER MOV IPSAV,AX MOV CSSAV,BX MOV FSSAV,CX MOV SPSAV,SP AFTER ALL THIS SP IS CORRECT MOV AX,DSSAV SET DEFAULT SEGMENT MOV S1,AX POINTER 1 & 2 MOV S2,AX MOV INTPRES,!1 INDICATE WE HAVE AN INTERRUPT * * ************************************************************ * * * NOW WE HAVE SAVED THE USERS ENVIRONMENT ENTIRELY * WE CAN SET UP THE MONITOR ENVIRONMENT * WITH NO FEARS FOR A SCREW UP * * MOV AX,!MSEG NOTE THAT WE CAN USE MOV SS,AX THE MONITOR STACK SEGMENT MOV AX,!MCSEG FOR ACCESSING USER DATA BLOCK MOV DS,AX MOV ES,AX MOV SP,!MSTAK RESET THE STACK * CALL RVIEW FOR A QUICK LOOK JMP GETCM FOR FURTHER WORK * * ************************************************************* * * INTEXIT POP AX NOWT TO DO POP DS THIS TIME IRET * * ******************************************************************* * * * * INTRES: * THIS RESETS THE USER ENVIRONMENT * INCLUDES SETTING OR RESETTING THE SINGLE STEP COUNTER * INTRES MOV AX,!MSEG SET UP DATA SEGMENT MOV DS,AX FOR EASY ACCESS CMP INTDIS,!1 SHOULD WE TURN OFF INTERRUPTS JNE IR5 NOT IF RESET AND FSSAV,!#FDFF OFF IT GOES IR5 AND FSSAV,!#FEFF CLEAR SINGLE STEP BIT CMP SSTEP,!1 IF WE WISH TO JNE IR3 HAVE SINGLE STEP OR FSSAV,!#0100 SET BIT ON MOV SI,IPSAV THIS COMPLICATED BIT MOV AX,CSSAV SEES IF THE NEXT INSTRUCTION IS MOV ES,AX IS AN INT3 IF SO IR4 MOV AL,(SI)[ES] IF SO AND IN SINGLE STEP CMP AL,!INT3 WE IGNORE JNE IR2 UNTIL NOT THIS INTRUCTION INC SI JMP IR4 IR2 MOV IPSAV,SI CLEVER STUFF HEY IR3 MOV SP,SPSAV FIRST USERS STACK MOV SS,SSSAV SET UP PUSH FSSAV NOW RETURN PUSH CSSAV PUSH IPSAV MOV ES,ESSAV MOV DI,DISAV MOV SI,SISAV MOV BP,BPSAV MOV DX,DXSAV MOV CX,CXSAV MOV BX,BXSAV MOV AX,AXSAV MOV INTPRES,!0 WE HAVE FINISHED MOV DS,DSSAV AFTER THIS IT IS USER DATA SEGMENT IRET * * *********************************************************************** * * * * USE THE 9.6 KB MAST LINK * * SELECT 'CONTROL BLOCK' VCMD OUT #BC * INITIALIZE PIT (TIMER) * PIT 1, TIMER 3 ( SO IT USES BDG3 ) * * SC1,SC0 = 0,0 COUNTER 3 * RL1,RL0 = 1,1 LOAD L.S. BYTE THEN M.S. * M2,M1,M0 = 0,1,1 MODE 3 FOR B.R.G. * BCD = 0 BINARY * SO, MOV AL,!#T00110110 * WRITE TO CONTROL (7) OUT #B7 * FOR B.R. OF 9600 AND DIV. BY 1 CLOCK LOAD COUNTER WITH 128 MOV AX,CONSPD[SS] MOV CL,!4 SHL AX,CL BECAUSE DIVIDE BY 1, NOT 16 OUT #B4 MOV AL,AH MOV AL,AH WASTE TIME OUT #B4 * B.R.G. IS NOW GOING * SELECT 'DATA BLOCK' OUT #BD * INITIALIZE UART MOV AL,!#40 OUT #B7 INTERNAL RESET MOV BX,!2 CALL DELAY * FIRST SEND MODE INSTRUCTION (7) * * S2,S1 = 0,1 1 STOP BIT * EP = 1 EVEN PARITY * PEN = 1 ENABLE PARITY * L2,L1 = 1,0 7 BITS OF DATA * B2,B1 = 0,1 BAUD RATE FACTOR = 1 * SO, MOV AL,!#T01111001 OUT #B7 PUSH AX POP AX * SEND COMMAND INSTRUCTION (7) * * EH = 0 NOT HUNT MODE * IR = 0 NOT INTERNAL RESET * RTS = 1 RTS TRUE * ER = 1 CLEAR ERROR FLAGS * SBRK = 0 NOT BREAK * RXE = 1 RECEIVE ENABLE * DTR = 1 DTR ON TO START WITH * TXEN = 1 TRANSMIT ENABLE * SO, MOV AL,!#T00110111 OUT #B7 PUSH AX POP AX * FCMD MOV DX,!UST3 B DLL USE THE LINK * * SETUP CLI ;DISABLE INTS OUT COMMBASE+#0C SELECT CONTROL WORD MOV AL,!#36 HOW TO READ OUT COMMBASE+#03 FOR USART0 MOV AL,!#40 BR=1200 LSB OUT COMMBASE+#00 MOV AL,!0 MSB OUT COMMBASE+#00 OUT COMMBASE+#0D SELECT DATA WORD MOV AL,!#40 OUT UST0 INTERNAL RESET PUSH AX POP AX MOV AL,!#7A SET UP USART AS COMPUTER OUT UST0 PUSH AX POP AX MOV AL,!#27 START IT OFF OUT UST0 PUSH AX POP AX RET * * * * LOAD CALL SETUP START UP COMMS MOV DX,!UST0 DLL MOV AL,!#37 CLEAR TTY ERROR FLAGS OUT CNCTL DLL1 IN CONST CH FROM CONSOLE TEST AL,!#20 JZ DLL2 NO SO IT IS CH TEST AL,!#10 IF PARITY ERROR THEN IGNORE THE CH JNE DLLA MOV AL,!#2F SEND BREAK ON THE LINE OUT MOV BX,!DELAYTIME LOAD DELAY >300MS FOR GANDALF CALL DELAY DLLA MOV AL,!#37 RESET FLAGS OUT CALL DELAY LET THINGS SETTLE JMP DLL RESET TTY DLL2 TEST AL,!RBR JZ DLL10 NO SO CHECK LINK IN CONIN GET IT AND AL,!PRTY0 PARITY OFF MOV BX,AX CMP AL,!#01 IS IT CONT A JZ FILL GET THE PROGRAM FROM LINK CMP AL,!#02 IS IT CONT B JZ GO YES BACK TO MONITOR DLL5 IN SEND IT TO LINK TEST AL,!1 IS IT READY JZ DLL5 LOOP TILL IS MOV AX,BX DEC DX OUT SEND TO LINK INC DX CMP DX,!UST3 IF 1270 CONN. THEN ECHO TO CONSOLE JE DLL11 DLL10 IN ANYTHING FROM THE LINE TEST AL,!2 JZ DLL1 NO SO CHECK CONSOLE DEC DX IN GET CH FROM LINK INC DX DLL11 AND AL,!PRTY0 CALL CO JMP DLL1 GO AND LOOK AT CONSOLE GO JMP GETCM START AGAIN FILL FILL1 CALL GETLIN GET CH FROM LINE CMP AL,!"O" IS IT AN O JNZ FILL1 LOOP UNTIL IT IS FILL5 CALL GETLIN GET THE NEXT CMP AL,!"R" IS IT THE R FROM "STORE" JZ DLL1 IF SO BACK TO TRANSPARENT MODE CMP AL,!"G" IS IT THE G FROM "PROG" JZ FILL8 START OF PROGRAM CMP AL,!"C" C INTROS OFFSET JNZ FILL5 NOT TRUE CH SO BACK FOR ANOTHER CALL RADD GET OFFSET MOV CX,!4 SHR AX,CX FOR SEGMENT ACCESS MOV ES,AX FROM EXTRA SEGEMNT JMP FILL1 GET NEXT LINE FILL8 CALL RADD GET TRUE ADD MOV SI,AX POINTER FOR ACCESS VIA SEGMENT FILL10 CALL RDATA GET THE CONTENTS JCC FILL1 CARRY DENOTES CR MOV (SI),AL[ES] INC SI JMP FILL10 GET NEXT CONTENTS GETLIN IN CH IN LINE TEST AL,!2 JZ GETLIN NO SO LOOP DEC DX IN INC DX AND AL,!PRTY0 STRIP OF PARITY CALL CO RET RETURN WITH CH IN C AND A *RNO READS A VALID HEX DIGIT OR SETS CARRY IF CR RNO CALL GETLIN GET A CH CALL VALDG IS IT VALID HEX JCC RNO1 RET RNO1 CMP AL,!CR JNZ RNO CLC RET *RDATA GETS 2 HEX DIGITS INTO A RDATA PUSH CX CALL RNO JCC RDATA1 CALL CNVBN SHL AX SHL AX SHL AX SHL AX MOV CX,AX CALL RNO JCC GO CALL CNVBN ADD AX,CX STC RDATA1 POP CX RET * RADD LOAD AN ADDRESS INTO AX RADD PUSH CX CALL RDATA MOV CH,AL CALL RDATA MOV AH,CH POP CX RET *DELAY THE VALUE IN BX TIME 40 MSEC DELAY PUSH BX PUSH CX DEL1 MOV CX,!0 LOOP $ DEC BX JNZ DEL1 POP CX POP BX RET * * * * ********************************************************************** * * * JUMP FROM POWER UP TO MONITOR * * ORG #7F0 POWER UP START JMPS START-BEGIN,MCSEG TO START OF MONITOR * * * END