Appendix H

SOME EXAMPLE PROGRAMS

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

game screenshot

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.

H-1


The circuit for the game is as follows:

game circuit

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

H-2


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.

H-3


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.

H-4


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.

H-5


H-2 Saving and Loading the Graphics Screen from Disk

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.

H-6


H-7


H-8


H-9


H-10


H-11


H-12


H-13


H-14


H-15


H-16


Having typed them in and saved them under the file names SSAVE.COM and SLOAD.COM, proceed as follows to use them with BASIC:

  1. Execute SSAVE on the CP/M command line. The SSAVE program will relocate the appropriate part of the program to the memory locations be- ginning with B400H.
  2. Execute SLOAD on the CP/M command line. The SLOAD program will relocate the appropriate part of the program to the memory locations be- ginning with B200H.
  3. Enter BASIC using the command: BASIC /M: &HB200

    This will load BASIC but with the upper memory limit for variables set to B200H, thus protecting the two loaded programs.

  4. Load and RUN the following program as an example:

    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

    H-17