Machine-code subroutines written using the mnemonic assembler can be incorporated into BASIC programs, and several examples are given in the following sections.
The following machine-code routine, 'Replace, can be used to perform a character-by-character substitution on a string. It assumes the existence of three strings called R, S, and T. The routine looks up each character of R to see if it occurs in string S and, if so, it is replaced with the character in the corresponding position in string T,
For example, if:
$S="TMP"; $T="SNF"
then the sequence:
$R="COMPUTER" LINK RR0
will change $R to "CONFUSER".
10 REM Replace 20 DIM LL(4),R(20),S(20),T(20) 40 FOR N=l TO 2; DIM P(-1) 50[ 60:LL0 LDX @0 70:LL1 LDY @0; LDA R,X 80 CMP @#D; BNE LL3; RTS finished 90:LL2 INY 100:LL3 LDA S,Y 110 CMP @#D; BEQ LL4 120 CMP R,X; BNE LL2 130 LDA T,Y; STA R,X replace char 140:LL4 INX; JMP LL1 next char 150] 160 NEXT N 200 END
The routine has many uses, including code-conversion, encryption and decryption, and character rearrangement.
To illustrate one application of the Replace routine, the following program converts any number from Arabic to Roman numerals:
10 REM Roman Numerals 20 DIM LL(4),Q(50) 30 DIM R(20),S(20),T(20) 40 FOR N=l TO 2; DIM P(-1) 50[ 60:LL0 LDX @0 70:LL1 LDY @0; LDA R,X 80 CMP @#D; BNE LL3; RTS finished 90:LL2 INY 100:LL3 LDA S,Y 110 CMP @#D; BEQ LL4 120 CMP R,X; BNE LL2 130 LDA T,Y; STA R,X replace char 140:LL4 INX; JMP LL1 next char 150] 160 NEXT N 200 $S="IVXLCDM"; $T="XLCDM??" 210 $Q=""; $Q+5="I"; $Q+10="ii" 220 $Q+15="iii"; $Q+20="iv"; $9+25="V" 230 $Q+30="vi"; $Q+35="vii" 240 Sq+40="viii"; $Q+45="ix" 250 DO $R="";D=10000 255 INPUT A 260 DO LINK LL0 270 $R+LEN(R)=$(Q+A/D*5) 280 A=A%D; D=D/10; UNTIL D=O 290 PRINT $R; UNTIL 0 Description of Program: Allocate labels and strings 40-160 Assemble Replace routine. 200 Set up strings of Roman digits 210-240 Set up strings of numerals for 0 to 9. 255 Input number for conversion 260 Multiply the Roman string R by ten by performing a character substitution. 270 Append string for Roman representation for A/D to end of R. 280 Look at next digit of Arabic number. 290 Print Roman string, and carry on. Variables: A Number for conversion D Divisor for powers of ten. LL(0..4) Labels for assembler routine. LL0 Entry point for Replace routine. N Counter for two-pass assembly. P Location counter. Q $(Q+5*x) is string for Roman numeral X. $R String containing Roman representation of A. $S Source string for replacement. $T Target string for replacement. Program size: 579 bytes.
The following program simulates a harpsichord; it uses the central section of the ATOM's keyboard as a harpsichord keyboard, with the keys assigned as follows:
_|_ E R _ Y U I _ P @
A S D F G H J K L ; [ ]
where the S key corresponds to middle C. The space bar gives a 'rest', and no other key on the keyboard has any effect.
The tune is displayed on a musical stave as it is played, with the black notes designated as sharps. Pressing RETURN will then play the music back, again displaying it as it is played.
The program uses the Index routine, described in Section 16.3, to look up the key pressed, and a version of the Bleep routine in Section 15.4.1.
1 REM Harpsichord 10 DIM S(23),T(26),F(0) 15 DIM WW(2),RR(2),Z(128) 20 DIM P(-1) 30 PRINT $21 100[\generate NOTE 110:WW0 STA F; LDA @0 120:WW2 LDX F 130:WW1 DEX; NOP; NOP; BNE WW1 140 EOR @4; STA #B002 150 DEY; BNE WW2; RTS 160\READ KEY & LOOK UP IN T 165:RR1 STX F; RTS 170:RR0 JSR #FFE3 180 LDX @25 190:RR2 CMP T,X; BEQ RR1 210 DEX; BPL RR2; BMI RR0 220] 230 PRINT $6 380 X=#8000 390 D=256*#22 393 S!20=#01016572 395 S!16=#018898AB 400 S!12=#01CBE401 410 S!8=#5A606B79 420 S!4=#8090A1B5 430 S!0=#C0D7F2FF 450 $T="ASDFGHJKL;[]?ER?YUI?P@? ?" 460 T?24=#1B; REM ESCAPE 470 CLEAR 0 480 DO K=32 500 FOR M=0 TO 127; LINK RR0 505 IF ?F<>25 GOTO 520 508 IF M<>0 Q=m 510 K=128; GOTO 540 520 Z?M=?F 530 GOSUB d 540 NEXT M 780 K=32 800 FOR M=0 TO Q-1; WAIT; WAIT 810 ?F=Z?M; GOSUB d 820 NEXT M 825 UNTIL 0 830dREM DRAW TUNE 840 IF K<31 GOTO e 850 CLEAR 0 860 FOR N=34 TO 10 STEP -6 870 MOVE 0,N; DRAW 63,N 880 NEXT N 890 K=0 900eIF ?F=23 GOTO s 910 IF ?F>11 K?(X+32*(27-?F))=35; K=K+1 920 K?(X+32*(15-?F%12))=15 930 K=K+1 960 A=S?(?F); Y=D/A 970 LINK WWO 980 RETURN 990sFOR N=0 TO 500;NEXT N 995 K=K+1; RETURN Description of Program: 100-150 Assemble bleep routine 160-210 Assemble index routine 393-430 Set up note values 450-460 Set up keyboard table 480-825 Main program loop 500-540 Play up to 128 notes, storing and displaying them. 800-820 Play back tune 830 d: Draw note on staves and play note 840-880 If first note of screen, draw staves 900-920 Plot note on screen 960-970 Play note 990-995 Wait for a rest Variables: A Note frequency D Duration count ?F Key Index K Column count on screen M Counter N Counter P Location counter Q Number of notes entered RR(0..2) Labels in index routine RR0 Entry point to read routine S?0..S?23 Vector of note periods T?0..T?26 Vector of keys corresponding to vector S WW(0..2) Labels in note routine WW0 Entry point to note routine X Screen address Y Number of cycles of note to be generated Z(0..128) Array to store tune. Program size: 1049 bytes Extra storage: 205 bytes Machine code: 41 bytes Total size: 1295 bytes
Bulls and Cows is a game of logical deduction which has become very popular in the plastic peg version marketed as 'Mastermind'. In this version of the game the human player and the computer each think of a 'code', consisting of a string of four digits, and they then take turns in trying to guess the other player's code. A player is given the following information about his guess:
The number of Bulls i.e. digits correct and in the right position. The number of Cows i.e. digits correct but in the wrong position.
Note that each digit can only contribute to one Bull or one
Cow. The human player specifies the computer's score as two
digits, Bulls followed by Cows. For example, if the code string
were '1234' the score for guesses of '0004, '4000', and
'4231' would be '10, '01', and '22' respectively.
The following program plays Bulls and Cows, and it uses a
combination of BASIC statements to perform the main input and
output operations, and assembler routines to speed up sections of
the program that are executed very frequently; without them the
program would take several minutes to make each guess.
10 REM Bulls & Cows 20 DIM M(3),N(3),C(0),B(0),L(9) 23 DIM GG(10),RR(10) 25 DIM LL(10) 50 GOSUB z; REM Assemble code 60 GOSUB z; REM Pass Two 10OO REM MASTERMIND ***** 1005 Y=1; Z=1 1007 @=2 1010 GOSUB c 1015 G=!M ;REM MY NUMBER 1020 GOSUB c; Q=!m 1030 I=0 1040 DO I=I+1 1050 PRINT "(" I ")" ' 1100 IF Y GOSUB a 1150 IF Z GOSUB b 1350 UNTIL Y=0 AND Z=0 1400 PRINT "END"; END 1999*********************************** 2000 REM Find Possible Guess 2010fGOSUB c; F=!M 2160wLINK LL7 2165 IF !M=F PRINT "YOU CHEATED"; END 2170 X=1 2180v!N=GG(X) 2190 LINK LL2 2200 IF !C&#FFF<>RR(X) THEN GOTO w 2210 IF X<I THEN X=X+1; GOTO v 2220 Q=!m; RETURN 3999*********************************** 4000 REM Choose Random Number 4005cJ=ABSRND 4007 REM Unpack Number 4010uFOR K=0 TO 3 4020 M?K=J%10 4030 J=J/10 4040 NEXT 4050 RETURN 4999*********************************** 5000 REM Print Guess 5010gFOR K=0 TO 3 5020 P. $(H&15+#30) 5030 H=H/256; NEXT 5040 RETURN 5999********%************************** 6000 REM Your Turn 6040aPRINT "YOUR GUESS" 6045 INPUT J 6050 GOSUB u 6060 !N=G 6065 LINK LL2 6070 P.?B" BULLS, "?C" COWS"' 6075 IF!C<>#400 RETURN 6080 IF Z PRINT"...AND YOU WIN"' 6083 IF Z:1 PRINT" ABOUT TIME T00!"' 6085 Y=0 6090 RETURN 6999***********************************
7000 REM My Turn 7090bPRINT "MY GUESS: 7100 H=Q; GOSUB g 7110 PRINT 7120 INPUT "REPLY" V 7140 RR(I)=(V/10)*256+V%10 7150 GG(I)=Q 7225 IF V<>40 GOSUB f; RETURN 7230 IF Y PRINT"...SO I WIN!"' 7235 Z=0 7240 RETURN 7999***********************************
9000zREM Find Bulls/Cows 9035 PRINT $#15 ;REM Turn off screen 9045 DIM P(-1) 9050[ 9055\ find bulls 6 cows for m:n 9060:LL2 LDA @0; LDX #13 ZERO L,B,C 9065:LL3 STA C,X; DEX; BPL LL3 9100 LDY @3 9105:LL0 9120 LDA M,Y 9130 CMP N,Y is bull? 9140 BNE LL4 no bull 9150 INC B count bull 9160 BPL LL1 no cows i 9165:LL4 9170 TAX not a bull 9180 INC L,X 9190 BEQ LL6 9200 BPL LL5 not a cow 9210:LL6 INC C 9220:LL5 LDX N,Y; DEC L,X 9225 BMI LL1; INC C 9260:LL1 DEY; BPL LLO again 9350 RTS 9360\ increment M 9370:LL7 SED; SEC; LDY @3 9380:LL9 LDA M,Y; ADC @#90 9390 BCS LL8; AND @#0F 9400:LL8 STA M,Y; DEY 9410 BPL LL9; RTS 9500] 9900 PRINT $#6 ;REM Turn Screen on 9910 RETURN
Description of Program:
20-25 Declare arrays and vectors 50-60 Assemble machine code 1010 Computer chooses code 1020 Choose number for first guess 1040-1350 Main program loop 1050 Print turn number 110G If you have not finished have a turn 1150 If I have not finished my turn 1350 Carry on until we have both finished 1999 Lines to make listing more readable. 2000-3999 f: Find a guess which is compatible with all your replies to my previous guesses. 4000-4999 c: Choose a random number 4007-4050 u: Unpack J into byte vector M, one digit per byte. 5000-5040 g: Print guess in K as four digits. 6000-6090 a: Human's guess at machine's number; print score. 7000-7240 b: Machine's guess at human's code. 9000-991O z: Subroutine to assemble machine-code routines 9055-9350 Find score between numbers in byte vectors M and N; return in ?B and ?C. 9360-9500 Increment number in vector M, in decimal, one digit per byte.Variables:?B Number of Bulls between vectors M and N ?C Number of Cows between vectors M and N GG(1..10) List of human's guesses H Computer's number I Turn number J Human's guess as 4-digit decimal number K Counter L Vector to count occurrences of digits in numbers LL(0..10) Labels in assembler routines LL2 Entry point to routine to find score between 2 codes LL7 Entry point to routine to increment M !M, !N Code numbers to be compared P Location counter Q Computer's guess, compatible with human's previous replies. RR(1..10) List of human's replies to guesses GG(1..10) Y Zero if human has finished Z Zero if computer has finished. Program size: 1982 bytes Additional storage: 152 bytes Machine-code: 223 bytes Total storage: 2357 bytesSample run:>RUN ( 1) YOUR GUESS?1122 0 BULLS, 0 COWS MY GUESS: 6338 REPLY?10 ( 2) YOUR GUESS?3344 0 BULLS, 0 COWS MY GUESS: 6400 REPLY?20 ( 3) YOUR GUESS?5566 0 BULLS, 0 COWS MY GUESS: 6411 REPLY?10 ( 4) YOUR GUESS?7788 1 BULLS, 1 COWS MY GUESS: 6502 REPLY?40 ...SO I WIN! ( 5) YOUR GUESS?