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