Listing of file='LASER.MAC;28' on disk='vmedia/laser_gun_keyboard-sector.ccvf'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; LASER GUN - SHOOT DOWN SPACE SHIPS
;
; REAL-TIME GAME WITH SPACE SHIPS MOVING IN TWO
; DIMENSIONS. SOUNDS BUILT IN FOR LASER FIRING AND
; SHIP EXPLOSIONS. USER CHOSES FROM 1-9 SHIPS ACTIVE
; AT ANY TIME.
;
; EXTERNALS :- REQUIRED SUBROUTINES
;
EXTRN BOOM ;MAKE EXPLOSION SOUND
EXTRN DECOUT ;CONVERT A BYTE TO ASCII DECIMAL NO.
EXTRN DELAY ;TIME DELAY
EXTRN DRWSYM ;DRAW A SHIP
EXTRN FIRCTL,FIRMSG,FIRED,HITMSG,HITS,DBCNT
;DO ALL THE SHOOTING - TWO VERSIONS
EXTRN INSTR ;INSTRUCTIONS - TWO VERSIONS
EXTRN MOVSHP ;MOVE A SHIP GRAPHIC
EXTRN RANDOM,RANPTR ;RANDOM NUMBER GENERATOR
EXTRN SNDSET ;SETUP SOUND CHIP
EXTRN TIME,SETTIM
;TIME CONTROL ROUTINE (DOWN COUNTER)
EXTRN JMPVEC
;ROUTINE SETS UP CORRECT JUMP ADDRESSES FOR
;THE VERSION OF FCS SO FCS ROUTINES CAN BE USED
; FCS ROUTINES
EXTRN CO
EXTRN OSTR ;OUTPUT A STRING
EXTRN SAVE ;SAVE ALL REGISTERS
;
; EQUATES :-
;
; SYSTEM ADDRESSES
;
TICKS EQU 81B8H ;TICKS OF REAL-TIME CLOCK
SECS EQU 81B9H ;SECONDS
USRINP EQU 81C5H ;USER INPUT JUMP VECTOR
KBDFL EQU 81DFH ;KEYBOARD INPUT FLAG
;
; PROGRAM PARAMETERS
;
PLAYTM EQU 3 ;PLAYING TIME ("MINUTES")
NUMSHP EQU 9 ;NUMBER OF SHIPS
NTYPE EQU 4 ;NUMBER OF TYPES OF SHIPS
SHPWID EQU 10 ;WIDTH OF SHIP GRAPHIC (IN BYTES,
; INCLUDING CCI'S)
SHPHGT EQU 3 ;HEIGHT OF SHIP GRAPHIC (IN LINES)
XMAX EQU 63 ;MAXIMUM X-COORD FOR SHIPS
YMAX EQU 31 ;MAXIMUM Y-COORD FOR SHIPS
MXSPCT EQU 4 ;MAXIMUM SPEED COUNT FOR SHIPS
;..............................................................
;
; MAIN PROGRAM
;
LASER: DI
LXI H,0 ;SAVE FCS STACK POINTER FOR RETURN
DAD SP
SHLD FCSSP
LXI SP,STACK
CALL JMPVEC ;SETUP JUMPS TO OSTR AND SAVE WITH
;CORRECT ADDRESSES FOR VERSION OF FCS
LXI H,ERASE ;ERASE THE SCREEN
CALL OSTR
MVI A,0C3H ;LOAD USER INPUT JUMP VECTOR
STA USRINP
LXI H,CHARIN
SHLD USRINP+1
MVI A,31 ;SETUP KEYBOARD INPUT FLAG
STA KBDFL
EI
CALL INSTR ;PRINT HEADING AND INSTRUCTIONS
LXI H,50
MVI A,10
CALL SNDSET
START: LXI H,SHPMSG ;ASK FOR NUMBER OF SHIPS
CALL OSTR
LXI H,KBCHR
MVI M,0
LAS10: MOV A,M ;WAIT FOR USER TO READ INSTRUCTIONS
ORA A ; AND CHOOSE NUMBER OF SHIPS
JZ LAS10
MVI M,0
SUI 48 ;CONVERT TO A DIGIT
ORA A
JZ LAS10 ;ZERO SHIPS IS ILLEGAL
CPI 10 ;MAKE SURE ITS A VALID DIGIT
JNC LAS10
STA NSHIP
CALL SETUP ;SETUP THE SCREEN, ETC.
;
; MAIN LOOP
;
MAIN: EI
LDA STOP ;SEE IF REQUEST TO STOP
ORA A
JNZ EXIT
LXI H,LSRMSG ;DISPLAY LASER ON SCREEN
CALL OSTR
CALL GENSHP ;GENERATE NEW SHIPS IF NECESSARY
CALL MOVSHP ;MOVE ALL THE SHIPS
LDA LOST
ORA A
JNZ BOMB
CALL FIRCTL ;SEE IF USER WANTS TO FIRE LASER
CALL TIME ;UPDATE TIME ...
JZ EXIT ; ... AND EXIT IF EXPIRED
JMP MAIN ;REPEAT .......
;..............................................................
;
; KEYBOARD INTERRUPT ROUTINE
;
CHARIN: CALL SAVE
MOV A,E
STA KBCHR ;SIMPLY STORE THE CHAR AND RETURN
CPI 'S' ;UNLESS IT'S AN 'S' FOR 'STOP',
JZ FINITO
CPI 27 ; OR AN ESCAPE
JZ FINITO ; IN WHICH CASE WE EXIT
RET
FINITO: MVI A,0FFH ;SWITCH RETURN ADDRESS
STA STOP
RET
KBCHR: DB 0
;..............................................................
;
; BOMB THE PROGRAM - USER LOST
;
BOMB: MVI A,5
BOMB10: PUSH PSW
MVI A,8
CALL RANDOM ;FLASH RANDOM COLORS ON SCREEN
ADI 16
STA COLOR
LXI H,FLASH
CALL OSTR
CALL BOOM ; AND EXPLODE A LOT
MVI A,100
CALL RANDOM
ADI 100
CALL DELAY
POP PSW
DCR A
JNZ BOMB10
MVI A,16 ;RETURN TO BLACK BG
STA COLOR
LXI H,FLASH
CALL OSTR
;..............................................................
;
; EXIT ROUTINE
;
EXIT: LXI H,HITMSG ;PRINT OUT FINAL SCORES
CALL OSTR
LXI H,FIRMSG
CALL OSTR
LXI H,FINMSG ;OUTPUT GAME OVER MESSAGE
CALL OSTR
LXI H,KBCHR
EX10: MVI M,0
EX20: MOV A,M ;WAIT ON USER TO ANSWER 'PLAY AGAIN ?'
ORA A
JZ EX20
CPI 'Y'
JZ EX30 ;START OVER IF ANSWER IS 'Y'
CPI 'N'
JNZ EX10 ;USER MUST TYPE 'Y' OR 'N'
LXI H,ERASE ;IF 'N', ERASE SCREEN,
CALL OSTR
MVI A,13
STA KBDFL ; RESTORE KEYBOARD FLAG TO FCS
MVI B,0 ; SET NO FCS ERROR,
LHLD FCSSP ; RESTORE FCS STACK POINTER,
SPHL
RET ; AND RETURN.
EX30: LXI H,ERASE ;ERASE SCREEN AND RESTART GAME
CALL OSTR
JMP START
;..............................................................
;
; SETUP ALL PARAMETERS AND SCREEN
;
SETUP: LXI H,ERASE ;ERASE SCREEN
CALL OSTR
LDA TICKS ;GENERATE A NEW RANDOM NUMBER SEED
MOV L,A
LDA SECS
CMA
MOV H,A
SHLD RANPTR
LXI H,SHPTYP ;ZERO OUT THE TEMPORARY SCT
MVI B,LSCTE
XRA A
SETU20: MOV M,A
INX H
DCR B
JNZ SETU20
LXI H,SCT ;NOW ZERO OUT THE WHOLE SCT
LDA NSHIP
MOV B,A
SETU30: PUSH B
SHLD HLSCT
CALL PUTSCT
LHLD HLSCT
CALL BMPSCT
POP B
DCR B
JNZ SETU30
MVI A,'0' ;ZERO OUT THE SHOT AND HIT COUNTERS
LXI H,FIRED-1
MOV M,A
DCX H
MOV M,A
DCX H
MOV M,A
DCX H
MOV M,A
LXI H,HITS-1
MOV M,A
DCX H
MOV M,A
DCX H
MOV M,A
DCX H
MOV M,A
LDA NSHIP ;ADJUST BUTTON DEBOUNCE FOR FIRING
MOV B,A ; ACCORDING TO NUMBER OF SHIPS
MVI A,NUMSHP+1
SUB B
ADI 3
RRC
RRC
ANI 3FH
STA DBCNT
XRA A
STA LOST
STA STOP
MVI A,PLAYTM ;SET UP THE "CLOCK"
CALL SETTIM
CALL TIME ;DISPLAY STARTING TIME
RET
;..............................................................
;
; GENERATE A SHIP
;
GENSHP: MVI A,5 ;CHECK 1 OUT OF 5 TIMES
CALL RANDOM
CPI 3
RNZ
LXI H,SCT
LDA NSHIP ;GET NUMBER OF SHIPS
MOV B,A
XRA A
GENS1: CMP M ;LOOK FOR AN UNUSED ENTRY IN SCT
JZ GENS2 ; (SHIP TYPE IS ZERO)
CALL BMPSCT
DCR B
JNZ GENS1
RET ;ALL SHIPS IN THE AIR
GENS2: SHLD HLSCT ;SAVE POINTER TO SCT
MVI A,NTYPE ;CHOOSE TYPE OF SHIP
CALL RANDOM
ADI 1
STA SHPTYP ;STORE IN TEMPORARY TABLE
LXI H,SHIPS-SHPLEN
LXI D,SHPLEN
GENS3: DAD D ;FIND POINTER TO SHIP GRAPHIC
DCR A
JNZ GENS3
SHLD GRPTR ;SAVE GRAPHICS POINTER
MVI A,MXSPCT ;CHOOSE "SPEEDS" (REALLY DELAY
CALL RANDOM ;COUNTERS WHICH ARE THE INVERSE
ADI 1 ;OF TRUE SPEEDS)
STA HORSPD ;HORIZONTAL "SPEED"
STA HORCNT ;SET UP INITIAL COUNT VALUE TOO
MVI A,2 ;PICK DIRECTION:-
CALL RANDOM ; 1 = +VE COORD DIRN
ORA A ; -1 = -VE COORD DIRN
JNZ GENS4
MVI A,-1
GENS4: STA HORDRN ;STORE DIRECTION
MVI A,MXSPCT ;SAME FOR VERTICAL
CALL RANDOM
ADI 1
STA VRTSPD ;VERTICAL "SPEED"
STA VRTCNT
MVI A,2
CALL RANDOM
ORA A
JNZ GENS5
MVI A,-1
GENS5: STA VRTDRN
MVI A,4
CALL RANDOM ;CHOOSE A SIDE OF THE SCREEN
ORA A
JZ LEFT
CPI 1
JZ RIGHT
CPI 2
JZ TOP
CPI 3
JZ BOTTOM
LEFT: MVI A,1 ;FORCE +VE HORIZONTAL DIRECTION SO
STA HORDRN ;SHIP MUST MOVE ONTO SCREEN
MVI A,1-SHPWID/2 ;START OUT JUST OFF SCREEN
STA XPOS
JMP VERT
TOP: MVI A,1 ;FORCE +VE VERTICAL DIRN (DOWN) TO
STA VRTDRN ;MAKE SHIP MOVE ONTO SCREEN
MVI A,1-SHPHGT ;START OUT OFF SCREEN AT TOP
STA YPOS
JMP HORIZ
RIGHT: MVI A,-1 ;SIMILARLY FOR OTHER EDGES OF SCREEN
STA HORDRN
MVI A,XMAX
STA XPOS
JMP VERT
BOTTOM: MVI A,-1
STA VRTDRN
MVI A,YMAX
STA YPOS
JMP HORIZ
VERT: MVI A,YMAX
CALL RANDOM
STA YPOS
JMP GENFIN
HORIZ: MVI A,XMAX
CALL RANDOM
STA XPOS
GENFIN: XRA A ;MARK SHIP AS NOT EXPLODING
STA XPLCNT
CALL PUTSCT ;SAVE NEW SHIP CONTROL TABLE
RET
;..............................................................
;
; BUMP THE POINTER TO THE SCT ENTRY
;
ENTRY BMPSCT
BMPSCT: PUSH D
LXI D,LSCTE
DAD D
POP D
RET
;..............................................................
;
; GET A SCT ENTRY INTO A SET OF NAMED LOCATIONS
;
ENTRY GETSCT
GETSCT: LHLD HLSCT
LXI D,SHPTYP
MVI B,LSCTE
GET10: MOV A,M
STAX D
INX H
INX D
DCR B
JNZ GET10
RET
;..............................................................
;
; PUT AN SCT ENTRY BACK INTO THE TABLE
;
ENTRY PUTSCT
PUTSCT: LHLD HLSCT
LXI D,SHPTYP
MVI B,LSCTE
PUT10: LDAX D
MOV M,A
INX H
INX D
DCR B
JNZ PUT10
RET
;..............................................................
;
; DATA AREA
;
; PUBLIC VARIABLES NEEDED FOR LINKAGES TO OTHER ROUTINES
;
PUBLIC LOST
PUBLIC SCT,HLSCT,NSHIP,SHPTYP,GRPTR,XPOS,YPOS
PUBLIC HORCNT,VRTCNT,HORDRN,VRTDRN,HORSPD,VRTSPD
PUBLIC XPLCNT,EXPLDE
LOST: DB 0 ;FLAG FOR END OF GAME IF USER LOSES
STOP: DB 0 ;FLAG FOR USER REQUEST TO STOP
HLSCT: DS 2 ;POINTER TO CURRENT SCT ENTRY
NSHIP: DB NUMSHP ;NUMBER OF SHIPS
; TEMPORARY STORAGE FOR A SCT (SHIP CONTROL TABLE) ENTRY
SHPTYP: DS 1 ;SHIP TYPE
GRPTR: DS 2 ;POINTER TO SHIP GRAPHIC
HORSPD: DS 1 ;HORIZONTAL "SPEED"
HORDRN: DS 1 ;HORIZONTAL DIRECTION
HORCNT: DS 1 ;HORIZONTAL COUNTER
VRTSPD: DS 1 ;SIMILARLY FOR VERTICAL
VRTDRN: DS 1
VRTCNT: DS 1
XPLCNT: DS 1 ;EXPLOSION COUNTER
XPOS: DS 1 ;X-COORD OF SHIP
YPOS: DS 1 ;Y-COORD OF SHIP
LSCTE EQU $-SHPTYP ;LENGTH OF AN ENTRY IN THE
; SHIP CONTROL TABLE
SCT: DS NUMSHP*LSCTE ;SHIP CONTROL TABLE
;..............................................................
;
; GRAPHICS FOR THE SHIPS
;
; DEFINITION OF THE CCI'S
BLK EQU 0 ;BLACK
BLU EQU 4 ;BLUE
CYN EQU 6 ;CYAN
GRN EQU 2 ;GREEN
RED EQU 1 ;RED
ROY EQU 19H ;RED ON YELLOW
YEL EQU 3
SHIPS:
CYLON: DB 20H,BLK,11H,CYN,65H,CYN,10H,CYN,20H,BLK
DB 14H,CYN,4FH,ROY,60H,CYN,4FH,ROY,15H,CYN
DB 65H,CYN,05H,CYN,5EH,CYN,05H,CYN,65H,CYN
TIEFGT: DB 7AH,BLU,20H,BLK,20H,BLK,20H,BLK,0AH,BLU
DB 6EH,BLU,67H,BLU,4FH,CYN,67H,BLU,6EH,BLU
DB 0BH,BLU,20H,BLK,20H,BLK,20H,BLK,79H,BLU
VIPER: DB 20H,BLK,20H,BLK,6EH,YEL,20H,BLK,20H,BLK
DB 20H,BLK,09H,YEL,4FH,RED,07H,YEL,20H,BLK
DB 08H,YEL,05H,YEL,20H,BLK,05H,YEL,06H,YEL
SAUCER: DB 20H,BLK,1EH,GRN,6AH,GRN,1CH,GRN,20H,BLK
DB 3CH,GRN,4FH,YEL,3AH,RED,4FH,YEL,3EH,GRN
DB 20H,BLK,5EH,GRN,5EH,GRN,5EH,GRN,20H,BLK
SHPLEN EQU ($-SHIPS)/NTYPE ;LENGTH OF A SHIP GRAPHIC
;
; GARBAGE FOR AN EXPLOSION
;
; NOTE THAT IT IS LONGER THAN THE OTHERS TO ALLOW
; FOR A RANDOM STARTING POSITION IN THE MESS
RDB EQU 0C1H ;RED+BLINK+PLOT
RYB EQU 0D9H ;RED ON YELLOW +BLINK+PLOT
YLB EQU 0C3H ;YELLOW+BLINK+PLOT
YRB EQU 0CBH ;YELLOW ON RED +BLINK+PLOT
EXPLDE: DB 4H,RYB,0C3H,YLB,0BCH,RDB,20H,BLK,0AAH,RYB
DB 3CH,YRB,20H,BLK,0A1H,YLB,1H,YRB,0C3H,RDB
DB 80H,YLB,22H,RYB,20H,BLK,01H,YLB,20H,BLK
DB 0C8H,RDB,0F0H,RYB,80H,YLB,20H,BLK,32H,YRB
DB 20H,BLK,16H,RDB,28H,YLB,60H,RYB,20H,BLK
;
; MESSAGES
;
SHPMSG: DB 6,3,'MAXIMUM NUMBER OF SHIPS (1-9) ? ',6,2,239
LSRMSG: DB 3,100,32,15,4BH,96,239 ;BLINKING MARKER
FINMSG: DB 6,45H,14,3,24,15,'G A M E O V E R',15
DB 6,3,3,28,27,'PLAY AGAIN ? ',239
ERASE: DB 15,29,6,2,12,3,64,0,239 ;ERASE SCREEN
FLASH: DB 30 ;FILL SCREEN WITH COLOR
COLOR: DB 18
DB 12,239
FCSSP: DS 2 ;SAVE FCS STACK POINTER
DS 100
STACK: DS 2 ;PROGRAM STACK
END LASER