; ; THIS ROUTINE IS THE PARALLEL DEVICE HANGLER ; NO PROVISION IS MADE FOR CONTROLLING THE PORT ; CONTROL BIT. ; ; ; PARALLEL INPUT DRIVER ; PASTAT: IN STAPT CMA ;INVERT STATUS FLAGS ANI PDR ;TEST BIT RZ IN PDATA ;GET DATA RET ; ; PARALLEL OUTPUT HANDLER ; PROUT: IN STAPT ;GET STATUS ANI PXDR ;TEST IF DEVICE IS READY JNZ PROUT ;LOOP UNTIL SO MOV A,B OUT PDATA RET ; ; ; OUTPUT A CR/LF FOLLOWED BY A PROMPT ; PROMPT: CALL CRLF MVI B,'>' ;THE PROMPT JMP SOUT ;PUT IT ON THE SCREEN ; ; CRLF: MVI B,LF ;LINE FEED CALL SOUT MVI B,CR ;CARRIAGE RETURN CALL SOUT IF EXT RET ENDF IF STD ; NOW OUTPUT THE NULLS LDA NUCNT ;GET DESIRED COUNT MOV C,A ;STORE IN C NULOT: DCR C RM ;RETURN WHEN PAST ZERO XRA A ;GET A NULL CALL OUTH JMP NULOT ENDF ; ; ; SCAN OFF OPTIONAL PARAMETER. IF PRESENT RETURN WITH ; VALUE IN HL AND COPY OF 'L' IN 'A'. IF NOT PRESENT ; RETURN WITH A "1" IN 'A' AND HL UNTOUCHED. ; PSCAN: CALL SBLK MVI A,1 ;DEFAULT VALUE RZ ;IF NONE CALL SHEX ;CONVERT VALUE MOV A,L ;GET LOWER HALF RET ; ; ; SCAN OVER UP TO 12 CHARACTERS LOOKING FOR A BLANK ; SBLK: MVI C,12 ;MAXIMUM COMMAND STRING SBLK1: LDAX D CPI BLANK JZ SCHR ;GOT A BLANK NOW SCAN PAST IT INX D CPI '=' ;ALSO ALLOW EQUAL TO STOP US JZ SCHR ;IF SO, PTR AT CHAR FOLLOWING DCR C ;NO MORE THAN TWELVE JNZ SBLK1 RET ;GO BACK WITH ZERO FLAG SET ; ; ; SCAN PAST UP TO 10 BLANK POSITIONS LOOKING FOR ; A NON-BLANK CHARACTER ; SCHR: MVI C,10 ;SCAN TO FIRST NONBLANK CHR IN 10 SCHR1: LDAX D ;GET NEXT CHARACTER CPI SPACE RNZ ;WE'RE PAST THEM INX D ;NEXT SCAN ADDRESS DCR C RZ ;COMMAND ERROR JMP SCHR1 ;KEEP LOOPING ; ; ; THIS ROUTINE SCANS OVER CHARACTERS, PAST BLANKS AND ; CONVERTS THE FOLLOWING VALUE TO HEX. ERRORS RETURN TO ; THE ERROR HANDLER. ; SCONV: CALL SBLK ;FIND IF VALUE IS PRESENT JZ ERR1 ;ABORT TO ERROR IF NONE ; ; ; THIS ROUTINE CONVERTS ASCII DIGITS INTO BINARY FOLLOWING ; A STANDARD HEX CONVERSION. THE SCAN STOPS WHEN AN ASCII ; SPACE IS ENCOUNTERED. PARAMETER ERRORS REPLACE THE ERROR ; CHARACTER ON THE SCREEN WITH A QUESTION MARK. ; SHEX: LXI H,0 ;CLEAR H & L SHE1: LDAX D ;GET CHARACTER IF EXT CPI 61H ;LOWER CASE? JC SHE2 ;NO ANI 5FH ;MAKE IT U.C. SHE2: EQU $ ENDF CPI 20H ;IS IT A SPACE RZ ;IF SO CPI '/' ;SLASH IS ALSO LEGAL RZ CPI ':' ;EVEN THE COLON IS ALLOWED RZ ; HCONV: DAD H ;MAKE ROOM FOR THE NEW ONE DAD H DAD H DAD H CALL HCOV1 ;DO THE CONVERSION JNC ERR1 ;NOT VALID HEXIDECIMAL VALUE ADD L MOV L,A ;MOVE IT IN INX D ;BUMP THE POINTER JMP SHE1 ; HCOV1: SUI 48 ;REMOVE ASCII BIAS CPI 10 RC ;IF LESS THAN 9 SUI 7 ;IT'S A LETTER CPI 10H RET ;WITH TEST IN HAND ; IF STD ; ; ***** TERMINAL COMMAND ***** ; ; THIS ROUTINE GETS CHARACTERS FROM THE SYSTEM KEYBOARD ; AND OUTPUTS THEM TO THE SELECTED OUTPUT PORT. IT IS ; INTENDED TO CONFIGURE THE SOL AS A STANDARD VIDEO ; TERMINAL. COMMAND KEYS ARE NOT OUTPUT TO THE OUTPUT ; PORT BUT ARE INTERPRETED AS DIRECT SOL COMMANDS. ; THE MODE COMMAND, RECEIVED BY THE KEYBOARD, PUTS THE SOL ; IN THE COMMAND MODE. ; ; ; TERM: CALL PSCAN ;FIND IF INPUT PARAMETER IS PRESENT STA IPORT ;SINP WILL USE THIS DRIVER (DEFAULT IS 1) CALL PSCAN ;NOW FOR THE OUTPUT DRIVER STA OPORT ; TERM1: CALL KSTAT ;IS THERE ONE WAITING? JZ TIN ;IF NOT MOV B,A ;SAVE IT IN B CPI MODE ;IS IT MODE? JZ COMN1 ;YES...RESET AND QUIT TERM JC TOUT ;NON-CURSOR KEY...SEND TO TERM PORT CALL VDMOT ;PROCESS IT JMP TIN ; TOUT: CALL SOUT ;OUTPUT IT TO THE SERIAL PORT TIN: CALL SINP ;GET INPUT STATUS JZ TERM1 ;LOOP IF NOT ANI 7FH ;NO HIGH BITS FROM HERE JZ TERM1 ;A NULL IS IGNORED MOV B,A ;IT'S OUTPUT FROM 'B' CPI 1BH ;IS IT A CONTROL CHAR TO BE IGNORED JNC TERM2 ;NO...TO VDM AS IS THEN CPI CR ;CR OR LF ARE SPECIAL CASES THOUGH JZ TERM2 ;AND MUST BE PASSED STD MODE TO VDM CPI LF JZ TERM2 LDA ESCFL ;A CTRL CHAR...ARE WE W/IN ESC SEQUENCE? ORA A ;IF YES, THEN OUTPUT CTRL CHAR DIRECTLY TO VDM JNZ TERM2 ;WE SURE ARE, LET VDM DRIVER HANDLE IT PUSH B ;SAVE THE CHARACTER MVI B,ESC ;CTRL CHAR TO VDM VIA ESC SEQUENCE CALL VDMOT MVI B,7 ;SAY TO PUT OUT NEXT CHAR AS IS CALL VDMOT ;ALMOST READY POP B ;RESTORE CHAR TERM2: EQU $ ;ALL READY TO OUTPUT THE CHAR CALL VDMOT ;PUT IT ON THE SCREEN JMP TERM1 ;LOOP OVER AND OVER ; ENDF ; ; ; ***** DUMP COMMAND ***** ; ; THIS ROUTINE DUMPS CHARACTERS FROM MEMORY TO THE ; CURRENT OUTPUT DEVICE. ALL VALUES ARE DISPLATED AS ; ASCII HEX. ; ; THE COMMAND FORM IS A FOLLOWS: ; ; DU ADDR1 ADDR2 ; ; THE VALUES FROM ADDR1 TO ADDR2 ARE THEN OUTPUT TO THE ; OUTPUT DEVICE. IF ONLY ADDR1 IS SPECIFIED THEN THE ; VALUE AT THAT ADDRESS IS OUTPUT. ; DUMP: CALL SCONV ;SCAN TO FIRST ADDRESS AND CONVERT IT PUSH H ;SAVE THE VALUE CALL PSCAN ;SEE IF SECOND WAS GIVIN POP D XCHG ;HL HAS START, DE HAS END ; DLOOP: CALL CRLF CALL ADOUT ;OUTPUT ADDRESS CALL BOUT ;ANOTHER SPACE TO KEEP IT PRETTY MVI C,16 ;VALUES PER LINE ; DLP1: MOV A,M ;GET THE CHAR PUSH B ;SAVE VALUE COUNT CALL HBOUT ;SEND IT OUT WITH A BLANK MOV A,L ;COMPARE DE AND HL SUB E MOV A,H SBB D JNC COMND ;ALL DONE POP B ;VALUES PER LINE INX H DCR C ;BUMP THE LINE COUNT JNZ DLP1 ;NOT ZERO IF MORE FOR THIS LINE JMP DLOOP ;DO A LFCR BEFORE THE NEXT ; ; ; OUTPUT HL AS HEX 16 BIT VALUE ; ADOUT: MOV A,H ;H FIRST CALL HEOUT MOV A,L ;THEN L FOLLOWED BY A SPACE ; HBOUT: CALL HEOUT CALL SINP ;SEE IF A CHAR WAITING JZ BOUT ;NO IF STD ANI 7FH ;CLR PARITY FIRST THO JZ COMND ;EITHER MODE OR CTRL-@ CPI ' ' ;IS IT A SPACE JNZ BOUT ;NO...IGNORE THE CHAR WTLP1: CALL SINP ;IF SPACE, WAIT UNTIL ANY OTHER KEY HIT JZ WTLP1 ;THIS ALLOWS LOOKING AT THE DISPLAY ENDF BOUT: MVI B,' ' JMP SOUT ;PUT IT OUT ; HEOUT: MOV C,A ;GET THE CHARACTER RRC ;MOVE THE HIGH FOUR DOWN RRC RRC RRC CALL HEOU1 ;PUT THEM OUT MOV A,C ;THIS TIME THE LOW FOUR ; HEOU1: ANI 0FH ;FOUR ON THE FLOOR ADI 48 ;WE WORK WITH ASCII HERE CPI 58 ;0-9? JC OUTH ;YUP ADI 7 ;MAKE IT A LETTER OUTH: MOV B,A ;OUTPUT IT FROM REGISTER 'B' JMP SOUT ; ; ; ***** ENTER COMMAND ***** ; ; THIS ROUTINE GETS VALUES FROM THE KEYBOARD AND ENTERS ; THEM INTO MEMORY. THE INPUT VALUES ARE SCANNED FOLLOWING ; A STANDARD 'GCLIN' INPUT SO ON SCREEN EDITING MAY TAKE ; PLACE PRIOR TO THE LINE TERMINATOR. A BACK SLASH '/' ; ENDS THE ROUTINE AND RETURNS CONTROL TO THE COMMAND MODE. ; A COLON ':' SETS THE PREVIOUS VALUE AS A NEW ADDRESS FOR ; ENTRY. ; ENTER: CALL SCONV ;SCAN OVER CHARS AND GET ADDRESS PUSH H ;SAVE ADDRESS XRA A STA OPORT ;ENTER VALUES TO SCREEN BUFFER ; ENLOP: CALL CRLF MVI B,':' CALL CONT ;GET LINE OF INPUT CALL CREM ;REMOVE THE CURSOR MVI C,1 ;START SCAN CALL VDAD2 ;GET ADDRESS XCHG ;....TO DE ; ; ENLO1: MVI C,3 ;NO MORE THAN THREE SPACES BETWEEN VALUES CALL SCHR1 ;SCAN TO NEXT VALUE JZ ENLOP ;LAST ENTRY FOUND, START NEW LINE ; CPI '/' ;COMMAND TERMINATOR JZ COMN1 ;IF SO, RETURN TO STANDARD INPUT CALL SHEX ;CONVERT VALUE CPI ':' ;ADDRESS TERMINATOR JZ ENLO3 ;GO PROCESS IF SO MOV A,L ;GET LOW PART AS CONVERTED POP H ;GET MEMORY ADDRESS MOV M,A ;PUT IN THE VALUE INX H PUSH H ;BACK GOES THE ADDRESS JMP ENLO1 ;CONTINUE THE SCAN ; ENLO3: XTHL ;PUT NEW ADDRESS ON STACK INX D ;MOVE SCAN PAST TERMINATOR JMP ENLO1 ; ; ; ***** EXECUTE COMMAND ***** ; ; THIS ROUTINE GETS THE FOLLOWING PARAMETER AND DOES A ; PROGRAM JUMP TO THE LOCATION GIVEN BY IT. IF PROPER ; STACK OPERATIONS ARE USED WITHIN THE EXTERNAL PROGRAM ; IT CAN DO A STANDARD 'RET'URN TO THE SOLOS COMMAND MODE. ; THE STARTING ADDRESS OF SOLOS IS PASSED TO THE PROGRAM ; IN REGISTER PAIR HL SO IT CAN ADJUST INTERNAL PARAMETERS ; FOR SOLOS OPERATION. ; ; EXEC: CALL SCONV ;SCAN PAST BLANKS AND GET PARAMETER EXEC1: PUSH H ;PUT GO ADDRESS ON STACK LXI H,START ;TELL THE PROGRAM WHERE WE CAME FROM RET ;AND DISPATCH IT ; ; ; THIS ROUTINE GETS A NAME OF UP TO 5 CHARACTERS ; FROM THE INPUT STRING. IF THE TERMINATOR IS A ; SLASH (/) THEN THE CHARACTER FOLLOWING IS TAKEN ; AS THE CASSETTE UNIT SPECIFICATION. ; ; NAMES: LXI H,THEAD ;POINT TO INTERNAL HEADER NAME: CALL SBLK ;SCAN OVER TO FIRST CHRS MVI B,6 ;UP TO SIX ARE ACCEPTED ; NAME1: LDAX D ;GET CHARACTER CPI ' ' ;NO UNIT DELIMITER JZ NFIL CPI '/' ;UNIT DELIMITER JZ NFIL MOV M,A INX D ;BUMP THE SCAN POINTER INX H DCR B JNZ NAME1 ;FALL THROUGH TO ERR1 IF TOO MANY CHRS IN NAME ; ; ; ***** SOLOS ERROR HANDLER ***** ; ERR1: XCHG ;GET SCAN ADDRESS TO HL IF STD ERR2: MVI M,'?' ;PUT QUESTION MARK ON SCREEN JMP COMN1 ;AND RETURN TO COMMAND MODE ENDF IF EXT ERR2: CALL CRLF ;PUT ^ BELOW BAD CHARACTER LXI D,40H DAD D ;MOVE DOWN ONE LINE MOV A,H CPI 0D0H ;WRAP? JNZ ERR3 ;NO MVI H,0CCH ERR3: MVI M,'^' JMP COMN1 ENDF ; ; ; HERE WE HAVE SCANNED OFF THE NAME. ZERO FILL FOR ; NAMES LESS THAN FIVE CHARACTERS. ; NFIL: MVI M,0 ;PUT IN AT LEAST ONE ZERO INX H DCR B JNZ NFIL ;LOOP UNTIL B IS ZERO ; CPI '/' ;IS THERE A UNIT SPECIFICATION? MVI A,1 ;PRETEND NOT JNZ DEFLT INX D ;MOVE PAST THE TERMINATOR CALL SCHR ;GO GET UNIT SPEC SUI '0' ;REMOVE ASCII BIAS ; DEFLT: EQU $ ;MOVE OVER TO INTERNAL REPRESENTATION ANI 1 ;JUST BIT ZERO MVI A,TAPE1 ;ASSUME TAPE ONE JNZ STUNT ;IF NON-ZERO, ITS ONE RAR STUNT: STA FNUMF ;SET IT IN RET ; ; ; ; THIS ROUTINE PROCESSES THE XEQ AND GET COMMANDS ; ; TXEQ: DB 3EH ;THIS BEGINS "MVI A,0AFH" TLOAD: XRA A ;A=0 MEANS TLOAD, ELSE TXEQ PUSH PSW ;SAVE FLAG FOR LATER LXI H,DHEAD ;PLACE DUMMY HEADER HERE CALL NAME ;SET IN NAME AND UNIT LXI H,0 ;PRETEND NO SECOND VALUE CALL PSCAN ;GO GET THE ADDRESS (IF PRESENT) ; TLOA2: XCHG ;PUT ADDRESS IN DE LXI H,DHEAD ;POINT TO DUMMY HEADER WITH NAME TO LOAD MOV A,M ;SEE IF A NAME WAS ENTERED ORA A ;IS THERE A NAME? JNZ TLOA3 ;YES...SEARCH FOR IT LXI H,THEAD ;NO NAME, LOAD 1ST FILE TLOA3: PUSH H ;SAVE PTR TO NAME TO LOAD CALL ALOAD ;GET UNIT AND SPEED POP H ;RESTORE PTR TO HDR TO LOAD CALL RTAPE ;READ IN THE TAPE JC TAERR ;TAPE ERROR? ; CALL NAOUT ;PUT OUT THE HEADER PARAMETERS POP PSW ;RESTORE FLAG FROM ORIGINAL ENTRY ORA A RZ ;AUTO XEQ NOT WANTED LDA HTYPE ;CHECK TYPE ORA A ;SET FLAGS JM TAERR ;TYPE IS NOW XEQ LDA THEAD+5 ;GET CHARACTER PAST NAME ORA A JNZ TAERR ;THE BYTE MUST BE ZERO FOR AUTO XEQ LHLD XEQAD ;GET THE TAPE ADDRESS JMP EXEC1 ;AND GO TO IT ; ; ; ***** GET COMMAND ***** ; ; THIS ROUTINE IS USED TO SAVE PROGRAMS AND DATA ON ; THE CASSETTE UNIT ; ; TSAVE: CALL NAMES ;GET NAME AND UNIT CALL SCONV ;GET START ADDRESS PUSH H ;USE THE STACK AS A REGISTER CALL SCONV ;GET END ADDRESS XTHL ;PUT END ON STACK, GET BACK START PUSH H ;SAVE START ON TOP OF STACK CALL PSCAN ;SEE IF OPTIONAL HEADER ADDRESS WAS GIVEN SHLD LOADR ;PUT HEADER ADDRESS IN PLACE ; POP H ;"FROM" ADDRESS TO HL POP D ;GET BACK END ADDRESS PUSH H ;SAVE FROM AGAIN FOR LATER MOV A,E ;NOW CALCULATE SIZE SUB L ;SIZE=END-START+1 MOV L,A MOV A,D SBB H MOV H,A INX H SHLD BLOCK ;STORE THE SIZE PUSH H ;SAVE IT FOR THE READ ALSO ; CALL ALOAD ;GET UNIT AND SPEED LXI H,THEAD ;POINT TO HEADER CALL WHEAD ;AND WRITE IT OUT ; NOW WRITE OUT THE DATA POP D ;GET SIZE TO DE POP H ;GET BACK "FROM" ADDRESS JMP WRLO1 ;WRITE OUT THE DATA AND RETURN ; ; ; OUTPUT ERROR AND HEADER ; TAERR: CALL CRLF MVI D,6 LXI H,ERRM ;POINT TO ERROR MESSAGE CALL NLOOP ;OUTPUT ERROR CALL NAOUT ;THEN THE HEADER JMP COMN1 ;AND BE SURE THE TAPE UNITS ARE OFF ; ERRM: ASC 'ERROR ' ; ; ; THIS ROUTINE READS HEADERS FROM THE TAPE AND OUTPUTS ; THEM TO THE OUTPUT DEVICE. IT CONTINUES UNTIL THE ; MODE KEY IS DEPRESSED. ; TLIST: CALL NAMES ;SET UP UNIT IF GIVEN CALL CRLF ; ; LLIST: CALL ALOAD MVI B,1 CALL TON ;TURN ON THE TAPE ; LIST1: CALL RHEAD JC COMN1 ;TURN OFF THE TAPE UNIT JNZ LIST1 CALL NAOUT ;OUTPUT THE HEADER JMP LIST1 ;LOOP UNTIL MODE IS DEPRESSED ; ; ; THIS ROUTINE GETS THE CASSETTE UNIT NUMBER AND ; SPEED TO REGISTER "A" FOR THE TAPE CALLS ; ALOAD: LXI H,FNUMF ;POINT TO THE UNIT SPECIFICATION LDA TSPD ;GET THE TAPE SPEED ORA M ;PUT THEM TOGETHER RET ;AND GO BACK ; ; ; THIS ROUTINE OUTPUTS THE NAME AND PARAMETERS OF ; THEAD TO THE OUTPUT DEVICE. ; ; NAOUT: MVI D,8 LXI H,THEAD-1 ;POINT TO THE HEADER CALL NLOOP ;OUTPUT THE HEADER CALL BOUT ;ANOTHER BLANK LHLD LOADR ;NOW THE LOAD ADDRESS CALL ADOUT ;PUT IT OUT IF STD LHLD BLOCK ;AND THE BLOCK SIZE ENDF IF EXT XCHG LHLD BLOCK ;GET BLOCK SIZE DAD D DCX H ;MAKE IT LAST ADDRESS ENDF CALL ADOUT JMP CRLF ;DO THE CRLF AND RETURN ; ; NLOOP: MOV A,M ;GET CHARACTER ORA A JNZ CHRLI ;IF IT ISN'T A ZERO MVI A,' ' CHRLI: CALL OUTH ;OUTPUT CHAR NOW INX H DCR D JNZ NLOOP RET ; ; ; ; ; ***** SET COMMAND ***** ; ; THIS ROUTINE GETS THE ASSOCIATED PARAMETER AND ; DISPATCHES TO THE PROPER ROUTINE FOR SETTING ; GLOBAL VALUES. ; CSET: EQU $ ;THIS IS THE SET COMMAND CALL SBLK ;LOOK FOR SET NAME JZ ERR1 ;MUST HAVE A LEAST SOMETHING!! PUSH D ;SAVE SCAN ADDRESS CALL SCONV ;CONVERT FOLLOWING VALUE XTHL ;GET SCAN ADDR BACK...SAVE VALUE ON STACK LXI D,SETAB ;SECONDARY COMMAND TABLE CALL FDCOM ;SEE IF IN TABLE JMP DISPO ;AND EITHER ERR OR OFF TO IT ; ; ; THIS ROUTINE SETS THE TAPE SPEED ; TASPD: ORA A ;IS IT ZERO? JZ SETSP ;YES...THAT'S A VALID SPEED MVI A,32 ;SET TO SLOW IF NON-ZERO SETSP: STA TSPD ;SPEED IS STORED HERE RET ; ; STSPD: MOV A,B ;ESCAPE COMES HERE TO SET SPEED DISPD: STA SPEED ;SET DISPLAY SPEED RET ; ; SET INPUT DRIVER ; SETIN: EQU $ STA IPORT RET ; ; SET OUTPUT DRIVER ; SETOT: EQU $ STA OPORT RET ; ; SET USERS CUSTOM INPUT DRIVER ADDRESS ; SETCI: SHLD UIPRT RET ; ; SET USERS CUSTOM OUTPUT DRIVER ADDRESS ; SETCO: SHLD UOPRT RET ; ; SET TYPE BYTE INTO HEADER ; SETTY: STA HTYPE RET ; ; SET EXECUTE ADDRESS INTO HEADER ; SETXQ: SHLD XEQAD RET ; ; IF STD SETNU: STA NUCNT ;SET THE NULL COUNT RET ;THAT'S DONE ENDF ; ; SETCR: EQU $ ;SET TO IGNORE CRC ERRORS STA IGNCR ;FF=IGNORE ERRORS, ELSE=NORMAL RET ; ; ; ; CUSTOM COMMAND NAME AND ADDRESS INTO CUSTOM COMMAND ; CUSET: CALL NAMES ;CUSTOM COMMAND ENTRY/REMOVAL LXI H,COMND ;DEFAULT ADDR IF NONE GIVEN CALL PSCAN ;GET RTN ADDRESS PUSH H ;SAVE RTN ADDRESS LXI H,THEAD ;POINT AT NAME TO SEARCH CALL FDCOU ;SEARCH IT IN CUSTOM TABLE JZ CUSE2 ;NOT IN TABLE...ENTER IT DCX D ;IN TABLE, REMOVE IT MVI M,0 ;CHANGE NEW NAME TO BE ZERO CUSE2 EQU $ MOV A,M ;GET 1ST CHAR OF NAME IF EXT CPI 61H ;LOWER CASE? JC CUSE3 ;NO ANI 5FH ;MAKE IT UPPER CASE CUSE3 EQU $ ENDF STAX D ;ENTER IT INTO TABLE INX D ;AND THE 2ND NAME INX H MOV A,M IF EXT CPI 61H JC CUSE4 ANI 5FH CUSE4 EQU $ ENDF STAX D ;NAME NOW ENTERED INX D ;GET SET TO ENTER ADDRESS POP H ;RESTORE RTN ADDR XCHG MOV M,E ;SET ADDR IN NOW INX H ;AND HI BYTE OF ADDR MOV M,D RET ;NAME IS NOW ENTERED OR CLEARED ;