ANTIC #8.03 / JULY 1989 / PAGE 17
Battle it out for construction space, in this month’s Super Disk Bonus. Exwall is a hard-hitting futuristic two player tank game written in assembly language. The program works on 8-bit computers with at least 48K memory, disk drive and two joysticks.
Exwall was written in fast-moving machine language by Andy Barton, who has been contributing to Antic since 1984. His programs include Spelling Flashcards (February 1989) and the ever-popular TYPO II. His Machine Language Stringer appears elsewhere in this issue.
Across eight battle zones, the robot war continues without end. Powerful robots battle it out for building space, over a terrain marked with stone fortress walls and blue rivers and lakes. Massive mobile factories, the robots move about, building and repairing the fortress walls, even as they try to destroy each other.
Your robot carries a cannon that fires explosive shells—but so does your opponent’s. In this high-tech slugfest, you must destroy your opponent’s fortresses and robot factory without being destroyed yourself. Your ranking reflects your success.
Don’t try to run Exwall directly from the Antic Monthly Disk. Instead, copy EXWALL.EXE to another disk that includes the DOS.SYS file. Use DOS command E to rename EXWALL.EXE to AUTORUN.SYS. Turn off your computer and remove all cartridges. Place the disk in Drive 1. Hold down the [OPTION] key if you’re using an XL or XE. Turn on the computer, and Exwall will load and run automatically.
Plug in two joysticks, one for each player. Use your joystick to move your robot factory up and down, forward, backward and diagonally. You can’t move through walls, over water, or into the farthest quarter of your opponent’s territory.
To build a wall, move the robot factory to the desired place. Then move back 1 or 2 spaces and stop. A two-layer wall will be built in front of the machine. Construction will stop when the area in front of the machine and within the crane’s reach is completed—or when you move the factory.
Press the joystick button once to fire your cannon. Press it a second time to explode the shell. Press and release the fire button quickly, or the shell will explode before you want it to. You can use unexploded shells to knock narrow channels in your own defenses, and then fire through the channels as you hide in the relative safety of your fortress.
You can’t move over water but you can build walls at the water’s edge. When these walls are destroyed the debris will fill in the water and allow you to move on.
A shell exploding next to a wall will penetrate deeply but not widely. Conversely, if the shell explodes before it reaches a wall it will destroy a wider area but with less penetration.
Crashing your robot into your opponent’s will destroy both machines—and possibly get you out of a tight situation. But it won’t help your ranking. On the other hand, daring players can significantly enhance their scores by moving in close and firing repeatedly into their opponent’s exploding robot.
Your July 1989 Antic Disk—featuring the Exwall Super Bonus game as well as every type-in program from this issue—will be shipped to you within 24 hours after receiving your order Just phone Toil-Free to the Antic Disk Desk at (800) 234-7001. The monthly disk is only 85-95 (plus $2 for shipping and handling) on your Visa or MasterCard. Or mail a 5595 check (plus $2 shipping and handling) to Antic Disk Desk, 544 Second Street, San Francisco, CA 94107.
;EXWALL ;BY JEFF & ANDY BARTON ;(c)1989, ANTIC PUBLISHING INC. LIST = 1 .OPT NOLIST .IF LIST .OPT LIST .ENDIF .OPT NOMLIST *= $7800 START.OF.CODE JMP INIT.1 ;START PROGRAM ; ;VARIABLES AND EQUATES ; RTCLOK = $12 ;HI-MID-LOW BYTE DELAY .BYTE $01 PMBASE = $D407 BASE = $7000 ;2K BOUNDARY BASEM = $7300 BASEP0 = $7400 BASEP1 = $7500 ; HPOSP0 = $D000 HPOSP1 = $D001 HPOSM0 = $D004 HPOSM1 = $D005 COLPM0 = $02C0 ;+1,2,3 COLPF0 = $02C4 ;+1,2,3,4 FLASHWALL = COLPF0+1 COLOR = $CD SVCOLOR = $02FB ; ;COLLISION REGISTERS M0PF = $D000 M1PF = $D001 P0PF = $D004 P1PF = $D005 M0PL = $D008 M1PL = $D009 P0PL = $D00C HITCLR = $D01E ; AUDF = $D200 AUDC = $D201 ; IOCB = $0340 CIOV = $E456 IOCOM .BYTE 0 PUTCHR = $0B GETCHR = $07 GRACTL = $D01D DMACTL = $022F ; TRIG0 = $0284 TRIG1 = $0285 STICK0 = $0278 STICK1 = $0279 ; VPOSP0 .BYTE 0 PREVPOSP0 .BYTE 0 SHDHPOSP0 .BYTE 0 PREHPOSP0 .BYTE 0 VPOSP1 .BYTE 0 PREVPOSP1 .BYTE 0 SHDHPOSP1 .BYTE 0 PREHPOSP1 .BYTE 0 VPOSM0 .BYTE 0 SHDHPOSM0 .BYTE 0 VPOSM1 .BYTE 0 SHDHPOSM1 .BYTE 0 WALLX0 .BYTE 0 WALLY0 .BYTE 0 WALLX1 .BYTE 0 WALLY1 .BYTE 0 HORDIR0 .BYTE 0 ;HOR. DIRECTION HORDIR1 .BYTE 0 ;VALUES 1,0,-1 VERDIR0 .BYTE 0 ; 1,0,-1 VERDIR1 .BYTE 0 ; 1,0,-1 ; EX0 .BYTE 0 ;COUNT EXPLOSION EX1 .BYTE 0 ;SIZE SKM0 .BYTE 0 ;USED IN MISSLE EXPANSION SKM1 .BYTE 0 ;USED IN MISSLE EXPANSION EXP = 2 ;PENETRATION ; HITP0 .BYTE 0 ;<>0=HIT,COUNT HITP1 .BYTE 0 ;CHANGE COLOR & INHIBIT JSTICK ; FIRE0 .BYTE 0 ;1=ON 2=EXPLODE FIRE1 .BYTE 0 ; BUILD0 .BYTE 0 ;<>1=NO 1=OK TO BUILD1 .BYTE 0 ;BUILD BUILDCOUNT0 .BYTE 0 ;<>0 ENABLES BUILDCOUNT1 .BYTE 0 ;1-5 BLOCKS SECONDLAYER0 .BYTE 0 ;0=LAYER 1 SECONDLAYER1 .BYTE 0 ;1=LAYER 2 ; MONLYMOVE .BYTE 3 ;0-3 START @ 3 ; TOPLIM .BYTE $20 ROUND .BYTE 0 BOTLIM .BYTE $B7 LLIMIT .BYTE $30 LLIMP1 .BYTE $50 RLIMP0 .BYTE $A8 RLIMM0 .BYTE $CF RLIMIT .BYTE $C8 EXLIM0 .BYTE $12 EXLIM1 .BYTE $12 ; TEMP .BYTE 0 TEMP2 .BYTE 0 TEMP3 .BYTE 0 TEMP4 .BYTE 0 TEMP5 .BYTE 0 ZTEMP = $CE ; SCORE0 .BYTE 0 SCORE1 .BYTE 0 ; VOL0 .BYTE 0 VOL1 .BYTE 0 WAIT0 .BYTE 0 WAIT1 .BYTE 0 WAITLIM = $03 ; TXROW = $0290 TXCOL = $0291 STRBUF = BASE ; FR0 = $D4 ;FLOAT POINT NUM FASC = $D8E6 ;F.P. TO ASCII STRING IFP = $D9AA ;INTEGER TO F.P. INBUF = $F3 ;POINT TO STRING ; .OPT NOLIST ; ; MACROS ; .MACRO CLEAR.PAGE ;%1 - START ADDRESS ;%2 - # OF PAGES LDA #%1/256 STA ZTEMP+1 LDA #0 STA ZTEMP LDX #%2 JSR CPSUB .ENDM ; .MACRO PLOT LDX %1 LDY %2 LDA #PUTCHR STA IOCOM JSR IOSUB .ENDM ; .MACRO DRAWTO LDX %1 LDY %2 JSR DRAWSUB .ENDM ; .MACRO COLOR .IF %1<256 LDA #%1 .ELSE LDA %1 .ENDIF STA COLOR .ENDM ; .MACRO HIT.WALL ;%1 - (0-1) PLAYER# COLOR 0 ;SET TO BKGRND TO ERASE WALL .IF %1=0 SET.X.Y.MISSLE 0 STX TEMP3 STY TEMP4 JSR HIT.SUB LDA EX0 BEQ HW.1 ; LDA #$08 CMP EX0 ;LIMIT EX BCC HW.1 ; STA EXLIM0 ;SHORTEN EX BCS HW.1.1 ; HW.1 JSR M0.OFF HW.1.1 .ELSE SET.X.Y.MISSLE 1 STX TEMP3 STY TEMP4 JSR HIT.SUB LDA EX1 BEQ HW.1 ; LDA #$08 CMP EX1 ;LIMIT EX BCC HW.1 ; STA EXLIM1 ;SHORTEN EX BCS HW.1.1 ; HW.1 JSR M1.OFF HW.1.1 .ENDIF .ENDM ; .MACRO CLEAR.MISSLE ;%1 - VPOSM(0-1) ;%2 - MISSLE DATA ;%3 - EX(0-1) LDA #%2 STA TEMP2 LDA %3 STA TEMP ;LOOP COUNT CLC ADC %1 JSR CLR.M.SUB .ENDM ; .MACRO FLASH ;%1 - COLP(0-1) CLC LDA %1 JSR FLASH.SUB STA %1 .ENDM ; .MACRO MOVE.PLAYER ;%1 - (0-1) [PLAYER #] ;%2 - HORDIRP(0-1) ;%3 - VERDIRP(0-1) ;%4 - IF USED, TOGGLES LIMIT CHECK LDA %2 BEQ MP.VERT ; .IF %1=0 BPL MP1 ; RIGHT ; LDX SHDHPOSP0 .IF %0>3 CPX LLIMIT BEQ MP.VERT ; .ENDIF STX PREHPOSP0 DEC SHDHPOSP0 ; MOVE LEFT LDA SHDHPOSP0 STA HPOSP0 JMP MP.VERT MP1 LDX SHDHPOSP0 .IF %0>3 CPX RLIMP0 BEQ MP.VERT ; .ENDIF STX PREHPOSP0 INC SHDHPOSP0 ; MOVE RIGHT LDA SHDHPOSP0 STA HPOSP0 .ELSE BPL MP2 ; RIGHT ; LDX SHDHPOSP1 .IF %0>3 CPX LLIMP1 BEQ MP.VERT ; .ENDIF STX PREHPOSP1 DEC SHDHPOSP1 ; MOVE LEFT LDA SHDHPOSP1 STA HPOSP1 JMP MP.VERT MP2 LDX SHDHPOSP1 .IF %0>3 CPX RLIMIT BEQ MP.VERT ; .ENDIF STX PREHPOSP1 INC SHDHPOSP1 ; MOVE RIGHT LDA SHDHPOSP1 STA HPOSP1 .ENDIF MP.VERT LDA %3 BNE MP.VERT.1 ; JMP MP.END ; MP.VERT.1 .IF %1=0 BPL MP.UP ; LDY VPOSP0 .IF %0>3 CPY BOTLIM BEQ MP.END ; .ENDIF STY PREVPOSP0 INC VPOSP0 ; DOWN JMP MP3 ; MP.UP LDY VPOSP0 .IF %0>3 CPY TOPLIM BEQ MP.END ; .ENDIF STY PREVPOSP0 DEC VPOSP0 ; UP MP3 JSR VERT.DRAW.P0 ; .ELSE BPL MP1.UP ; LDY VPOSP1 .IF %0>3 CPY BOTLIM BEQ MP.END ; .ENDIF STY PREVPOSP1 INC VPOSP1 ; DOWN JMP MP4 ; MP1.UP LDY VPOSP1 .IF %0>3 CPY TOPLIM BEQ MP.END ; .ENDIF STY PREVPOSP1 DEC VPOSP1 ; UP MP4 JSR VERT.DRAW.P1 .ENDIF MP.END .ENDM ; .MACRO SET.X.Y.WALL ; CONVERT P/M COORDINATES -> SCREEN X,Y ;& PUT VALUES IN X & Y REGISTERS ;%1 - (0-1) PLAYER'S # ; LDX #0 .IF %1=0 LDA DATAP0,X ;HEIGHT OF PLAYER LSR A ;DIVIDE BY 2 CLC ADC VPOSP0 ;MIDDLE OF PLAYER STA TEMP LDA SHDHPOSP0 CLC ADC #12 ;2 SPACE INFRONT JSR SETXY.SUB .ELSE LDA DATAP1,X ;PLAYER HEIGHT LSR A ;DIVIDE BY 2 CLC ADC VPOSP1 ;MID OF PLAYER STA TEMP LDA SHDHPOSP1 SEC SBC #5 ;2 SPACE INFRONT JSR SETXY.SUB .ENDIF .ENDM ; .MACRO SET.X.Y.MISSLE ; CONVERT P/M COORDINATES -> SCREEN X,Y ;& PUT VALUES IN X & Y REGISTERS ;%1 - (0-1) MISSILE'S # ; .IF %1=0 LDA VPOSM0 TAX SEC SBC EX0 ;NO EFFECT IF =0 STA TEMP TXA CLC ADC EX0 JSR SETXY.SUB.1 STY TEMP2 INC SHDHPOSM0 LDA SHDHPOSM0 DEC SHDHPOSM0 JSR SETXY.SUB .ELSE LDA VPOSM1 TAX SEC SBC EX1 STA TEMP TXA CLC ADC EX1 JSR SETXY.SUB.1 STY TEMP2 LDA SHDHPOSM1 JSR SETXY.SUB .ENDIF .ENDM ; .MACRO ?WALL ;IS THERE A WALL HERE? ;%1 - WALLX(0-1) ;%2 - WALLY(0-1) ;%3 - JUMP LABLE ;%4 - PLAYER # LDX %1 LDY %2 LDA #GETCHR STA IOCOM JSR IOSUB CMP #1 ;WALL COLOR .IF %4=0 BNE WL.0 ; JMP %3 WL.0 JSR B0.SUB2 .ELSE BNE WL.1 ; JMP %3 WL.1 JSR B1.SUB2 .ENDIF .ENDM ; .MACRO EXPAND.MISSILE ;%1 - (0-1) MISSILE # .IF %1=0 LDA EX0 STA TEMP2 LSR A BCS EM0.0 ; LDA VPOSM0 STA TEMP LDA #1 STA TEMP4 ASL A STA TEMP3 JSR EX.M.SUB INC EX0 INC EX0 EM0.0 INC EX0 .ELSE LDA EX1 STA TEMP2 LSR A BCS EM1.0 ; LDA VPOSM1 STA TEMP LDA #4 STA TEMP3 ASL A STA TEMP4 JSR EX.M.SUB INC EX1 INC EX1 EM1.0 INC EX1 .ENDIF .ENDM ; .MACRO CENTER.M ;%1 - MISSILE #(0-1) LDX #0 .IF %1=0 LDA DATAP0,X LSR A ;/2 CLC ADC VPOSP0 STA VPOSM0 .ELSE LDA DATAP1,X LSR A CLC ADC VPOSP1 STA VPOSM1 .ENDIF TAY .ENDM ; .MACRO CHECK.STICK ;%1 - (0-1) PLAYER # JSR CHECK.STICK.SUB .IF %1=0 BCC CS.5A ; LDY #-1 STY TEMP2 ; LEFT INC TEMP3 CS.5A ROR A BCC CS.6 ; LDY #1 STY TEMP2 ; RIGHT STX TEMP3 .ELSE BCC CS.5B ; LDY #-1 STY TEMP2 ; LEFT STX TEMP3 CS.5B ROR A BCC CS.6 ; LDY #1 STY TEMP2 ; RIGHT INC TEMP3 .ENDIF CS.6 .ENDM ; .MACRO SOUND ;%1 %2 %3 %4 SAME AS BASIC JSR SOUND.SUB LDX #%1*2 .IF %2>255 LDA %2 .ELSE LDA #%2 .ENDIF STA AUDF,X .IF %4>255 LDA %4 .ELSE LDA #%4 .ENDIF CLC ADC #%3*16 STA AUDC,X .ENDM ; .MACRO POS ;%1,%2 = X,Y POS. TEXT WINDOW LDA #%1 STA TXCOL LDA #%2 STA TXROW .ENDM ; .MACRO PRINT ;%1 = STRING TO PRINT JMP *+%1+3 ; STR .BYTE %$1 LDA #<STR STA ZTEMP LDA #>STR STA ZTEMP+1 LDY #%1 ; STRING LENGTH JSR PRINT.SUB .ENDM ; .MACRO PRINT.NUM ;%1 = VARIABLE ;SET POS FIRST LDA %1 STA FR0 LDA #0 STA FR0+1 JSR PRINT.NUM.SUB .ENDM ; ; ;INITIALIZE ; INIT.1 LDA #ROUND1&$FF STA RDOFFSET LDA #ROUND1/256 STA RDOFFSET+1 ; ;INITIALIZE ROUNDS ; INIT.ROUND ; ;CLOSE #6 LDX #$60 LDA #$0C ;CLOSE STA IOCB+2,X JSR CIOV ;GR. 5 LDX #$60 LDA #5 ;GR.5 STA IOCB+$0B,X LDA #$1C STA IOCB+$0A,X LDA #SCREEN&$FF STA IOCB+4,X LDA #SCREEN/256 STA IOCB+5,X LDA #2 STA IOCB+8,X LDA #0 STA IOCB+9,X LDA #3 ;OPEN STA IOCB+2,X JSR CIOV ; ;SET P/M BASES ; LDA #BASE/256 STA PMBASE LDA #3 STA GRACTL LDA #62 STA DMACTL ; STA $02F0 ;CURSOR OFF LDA #0 STA 82 ;RH TEXT MARGIN ; ;PRINT TITLES ; POS 15,0 PRINT ".........." POS 1,1 PRINT "............... EXWALL ............... . PLAYER 1 ZONE PLAYER 2 . ." POS 14,3 PRINT "<..- RANK -..> ." ; ;SOUNDS OFF LDX #7 LDA #0 SF STA AUDF,X DEX BPL SF ; ;CLEAR P/M AREA ; CLEAR.PAGE BASEM,3 ; ;CLEAR HIT REGISTERS ; STA HITCLR ; ;DRAW SCREEN ; INC ROUND ; R1.0 LDY #0 ; JSR RDOFFSET.TO.ZTEMP COLOR 3 ;WATER JSR DRAW.SUB ; JSR INC.ZTEMP COLOR 1 ;WALLS JSR DRAW.SUB ; JSR INC.ZTEMP LDA (ZTEMP),Y STA SHDHPOSP0 STA HPOSP0 JSR INC.ZTEMP LDA (ZTEMP),Y STA SHDHPOSP1 STA HPOSP1 JSR INC.ZTEMP LDA (ZTEMP),Y STA VPOSP0 JSR INC.ZTEMP LDA (ZTEMP),Y STA VPOSP1 JSR INC.ZTEMP ;POINT TO NEXT ROUND JSR ZTEMP.TO.RDOFFSET ; ;LOAD PLAYER DATA ; LDA #200 ;GREEN STA COLPM0 LDA #88 ;PURPLE STA COLPM0+1 JSR VERT.DRAW.P0 JSR VERT.DRAW.P1 ; POS 22,2 PRINT.NUM ROUND POS 7,3 PRINT.NUM SCORE0 POS 31,3 PRINT.NUM SCORE1 ; ; MAIN PROGRAM LOOP ; ;TIMER ROUTINE ; TIME.DELAY LDA RTCLOK+2 ;JIFFS CMP DELAY BCC TIME.DELAY ;LOOP UNTIL TIME UP LDA #0 STA RTCLOK+2 ;RESET CLOCK DEC MONLYMOVE ;MISSILE MOVES BPL HIT? ;4X FOR EACH ; LDA #5 ;PLAYER MOVE STA MONLYMOVE ;=0 PLAYER CAN MOVE HIT? LDA P0PF ;PLAYER -> WALL BEQ H1.1 ; LDA HORDIR0 BEQ H0.1 ; EOR #$FE ;REVERSE DIRECTION STA HORDIR0 H0.1 LDA VERDIR0 BEQ H0.2 ; EOR #$FE STA VERDIR0 H0.2 MOVE.PLAYER 0,HORDIR0,VERDIR0 LDA #0 STA HORDIR0 STA VERDIR0 H1.1 LDA P1PF ;PLAYER -> WALL BEQ H2.1 ; LDA HORDIR1 BEQ H1.2 ; EOR #$FE ;REVERSE DIRECTION STA HORDIR1 H1.2 LDA VERDIR1 BEQ H1.3 ; EOR #$FE STA VERDIR1 H1.3 MOVE.PLAYER 1,HORDIR1,VERDIR1 LDA #0 STA HORDIR1 STA VERDIR1 H2.1 LDA M0PF ;MISSLE -> WALL AND #3 ; IGNORE WATER BEQ H2.2 SOUND 2,40,0,14 HIT.WALL 0,SHDHPOSM0,VPOSM0 H2.2 LDA M1PF ;MISSLE -> WALL AND #3 ; IGNORE WATER BEQ H3.1 ; SOUND 3,40,0,14 HIT.WALL 1,SHDHPOSM1,VPOSM1 H3.1 LDA M0PL MISSLE -> PLAYER AND #2 BEQ H4.1 ; ;PLAYER EXPLODING ROUTINE INC SCORE0 JSR M0.OFF JSR STOP.BUILD1.1 INC HITP1 ; H4.1 LDA M1PL ;MISSLE -> PLAYER AND #1 BEQ H4.2 ; INC SCORE1 JSR M1.OFF JSR STOP.BUILD0.1 INC HITP0 ; H4.2 LDA P0PL ;PLAYER <--> PLAYER BEQ H5.1 ; JSR STOP.BUILD0.1 JSR STOP.BUILD1.1 INC HITP0 INC HITP1 ; H5.1 LDA HITP0 BEQ H6.1 ; FLASH COLPM0 INC HITP0 LDA HITP0 LSR A AND #15 EOR #15 STA TEMP SOUND 0,65,0,TEMP LDA #95 ; LIMIT OF FLASHING CMP HITP0 BCS H6.1 ; >= HITP0 LDA #0 STA HITP0 CLEAR.PAGE BASEP0,1 LDA HITP1 BNE H6.1 ;P1 EXPLODING JSR M1.OFF JSR STOP.BUILD1.1 JMP END.OF.ROUND H6.1 LDA HITP1 BEQ CLEAR.HIT FLASH COLPM0+1 INC HITP1 LDA HITP1 LSR A AND #15 EOR #15 STA TEMP SOUND 1,60,0,TEMP LDA #95 ; LIMIT OF FLASHING CMP HITP1 BCS CLEAR.HIT ; >= HITP1 LDA #0 STA HITP1 CLEAR.PAGE BASEP1,1 LDA HITP0 BNE CLEAR.HIT ; P0 EXPLODING JSR M0.OFF JSR STOP.BUILD0.1 JMP END.OF.ROUND ; CLEAR.HIT STA HITCLR ; ; ;^^^^^ CHECK BUTTONA ^^^^^ ; BUTTON1.1 LDA WAIT0 BEQ BT1.1 DEC WAIT0 JMP BT2.1 BT1.1 LDA HITP0 BNE BT2.1 ;CAN'T FIRE WHEN HIT LDA EX0 BNE BT2.1 LDA TRIG0 BNE BT2.1 ; NOT PRESSED LDA #WAITLIM STA WAIT0 LDA FIRE0 BNE BT1.2 INC FIRE0 LDA #6 STA VOL0 JMP BT2.1 BT1.2 LDA #EXP STA SKM0 ;PENETRATION OF EXPLO INC EX0 ;SET MISSLE EXPLOTION LDA #10 STA VOL0 BT2.1 LDA WAIT1 BEQ BT2.1.1 DEC WAIT1 JMP M0.0 BT2.1.1 LDA HITP1 BNE M0.0 ;CAN'T FIRE WHEN HIT LDA EX1 BNE M0.0 LDA TRIG1 BNE M0.0 ; NOT PRESSED LDA #WAITLIM STA WAIT1 LDA FIRE1 BNE BT2.2 INC FIRE1 LDA #6 STA VOL1 JMP M0.0 ; BT2.2 LDA #EXP STA SKM1 ;PREPAR OF EXPLOSO INC EX1 ;SET MISSLE EXPLOTION LDA #10 STA VOL1 ; MOVE MISSILE ROUTINE M0.0 LDA FIRE0 BNE M0.01 ; JMP M1.0 ; M0.01 CMP #1 BNE M0.1 ; LDA SHDHPOSP0 CLC ADC #7 STA SHDHPOSM0 CENTER.M 0 LDA #3 ORA BASEM,Y STA BASEM,Y INC FIRE0 M0.1 INC SHDHPOSM0 LDY SHDHPOSM0 STY TEMP SOUND 2,TEMP,8,VOL0 STY HPOSM0 CPY RLIMM0 BCC M0.2 ; JSR M0.OFF JMP M1.0 ; M0.2 LDA EX0 BEQ M1.0 ; CMP EXLIM0 BCC M0.21 ; JSR M0.OFF JMP M1.0 ; M0.21 DEC SKM0 BNE M1.0 ; LDA #EXP STA SKM0 EXPAND.MISSILE 0 ; M1.0 LDA FIRE1 BNE M1.01 ; JMP CK.M.ONLY ; M1.01 CMP #1 BNE M1.1 ; LDY SHDHPOSP1 DEY STY SHDHPOSM1 CENTER.M 1 LDA #$0C ORA BASEM,Y STA BASEM,Y INC FIRE1 M1.1 DEC SHDHPOSM1 LDY SHDHPOSM1 TYA EOR #$FF STA TEMP SOUND 3,TEMP,8,VOL1 STY HPOSM1 CPY LLIMIT BCS M1.2 ; JSR M1.OFF JMP CK.M.ONLY ; M1.2 LDA EX1 BEQ CK.M.ONLY ; CMP EXLIM1 BCC M1.21 ; JSR M1.OFF JMP CK.M.ONLY ; M1.21 DEC SKM1 BNE CK.M.ONLY ; LDA #EXP STA SKM1 EXPAND.MISSILE 1 ; CK.M.ONLY LDA MONLYMOVE ;MISSLE MOVES BEQ CHECK.STICK0 ; JMP TIME.DELAY ; CHECK.STICK0 LDA #0 LDX #$FF LDY BUILD0 CPY #1 BEQ S0.1 ; STA BUILD0 S0.1 LDY HITP0 ;CAN'T MOVE IF HIT BNE S0.1.1 ; LDA #$0F EOR STICK0 BNE S0.2 ;MOVEMENT DETECTED ; S0.1.1 STA VERDIR0 STA HORDIR0 LDX BUILD0 BNE S0.1.2 ; SOUND 0,0,0,0 S0.1.2 JMP CHECK.STICK1 ; S0.2 PHA TXA PHA SOUND 0,245,6,6 PLA TAX PLA LDY #0 STY TEMP STY TEMP2 LDY BUILD0 STY TEMP3 CHECK.STICK 0 LDA TEMP STA VERDIR0 LDA TEMP2 STA HORDIR0 LDA TEMP3 STA BUILD0 CMP #1 BEQ CHECK.STICK1 ; LDA BUILDCOUNT0 BEQ CHECK.STICK1 ; JSR STOP.BUILD0 ; CHECK.STICK1 LDA #0 LDX #$FF LDY BUILD1 CPY #1 BEQ S1.1 ; STA BUILD1 S1.1 LDY HITP1 ;CAN'T MOVE IF HIT BNE S1.1.1 ; LDA #$0F EOR STICK1 BNE S1.2 ;MOVEMENT DETECTED ; S1.1.1 STA VERDIR1 STA HORDIR1 LDX BUILD1 BNE S1.1.2 ; SOUND 1,0,0,0 S1.1.2 JMP MP0.0 ; S1.2 PHA TXA PHA SOUND 1,235,6,6 PLA TAX PLA LDY #0 STY TEMP STY TEMP2 LDY BUILD1 STY TEMP3 CHECK.STICK 1 LDA TEMP STA VERDIR1 LDA TEMP2 STA HORDIR1 LDA TEMP3 STA BUILD1 CMP #1 BEQ MP0.0 ; LDA BUILDCOUNT1 BEQ MP0.0 ; JSR STOP.BUILD1 ; ; MOVE PLAYER ROUTINE MP0.0 MOVE.PLAYER 0,HORDIR0,VERDIR0,1 MP1.0 MOVE.PLAYER 1,HORDIR1,VERDIR1,1 ; ; BUILD WALLS ROUTINE B0.0 LDA BUILD0 CMP #1 BEQ B0.01 ; JMP B1.0 ; B0.01 SOUND 0,60,4,8 LDX WALLX0 BNE B0.02 ; LDA #1 STA BUILDCOUNT0 SET.X.Y.WALL 0 STX WALLX0 STY WALLY0 B0.02 LDA #1 CMP BUILDCOUNT0 BNE B0.1 ; ASL BUILDCOUNT0 ?WALL WALLX0,WALLY0,B0.1,0 JMP B1.0 ; B0.1 LDA #2 CMP BUILDCOUNT0 BNE B0.2 ; ASL BUILDCOUNT0 JSR B0.SUB1 DEC WALLY0 ?WALL WALLX0,WALLY0,B0.2,0 JMP B1.0 ; B0.2 LDA #4 CMP BUILDCOUNT0 BNE B0.3 ; ASL BUILDCOUNT0 JSR B0.SUB1 INC WALLY0 INC WALLY0 ?WALL WALLX0,WALLY0,B0.3,0 JMP B1.0 ; B0.3 LDA #8 CMP BUILDCOUNT0 BNE B0.4 ; ASL BUILDCOUNT0 JSR B0.SUB1 DEC WALLY0 DEC WALLY0 DEC WALLY0 ?WALL WALLX0,WALLY0,B0.4,0 JMP B1.0 ; B0.4 LDA #16 CMP BUILDCOUNT0 BNE B0.5 ; ASL BUILDCOUNT0 JSR B0.SUB1 INC WALLY0 INC WALLY0 INC WALLY0 INC WALLY0 ?WALL WALLX0,WALLY0,B0.5,0 JMP B1.0 ; B0.5 JSR B0.SUB1 LDA SECONDLAYER0 BNE B0.6 ; INC SECONDLAYER0 DEC WALLX0 DEC WALLY0 DEC WALLY0 LDA #1 STA BUILDCOUNT0 JMP B1.0 ; B0.6 JSR STOP.BUILD0 ; B1.0 LDA BUILD1 CMP #1 BEQ B1.01 ; JMP B2 ; B1.01 SOUND 1,60,4,8 LDX WALLX1 BNE B1.02 ; LDA #1 STA BUILDCOUNT1 SET.X.Y.WALL 1 STX WALLX1 STY WALLY1 B1.02 LDA #1 CMP BUILDCOUNT1 BNE B1.1 ; ASL BUILDCOUNT1 ?WALL WALLX1,WALLY1,B1.1,1 JMP B2 ; B1.1 LDA #2 CMP BUILDCOUNT1 BNE B1.2 ; ASL BUILDCOUNT1 JSR B1.SUB1 DEC WALLY1 ?WALL WALLX1,WALLY1,B1.2,1 JMP B2 ; B1.2 LDA #4 CMP BUILDCOUNT1 BNE B1.3 ; ASL BUILDCOUNT1 JSR B1.SUB1 INC WALLY1 INC WALLY1 ?WALL WALLX1,WALLY1,B1.3,1 JMP B2 ; B1.3 LDA #8 CMP BUILDCOUNT1 BNE B1.4 ; ASL BUILDCOUNT1 JSR B1.SUB1 DEC WALLY1 DEC WALLY1 DEC WALLY1 ?WALL WALLX1,WALLY1,B1.4,1 JMP B2 ; B1.4 LDA #16 CMP BUILDCOUNT1 BNE B1.5 ; ASL BUILDCOUNT1 JSR B1.SUB1 INC WALLY1 INC WALLY1 INC WALLY1 INC WALLY1 ?WALL WALLX1,WALLY1,B1.5,1 JMP B2 ; B1.5 JSR B1.SUB1 LDA SECONDLAYER1 BNE B1.6 ; INC SECONDLAYER1 INC WALLX1 DEC WALLY1 DEC WALLY1 LDA #1 STA BUILDCOUNT1 JMP B2 ; B1.6 JSR STOP.BUILD1 B2 JMP TIME.DELAY ; END.OF.ROUND LDY #0 JSR RDOFFSET.TO.ZTEMP LDA (ZTEMP),Y CMP #$FF BNE ER1 ;MORE ROUNDS ; STY ROUND ; RESET LDA #ROUND1&$FF STA RDOFFSET LDA #ROUND1/256 STA RDOFFSET+1 ER1 JMP INIT.ROUND ; SCREEN .BYTE "S:" ; ;SUBROUTINES CPSUB LDY #0 CPS.1 STA (ZTEMP),Y INY BNE CPS.1 ; DEX BNE CPS.2 ; RTS CPS.2 INC ZTEMP+1 JMP CPS.1 ; INC.ZTEMP INC ZTEMP BNE IT1.1 ; INC ZTEMP+1 IT1.1 RTS ; SET.UP.PLOT JSR INC.ZTEMP LDA (ZTEMP),Y STA TEMP JSR INC.ZTEMP LDA (ZTEMP),Y STA TEMP2 RTS ; VERT.DRAW.P0 LDY #0 LDA DATAP0,Y ; # OF BYTES TO LOAD TAY LDX VPOSP0 ; OFFSET FROM BASE VD1.0 LDA DATAP0,Y STA BASEP0,X INX DEY BNE VD1.0 ; RTS ; VERT.DRAW.P1 LDY #0 LDA DATAP1,Y ; # OF BYTES TO LOAD TAY LDX VPOSP1 ; OFFSET FROM BASE VD1.1 LDA DATAP1,Y STA BASEP1,X INX DEY BNE VD1.1 ; RTS ; IOSUB STY $54 ; ROWCRS STX $55 ; COLCRS LDA #0 STA $56 ; MSB COLCRS LDX #$60 STA IOCB+8,X ;BUFF LENGTH STA IOCB+9,X ; " " LDA IOCOM ;PUTCHR / GETCHR STA IOCB+2,X LDA COLOR ; PLAYFIELD # JSR CIOV RTS ; DRAWSUB LDA COLOR STA SVCOLOR ; COLOR TO DRAW WITH LDA $54 STA $5A ;OLD ROWCRS DEC $55 LDA $55 STA $5B ;OLD COLCRS STY $54 ;ROWCRS STX $55 ;COLCRS LDA #0 STA $56 ;MSB LDX #$60 ;IOCB #6 LDA #$11 ;DRAW STA IOCB+2,X JSR CIOV RTS ; M0.OFF SOUND 2,0,0,0 CLEAR.MISSLE VPOSM0,$FC,EX0 M0.OFF.1 LDA #0 STA SHDHPOSM0 STA HPOSM0 STA FIRE0 STA EX0 STA SKM0 LDA #$12 STA EXLIM0 RTS ; M1.OFF SOUND 3,0,0,0 CLEAR.MISSLE VPOSM1,$F3,EX1 M1.OFF.1 LDA #0 STA SHDHPOSM1 STA HPOSM1 STA FIRE1 STA EX1 STA SKM1 LDA #$12 STA EXLIM1 RTS ; CLR.M.SUB TAX ASL TEMP ;COUNT * 2 CM.1 LDA BASEM,X AND TEMP2 STA BASEM,X DEX DEC TEMP BPL CM.1 ; RTS ; FLASH.SUB ADC #$10 ;INC HUE STA TEMP AND #$0F ;GET LUMIN. BEQ FL1.1 ; LDA #$F0 AND TEMP ;INVERT LUMIN. RTS ; FL1.1 LDA #$0F ORA TEMP ;INVERT LUMIN. RTS ; CHECK.STICK.SUB ROR A BCC CS.3 ; LDY #1 STY TEMP ;UP STX TEMP3 CS.3 ROR A BCC CS.4 ; LDY #-1 STY TEMP ; DOWN STX TEMP3 CS.4 ROR A RTS ; SETXY.SUB SEC SBC #$30 ;START OF SCREEN LEFT LSR A ;DIV BY 2 TAX ;= SCREEN X COORDINATE LDA TEMP SETXY.SUB.1 SEC SBC #$20 ;START OF SCREEN TOP LSR A ;DIV BY 4 LSR A CMP #50 ;IF OFF TOP BCC SETXY.SUB.2 ;OF SCREEN ; LDA #0 ;SET TO = 0 SETXY.SUB.2 TAY ;= SCREEN Y COORDINATE RTS ; B0.SUB1 COLOR 1 PLOT WALLX0,WALLY0 RTS ; B0.SUB2 COLOR 2 PLOT WALLX0,WALLY0 RTS ; B1.SUB1 COLOR 1 PLOT WALLX1,WALLY1 RTS ; B1.SUB2 COLOR 2 PLOT WALLX1,WALLY1 RTS ; EX.M.SUB ;X = EX(0-1) ;TEMP = VPOSM(0-1) ;TEMP3 = MISSILE SHAPE DATA ;TEMP4 = MISSILE SHAPE DATA ; LDA TEMP SEC SBC TEMP2 TAY LDA TEMP4 ORA BASEM,Y STA BASEM,Y INY INY LDA TEMP3 ORA BASEM,Y STA BASEM,Y ; LDA TEMP CLC ADC TEMP2 TAY LDA TEMP4 ORA BASEM,Y STA BASEM,Y DEY DEY LDA TEMP3 ORA BASEM,Y STA BASEM,Y RTS ; RDOFFSET.TO.ZTEMP LDA RDOFFSET STA ZTEMP LDA RDOFFSET+1 STA ZTEMP+1 RTS ; ZTEMP.TO.RDOFFSET LDA ZTEMP STA RDOFFSET LDA ZTEMP+1 STA RDOFFSET+1 RTS ; STOP.BUILD0 JSR B0.SUB1 STOP.BUILD0.1 SOUND 0,0,0,0 LDY #0 STY WALLY0 STY WALLX0 STY BUILD0 STY BUILDCOUNT0 STY SECONDLAYER0 RTS ; STOP.BUILD1 JSR B1.SUB1 STOP.BUILD1.1 SOUND 1,0,0,0 LDY #0 STY WALLY1 STY WALLX1 STY BUILD1 STY BUILDCOUNT1 STY SECONDLAYER1 RTS ; SOUND.SUB LDA #0 STA $D208 ;AUDCTL LDA #3 STA $D20F ;SKCTL STA $0232 ;& SHADOW RTS ; PUTCHR.SUB LDX #0 STX IOCB+8 STX IOCB+9 LDA #PUTCHR STA IOCB+2 PCLOOP LDY TEMP LDA STRBUF,Y JSR CIOV DEC TEMP BPL PCLOOP ; RTS ; PRINT.SUB DEY STY TEMP LDX #0 SLOOP LDA (ZTEMP),Y ;REVERSE ORDER STA STRBUF,X ;OF CHARACERS INX ;IN STRING DEY BPL SLOOP ; JSR PUTCHR.SUB RTS ; PRINT.NUM.SUB JSR IFP ;INT. TO F.P. JSR FASC ;F.P. TO ASCII STRING ; LDY #0 PN1 LDA (INBUF),Y ;COUNT CHARACTERS BMI PN2 ;IN STRING ; INY JMP PN1 ; PN2 STY TEMP LDX #0 PN3 LDA (INBUF),Y ;REVERSE STRING & AND #$7F ;CLEAR BIT 7 STA STRBUF,X INX DEY BPL PN3 ; JSR PUTCHR.SUB RTS ; DRAW.SUB LDA (ZTEMP),Y ;NUM OF X,Y; X,Y BEQ R1.2 ;SKIP IF "0" ; STA TEMP5 ;# PLOT DRAWTO SETS R1.1 JSR SET.UP.PLOT JSR INC.ZTEMP LDA (ZTEMP),Y STA TEMP3 JSR INC.ZTEMP LDA (ZTEMP),Y STA TEMP4 PLOT TEMP,TEMP2 DRAWTO TEMP3,TEMP4 LDY #0 DEC TEMP5 BNE R1.1 ;DO NEXT SET ; R1.2 JSR INC.ZTEMP LDA (ZTEMP),Y ; NUM PLOT POINT SETS BEQ R1.4 ;SKIP IF "0" ; STA TEMP5 ; SETS R1.3 JSR SET.UP.PLOT PLOT TEMP,TEMP2 LDY #0 DEC TEMP5 BNE R1.3 ; R1.4 RTS ; HIT.SUB HS.LOOP LDA #GETCHR STA IOCOM JSR IOSUB CMP #3 BEQ HS.LOOP.1 ; LDA #PUTCHR STA IOCOM LDX TEMP3 LDY TEMP4 JSR IOSUB HS.LOOP.1 LDY TEMP4 CPY TEMP2 BEQ HS.1 ; LDX TEMP3 INC TEMP4 LDY TEMP4 JMP HS.LOOP ; HS.1 RTS ; .OPT NOLIST *= $8800 ;^^^^^^^^^^^^ ;PLAYER DATA Format ; 1- # of data bytes ; 2- '0' first byte ; 3- player byte data in reverse order ; 4- '0' last byte ;^^^^^^^^^^^^ DATAP0 .BYTE 9,0,102,255,56,254,248,177,159,0 DATAP1 .BYTE 9,0,86,255,15,127,15,154,242,0 ; *= COLPM0 .BYTE 216,170 *= $8880 ;******************************** ;DATA FOR SCREEN DISPLAY OF EACH ROUND ;Format: COLOR 2 water ; 1- # of plot/drawto sets ; 2- 4 byte sets x,y, x,y ; 3- # of plot point sets ; 4- 2 byte sets x,y ; COLOR 1 walls ; 5- # of plot/drawto sets ; 6- 4 byte sets x,y, x,y ; 7- # of plot point sets ; 8- 2 byte sets x,y ; 9- P0 horz. pos. X*2+48 ; 10- P1 " " " ; 11- P0 vert. offset Y*4+32 ; 12- P1 " " " ; ; 13- "255" FLAGS END OF DATA. AFTER LAST SCREEN ONLY !! ;******************************** RDOFFSET .WORD 0 ;ROUNDS DATA OFFSET POINTER ROUND1 .BYTE 2,39,0,39,39,40,0,40,39,0 .BYTE 36,10,7,10,19,11,7,11,19,12,7,12,19,13,7,13,19,14,7,14,19,15,7,15,19,23,2,26,5,24,2,27,5,25,2,28,5 .BYTE 28,7,28,10,29,7,29,10,30,7,30,10,29,12,29,15,30,12,30,15,31,12,31,15,28,17,28,20,29,17,29,20 .BYTE 30,17,30,20,26,22,23,25,27,22,24,25,28,22,25,25,54,14,49,19,55,14,50,19,56,14,51,19,48,21,48,30 .BYTE 49,21,49,30,50,21,50,30,49,32,54,37,50,32,55,37,51,32,56,37,64,19,64,32,65,19,65,32,66,19,66,32 .BYTE 67,19,67,32,68,19,68,32,69,19,69,32,0,52,200,80,128 ROUND2 .BYTE 27,39,0,39,24,40,0,40,26,41,24,41,30,42,26,42,28,40,28,40,32,39,31,37,35,39,32,37,37,38,37,39,39 .BYTE 38,38,38,39,22,2,25,2,21,3,25,3,56,2,60,2,56,3,59,3,17,10,19,10,16,11,20,11,16,12,20,12,16,13,20,13 .BYTE 17,14,19,14,62,10,64,10,61,11,65,11,61,12,65,12,61,13,65,13,62,14,64,14,29,36,23,38,30,36,23,38 .BYTE 51,36,54,38,52,36,54,38,0 .BYTE 20,10,15,14,19,14,21,10,25,70,15,66,19,66,21,70,25,32,2,32,10,33,2,33,11,34,2,34,11,35,2,35,13 .BYTE 36,2,36,13,42,2,42,13,43,2,43,13,44,2,44,11,45,2,45,11,46,2,46,10,18,25,23,30 .BYTE 22,31,25,31,20,33,20,37,62,25,57,30,55,31,58,31,60,33,60,37,2,21,32,59,32,48,200,109,109 ROUND3 .BYTE 10,8,1,70,38,9,1,71,38,0,0,8,0,4,1,7,2,72,37,75,38,71,39,79,39,5,26,14,39,8,26,15,39,64,0,71,14 .BYTE 65,0,74,14,0 .BYTE 22,8,7,8,12,9,7,9,12,10,7,10,12,8,15,8,16,9,15,9,18,10,15,10,20,15,11,15,16,16,11,16,16,17,11,17,16 .BYTE 16,19,16,23,17,19,17,27,63,13,63,20,64,16,64,20,63,23,63,29,64,23,64,29,65,23,65,29,70,19,70,24 .BYTE 71,21,71,24,72,23,72,24,70,27,70,32,71,27,71,32,72,27,72,32,0 .BYTE 52,198,68,152 ROUND4 .BYTE 0,38,20,2,20,5,20,13,22,9,25,2,26,6,26,12,31,25,32,8,33,13,33,32,34,4,34,14,36,23,37,28,38,18 .BYTE 39,18,39,19,41,33,44,30,45,23,46,22,47,3,47,11,50,8,51,15,52,5,53,1,56,8,57,3,57,14,60,11,61,17 .BYTE 69,6,71,3,71,13,72,12,75,8 .BYTE 20,10,18,16,24,11,18,17,24,12,18,18,24,16,26,16,29,17,26,17,29,18,26,18,29,14,26,14,29,16,31,10,37 .BYTE 17,31,11,37,18,31,12,37,67,17,60,24,68,17,61,24,69,17,62,24,60,26,60,29,61,26,61,29,62,26,62,29 .BYTE 64,26,64,29,60,31,67,37,61,31,68,37,62,31,69,37,4,65,26,65,29,13,26,13,29 .BYTE 64,182,140,140 ROUND5 .BYTE 14,25,0,56,9,25,1,56,10,57,9,67,13,57,10,66,14,63,13,64,19,67,14,64,20,63,19,16,19,63,20,16,20 .BYTE 15,19,12,25,15,20,16,26,12,26,23,30,13,25,23,29,24,29,54,38,24,30,54,39 .BYTE 4,24,0,64,14,15,25,55,39 .BYTE 3,21,21,55,21,21,22,55,22,21,23,55,23,0 .BYTE 80,166,96,120 ROUND6 .BYTE 0,0,0,0,50,200,40,100 ROUND7 .BYTE 0,0,0,0,108,140,108,108 ROUND8 .BYTE 10,15,0,15,39,64,0,64,39,16,7,59,7,16,15,59,15,16,28,59,28,16,36,59,36 .BYTE 20,3,63,3,20,11,63,11,20,24,63,24,20,32,63,32,0,2,16,19,63,19,16,20,63,20,0,82,166,100,116 .BYTE 255 ; *** FLAG END OF LAST SCREEN DATA *** ; *= $02E0 .WORD START.OF.CODE .END