Two examples of programs are given in this appendix. They show different uses
of function calls. One covers the use of the A/D Converter, which can only be
used with a BIOS call. This is then linked to BASIC to show how the two can be
combined. The second shows how the screen data can be saved to disk, and so
covers examples of sending and receiving data to the 6301 slave proces- sor. It
also covers disk handling and a certain amount of error checking. Two programs
are given, to save and read the screen data. Again they are linked to BASIC, but
as they are longer programs this needs to be done in a different way. They could
be poked in, but the code has be written to locate itself into the correct
position before BASIC is loaded.
H-1 A Simple Game Illustrating Use of the A/D/ Converter
The following program shows the use of the ADCVRT BIOS routine to enable the
voltage across a variable resistor to be read. By rotating the shaft of the
resistor the voltage read by the A/D converter will vary in proportion to the
amount of rotation. This can then be used as a means of altering the position of
a "bat" on the screen to play a simple game. This game shows how the BIOS
routine can be used and how it can be linked to a BASIC program through the CALL
statement of BASIC.
The circuit for the game is as follows:
The circuit comprises a battery to provide the voltage, a variable resistor and the neccessary connecting wires. The connections to the A/D interface are shown in section 4. 6.
The program listing is as follows:
10 '* A/D CONVERTER IN A GAME * 20 ' 30 CLEAR ,&HC000: GOSUB 4000: GOTO 300 40 ' SUBROUTINES 50 LOCATE X,Y : PRINT "O"; : X1=X : Y1=Y : RETURN 60 LOCATE X1,Y1 : PRINT " "; : RETURN 70 X=X+DX 80 IF X<2 THEN X=4-X : DX=-DX 90 IF X>79 THEN X=158-X : DX=-DX 100 RETURN 110 ' 200 CALL ADC(CH%,ADD%) : ADD%=ADD%*74/BMAX+2 : IF ADD%>75 THEN ADD%=75 210 PX=ADD% 220 LOCATE PX1,8 : PRINT " "; CHR$(&H1E) 230 LOCATE PX,8 : PRINT STRING$(5,140); CHR$(&H1E) : PX1=PX : RETURN 240 ' 250 ' 290 ' MAIN PROGRAM 300 ' 310 SCREEN 3,,0 : CLS : CH%=0 : PX=2 : PX1=2 : X=2 : X1=2 : SCORE=0 : N=0 : BALL=1 320 LINE (5,0) - (5,63) : LINE (475,0) - (475,63) 330 LOCATE 10,1 : PRINT "SCORE" : LOCATE 30,1 : PRINT "BALL NUMBER"; BALL 340 X = INT(RND*78)+2 : DX = FIX ((RND*2-1)*(N/5+1)) 360 Y=2 : GOSUB 200 : GOSUB 50 370 FOR Y = 3 TO 7 380 GOSUB 70 : GOSUB 200 : GOSUB 60 : GOSUB 50 : GOSUB 200 390 NEXT Y 400 Y=8 : GOSUB 70 : GOSUB 200 410 IF X=PX OR X=PX+4 THEN SOUND 1200,20 : DSCORE=1 : GOTO 800 420 IF X=PX+1 OR X=PX+3 THEN SOUND 1800,20 : DSCORE=2 : GOTO 800 430 IF X=PX+2 THEN SOUND 2400,20 : DSCORE=3 : GOTO 800 440 DSCORE=0 : GOSUB 60 : GOSUB 50 : SOUND 600,50 800 SCORE=SCORE+DSCORE : LOCATE 18,1 : PRINT SCORE; 810 BALL=BALL+1 : IF BALL >20 THEN 1000 820 GOSUB 60 830 N=N+1 : GOTO 330
1000 CLS : LOCATE 20,1 : PRINT "HIGH SCORE"; HSCORE 1010 LOCATE 20,3 : PRINT "Your score was"; SCORE 1020 LOCATE 20,5 : PRINT "Play again (y/n)"; Y$=INPUT$(1) 1030 IF SCORE > HSCORE THEN HSCORE=SCORE 1040 IF Y$<>"Y" AND Y$<>"y" THEN CLS : END ELSE 310 1050 ' 1060 ' 4000 ' SUBROUTINE FOR LOADING MACHINE CODE 4010 CLS 4020 AD=&HC000 4030 READ DAT$ 4040 IF DAT$="end" THEN 4240 4050 IF DAT$ = "LB" THEN POKE AD, PEEK(1) + &H6F : AD=AD+1 : GOTO 4030 4060 IF DAT$ = "HB" THEN POKE AD, PEEK(2) : AD=AD+1 : GOTO 4030 4070 POKE AD,VAL("&h"+DAT$) 4080 AD=AD+1 : GOTO 4030 4090 DATA D5 :'PUSH DE PUSH ADD% POINTER 4100 DATA 4E :'LD C,(HL) SET ADC CHANNEL 4110 DATA CD,LB,HD :'CALL ADCVRT CALL A/D CONVERTER 4120 DATA D1 :'POP DE POP ADD% POINTER 4130 DATA E6,FC :'AND 0FCH MASK BITS 0 AND 1 4140 DATA 1F :'RRA ROTATE RIGHT 4150 DATA 1F :'RRA ROTATE RIGHT 4160 DATA 12 :'LD (DE),A ADD% = DATA RETURNED 4170 DATA 13 :'INC DE ADD% MSB 4180 DATA AF :'XOR A ZERO A REGISTER 4190 DATA 12 :'LD (DE),A ADD% MSB = 0 4200 DATA C9 :'RET RETURN TO BASIC 4210 DATA end 4220 ' 4230 ' 4240 ADC=&HC000 : ' ADRESS TO CALL MACHINE CODE SUBROUTINE 4250 ' 4260 ' DETERMINE MAX RESPONSE TO BATTERY 4270 ' 4280 LOCATE 15,2 : PRINT "TURN RESISTOR TO GIVE MAXIMUM VALUE" 4290 LOCATE 15,3 : PRINT "THEN PRESS SPACE BAR" 4300 LOCATE 20,5 : PRINT "RESPONSE = " 4310 CALL ADC(CH%,ADD%) : LOCATE 40,5,0 : PRINT ADD% 4320 IF INKEY$ = " " THEN BMAX = ADD% : RETURN ELSE 4300
The main part of the program consists of a series of subroutines to move the "ball" on the screen, and move the "bat" in response to changes in the posi- tion of the resistor. These subroutines are at the beginning of the program (lines 50 to 230).
Line 200 reads the value of the voltage from the A/D converter.
Lines 310 to 1040 form the main part of the program which handles the ball.
Lines 4000 to 4190 load the machine code routine.
Lines 4260 to 4300 use the machine code routine to read the A/D converter.
They also allow setting of the maximum value of the voltage returned to be used
in line 200, so that the maximum sensitivity of movement can be obtained for the
battery being used.
Since the object of this appendix is to show the use of the BIOS call, only the machine code routine and the BASIC CALL will be described in detail.
The BASIC CALL statement is used with a list of parameters. This allows the channel of the A/D converter to be varied as well as returning a value of the voltage into a named variable. The channel is passed to the machine code rou- tine by means of the variable CH%, and the voltage is read back into the varia- ble ADD%. Further details of using the CALL statement are given in the BASIC Reference Manual (Appendix D). When two parameters are passed to the machine language subroutine, the location in memory of the first variable (in this case the channel CH%) will be placed in register pair HL. The address of the second variable (in this case ADD%) will placed in register pair DE.
The machine code subroutine first stores the address of the variable ADD% on the stack (data in line 4090). It then loads the channel number into register C (data in line 4100). The ADCVRT routine is then called (data in line 4110). In order to specify the address of ADCVRT, BASIC lines 4050 and 4060 are used. The low byte is determined by taking the low byte of WBOOT from loca- tion 0001 in the main memory bank, and adding the offset for the ADCVRT routine (6FH). The high byte is then obtained as the high byte of WBOOT ob- tained from location 0002 in the main memory bank. On return from the ADCVRT routine, register A contains the value of the voltage, in the top six bytes. After retreiving the location of the variable ADD% from the stack (data in line 4120), the two lowest bits of the returned voltage are made zero by an AND operation with the value FCH, so that any values in the lowest two bytes do not affect the result. (Data in line 4130.) If no further change was made the byte would give number in the range 4 to 255, since the least significant bits are always zero. Thus two rotations are made (data in lines 4140 and 4150) to make the most significant bits always zero. The contents of register A are then placed in the first byte of the variable ADDVo by loading register A into the address pointed to by register pair DE (data in line 4160). By incrementing the value of register pair DE, and making register A zero performing an XOR operation on register A with itself, the next byte of the variable ADD% is made zero. This ensures the variable ADD% is always a one byte variable. The data for these operations are to be found in lines 4170 to 4190. Finally the routine returns to BASIC.
The address for the machine code subroutine is assigned to the variable ADC
in line 4240. The BASIC CALL statement can only call to a variable.
As an illustration of the use of the routine, and because the battery could
vary in voltage, lines 4280 to 4320 will show the variation of the voltage as
the resis- tor spindle is turned, from zero up to the maximum value. A value of
63 will denote 2.0 volts. Since the battery voltage in the diagram is 1.5 volts,
the maxi- mum value obtained will be in either 46 or 47.
The following two listings show heavily commented programs written with the MACRO-80 assembler in Z-80 code. The comments should be sufficient for an assembler programmer to follow, although they may require the OS Refer- ence Manual or the Technical Reference Manual for further details of the use of the slave processor.
For those users wishing to enter the programs, use either the MACRO-80 as-
sembler, or the dumps at the end of the listings together with the pertinent in-
structions. A BASIC listing is given as an example to show how such programs can
be used with BASIC.
Having typed them in and saved them under the file names SSAVE.COM and SLOAD.COM, proceed as follows to use them with BASIC:
This will load BASIC but with the upper memory limit for variables set to B200H, thus protecting the two loaded programs.
10 SCREEN 3,0,0:CLS 20 LINE (0,0) - (479,63),,B 30 LINE (0,0) - (479,63) 40 LINE (479,0) - (0,63) 50 S = &HB400: L = &HB200: REM start addresses to Save and Load 60 CALL S 70 CLS: LOCATE 27,1: PRINT "The screen has been saved." 80 LOCATE 24,5: PRINT "Press any key to load the screen." 90 IF INKEY$ = " " THEN 80 100 CLS 110 CALL L 120 LOCATE 24,5: PRINT "Press any key to exit" 130 IF INKEY$ = " " THEN 130 140 SCREEN 0