A=-((X=76)+(X=83)*2+(X=82)*3+(X=69)*4)
and A would then be suitable for use in a statement of the form ON A GOTO...
The methods of using menu programs are described in Section 11.7.
A=GET
or
A$=GET$
(Note the difference from some other microcomputers, where GET is a Command rather than a function.)
It is possible to use GET$ for multiple character input. Lines 220 to 260 of Example 4.10 use GET$ to input a character string, in the form of an array, Which might be much longer than the 255 character maximum of INPUT.
It can on occasion be useful, as pointed out above, to be able to use the cursor editing keys, particularly the arrow keys, for normal input. This can be achieved with the command
*FX 4,1
After this command has been issued, the arrow and COPY keys can no longer be used for screen editing. Instead, when pressed they return normal ASCII codes, as follows
COPY | 135 |
136 | |
137 | |
138 | |
139 |
These keys can be picked up in the usual way with GET$, in a statement such as
IF GET$=CHR$(135) THEN...
*FX 4,0 restores the keys to their normal function, and note that this must be issued before the end of a program, as the keys will remain disabled after the program has ended. (Note that *FX 4,2 has a second action - it enables the five keys to act as further function keys, with numbers 11 to 15.)
In a similar fashion to *FX 4,1
*FX 229,1
disables the normal action of the ESCAPE key, and it returns its standard ASCII value of 27. *FX 229,0 restores the normal action.
150 IF INKEY(0)>=0 THEN GOTO 200
which would accomplish this.
However, if a key had been pressed earlier, this would be picked up the first time round the loop. It is possible to 'flush' (i.e. empty) the keyboard buffer at any time before you enter the loop by
*FX15,1
to avoid this possibility.
10 CLS 20 PRINT "When a message appears on the screen" 30 PRINT '"press any key" 40 TIME=0 50 REPEAT: UNTIL TIME>400 60 CLS 70 PAUSE=INT(1000*RND(1)) 80 TIME=0 90 REPEAT: UNTIL TIME>PAUSE 100 *FX 15,1 110 REM CLEARS KEYBOARD BUFFER 120 PRINT TAB(15X2) ;"PRESS NOW!" 130 TIME=0 140 REPEAT 150 T=TIME 160 UNTIL INKEY(0)>=0 170 PRINT '"You took ";T/100;" seconds" 180 PRINT '"Do you want to try again? (Y/N)" 190 YN$=GET$ 200 IF YN$="Y" THEN GOTO 10
Since INKEY not only detects a key-press, but also returns its ASCII value, the program could be modified to look for a particular character selected at random. 64+RND(26) would generate the ASCII code for any capital letter, or more ambitiously 32+RND(94) would produce the ASCII code for any printable character.
10 MODE 4 20 START=0 30 REPEAT 40 MOVE 0,500+400*SIN(RAD(START)) 50 FOR ANGLE=0 TO 360 STEP 5 60 DRAW 3*ANGLE ,500+400*SIN(RAD (ANGLE+START)) 70 IF INKEY(0)>=0 THEN PROC_wait 80 NEXT ANGLE 90 START=START-20 100 UNTIL START=-360 110 END 1000 DEF PROC_wait 1010 *FX 15,1 1020 REPEAT 1030 UNTIL INKEY(0)>=0 1040 ENDPROC
Line 70 is the key line, where INKEY is used within the plotting loop to check for a key-press, and if detected, call PROC_wait.
The third use of INKEY is with a negative argument. INKEY then checks whether a key is being pressed at that instant, returning -1 or zero according to whether the key is pressed or not. This form of the INKEY statement checks for a particular key, the key being determined by the value of the negative argument. The value of the number does not correspond to the key's ASCII code, but follows an obscure and seemingly random table which is given in Appendix 1.
The most obvious application for this mode of INKEY is for games, where action must be taken according to which key has been pressed, but only for as long as the key is pressed. This mode of INKEY is not applicable to INKEY$ (it would be superfluous anyway).
All keys, including those such as CAPS LOCK, SHIFT, ESCAPE and the function keys, have a code. However, using keys such as ESCAPE or the arrow keys will give rise to a problem, because as soon as the INKEY command has been completed, when the user will almost certainly still have his finger on the key, the usual function will come into effect. It will again be necessary to turn off their normal functions with *FX 4,1 and *FX 229,1 as explained above.
100 REPEAT 110 PRINT "Random number = ";RND(1) 120 PRINT "Do you want another number? (Y/N)" 130 INPUT YN$ 140 IF YN$<>"Y" AND YN$<>"N" THEN PROC_wrongkey 150 UNTIL YN$="N" 160 END 1000 DEF PROC_wrongkey 1010 REPEAT 1020 PRINT "Please press the 'Y' key for 'YES'" 1030 PRINT "or the 'N' key for 'NO'" 1040 INPUT YN$ 1050 UNTIL YN$="Y" OR YN$="N" 1060 ENDPROC
Note that whichever key is pressed (apart from <BREAK>) the result should be intelligible to the user and the program will not crash.
The question requiring a yeslno response is actually a very common situation, but conventions vary as to whether the user responds with Y (N) or YES (NO). The program can be made to accept either response, (but also unfortunately YABOO or NUTS) by using INPUT with the string YN$, then testing the first character of YN$ for a Y or N. Try the following modifications to the above program
140 IF LEFT$(YN$,1)<>"Y" AND LEFT$(YN$,1)<>"N" THEN PROC_wrongkey 150 UNTIL LEFT$(YN$,1)="N" 1050 UNTIL LEFT$(YN$,1)="Y" OR LEFT$(YN$,1)="N"
... ... ... 100 REPEAT 110 INPUT "Type a number: ",NUM 120 IF NUM<>INT(NUM) THEN PROC_invalid 130 UNTIL NUM=INT(NUM) ... ...
where PROC invalid prints out a suitable warning message.
On the BBC microcomputer, a value typed into a numerical variable in response to an INPUT command acts as if it were input as a string and converted to a numeric value by the VAL command (see Section 4.4). Although at first sight this appears to be a user-friendly technique, it suffers from the danger that there is no warning if a non-number key is accidentally pressed. The particularly prevalent mistake is to type the letter O instead of zero, for example 1O for 10, which would be converted to 1 with no warning, or perhaps more disastrously O.1 for 0.1 which would be converted to zero.
To avoid this possibility it is advisable to adopt a somewhat indirect approach to numerical input. You can pre-empt the operation of INPUT if the 'number' is initially input as a string variable and the function VAL is then used to convert it to an arithmetic variable (if the conversion is possible, otherwise VAL will give the result zero). Therefore, we can test whether the STR$ of the arithmetic variable is equal to the original string and, if not, issue a warning and reprompt for input.
... ... 100 REPEAT 110 PRINT "Input a number" 120 PROC_validate 130 UNTIL TEST=1 ... ... 990 END 1000 DEF PROC_validate 1010 REM PROCEDURE TO VALIDATE NUMERICAL INPUT 1020 LOCAL ST$ 1030 INPUT ST$ 1040 NUM=VAL(ST$) 1060 IF ST$=STR$(NUM) THEN TEST=1: ENDPROC 1070 PRINT "PLEASE DO NOT PRESS ANY NON-NUMBER KEYS" 1080 PRINT "(apart from 'E' for a number" 1090 PRINT "in exponent form)" 1100 TEST=0 1110 ENDPROC
These sections of program will assign the required number to the arithmetic variable NUM. The procedure can be used whenever a number is to be input (though it would be necessary to assign NUM to the required variable).
120 INPUT NUM
and repeat the tests. In the latter case there will be no warning of the incorrect input.
One limitation of this kind of validation is that it is necessary for the number to be typed in in the same format as is adopted by the STR$ function for that particular number (i.e. exponent form for numbers outside the range 0.1 to 109). A much more complex checking process is required in order to detect any invalid input without imposing this restriction on the user, or alternatively using INPUT directly with a number and risking incorrect input. The next subroutine will accept almost any valid input, but trap any error.
10 REPEAT 20 PRINT "INPUT A NUMBER" 30 PROC_validate 40 PRINT "YOUR NUMBER IS: ";ZQ 50 UNTIL FALSE 60 END 10000 DEF PROC_validate 10010 REM PROCEDURE TO VALIDATE THE INPUT OF A NUMBER 10020 REM THE NUMBER IS RETURNED IN VARIABLE ZQ 10030 REM DPTS COUNTS DECIMAL POINTS 10040 REM EXN " EXPONENT E'S 10050 REM ST MARKS THE START OF NUMBERS 10060 REM NMT COUNTS THE POWER OF 10 OF THE MANTISSA 10070 REM INP$ IS THE NUMBER 10080 REM EX$ IS THE EXPONENT 10090 REM CH$ IS A SINGLE CHARACTER OF THE NUMBER 10100 LOCAL J,DPTS,EXN,ST,NMT,INP$,NUM$,CH$,CANC$,LST$ 10110 INP$="": NUM$="": DPTS=0: EXN=0: ST=0: NMT=0 10120 PROC_inchar 10130 PRINT 10140 ZQ=VAL(INP$) 10150 ENDPROC 11000 DEF PROC_inchar 11010 CH$=GET$ 11020 IF CH$=CHR$(13) THEN ENDPROC 11030 IF CH$=CHR$(127) THEN PROC_cancel: ENDPROC 11040 PRINT CH$; 11050 IF ((CH$<"0" OR CH$>"9") AND CH$<>"." AND CH$<>"-" AND CH$<>"+" AND CH$<> "E" AND CH$<>CHR$(13)) THEN PROC_invalid: ENDPROC 11060 IF (CH$="-" OR CH$="+") AND ST=1 THEN PROC_invalid: ENDPROC 11070 IF EXN>0 OR DPTS>0 OR CH$<"0" OR CH$>"9" THEN ELSE IF NMT<=37 THEN NMT=NMT+1 ELSE PROC_invalid: ENDPROC 11080 IF EXN=0 OR CH$<"0" OR CH$>"9" THEN ELSE IF (VAL(NUM$+CH$)+NMT)<=38 THEN NUM$=NUM$+CH$ ELSE PROC_invalid: ENDPROC 11090 IF CH$<>"." THEN ELSE IF DPTS=0 AND EXN=0 THEN DPTS=1 ELSE PROC_invalid: ENDPROC 11100 ST=1 11110 IF CH$<>"E" THEN ELSE IF EXN=0 THEN EXN=1: ST=0: ELSE PROC_invalid: ENDPROC 11120 INP$=INP$+CH$ 11130 PROC_inchar 11140 ENDPROC 12000 DEF PROC_invalid 12010 PRINT CHR$(7);CHR$(127); 12020 PROC_inchar 12030 ENDPROC 13000 DEF PROC_cancel 13010 IF LEN(INP$)=0 THEN VDU 7: PROC_inchar: ENDPROC 13020 PRINT CH$;: CANC$=RIGHT$(INP$,1) 13030 INP$=LEFT$(INP$,LEN(INP$)-1) 13040 IF LEN(INP$)=0 THEN LST$="" ELSE LST$=RIGHT$(INP$,1) 13050 IF LST$="E" OR LST$="" THEN ST=0 ELSE ST=1 13060 IF CANC$="." THEN DPTS=0 13070 IF CANC$="E" THEN EXN=0 13080 IF CANC$="+" OR CANC$="-" THEN ST=0 13090 IF EXN=0 AND DPTS=0 AND CANC$>="0" AND CANC$<="9" THEN NMT=NMT-1 13100 IF EXN>0 AND CANC$>="0" AND CANC$<="9" THEN NUM$=LEFT$(NUM$, LEN(NUM$)-1) 13110 PROC_inchar 13120 ENDPROC
Note the use of recursion, and also the use of null statements between THEN and ELSE to avoid the ambiguity of IF...THEN...IF...THEN...ELSE.
PRINT ''"LEAVE A SPACE"'"NEW LINE"
is equivalent to
PRINT: PRINT: PRINT "LEAVE A SPACE": PRINT "NEW LINE"
The effect of the semicolon is to separate items which are to be printed consecutively, with no intervening spaces. For instance
PRINT "DIAL";999;"F0R POLICE"
This appears as
DIAL999FOR POLICE
with no spaces. In order to space it out properly, it is essential to put spaces inside the quotation marks
PRINT "DIAL ";999;" FOR POLICE" PRINT "DIAL";999; "FOR POLICE"
will not do
Note that very often it is unnecessary to include the semicolons. Whenever the computer can make sense of the print list without them, it will do so. Generally speaking, almost anything but numbers or real variables can be PRINTed without intervening semicolons. The problem with numbers and real variables is that they simply merge into one another. Even string and integer variables, on the other hand, can be distinguished by the $ or % at the end.
Thus we could put
PRINT "DIAL "999" FOR POLICE"
Similarly
A$= "STRINGING " B$= "THINGS " C$= "TOGETHER " PRINT A$B$C$
will produce the desired message, because the computer recognizes the dollar signs as denoting the end of each string variable.
However, it is not always possible to leave the semicolons out. Try the effect of
PRINT "STRINGING ""THINGS ""TOGETHER"
Two consecutive quotation marks are used to generate an actual quotation mark within a string. (They are also needed at the start of a DATA item or a string response to INPUT, because these may optionally be enclosed in quotation marks - for example, if a comma is to be included in the string. See Section 4.2.3.)
Generally speaking, it is best to develop the good habit of always including the semicolon.
One extra feature of the semicolon is that, if used at the end of a PRINT statement, it suppresses the newline, and leaves the cursor immediately after the printed text, which will enable you to carry on printing at a later stage if you wish. Try
PRINT "PUTTING THINGS";: PRINT "TOGETHER"
Also try just
PRINT "SO FAR SO GOOD";
The comma serves quite a different function. It behaves exactly like a preset tabulator key on a typewriter, so that each comma moves the cursor to the next available tab position across the screen. Normally the tab positions are ten characters apart. Try
PRINT "ME","AND YOU","AND US","." PRINT "TOO LONG FOR ONE","TAB POSITION"
Ending a PRINT statement with a comma will not cause the next PRINT to occur on the same line.
The default 'tab setting' of 10 characters can be changed. This value forms the first byte of the resident integer variable @?%, so changing this, for example to
@%=@%+5
will increase the spacing to 15 characters.
PRINT "OTHER,A.N.(type 5 spaces)01-234-56 78(type 4 spaces)LONDON" PRINT "OTHER,A.N.";SPC(5);"01-234-5678";SPC(4);"LONDON" PRINT "OTHER,A.N.";TAB(15);"01-234-5678";TAB(30);"LONDON" PRINT "OTHER,A.N.";SPC(15-POS);"01-234-5678";SPC(30-POS); "LONDON"
10 DIM A$(10,5) ,HEAD$(5) 20 CLS 30 FOR J=1 TO 5 : HEAD$(J)="COL"+STR$(J): NEXT J 40 FOR J=1 TO 5 50 FOR K=1 TO 10 60 A$(K,J)=STR$(K)+STR$(J) 70 NEXT K 80 NEXT J 90 PROC_table 100 END
10 REM PROGRAM TO ILLUSTRATE TAB(X,Y) 20 CLS 30 A$="A MAN A PLAN A CANAL PANAMA" 40 L=LEN(A$) 50 LFT=INT(19-L/2) 60 FOR J=1 TO L 70 PRINT TAB (LFT+J-1,8);MID$(A$,J,1) 80 PRINT TAB(LFT+L-J,16) ;MID$(A$,L+1-J,1) 90 TIME=0 100 REPEAT: UNTIL TIME=20 110 NEXT J 120 PRINT TAB(0,24);
If you have the supplementary disc which is available to accompany this book, program TABDEMO shows a more sophisticated use of TAB(X,Y), for an attractive method of input of data to set up a simple database.
Corresponding to the function POS, which is useful in conjunction with TAB (X) and SPC, there is a second function VPOS which returns the vertical position of the cursor. Thus to move to the start of the current line, you might use
PRINT TAB(0,VP0S);
After using TAB(X, Y) in a PRINT statement, note that TAB(X) and commas will be reset to measure from the position of the cursor after the TAB(X,Y) call, instead of the left-hand edge of the screen.
WIDTH 72
would restrict an 80 column printer to 72 columns, which would be a more suitable width for A4 paper.
PRINT 12345,67890
the result is
.....12345.....67890
(Note that the dots do not appear on the screen, but indicate the number of spaces between the characters printed.) The effect of the semi-colon is not only to act as a separator in the PRINT list, but also to cancel this right justification. Try
PRINT ;12345,67890
The reason for the right justification is so that integer numbers of different lengths, printed in a column, all have their units column aligned. Try
PRINT 1: PRINT 23: PRINT 456
However, real numbers with decimal fractions cannot be aligned this way unless they all have the same number of decimal places. Try
PRINT 1.2: PRINT 3.4: PRINT 5.67
If you want to retain this right justification while tabulating with TAB(X) or TAB(X, Y) rather than commas, you must omit the semicolons which good practice would normally dictate that you should include. Try
PRINT 1 TAB(15) 23: PRINT 45 TAB(15) 678
then
PRINT 1;TAB(15);23: PRINT 45;TAB(15);678
On the other hand, if you want numbers printed with spaces in between, then you must include the semicolons. Compare
PRINT 12" "34" "56 and PRINT 12;" ";34;" ";56
@%=&20000+&100*N+W
10 CLS 20 @%=&2020A 30 FOR ROW=1 TO 20 40 FOR C0L=1 TO 3 50 REPEAT 60 NUM=FNrannum 70 UNTIL ABS(NUM)<1E5 AND ABS(NUM)>0.1 80 PRINT ,NUM; 90 NEXT COL 100 PRINT 110 NEXT ROW 120 END 1000 DEF_FNrannum 1010 LOCAL DECPLACES, NUM 1020 DECPLACES=10^RND(6)-1) 1030 NUM=INT((RND(1)-0.5)*10^RND(9)) 1040 =NUM/DECPLACES
It would be as well to press <BREAK> after using this program, to restore the default value for @%.
The variable @% can do a great deal more than just produce a fixed number of decimal places, but its use is quite complicated, and is therefore described in Appendix F.
The biggest limitation of the example above is that all columns must be of equal width and, moreover, the decimal places are displayed even for integers. We might, however, want a column of 3 figure integers, two columns of numbers of up to 7 significant figures, having two decimal places, then two columns of numbers less than one, having just 3 decimal places. What is needed is a way in which successive numbers can be printed in different formats.
10000 DEF PROC_formprint(NUM,N,W) 10010 REM PROCEDURE TO PRINT NUM 10020 REM WITH A FIELD WIDTH OF W 10030 REM AND N DECIMAL PLACES. 10040 LOCAL ST1$,ST2$,ST3$,ST4$,ST5$,M,J,DPPOS 10050 @%=@% OR & 1000000 10060 ST1$=" "+STR$(NUM) 10070 ST2$=" " 10080 ST3$="": ST4$="" 10090 ST5$="." 10100 IF NUM=INT(NUM) THEN ST1$=ST1$+".":ST5$=" " 10110 M=W-N+(N>0): REM M IS MINIMUM NUMBER OF FIGURES BEFORE DECIMAL POINT 10120 DPPOS=0 10130 REPEAT 10140 DPPOS=DPPOS+1 10150 UNTIL MID$(ST1$,DPP0S,1)="." OR DPP0S=LEN(ST1$) 10160 IF DPPOS>M THEN ST3$=LEFT$(ST1$,DPPOS-1): GOTO 10210 10170 ST3$=LEFT$( ST1$,DPPOS-1) 10180 FOR J=DPPOS TO M 10190 ST3$=ST2$+ST3$ 10200 NEXT J 10210 ST4$=RIGHT$(ST1$,LEN(ST1$)-DPP0S) 10220 FOR J=1 TO N 10230 ST4$=ST4$+ST2$ 10240 NEXT J 10250 PRINT ;ST3$; 10260 IF N>0 THEN PRINT ;ST5$+LEFT$(ST4$,N); 10270 ENDPROC
Adapt the program from Example 11.7 to generate numbers with the same random format as before, and print them using the above procedure, by deleting line 20 and replacing line 80 by
80 PR0C_formprint(NUM,4,13)
Add the procedure above and test out the program. You will probably find this procedure easier to use than @% as described in Appendix F.
PRINT "ABCD";CHR$(129);"efgh";CHR$(130);"IJKL"
ASCII codes 129 and 130 alter the colour of the rest of the line to red and green respectively. Notice that the codes each occupy a character cell. It is not possible to produce a continuous line of text, such as
ABCDefgh
with, say, the lower case letters of different colour to that of the capitals. The same range of steady colours is available in Mode 7 as in Mode 2 (with the exception of black), and the codes that produce them are shown in Table 11.1.
Table 11.1 Special display codes for Mode 7.
Special effects | |||
Colour | Code | Code | Purpose |
red | 129 | 136 | flash on |
green | 130 | 137 | flash off |
yellow | 131 | 141 | double height characters |
blue | 132 | 140 | normal characters |
magenta | 133 | 157 | new background colour |
cyan | 134 | 156 | black background |
white | 135 | 152 | conceal display |
PRINT "ABCD<SHIFT-f1>efgh<SHIFT-f2>IJKL"
This method has the additionial advantage that the colours show up when the program is listed in Mode 7, but watch out for the fact that the codes will not be apparent in a printer listing of the program.
Just as in the other modes, it is possible to change the background from black to a colour, or back again to black. Code 157 must be issued after the code of the background colour you want. You will then need to issue a new colour code for the foreground text, or it will be invisible. For example, to print in green on a red background you would need
VDU 129,157,130: PRINT "THIS MAKES ME SEE RED"
This is where the VDU command becomes particularly useful.
You will see that the above line creates a complete background line in red. You could prevent this by finishing with code 156, which causes the background to revert to black. However, the leading 'spaces' of the two codes cannot be prevented from appearing in red. Try
VDU 129,157,130: PRINT "ON AND OFF";: VDU 156: PRINT
Another special effect in Mode 7 is the production of double height (but normal width) characters, which is initiated by code 141 (and switched off, if necessary later in the line, by 140). An unexpected feature, but which can be understood from the strict way that Mode 7 works with character cells only, is that double height letters must be printed twice on successive lines, both lines being identical (including code 141 at the start). Try the effect out with lines such as
PRINT CHR$(141);"A BIG MESSAGE": PRINT CHR$(141); "A BIG MESSAGE"
Try also the effect of disobeying the rules, with for instance
PRINT CHR$(141);"NOT A": PRINT CHR$(141) ;"MATCH"
There are four obvious ways when using Mode 7 to emphasize a section of text.
1. Use coloured text.
2. Use double height text.
3. Use flashing text. This is particularly eye catching, and can be used to tell the user what to do - for example
PRINT CHR$(136);"Press space bar to continue"
In other contexts it should be used in moderation or it can become overpowering.
4. To print text on a white or coloured background (unlike other modes, it is not possible to have black on a coloured backgound).
The following program illustrates all these techniques.
10 MODE 7 20 CLS 30 DIM DY$(7) 40 FOR I=1 TO 7: READ DY$(I): NEXT I 50 PRINT TAB(10,6);CHR$(130);CHR$(141);"SPELLING TEST" 'TAB(10);CHR$(130);CHR$(141);"SPELLING TEST" 60 PRINT TAB(10,9);CHR$(131);"Days of the week" 70 FOR I=1 TO 10 80 DAY=RND(7) 90 PRINT TAB(0,12);"What is the name of day ";DAY; " of the Week? " 100 PRINT SPC(14);: INPUT DAY$ 110 PRINT TAB(0,12) ;SPC(80) 120 IF DAY$=DY$(DAY) THEN PRINT TAB(13,12);CHR$(129); CHR$(136);"CORRECT":SC=SC+1: ELSE PRINT TAB(0,12); CHR$(132);"Day ";DAY;" of the week is spelt:-"; CHR$(136);DY$(DAY) 130 PRINT TAB(5,23) ;CHR$(136); CHR$(134);"Press any key to continue": A$=GET$ 140 PRINT TAB(0,23);SPC(40); 150 NEXT I 160 CLS 170 IF SC>=8 THEN PRINT TAB(10,10);CHR$(141); "CONGRATULATIONS"'TAB(10);CHR$(141);"CONGRATULATIONS" 180 PRINT TAB(7,15);CHR$(133);"You scored ";SC;" out of 10" 190 DATA SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY SATURDAY
10000 DEF PROC_inverse(TEXT$) 10010 LOCAL WHITE 10020 A%=135 10030 MD=USR(&FFF4) 10040 MD=(MD AND &FFFFFF) DIV &10000 10050 IF MD=7 THEN GOTO 10130 10060 WHITE=1 10070 IF MD=1 OR MD=5 THEN WHITE=3 10080 IF MD=2 THEN WHITE=7 10090 COLOUR 128+WHITE: COLOUR 0 10100 PRINT TEXT$; 10110 COLOUR 128: COLOUR WHITE 10120 ENDPROC 10130 VDU 157,132: PRINT TEXT$; 10140 VDU 156,135 10150 ENDPROC
1. PAY - a program that deals with the company payroll.
2. TAX - a program that deals with tax liabilities.
3. BONUS - a program which deals with the company's bonus and incentives scheme.
10 REM MENU PROGRAM 20 CLS 30 DIM P$(3) 40 P$(1)="PAY" 50 P$(2)="TAX 60 P$(3)="BONUS" 70 PRINT "The programs avaiLabLe on this disc" 80 PRINT '"deal with:" 90 PRINT '"1) The company payroll" 100 PRINT '"2) Tax liabilities" 110 PRINT '"3) The company's bonus and incentive" 120 PRINT "scheme" 130 PRINT '""Press 1, 2 or 3 for your choice" 140 A$=GET$ 150 IF VAL(A$)<1 OR VAL(A$)>3 THEN PRINT "YOU MUST PRESS KEYS 1, 2 OR 3": GOTO 140 160 CHAIN P$(VAL(A$))
It is frequently convenient in a turnkey system for the last executed statement of the programs on the disc (PAY, TAX and BONUS in the above example) to bring the user directly back to the menu by rerunning the menu program. The command
CHAIN "MENU"
will achieve this.
5 *TV0,1 10 MODE 1 20 DIM PROG$(6) 30 PROG$(1)="PAY" 40 PROG$(2)="TAX" 50 PROG$(3)="BONUS" 60 PROG$(4)="PROFIT" 70 PROG$(5)="BALANCE" 80 PROG$(6)=" INVESTMENT" 90 PRINT TAB(0,3);"This disc contains programs for the" 100 PRINT '"company's financial affairs" 110 PRINT 120 STARS$=STRING$(40,"*") 130 PRINT STARS$; 140 GAP$="*"+STRING$(38," ")+"*" 150 PRINT GAP$; 160 PRINT "* 1) The company payroll *"; 170 PRINT GAP$; 180 PRINT "* 2) Tax liabilities *"; 190 PRINT GAP$; 200 PRINT "* 3) Bonus and incentive scheme *"; 210 PRINT GAP$; 220 PRINT "* 4) Profit and loss account *"; 230 PRINT GAP$; 240 PRINT "* 5) Balance sheet *"; 250 PRINT GAP$; 260 PRINT "* 6) The company's investments *"; 270 PRINT GAP$ ; 280 PRINT "* 7) END *"; 290 PRINT GAP$ ; 300 PRINT STARS$ 310 PRINT "Press: "; 320 PROC_inverse("<SPACE BAR>") 330 PRINT " to move up and down" 340 PRINT " the list" 350 PRINT 'SPC(7); 360 PROC_inverse("<RETURN>") 370 PRINT " to run required program" 380 VDU 23;8202;0;0;0;: REM TURN OFF CURSOR 390 VDU 19,1,8;0;: VDU 19,130,143;0; 400 PROGNUM=2: DIRN=-1: CURS=11 405 PROC_arrow 410 REPEAT 420 CH$=GET$ 430 IF CH$=" " THEN PROC_arrow 440 UNTIL CH$=CHR$(13) 450 MODE 1: REM ALSO RESTORES CURSOR 460 IF PROGNUM<7 THEN PRINT TAB(7,15);:PROC_inverse ("Loading requested program"): B%=PROGNUM: C%=1: CHAIN PROG$(PROGNUM) 470 END 10000 DEF PROC_inverse(TEXT$) 10010 COLOUR 129: COLOUR 0 10020 PRINT TEXT$; 10030 COLOUR 128: COLOUR 1 10040 ENDPROC 20000 DEF PROC_arrow 20010 PRINT TAB(2,CURS);" "; 20020 IF PROGNUM=1 OR PROGNUM=7 THEN DIRN=-DIRN 20030 PROGNUM=PROGNUM+DIRN 20040 CURS=2*PROGNUM+7 20050 COLOUR 1: COLOUR 130 20060 PRINT TAB(2,CURS);"->"; 20070 COLOUR 4: COLOUR 128 20080 ENDPROC
reciprocal of N
ten to power N
factorial of N
PI to N decimal points
N random numbers
Use a second GET to request a single number argument for the operation, with an explanatory request.
(Factorial N can be obtained from PROD=1: FOR J=1 TO N: PROD= PROD*J: NEXT J).