; VAL - TERMINAL INPUT ROUTINES ; LAST EDIT: 12-NOV-80 ; ;- .NLIST .SBTTL DESCRIPTION .NLIST BEX CND TOC MD .LIST TTM .TITLE VAL .LIST .IDENT /V003/ .NLIST .NLIST SEQ LOC BIN .LIST ; ; TO ENABLE FULL DESCRIPTION IN THE ASSEMBLY LISTING ; DEFINE THE SYMBOL BLURB ;BLURB=0 ; ; THIS MODULE MUST BE ASSEMBLED PRECEDED BY THE FILE VALMFD ; .NLIST .IF DF BLURB .LIST ;+ ; ; THE MODULE VALIO CONTAINS ROUTINES FOR TERMINAL PROMPTING ; AND INPUT. THESE ARE: ; CLUINT - TO PROMPT FOR AND READ A VALUE AS AN INTEGER ; CLUREA - TO PROMPT FOR AND READ A VALUE AS A REAL ; CLUSTR - TO PROMPT FOR AND READ A VALUE AS A NAME OR ; TEXT STRING ; CLUDIR - TO PROMPT FOR A NAME AND LOOK UP A VALUE IN ; A DIRECTORY. ; ; START MUST HAVE BEEN CALLED PRIOR TO ANY OF THESE CALLS. ; ; IN EACH CASE THE BASIC CALLING FORMAT IS: ; I=CLUXXX('NAME','PROMPT ? '....OTHER ARGS) ; OR I=XXXVAL( " ) ; WHERE: NAME - NAME OF A COMMAND LANGUAGE VARIABLE ; TO BE USED AS THE REPLY IF CLONE ; IS ACTIVE AND SUCH A VARIABLE EXISTS. ; IF NAME IS NULL, NO LOOKUP OCCURS. ; PROMPT- PROMPT STRING TO BE USED TO REQUEST ; INPUT. IF NULL '? ' IS ASSUMED. ; THE REMAINING ARGUMENTS ARE CALL DEPENDANT AND ; ARE DESCRIBED BELOW. ; ; THE TYPE OF THESE FUNCTIONS SHOULD BE DECLARED EXPLICITLY ; AND PREFERABLY BY THE INCLUSION OF A DEFINITION FILE. ; ; ; INPUT IS PARSED BY THE MODULE READIT. ; REPLY VALUES MAY BE PLACED MULTIPLY ON A LINE SEPARATED BY ; SPACES OR COMMAS. NO TYPE RESTRICTIONS ARE PLACED ON NUMERIC ; REPLIES, WHEN REQUESTING AN INTEGER REAL REPLIES ARE TRUNCATED. ; LARGE OR SMALL VALUES MAY BE ENTERED IN EXPONENT FORM AS X.XXEY ; WHERE X.XX REPRESENTS ANY VALUE AND Y A POSITIVE OR NEGATIVE ; DECIMAL EXPONANT. THUS: ; 30 30.5 AND 3E1 ; ALL RETURN A VALUE OF 30 IN A CALL TO CLUINT. ; ; ; AN ADDITIONAL SET OF ENTRY POINTS PREFIXED VAL IS PROVIDED ; WHICH RETURN THE RESULT TO A SPECIFIED VARIABLE BUT WHICH ; DO NOT TAKE A NAME AND PROMPT ARGUMENT. FOR THESE ; ENTRIES THE PROMPT SHOULD BE ISSUED SEPERATLY WITH ; THE ROUTINE OUT. ; I=CLUINT(,'ENTER A NUMBER ? ') ; IS THE SAME AS: ; CALL OUT('ENTER A NUMBER ') ; CALL VALINT(I) ; ; ; ; ; ;- .NLIST .ENDC .LIST ; ; NPAGE .NLIST .SBTTL DEFINITIONS .LIST SEQ,LOC,BIN .LIST ; ; .PSECT VALIO ; RDOFF$ ;DEFINE OFFSETS ; ; FORTRAN PARAMETER BLOCK OFFSETS P1=2 P2=4 P3=6 P4=10 P5=12 P6=14 P7=16 ; ; OFFSETS TO SAVBLK ENTRYS E..CLO=VI.SAV+0 ;FILE CLOSE ROUTINE E..ABT=VI.SAV+2 ;CTRL-Z PROCESSOR E..INT=VI.SAV+4 ;INTEGER INPUT ERROR PROCESSOR E..REA=VI.SAV+6 ;REAL INPUT ERROR PROCESSOR E..DIR=VI.SAV+10;DIRECTORY INPUT ERROR PROCESSOR E..UKN=VI.SAV+12;OTHER ERROR PROCESSOR S..LIN=VI.SAV+14;LINE NUMBER FOR ERROR MESSAGES S..LUN=VI.SAV+16;LUN NUMBER FOR ERROR MESSAGES ; ; REGISTER CONVENTIONS ; R0 POINTS TO LOCAL IMPURE AREA WHICH CONTAINS THE READIT ; BLOCK FOLLOWED BY OTHER LOCAL DATA. ; R1 POINTS TO THE SHARED COMUNICATIONS BLOCK. ; ; ALL CALLER REGISTERS NOT USED FOR RESULT TRANSMISSION ; ARE PRESERVED THROUGH THESE CALLS. ; ; NPAGE .NLIST .NLIST SEQ,LOC,BIN .SBTTL INTEGER READ--VALINT,CLUINT .IF DF BLURB .LIST ;+ ; ; THE NUMERIC INPUT ROUTINES PROVIDE THE FOLLOWING FEATURES: ; RANGE CHECKING OF REPLIED VALUE WITH INTERNAL RE-PROMPTING. ; RETURN OF DEFAULT VALUE IF CR IS TYPED. ; ARRAY READ OF ANY NUMBER OF VALUES. ; ; THE BASIC CALL IS: ; ; CLUXXX(NAME,PROMPT,DEFAULT,MIN,MAX) ; ; OR VALXXX(V,DEFAULT,MIN,MAX,LEN,IOFF) ; ; THE TYPE OF THE ARGUMENTS: DEFAULT,MIN,MAX IS THE TYPE OF THE ; INPUT REQUEST. ; ; IF THE ARGUMENTS LEN AND IOFF ARE SUPPLIED IN A VAL CALL, LEN ; VALUES ARE READ TO THE ARRAY V STARTING AT OFFSET IOFF. ; ; ; VALINT - INPUT AN INTEGER ; ; CALLING FORMAT: ; ; I=CLUINT(NAME,PROMPT[,IDEF,ILOW,IHIGH,INO,IOFF]) ; OR CALL VALINT(I[,IDEF,ILOW,IHIGH,INO,INOFF) ; ;WHERE: I RECEIVES THE INTEGER VALUE OF THE ITEM READ ; DEF IS THE DEFAULT VALUE ; ILOW,IHIGH SPECIFY A RANGE ; INO IS THE NUMBER OF ITEMS TO READ IF I IS AN ARRAY ; IOFF IS THE START OFFSET IN I IF IT IS AN ARRAY ; ;- ; .NLIST .ENDC .LIST SEQ,LOC,BIN .LIST ; INTVAL:: CLUINT::JSR R5,STRNP MOV SP,RD.VL(R0);SAVE DESTINATION ADDRESS BR INT1 ; VALINT::JSR R5,NULLNP MOV P1(R5),RD.VL(R0);SAVE DESTINATION ADDR. ; ; N.B. PARAMETER OFFSETS ARE ONE OUT OF STEP IN CLU CALLS INT1: MOVB #7,RD.ICH(R0) ;INTEGER READ,NO DEFAULTS MOVB #1,RD.INW(R0) ;NO RANGE CHECK DEC R4 BLE 2$ ;DEFAULTS SUPPLIED CMP P2(R5),#-1 BEQ 3$ BICB #2,RD.ICH(R0) ;ENABLE DEFAULT MOV P2(R5),RD.DFA(R0);DEFAULT ADDRESS 3$: DEC R4 BEQ 2$ ;RANGE CHECK? BICB #4,RD.ICH(R0) ;ENABLE RANGE CHECKING MOV P3(R5),RD.LWA(R0);ADDRESS OF LOW LIMIT DEC R4 MOV P4(R5),RD.HWA(R0);ADDRESS OF HIGH LIMIT DEC R4 BEQ 2$ ;ARRAY READ? MOV @P5(R5),RD.WC(R0);NUMBER OF ITEMS MOV #1,RD.OFF(R0) ;DEFAULT OFFSET DEC R4 BEQ 1$ ;LEAVE DEFAULT MOV @P6(R5),RD.OFF(R0);STARTING ELEMENT 1$: MOVB #7,RD.INW(R0) ;READ INTEGER ARRAY 2$: RDT$ ,INPUT,,ERR1 JMP VALOUT ; NPAGE .NLIST .SBTTL REAL READ--VALREA,CLUREA .IF DF BLURB .LIST ;+ ; ; VALREA - INPUT A REAL ; CALLING FORMAT: ; ; R=CLUREA(NAME,PROMPT[,RDEF,RLOW,RHIGH,RNO,ROFF]) ; OR CALL VALREA(R[,RDEF,RLOW,RHIGH,RNO,RNOFF) ; ;WHERE: R RECEIVES THE VALUE OF THE REAL READ ; RDEF IS THE DEFAULT VALUE ; RLOW,RHIGH SPECIFY A RANGE ; INO IS THE NUMBER OF ITEMS TO READ IF R IS AN ARRAY ; IOFF IS THE START OFFSET IN R IF IT IS AN ARRAY ; ;- .NLIST .ENDC .LIST SEQ,LOC,BIN .LIST ; ; REAVAL:: CLUREA::JSR R5,STRNP MOV SP,RD.VL(R0) ;RESULT ADDRESS BR REA1 ; VALREA::JSR R5,NULLNP MOV P1(R5),RD.VL(R0) ;RESULT ADDRESS MOV P1(R5),RD.VL(R0);DESTINATION ADDR. ; ; N.B PARAMETER OFFSETS ARE OUT OF STEP IN CLU CALLS! REA1: MOVB #7,RD.ICH(R0) ;REAL READ,NO DEFAULT MOVB #2,RD.INW(R0) ;NO RANGE CHECKS DEC R4 BLE 2$ ;DEFAULT SUPPLIED? CMP P2(R5),#-1 ;NULL ? BEQ 3$ BICB #2,RD.ICH(R0) ;YES-ENABLE DEFAULTS MOV P2(R5),RD.DFA(R0);ADDRESS OF DEFAULT 3$: DEC R4 BEQ 2$ ;RANGE CHECK? BICB #4,RD.ICH(R0) ;SET RANGE CHECKING MOV P3(R5),RD.LWA(R0);ADDR OF LOW LIMIT DEC R4 MOV P4(R5),RD.HWA(R0);ADDRESS OF HIGH LIMIT DEC R4 BEQ 2$ ;ARRAY READ? MOV @P5(R5),RD.WC(R0);NUMBER OF ITEMS MOV #1,RD.OFF(R0) ;DEFAULT START ELEMENT DEC R4 BEQ 1$ ;OFFSET SUPPLIED? MOV @P6(R5),RD.OFF(R0) ;SET START 1$: MOVB #8.,RD.INW(R0) ;READ REAL ARRAY 2$: RDT$ ,INPUT,,ERR1 JMP VALOUT NPAGE .NLIST .NLIST SEQ,LOC,BIN .SBTTL STRING READ--VALSTR,CLUSTR .IF DF BLURB .LIST ;+ ; ; VALSTR - INPUT A STRING ; ; CALLING FORMAT: ; ; LEN=CLUSTR(NAME,PROMPT,ARRAY,LMAX[,LEN,ITYPE]) ; OR CALL VALSTR(ARRAY,LMAX[,LEN,ITYPE]) ; ;WHERE: ARRAY IS DESTINATION ARRAY LENGTH LMAX BYTES ; LEN RECEIVES THE # OF CHARS READ ; ITYPE IS A FLAG WORD,BIT ASSIGNMENTS BEING ; 0 CLEAR READ TO END OF LINE ; SET READ TO NEXT DELIMETER(CLUCH MODE) ; 1 CLEAR DO NOT TERMINATE WITH ZERO BYTE ; SET TERMINATE WITH ZERO BYTE ; (DEFAULT ITYPE IS 0) ; ; UNUSED LENGTH OF BUFFER IS PADDED WITH BLANKS. ; ;- .NLIST .ENDC .LIST SEQ,LOC,BIN .LIST ; STRVAL:: CLUSTR::JSR R5,STRNP ADD #2,R5 ;OFFSET PARAMETER LIST DEC R4 BR STR1 ; VALSTR::JSR R5,NULLNP STR1: MOV P1(R5),RD.STR(R0);SAVE STRING BUFFER MOV @P2(R5),RD.LEN(R0);AND SAVE LENGTH MOVB #6,RD.ICH(R0) ;STRING, NO LIMIT, NO DEFAULT MOVB #6,RD.INW(R0) ;READ TO END OF LINE CLR -(SP) ;INIT MODE FLAG CMP R4,#4 ;ITYPE SPECIFIED? BLT 1$ MOV @P4(R5),(SP) ;IF SO PICK IT UP BIT #1,(SP) ;LINE/SYMBOL MODE ? BEQ 1$ MOVB #5,RD.INW(R0) ;IF SYMBOL SET BIT 1$: RDT$ ,INPUT,,ERR1 ;CALL READIT MOVB RD.SI(R0),R2 ;GET STRING LENGTH CMPB RD.ITW(R0),#7 ;ITW=LEAVE? BEQ 7$ ;IF SO NOTHING TO DO CMP R4,#3 ;LEN WANTED? BLT 2$ ;SKIP IF NOT CMP P3(R5),#-1 ;NULL ? BEQ 2$ MOV R2,@P3(R5) ;AND RETURN LENGTH 2$: MOV R2,2(SP) ;RETURN RESULT OF CLU FUN. 5$: BIT #2,(SP) ;ZERO BYTE REQUIRED ? BEQ 7$ CMP R2,RD.LEN(R0) ;IS BUFFER FULL ? BLT 6$ DEC R2 ;IF SO BACKSPACE ONE 6$: ADD RD.STR(R0),R2 ;ADDR OF END OF BUFFER CLRB (R2)+ 7$: ADD #2,SP ;POP ITYPE JMP VALOUT ; ; NPAGE .NLIST .NLIST SEQ,LOC,BIN .SBTTL DIRECTORY LOOKUP--VALDIR,CLUDIR .IF DF BLURB .LIST ;+ ; ; VALDIR - PERFORM A DIRECTORY LOOKUP ; ; CALLING FORMAT: ; ; I=CLUDIR('NAME','PROMPT',IDIR[,IDEF,ILOW,IHIGH]) ; OR CALL VALDIR(I,IDIR[,IDEF,ILOW,IHIGH]) ; ;WHERE: I RECEIVES AN INTEGER VALUE,BEING ; THE RESULT OF THE LOOKUP,OR THE VALUE TYPED ; IDIR IS A DIRECTORY STRING IN THE FORMAT DESCRIBED BELOW ; IDEF IS THE DEFAULT VALUE FOR THE REQUEST ; ILOW,IHIGH ARE RANGE LIMITS FOR THE VALUE ; ; DIRECTORY STRING FORMAT IS: ; BYTE DIR(N) ; DATA DIR/0,'A','B',FLAG,VAL1,'C','D',FLAG,VAL2.......0,0/ ; WHERE : A,B... REPRESENT TEXT OF ANY LENGTH UP TO FLAG. ; IF FLAG IS ZERO ANY NON-AMBIGUOUS MATCH ; IS ACCEPTABLE, WHILST IF FLAG IS -1 ONLY ; AN EXACT MATCH WITH THE TEXT IS ACCEPTED. ; AN UNREGOGNISED STRING RETURNS A VALUE OF 0 ; ; OR IN MACRO: ; IDIR: .BYTE 0 ; .ASCII /TEXT/ ) ; .BYTE FLAG ) REPEATED FOR N TEXT ITEMS ; .BYTE VALUE ) ; .BYTE 0,0 ; ; ;- .NLIST .ENDC .LIST SEQ,LOC,BIN .LIST ; DSTRL=6;# OF WORDS TO BE ALLOCATED FOR BUFFERING STRING ; DIRVAL:: CLUDIR::JSR R5,STRNP MOV SP,RD.VL(R0) ;ADDRESS FOR RESULT BR DIR1 ; VALDIR::JSR R5,NULLNP MOV P1(R5),RD.VL(R0);DESTINATION ADDRESS ; ;N.B. PARM. OFFSETS IN CLU CALLS ARE INCORRECT DIR1: MOVB #6,RD.ICH(R0) ;SET STRING READ MOVB #9.,RD.INW(R0) ;DIRECTORY MODE DEC R4 MOV P2(R5),RD.LIB(R0);DIRECTORY ADDRESS DEC R4 BLE 1$ ;ANY DEFAULT? CMP P3(R5),#-1 BEQ 2$ BICB #2,RD.ICH(R0) ;YES-SET DEFAULT MOV P3(R5),RD.DFA(R0);AND DEFAULT ADDRESS 2$: DEC R4 BEQ 1$ ;RANGE CHECK? BICB #4,RD.ICH(R0) ;YES-SET CHECKING MOV P4(R5),RD.LWA(R0);STORE ADDR OF LOW MOV P5(R5),RD.HWA(R0);AND OF HIGH 1$: MOV #DSTR,RD.STR(R0);STORE BUFFER ADDRESS MOV #DSTRL*2,RD.LEN(R0);AND LENGTH RDT$ ,INPUT,,ERR1 JMP VALOUT ; DSTR: .BLKW DSTRL ; ; NPAGE .NLIST .SBTTL COMMON REQUEST PROCESSING .LIST ; THE FOLLOWING ROUTINES DEAL WITH COMPLETION ; OF AN INPUT REQUEST AND THE PROCESSING OF ; ANY ERRORS WHICH MAY OCCURE. ; .GLOBL CLRERR ;ROUTINE TO ERASE ERROR MESSAGES ON ;LINE ADDRESSABLE DISPLAYS. ; VALOUT: BIT #ST.ERR,VC.STA(R1);DID REQUEST FAIL ? BEQ 1$ ;IF NOT RETURN MOV R0,R5 ;ELSE CLEAR MESSAGE ADD #VI.SCR,R5 MOVB #2,(R5) ;SET PARMS FOR CLEAR ROUTINE MOV R0,P1(R5) ;SET PARMS FOR CLEAR CALL ADD #VI.DLN,P1(R5) MOV R0,P2(R5) ADD #S..LIN,P2(R5) CALL CLRERR BIT #ST.SPC,VC.STA(R1);ARE WE IN SPECIAL MODE ? BNE 1$ ;IF SO LEAVE ERROR SET BIC #ST.ERR,VC.STA(R1);CLEAR ERROR STATUS 1$: CALL OUTCLR ;CLEAR ANY UNUSED OUTS MESSAGES. CALL VRSCTX ;RESTORE USER CONTEXT UNSAVE ;RESTORE USER REGISTERS RETURN ;RETURN TO USER ; ; ; ERR1 IS CALLED BY THE READIT MACRO TO PROCESS RANGE ; AND OTHER ERRORS WHICH ARE DETECTED BY READIT. A ; MESSAGE IS PRODUCED AND THE BUFFER CLEARED SO THAT ; ON RETURN TO READIT A NEW REQUEST IS ISSUED. ; ERR1: MOV R5,-(SP) CMPB #-2,RD.ITW(R0) ;WAS IT AN ABORT BEQ ABO ;IF SO GO PROCESS BIS #ST.ERR,VC.STA(R1);SET ERROR INDICATOR MOV R0,R5 ;SET UP A FORTRAN CALL BLOCK ADD #VI.SCR,R5 MOV R0,P1(R5) ;SET LUN ARGUMENT ADD #VI.DLN,P1(R5) MOV R0,P2(R5) ;AND LINE # ARG. ADD #S..LIN,P2(R5) MOV RD.KP(R0),R2 ;FORM LINE POINTER SUB RD.IA(R0),R2 MOVB R2,VC.LBF(R1) ;SET COUNT TO POSITION OF ERROR MOV R1,P3(R5) ADD #VC.LBF,P3(R5) ;SET BUFFER ADDRESS CMPB #-12.,RD.IST(R0);DOES IST INDICATE RANGE ERROR BEQ ERR2 ;IF SO GO PRODUCE MESSAGE MOV #3,(R5) ;SET 3 ARGS CALL @E..UKN(R0) BR ERR3 ERR2: MOV RD.LWA(R0),P5(R5);LOW LIMIT MOV RD.HWA(R0),P6(R5);HIGH LIMIT CMPB #9.,RD.INW(R0) ;DIRECTORY MODE? BEQ 5$ ;YES MOV #6,(R5) ;BLOCK LENGTH FOR INT & REAL CMPB #2,RD.INW(R0) ;REAL OR INTEGER BEQ 4$ CMPB #8.,RD.INW(R0) BEQ 4$ 3$: MOV R0,P4(R5) ;ADDRESS OF VALUE ADD #RD.INT,P4(R5) CALL @E..INT(R0) BR ERR3 4$: MOV R0,P4(R5) ;ADDRESS OF REAL VALUE ADD #RD.REA,P4(R5) CALL @E..REA(R0) ;GO PRODUCE MESSAGE BR ERR3 5$: MOV #7,(R5) ;NO. OF PARAMETERS MOV R0,P4(R5) ;ADDRESS OF DIRECTORY VALUE ADD #RD.INT,P4(R5) MOV RD.LIB(R0),P7(R5);ADDRESS OF DIRECTORY CALL @E..DIR(R0) ; ERR3: CALL CLRBUF ;CLEAR BUFFER MOV (SP)+,R5 RETURN ; CLRBUF: CLRB RD.IST(R0) ;THROW AWAY REST OF BUFFER MOVB #1,RD.ITW(R0) CLRB @RD.KP(R0) RETURN ; ; THIS EXIT FROM ERR1 IS TAKEN WHEN ; A CTRL Z TYPED BY THE USER. IT IN TURN CALLS ; A USER SPECIFIED CTRL Z PROCESSOR ROUTINE. ; ABO: CALL CLRBUF ;CLEAR BUFFER CALL VRSCTX ;RESTORE CALLER CONTEXT CALL @E..ABT(R0) CALL VMAP ;AND RE-MAP MOV (SP)+,R5 RETURN ; ; ; STRNP - STORE NAME AND PROMPT FOR A CLUCH CALL ; CALLED VIA JSR R5,STRNP ; ; STRNP: MOV R4,-(SP) MOV R3,-(SP) MOV R2,-(SP) MOV R1,-(SP) MOV R0,-(SP) MOV R5,-(SP) ;SET OUR RETURN ADDRESS MOV 14(SP),R5 ;RESTORE ARGUMENT LIST CALL VPRMPT CALL VMAP MOVB (R5),R4 ;GET NUMBER OF ARGUMENTS ADD #2,R5 ;ALLIGN ARGUMENT LIST DEC R4 ;WITH VAL CALL RETURN ; ; ; NULLNP - LOAD NULL PROMPT FOR A VAL CALL ; CALLED VIA JSR R5,NULLNP ; ; NULLNP: MOV R4,-(SP) MOV R3,-(SP) MOV R2,-(SP) MOV R1,-(SP) MOV R0,-(SP) MOV R5,-(SP) ;SET OUR RETURN ADDRESS MOV 14(SP),R5 ;RESTORE ARGUMENT LIST CALL VMAP MOVB (R5),R4 ;GET NUMBER OF ARGS CLRB VC.NAM(R1) ;NULL NAME CLRB VC.PRM(R1) ;NULL PROMPT RETURN ; ; ; INPUT READS A NEW LINE OF DATA ; SPACE=40 ; INPUT: MOV R4,-(SP) MOV R5,-(SP) 1$: MOV #NULL,R5 CALL VINPUT ;READ A LINE CALL VMAP ;RE-MAP VALCOM MOV R1,R2 ;POINT TO BUFFER ADD #VC.LBF+1,R2 2$: CMPB (R2)+,#SPACE ;STRIP LEADING SPACES BEQ 2$ CMPB -(R2),#'? ;HELP REQUEST ? BNE 3$ CALL VALHLP ;PRINT HELP INFO CALL VMAP ;RESTORE MAPPING BIS #ST.ERR,VC.STA(R1);ENABLE SPECIAL MODE BR 1$ ;AND READ AGAIN ; 3$: MOV (SP)+,R5 MOV (SP)+,R4 RTNINS: RETURN ; NULL: .WORD 0 ; ; ; NOW INITIALIZE VALIMP WITH THE VAL ERROR PROCESSOR ROUTINES. ; VALSAV MAY BE CALLED TO MODIFY THESE LOCATIONS. ; .PSECT VALIMP OVR,D,GBL ; VALIMP: .=VALIMP+VI.SAV .WORD 0 ;NULL CLOSE FILES ROUTINE .WORD ABORT ;CONTROL Z PROCESSOR .WORD INTERR .WORD REAERR .WORD DIRERR .WORD OTHERR .WORD 230. ;MESSAGE OUTPUT LINE ; .END