home *** CD-ROM | disk | FTP | other *** search
- ; THE GAME OF DEFLECTION BY ANDREW A. RECUPERO
- ; FROM KILOBAUD FEB '78 #14
- ;
- ; TO START TYPE 0,1,2,3
- ; 0=1 TARGET, CLEAR FIELD
- ; 1=1 TARGET, SHIFT DEFLECTORS
- ; 2=3 TARGETS, CLEAR FIELD
- ; 3=3 TARGETS, SHIFT DEFLECTORS
- ;
- ; THE OBJECT OF THE GAME IS TO HIT TARGET(S) BY
- ; DEFLECTING THE RUNNER INTO THE TARGET.
- ;
- ; DEFLECT TARGET BY TYPING A "/" OR A "\".
- ;
- ; ALL TARGETS MUST BE HIT WITHIN A FIXED TIME.
- ;
- ;SYSTEM EQUATES:
- ;
- ORG 100H
- STATUS EQU 00 ;KEYBOARD STATUS PORT
- STROBE EQU 80H ;KEYBOARD STROBE BIT
- DATA EQU 1 ;KEYBOARD DATA PORT
- VDMRAM EQU 0CC00H ;VDM STARTING ADDR.
- VDMPAGE EQU 0CCH ;VDM RAM PAGE
- VDMPORT EQU 0C8H ;VDM PORT
- TARGET EQU 05 ;TARGET SYMBOL
- RUNNER EQU 07 ;RUNNER SYMBOL
- USLSH EQU 2FH ;UP SLASH SYMBOL "/"
- DSLSH EQU 5CH ;DOWN SLASH SYMBOL "\"
- LEFT EQU 80H ;RUNNER
- DOWN EQU 40H ; DIRECTION
- UP EQU 20H ; CONTROL
- RIGHT EQU 10H ; EQUATES
- ;
- ;
- ; PROGRAM START
- ;
- GSTART LXI SP,STACK+8 ;INITIALIZE STACK
- CALL CLSCRN ;CLEAR SCREEN
- REIDLE CALL DRUNER ;DISPLAY RUNNER
- IDLE CALL ACTION ;MOVE RUNNER
- CALL DELAY ;TIME DELAY AND CHECK INPUT
- MOV A,C ;KEYBOARD INPUT TO ACC.
- ORA A ;TEST FOR NON-ZERO
- JZ IDLE
- MVI M,20H ;REMOVE RUNNER
- RRC ;SHIFT DEFLECTORS?
- PUSH PSW ;SAVE GAME OPTION IN 'A' REG
- JC SHIFT ;JUMP TO SHIFT IF YES
- CALL CLSCRN ;DO NOT SHIFT, CLEAR SCREEN
- JMP INIT
- SHIFT LXI B,VDMRAM ;SHIFT
- MOV D,B ; SCREEN
- MOV E,C ; ONE
- INX D ; POSITION
- SMOR LDAX D ; TO
- STAX B ; THE
- INX B ; LEFT
- INX D
- MOV A,D
- CPI VDMPAGE+4
- JNZ SMOR ;GO SHIFT MORE IF NOT DONE
- INIT POP PSW ;RESTORE GAME OPTION TO 'A' REG
- MVI C,1 ;SET FOR ONE TARGET
- RRC ;GAME OPTION BIT 0 TO CARRY FLG
- MVI A,TARGET ;TARGET SYMBOL TO 'A' REG
- JNC GAM1 ;JUMP FOR 1 TARGET OPTION
- MVI C,3 ;INITIALIZE FOR 3 TARGETS
- STA VDMRAM+34CH ;PUT TARGET LEFT OF CENTER
- STA VDMRAM+2F4H ;TARGET TO THE RIGHT
- GAM1 STA VDMRAM+320H ;TARGET IN THE MIDDLE
- MOV A,C
- STA TARNUM ;STORE # OF TARGETS
- LXI H,1C0H ;INITIALIZE GAME TIMER
- SHLD TIMER ;SAVE TIMER VALUE
- CALL DRUNER ;START GAME, DISPLAY RUNNER
- ;
- ;
- ; THIS IS THE MAIN LOOP FOR THE GAME
- ;
- MAINLP CALL DELAY ;WAIT & CHECK KEYBOARD
- CALL ACTION
- PUSH H ;SAVE HL
- LHLD TIMER ;GET GAME TIMER
- DCX H ;DECREMENT TIMER
- MOV A,H ;CHECK IF GAME
- ORA L ; TIMER EXPIRED
- SHLD TIMER ;STORE UPDATED TIMER
- POP H ;RESTORE HL
- JNZ MAINLP ;JMP IF TIMER DIDN'T EXPIRE
- LXI B,LOSE ;DISPLAY NO
- CALL SHOW ; TIME MESSAGE
- CALL WAER ;WAIT & ERASE MESSAGE
- JMP GSTART ;TIMER EXPIRED, RESTART GAME
- ;
- ;
- ; INITIALIZE AND DISPLAY RUNNER
- ; 'B' HOLDS MOTION DIRECTION AS:
- ; REG BIT 7 6 5 4
- ; | | | |
- ; | | | RIGHT
- ; | | UP
- ; | DOWN
- ; LEFT
- ;
- DRUNER LXI H,VDMRAM+40H ;RUNNER STARTING POS.
- LXI D,100H ;X,Y RUNNER POS. D=VERT E=HORZ
- MVI M,RUNNER ;DISPLAY RUNNER
- MVI B,RIGHT ;INITIALIZE RIGHT MOTION
- RET
- ;
- ;
- ; ALL RUNNER MOVEMENT DONE HERE
- ;
- ACTION MOV A,M ;CHECK IF
- CPI RUNNER ; RUNNER
- JNZ DF010 ; DISPLAYED
- MVI M,20H ;REMOVE RUNNER FROM FIELD
- ;
- ; CALCULATE NEW RUNNER POSITION
- ;
- DF010 MOV A,B
- CPI RIGHT ;IS MOTION TO RIGHT?
- JNZ DF012 ;JUMP IF NO
- INR E ;MOVE 1 POS TO THE RIGHT
- DF012 CPI UP ;IS MOTION UP?
- JNZ DF014 ;JUMP IF NO
- DCR D ;MOVE 1 POS UP
- DF014 CPI DOWN ;IS MOTION DOWN?
- JNZ DF016 ;JUMP IF NO
- INR D ;MOVE 1 POS DOWN
- DF016 CPI LEFT ;IS MOTION TO THE LEFT?
- JNZ DF018 ;JUMP IF NO
- DCR E ;MOVE 1 POS TO LEFT
- ;
- ; CALCULATE FIELD POSITION FROM HORZ AND VERT VALUES
- ; IN DE WITH RESULT IN HL
- ;
- DF018 MOV A,D
- RRC
- RRC
- MOV L,A
- ANI 03
- ORI VDMPAGE
- MOV H,A ;SAVE HIGH PART OF ADDR.
- MOV A,L
- ANI 0C0H
- ADD E
- MOV L,A ;SAVE LOW PART OF ADDR.
- MOV A,M ;CHECK NEXT FIELD POSITION
- CPI TARGET ;IS IT A TARGET?
- JNZ DF019 ;JUMP IF DIDN'T HIT TARGET
- ;
- ; HIT A TARGET
- ;
- MVI M,20H ;REMOVE TARGET
- LDA TARNUM ;GET # OF TARGETS LEFT
- DCR A ;REDUCE BY ONE
- STA TARNUM ;STORE UPDATED TARGET NUMBER
- RNZ ;RETURN IF MORE TARGETS
- POP D ;ALL TARGETS GONE, FIX STACK
- LXI B,WIN ;DISPLAY
- CALL SHOW ; WIN MESSAGE
- CALL WAER ;WAIT & ERASE MESSAGE
- JMP REIDLE ;GO TO IDLE LOOP
- ;
- DF019 MOV A,C ;PUT KEYBOARD DATA IN 'A' REG
- CPI USLSH ;IS IT AN UPSLASH "/" ?
- JZ DF020 ;JUMP IF YES
- CPI DSLSH ;IS IT A DOWNSLASH "\" ?
- JZ DF020 ;JUMP TO ANALYZE DEFLECTOR
- ;
- ; CHECK FOR RUNNER HITTING A DEFLECTOR
- ;
- DELCK MOV A,M
- CPI 20H ;IS NEXT POSITION A SPACE?
- JNZ CHGMOT ;DEFLECTOR IF NO, CHNGE DIR
- CALL EDGCK ;REVERSE MOTION IF AT EDGE
- MVI M,RUNNER ;DISPLAY RUNNER AT NEW LOCATION
- RET
- DF020 MOV M,A ;INPUT WAS VALID, DISPLAY IT
- ;
- ; CHANGE DIRECTION OF RUNNER MOTION
- ;
- CHGMOT CPI DSLSH ;IS IT A DOWNSLASH?
- MOV A,B ;DIRECTION FLAG TO 'A' REG
- JNZ UPSLH ;JUMP IF NOT DOWN SLASH
- ANI 0C0H ;IS MOTION LEFT OR DOWN?
- MOV A,B ;RESTORE DIRECTION FLAG TO 'A'
- JZ DF030 ;JUMP IF NOT LEFT OR DOWN
- RRC ;CHANGE DIRECTION TO
- RRC ; RIGHT OR UP
- JMP DF050
- DF030 RLC ;CHANGE DIRECTION TO
- RLC ; LEFT OR DOWN
- JMP DF050
- UPSLH ANI 0A0H ;IS MOTION TO LEFT OR UP?
- MOV A,B ;DIRECTION FLAG TO 'A' REG
- JZ DF040 ;JUMP IF NOT LEFT OR UP
- RRC ;CHANGE DIR TO RIGHT OR DOWN
- JMP DF050
- DF040 RLC ;CHANGE MOTION TO RIGHT OR DOWN
- DF050 MOV B,A ;SAVE NEW DIRECTION
- CALL EDGCK ;IS RUNNER AT EDGE OF FIELD?
- MOV A,M ;GET DEFLECTOR IN CASE AT EDGE
- JZ CHGMOT ;IF AT EDGE, CHANGE DIRECTION
- RET
- ;
- ; THIS ROUTINE CHECKS FOR EDGE OF FIELD, REVERSES MOTION,
- ; SETS ZERO FLAG IF AT EDGE
- ;
- EDGCK MOV A,B ;LOAD MOTION DETECTOR
- CPI RIGHT ;TO RIGHT?
- JNZ DF060 ;JUMP IF NO
- MVI A,3FH ;3FH=RIGHT EDGE
- CMP E
- RNZ ;RETURN IF NOT AT RIGHT EDGE
- MVI B,LEFT ;REVERSE DIRECTION TO LEFT
- RET
- DF060 CPI UP ;CHECK FOR UP MOTION
- JNZ DF070 ;JUMP IF MOTION NOT UP
- XRA A
- ORA D ;CHECK FOR TOP VERT=0
- RNZ ;RETURN IF NOT AT TOP
- MVI B,DOWN ;REVERSE DIRECTION TO DOWN
- RET
- DF070 CPI DOWN ;CHECK FOR DOWN MOTION
- JNZ DF080 ;JUMP IF MOTION NOT DOWN
- MVI A,0FH ;CHECK FOR BOTTOM VERT=0FH
- CMP D
- RNZ ;RETURN IF NOT AT BOTTOM
- MVI B,UP ;REVERSE DIRECTION TO UP
- RET
- DF080 XRA A ;MUST BE MOTION TO LEFT
- ORA E ;CHECK FOR LEFT EDGE HORZ=0
- RNZ ;RETURN IF NOT AT LEFT EDGE
- MVI B,RIGHT ;REVERSE DIRECTION TO RIGHT
- RET
- ;
- ; THIS ROUTINE PERFORMES TIME DELAY WHILE CONTINUOUSLY
- ; CHECKING FOR KEYBOARD INPUT. INPUT RETURN IN 'C'
- ;
- DELAY MVI C,0 ;INITIALIZE INPUT SAVE REG
- PUSH D ;FREE UP DE REG
- LXI D,700H ;LOAD DELAY VALUE
- DL01 DCX D ;DECREMENT DELAY COUNTER
- IN STATUS ;GET KEYBOARD STATUS
- ANI STROBE ;CHECK STROBE
- JNZ DL02 ;JUMP IF NO INPUT
- IN DATA ;GET KEYBOARD DATA
- ANI 7FH ;REMOVE BIT 7
- MOV C,A ;SAVE INPUT IN 'C' REG
- DL02 MOV A,D ;CHECK FOR
- ORA E ; TIMER=0
- JNZ DL01
- POP D ;DELAY OVER, RESTORE DE REG
- RET
- ;
- ; THIS ROUTINE INITIALIZES THE VDM PORT & CLEARS SCREEN
- ;
- CLSCRN XRA A ;CLEAR VDM PORT
- OUT VDMPORT ;OUTPUT IT
- LXI H,VDMRAM ;POINT TO START OF VDM RAM
- MVI A,VDMPAGE+4 ;'A' REG=END OF VDM RAM
- CL01 MVI M,20H ;BLANK LOC GIVEN BY HL
- INX H
- CMP H ;DONE?
- JNZ CL01 ;JUMP IF NOT
- RET
- ;
- ; THIS ROUTINE DISPLAYS MESSAGE POINTED TO BY BC REG
- ;
- SHOW LXI D,VDMRAM+31DH ;POINT TO DISPLAY LOCATION
- MVI H,7 ;MESSAGE LENGTH=7
- SH01 LDAX B ;GET BYTE OF MESSAGE
- STAX D ;DISPLAY IT
- INX D ;BUMP TO
- INX B ; NEXT BYTE
- DCR H ;DECREMENT COUNT
- JNZ SH01 ;DONE?
- RET
- ;
- ; THIS ROUTINE WAITS AWHILE AND THEN REMOVES MESSAGE
- ;
- WAER MVI D,32 ;LOAD UNITS OF DELAY
- WDLY CALL DELAY ;WAIT ONE UNIT OF DELAY
- DCR D ;CHECK IF
- JNZ WDLY ; DONE WAITING
- LXI B,BLNK ;POINT TO ALL BLANKS
- JMP SHOW ;DISPLAY BLANKS TO ERASE & RET
- ;
- ; MESSAGES
- ;
- WIN DB 'WINNER '
- LOSE DB 'NO TIME'
- BLNK DB ' '
- ;
- ; SAVE AREAS AND STACK
- ;
- TIMER DS 2 ;TIMER SAVE AREA
- TARNUM DS 1 ;NUMBER OF TARGETS
- STACK DS 8 ;STACK AREA (ONLY 4 DEEP)
-