; ***************************** ; * P O N G * ; * by GARY S. DOMROW * ; * (c) 1986 ANALOG Computing * ; ***************************** ; ;O.S. RAM Z-PAGE ; BOOT = $09 ;O.S. BOOT FLAG DOSVEC = $0C ;INIT. VECTOR RTCLOK = $14 ;REAL TIME CLOCK ATRACT = $4D ;ATTRACT FLAG ; ;O.S. RAM ; COLDST = $0244 ;COLD START FLAG SDLSTL = $0230 ;DISP LIST PTR PADDL0 = $0270 ;PADDLES SDMCTL = $022F ;DIRECT MEMORY ACCESS CONTROL GPRIOR = $026F ;PRIORITY REGISTER PCOLR0 = $02C0 ;PLAYER 0 COLOR PTRIG0 = $027C ;PADDLE TRIGGER 0 CH = $02FC ;CHARACTER PRESSED ; ;O.S. ENTRY POINTS ; SETVBV = $E45C ;SET VERTICAL BLANK VECTOR XITVBV = $E462 ;EXIT VERTICAL BLANK WRMVEC = $E474 ;WARM START VECTOR ; ;O.S. REGISTER ; GRACTL = $D01D ;PM GRAPHICS CONTROL PMBASE = $D407 ;PM BASE REGISTER RANDOM = $D20A ;RANDOM NUMBER GENERATOR HITCLR = $D01E ;COLLISION CLEAR REGISTER AUDF1 = $D200 ;AUDIO FREQ. 1 AUDC1 = $D201 ;AUDIO CONTROL 1 AUDCTL = $D208 ;AUDIO CONTROL SKCTL = $D20F ;SERIAL CONTROL CONSOL = $D01F ;CONSOLE SWITCHES HPOSP0 = $D000 ;HORIZ POSITION PLAYER 0 HPOSM0 = $D004 ;HORIZ POSITION MISSLE 0 M0PL = $D008 ;MISSILE-PLAYER COLLISIONS M0PF = $D000 ;MISSILE-PLAYFIELD COLLISIONA HSCROL = $D404 ;HORIZ SCROLL REGISTER VSCROL = $D405 ;VERT SCROLL REG ; ;MY Z-PAGE ; *= $80 ; GPNTR DB 0,0 ;GENERAL POINTER VOL DB 1 ;VOLUME NOTE DB 1 ;NOTE LOCK DB 1 ;PADDLE MOVE FLG SCORE1 DB 1 ;PLAYER 1 SCORE SCORE2 DB 1 ;PLAYER 2 SCORE COLR DB 1 ;COLOR TYPE DB 1 ;GAME TYPE SRVDR DB 1 ;SERVE DIRECTION TEMP2 DB 1 TEMPX DB 1 TEMPY DB 1 JMPVEC DB 0,0 ;JUMP VECTOR COUNT DB 1 ;COUNTER ; ;EQUATES ; PMB = $20 ;PM BASE (HI BYTE) P1SC = 5 ;PLYR 1 SCORE POSITION P2SC = 14 ;PLYR 2 SCORE POSITION MISL = PMB*256+384 ;MISSILE MEMORY PLR0 = MISL+128 ;PLAYER 0 MEMORY PLR1 = PLR0+128 ;PLAYER 1 PLR2 = PLR1+128 ;PLAYER 2 PADCLR = $D6 ;PADDLE COLOR MINY = $FE ;MINIMUM Y CHANGE MAXY = 2 ;MAXIMUM Y CHANGE ; ;START OF CODE ; *= $2800 ; WAIT60 LDA RTCLOK MWAIT CMP RTCLOK BEQ MWAIT RTS ; START LDA # WRMSTRT STA DOSVEC+1 LDA #0 STA COLDST LDA #1 STA BOOT? JSR DLBUILD ;BUILD D LIST ; ;ENTRY FOR RESET ; WRMSTRT LDX #$FF ;RESET STACK TXS JSR CLEARALL LDA #0 STA VSCROL STA VOL STA NOTE STA COUNT STA AUDCTL LDA # DLIST STA SDLSTL+1 LDA #3 STA SKCTL JSR WAIT60 JSR ZPMS LDA #1 STA LOCK LDA #7 ;INITIALIZE VBI LDX # >VBI LDY # SCRNMEM+19 ;MEMORY STA GPNTR+1 LDY #0 LDX #43 WLP LDA #$AA ;COLOR 2 FOR VERTICAL STA (GPNTR),Y CLC ;ADD TO POINTER LDA GPNTR ADC #20 STA GPNTR BCC WLP2 INC GPNTR+1 WLP2 DEX ;DO IT 43 TIMES BNE WLP RTS ; ;CLEAR ALL SCREEN MEMORY ; CLEARALL LDA # SCORELINE STA GPNTR+1 LDX #6 ;AND DO 6 PAGES LDA #0 TAY CLRLP STA (GPNTR),Y INY BNE CLRLP INC GPNTR+1 DEX BNE CLRLP RTS ; ; ;VERTICAL BLANK ROUTINE TO MOVE ;PADDLES AND DO SOUNDS ; VBI LDA #8 ;IS START PRESSED?? STA CONSOL LDA CONSOL CMP #6 BNE CHKLOCK ;NO. JMP WRMVEC ;YES. DO A WARM START ; CHKLOCK LDA LOCK ;ARE PADDLES LOCKED?? BEQ VBICONT ;NO. JMP XITVBV ;YES, GET OUT ; VBICONT LDA PADDL0 ;G LDY #0 JSR SCALEPAD ;SCALE IT PROPERLY STA TEMPY ;AND SAVE LDA NUMPD1 ;NUMBER OF PADDLES FOR PLAYER 1 STA NPDTMP PD1DR DEC NPDTMP LDA NPDTMP ;MORE PADDLES?? BMI NOPD1 ;NO LDY YP1 ;YES JSR ERAPAD ;ERASE PADDLE 1 LDY NPDTMP ;FIND X POSITION LDX XP1,Y LDY TEMPY ;Y POSITION LDA NPDTMP JSR DRAWPAD ;AND DRAW IT JMP PD1DR ;DO MORE ; NOPD1 LDA TEMPY ;PUT Y IN PLACE STA YP1 LDA PADDL0+1 ;AND DO PLAYER 2 LDY #1 JSR SCALEPAD ;SCALE IT STA TEMPY LDA NUMPD2 ;SAME LOGIC STA NPDTMP ;AS BEFORE PD2DR DEC NPDTMP LDA NPDTMP BMI NOPD2 CLC ;EXCEPT, WE MUST ADC #2 ;LET IT KNOW WHO'S LDY YP2 ;PADDLE TO ERASE JSR ERAPAD LDY NPDTMP LDX XP2,Y LDY TEMPY CLC LDA NPDTMP ADC #2 ;AND TO DRAW JSR DRAWPAD JMP PD2DR ; NOPD2 LDA TEMPY STA YP2 LDA VOL ;AND SOUNDS?? BEQ NOVOLDEC ;NO DEC VOL ;YES, DEC IT NOVOLDEC LDA VOL ;GET VOLUME ORA #$A0 ;WITH NO DISTORTION STA AUDC1 ;AND STORE LDA NOTE ;GET NOTE STA AUDF1 ;AND STORE LDA ALTFL ;IF ALTERNATING, BEQ OUTVBI ;MAKE ONE LDA ALTFL ;PLAYER BRIGHTER AND #$02 ;THAN THE OTHER TAX LDA #PADCLR+4 STA PCOLR0,X STA PCOLR0+1,X LDA ALTFL ;LOOKS TRICKIER EOR #$03 ;THAN IT IS HERE AND #$02 ;I'M JUST TAX ;FINDING PLAYER TO LDA #PADCLR ;MAKE DARKER STA PCOLR0,X STA PCOLR0+1,X OUTVBI JMP XITVBV ;END OF VBI ; ;BUILD A DISPLAY LIST ; DLBUILD LDA #10 ;GRAPHICS 5 IN BASIC LDX #42 ;42 MODE LINES DLLP STA DLMAIN,X DEX BPL DLLP LDA #$41 ;JVB INST STA DLMAIN+43 LDA # DLIST STA DLMAIN+45 RTS ; ;SCALE PADDLE INPUT TO PM LOC ; SCALEPAD LSR A ;DIVIDE BY TWO SEC ;AND TAKE AWAY 7 SBC #7 ;TO CENTER. BMI LO CMP #26 ;NOW CHECK LOWER BCS CHECKHI LO LDA #26 BNE AOK ; CHECKHI CMP #102 ;TOO BIG? BCC AOK ;NO. LDA #101 ;YES. USE 101 AOK RTS ; ;ERASE A PADDLE ; ERAPAD PHA STY TEMP2 ;SAVE Y LDA # PLR0 STA GPNTR+1 PLA ;GET PLAYER NUMBER JSR PLPNTR ;AND ADD TO POINTER LDY TEMP2 ;GET Y BACK LDX #9 LDA #0 ERALP STA (GPNTR),Y ;AND STICK SOME INY ;ZEROES IN DEX ;SOMEWHERE BPL ERALP RTS ; ;ADJUST POINTER ACCORDING TO PLAYER NUMBER ; PLPNTR TAY ADDLP DEY ;GET OUT WHEN WE BMI OUTPLP ;GET TO ZERO CLC ;ADD 128 FOR EACH LDA GPNTR ;PLAYER ADC #$80 STA GPNTR BCC ADDLP INC GPNTR+1 JMP ADDLP OUTPLP RTS ; ;DRAW PADDLE ; DRAWPAD STY TEMP2 ;DO SAME STUFF PHA ;AS IN ERASE, TAY TXA STA HPOSP0,Y LDA # PLR0 STA GPNTR+1 PLA JSR PLPNTR LDX #9 LDA #3 LDY TEMP2 ;(INSTEAD OF 0) DRLP STA (GPNTR),Y INY DEX BPL DRLP RTS ; ;DRAW TOP AND BOTTOM ; SETSCRN LDA #$55 ;USE COLOR 1 LDX #19 ;20 BYTES (0-19) SETLP1 STA SCRNMEM,X ;PUT ON SCREEN STA SCRNMEM+860,X DEX BPL SETLP1 RTS ; ;INITIALIZE PLAYER-MISSILE GRAPHICS ; PMINIT LDA #PMB ;TELL IT WHAT STA PMBASE ;MEMORY TO USE LDA #46 ;AND DOUBLE-LINE STA SDMCTL ;RESOLUTION JSR ZPMS LDA #3 ;PLAYERS AND MISSILES STA GRACTL LDA #$11 ;SET PRIORITY STA GPRIOR RTS ; ;ZERO PLAYERS, MISSILES, AND X LOCATIONS ; ZPMS LDX #12 ;SET X LOCATIONS LDA #0 ;AND WIDTHS TO ZPMLP STA HPOSP0,X ;ZERO. DEX BPL ZPMLP LDA #PMB STA GPNTR+1 LDA #0 ;POINT TO PM STA GPNTR ;MEMORY LDX #4 ;AND FOUR PAGES TAY ZPMEMLP STA (GPNTR),Y ;AND ZERO INY ;IT OUT BNE ZPMEMLP INC GPNTR+1 DEX BNE ZPMEMLP RTS ; ;DRAW PLAYING FIELD ACCORDING TO TYPE ; TYPEOK JSR CLEARALL ;CLEAR WHAT WAS THERE JSR WAIT60 JSR CLNSCRLN ;AND SCORELINE LDA #0 STA VSCROL LDA TYPE ;GET TYPE ASL A ASL A ASL A ASL A ;*16 TAX ;AS OFFSET TO TABLE LDY #0 PRTYPELP LDA STNDRD,X ;PRINT GAME TYPE STA SCORELINE,Y INX INY CPY #$10 BNE PRTYPELP JSR ZPMS ;ZERO P/M AREA JSR SETSCRN ;DO TOP & BOTTOM JSR MIDLINE ;AND MIDDLE LINE LDA TYPE CMP #4 BEQ TYPE4 LDA # SCRNMEM STA MAINWORD+1 TYPE4 LDA TYPE ;TYPE * 2 FOR ASL A ;JUMP TABLE TAX LDA JMPTAB,X ;GET JUMP TABLE STA JMPVEC ;ENTRIES INX LDA JMPTAB,X STA JMPVEC+1 JMP (JMPVEC) ;AND OFF WE GO ; ;PRINT TITLE SCREEN ; PTITLE LDA DLIST+3 ORA #$10 ;SET HSCROL BIT STA DLIST+3 JSR SETSCRN ;SET TOP AND BOTTOM LDA # TITLE STA GR2WORD+1 LDX #110 ;FOR 110 CHARACTERS LDA #8 STA HSCROL ;INITIALIZE SCROLL STA COUNT ;AND COUNTER TBGLP JSR WAIT60 ;SIT AROUND FOR A WHILE LDA PTRIG0 ;CHECK FOR TRIGGER AND PTRIG0+1 ;PRESSED EITHER BEQ OUTPTITLE ;PADDLE DEC COUNT ;COUNTDOWN LDA COUNT ;WHEN BELOW ZERO, BPL OKCOUNT LDA #7 ;SET BACK TO 7 STA COUNT INC GR2WORD ;AND INCREMENT BNE OKCOUNT ;LMS IN D LIST INC GR2WORD+1 OKCOUNT LDA COUNT ;SET SCROLL STA HSCROL ;REGISTER BNE TBGLP ;IF ZERO, DEX ;DEC CHARACTER COUNT BNE TBGLP BEQ PTITLE ;AND REPEAT ; OUTPTITLE LDA #15 ;RESET SCROLL STA HSCROL ;RESET POINTER LDA # <SCORELINE STA GR2WORD LDA # >SCORELINE STA GR2WORD+1 LDA DLIST+3 AND #$EF ;RESET HSCROL BIT STA DLIST+3 RTS ;AND LEAVE ; ;CLEAN SCORE LINE OF ALL GARBAGE ; CLNSCRLN LDA #0 LDX #39 ;20 BYTES WIDE *2 CLNSCR STA SCORELINE,X DEX BPL CLNSCR RTS ; ;NEXT ROUTINES SET UP INITIAL ;CONDITIONS FOR GAME PLAY ; ;STANDARD GAME ; STANDARDSU LDA #1 ;EACH GET ONE STA NUMPD1 ;PADDLE TO MOVE STA NUMPD2 LDA #46 ;PUT THEM ON STA XP1 ;OPPOSITE SIDES LDA #200 ;OF THE SCREEN STA XP2 LDA #0 ;NO ALTERNATION STA ALTFL LDA #1 ;START AT SPEED 1 STA STRSPD LDA #8 ;8 HITS BEFORE SPEED INCREASES STA MAXHIT LDA #$FF ;ALTERNATE SERVES STA SRVFL RTS ; ;PRACTICE SET UP ; PRACTICESU LDA #1 ;ONLY ONE PADDLE STA NUMPD1 LDA #0 STA NUMPD2 LDA #90 ;NEAR MIDDLE STA XP1 LDA #1 ;START AT ONE STA STRSPD LDA #8 ;8 HITS STA MAXHIT LDA #0 ;NO ALTERNATION STA ALTFL JSR WALL ;DRAW A WALL LDA #0 ;NO SERVE ALTERNATION STA SRVFL RTS ; ;HOCKEY PONG SET UP ; HOCKEYSU LDA #2 ;TWO PADDLES EACH STA NUMPD1 STA NUMPD2 LDA #44 ;ON END STA XP1 LDA #156 ;AND NEAR MIDDLE STA XP1+1 LDA #198 ;ON END STA XP2 LDA #88 ;AND NEAR MIDDLE STA XP2+1 LDA #1 ;START AT ONE STA STRSPD LDA #8 ;8 HITS STA MAXHIT LDA #0 ;NO ALTERNATION STA ALTFL JSR HOCKSIDES ;DRAW SIDES LDA #$FF ;ALTERNATE SERVES STA SRVFL RTS ; ;WALL PONG SET UP ; WALLBALLSU LDA #1 ;ONE PADDLE EACH STA NUMPD1 STA NUMPD2 STA STRSPD ;START AT ONE LDA #8 ;8 HITS STA MAXHIT LDA #90 ;BOTH PADDLES STA XP1 ;NEAR MIDDLE LDA #94 STA XP2 LDA #1 ;ALTERNATE HITS STA ALTFL JSR WALL ;DRAW WALL LDA #0 ;NO ALTERNATING SERVE STA SRVFL RTS ; ;DRAW PARTIAL SIDES FOR HOCKEY ; HOCKSIDES LDA # <SCRNMEM+20 STA GPNTR ;POINT TO SCREEN LDA # >SCRNMEM+20 STA GPNTR+1 LDX #9 ;NINE MODE LINES TOPLP LDY #0 LDA #$80 ;IN COLOR 1 STA (GPNTR),Y LDY #19 ;ON BOTH ENDS LDA #2 ;OF SCREEN STA (GPNTR),Y CLC LDA GPNTR ;ADD SIZE OF ADC #20 ;ONE LINE STA GPNTR BCC TOPLP1 INC GPNTR+1 TOPLP1 DEX BPL TOPLP ;DONE WITH TOP HALF CLC LDA GPNTR ADC #$B8 ;SKIP A BUNCH OF STA GPNTR ;MODE LINES LDA GPNTR+1 ADC #1 STA GPNTR+1 LDX #9 BOTLP LDY #0 ;AND DO SIDES LDA #$80 ;ON BOTTOM HALF STA (GPNTR),Y LDY #19 LDA #2 STA (GPNTR),Y CLC LDA GPNTR ADC #20 STA GPNTR BCC BOTLP1 INC GPNTR+1 BOTLP1 DEX BPL BOTLP RTS ; ;GET TOP HALF OF BCD NUMBER ; TOPHALF LSR A ;DIVIDE BY 16 LSR A LSR A LSR A BEQ TOPZERO ;IF ZERO, LEAVE BLANK ORA #$D0 ;IF NOT, MAKE IT NUMERIC TOPZERO RTS ; ;GET BOTTOM HALF OF BCD NUMBER ; BOTHALF AND #$0F ORA #$D0 RTS ; ;LET PLAYER CHOSE GAME ; SETUP LDA PTRIG0 ;IF EITHER TRIG AND PTRIG0+1 ;IS PRESSED, WAIT BEQ SETUP LDA #0 ;INITIALIZE STA TYPE STA SRVDR JSR TYPEOK LDA #$15 ;SET ENDING SCORE STA TOPSCR STARTOVER LDA #0 ;WAIT FOR THE STA JIFCNT ;PADDLE TO GO STA LOCK ;IN 1 DIRECTION JSR WAIT60 LDA #1 ;FOR A WHILE STA LOCK CHECKMORE LDA PADDL0 STA LASTPAD CLC LDA RTCLOK ;CHECK PADDLE ADC #3 ;EVERY THIRD STA COUNT ;JIFFY WAIT03 JSR WAIT60 LDA PTRIG0 ;BUT CONSTANTLY AND PTRIG0+1 ;CHECK PADDLE BEQ TYPECHOSEN ;BUTTONS LDA COUNT CMP RTCLOK BNE WAIT03 LDA PADDL0 CMP LASTPAD BEQ CHECKMORE BCS CNTDN LDA JIFCNT ;IF DIRECTION CHANGED, BMI STARTOVER ;TRY AGAIN INC JIFCNT ;ADD TO COUNTER LDA JIFCNT CMP #3 ;IS IT 3? BNE CHECKMORE ;NO. WAIT BEQ INCTYPE ;CHANGE GAME TYPE ; CNTDN DEC JIFCNT ;DECR. COUNTER LDA JIFCNT BPL STARTOVER CMP #$FD ;IS IT -3? BNE CHECKMORE ;NO. WAIT. DEC TYPE ;CHANGE GAME TYPE LDA TYPE BPL TYPECONT01 LDA #3 STA TYPE TYPECONT01 JSR LASTTYPE ;SET UP TYPES JSR SCROLLDN ;SCROLL DOWN JMP TYPECONT ;GO BACK FOR MORE ; INCTYPE INC TYPE ;INCR GAME TYPE LDA TYPE CMP #4 BNE TYPECONT02 LDA #0 STA TYPE TYPECONT02 JSR NEXTTYPE ;SET UP TYPES JSR SCROLLUP ;AND SCROLL UP TYPECONT LDX #3 ;RESET PADDLE LDA #PADCLR ;COLORS PDCOLRLP STA PCOLR0,X DEX BPL PDCOLRLP JSR TYPEOK ;SET UP GAME SCREEN JMP STARTOVER ;AND GO BACKE ; TYPECHOSEN LDA PTRIG0 ;WAIT FOR AND PTRIG0+1 ;TRIG RELEASE BEQ TYPECHOSEN LDA #0 STA COUNT RTS ; NEXTTYPE LDA TYPE ;PUT NEXT TYPE ASL A ;TITLE IN ASL A ;SECOND LINE OF ASL A ;MEMORY ASL A TAX LDY #0 PRTYPELP2 LDA STNDRD,X STA SCORELINE+20,Y INX INY CPY #$10 BNE PRTYPELP2 RTS ; ;SCROLL TWO MEMORY LINES UP ; SCROLLUP LDA #0 STA COUNT SCRLUPLP LDA COUNT STA VSCROL JSR WAIT60 INC COUNT LDA COUNT CMP #$10 ;16 TIMES BNE SCRLUPLP RTS ; ;SCROLL TWO MEMORY LINES DOWN ; SCROLLDN LDA #15 STA COUNT SCRLDNLP LDA COUNT STA VSCROL JSR WAIT60 DEC COUNT LDA COUNT BPL SCRLDNLP RTS ; ;MOVE CURRENT TYPE TO SECOND ;LINE, AND NEW TYPE TO FIRST ; LASTTYPE LDA TYPE ASL A ASL A ASL A ASL A TAX LDY #0 LASTTYPELP LDA SCORELINE,Y ;1ST TO 2ND STA SCORELINE+20,Y LDA STNDRD,X ;NEW TO 1ST STA SCORELINE,Y INX INY CPY #$10 BNE LASTTYPELP RTS ; ;STORAGE ; XP1 .BYTE 0,0 ;PADDLE X POSITIONS XP2 .BYTE 0,0 YP1 .BYTE 0 ;PADDLE Y POSITIONS YP2 .BYTE 0 BALLX .BYTE 0 ;BALL X POS BALLY .BYTE 0 ;BALL Y POS CHNGX .BYTE 0 ;BALL X CHANGE CHNGY .BYTE 0 ;BALL Y CHANGE TOPSCR .BYTE 0 ;ENDING SCORE HITS .BYTE 0 ;NUMBER OF HITS MAXHIT .BYTE 0 ;# OF HITS BEFORE SPEED CHANGE STRSPD .BYTE 0 ;STARTING SPEED CHNGTAB .BYTE -3,-2,-2,-1,-1,0,0,1,1,2,2,3 NUMPD1 .BYTE 0 ;NUMBER OF PADDLES NUMPD2 .BYTE 0 ;ON EACH SIDE NPDTMP .BYTE 0 ;TEMP # OF PADDLES MISPL .BYTE 0 ;COLLISION REG MISPF .BYTE 0 ;HOLDERS TITLE .SBYTE ' P O N G BY GARY DOMROW ' .SBYTE 'OF THE SUMMIT SOFTWARE GROUP' .SBYTE ' for analog computing ' WINNER .SBYTE 'WINNER' COLORS .BYTE $D4,$D4,$D4,$D4,$94,$94,$94,$0A,$00 JMPTAB .WORD STANDARDSU,HOCKEYSU,WALLBALLSU,PRACTICESU SRVFL .BYTE 0 ;SERVE FLAG ALTFL .BYTE 0 ;ALTERNATE HITS LASTPAD .BYTE 0 ;PADDLE VALUE JIFCNT .BYTE 0 ;JIFFY COUNTER STNDRD .SBYTE ' STANDARD PONG' .SBYTE ' HOCKEY PONG ' .SBYTE ' WALL PONG ' .SBYTE ' PRACTICE ' ; ;DISPLAY LIST & STORAGE ; DLIST .BYTE $70,$70,$70,$67 GR2WORD .WORD SCORELINE .BYTE $07,$4A MAINWORD .WORD SCRNMEM DLMAIN 46 SCORELINE 40 SCRNMEM 880 ; ; *= $02E0 ; .WORD START End START