0100 ;D1:MCP.M65 0110 ; 0120 .TITLE "MULTI-COLOR PLAYER" 0130 ; V.100685, BY PATRICK BASS 0140 ; (c) 1985, ANTIC PUBLISHING 0150 ; 0160 .SET 1,20 0170 .TAB 8,12,30 0180 TOTALCODE = ENDCODE-STARTOFCODE 0190 .OPT NO LIST 0200 .OPT NO MLIST 0210 ; 0220 STARTOFCODE = $3000 0230 ; 0240 ;----------------------------- 0250 ; Display List equates... 0260 ; 0270 ; OFFSET is the number of scan lines down the line-by-line 0280 ; coloring starts. 0290 OFFSET = $20 0300 BLANK8 = $70 ;Blank 8 lines. 0310 LMS = $40 ;Load Mem Scan. 0320 MODE6 = 6 ;ANTIC mode 6. 0330 INT = $80 ;DL Interrupt. 0340 JMPWT = $41 ;Jump, wait. 0350 ; 0360 ;----------------------------- 0370 ; Following are ATARI standard. 0380 WSYNC = $D40A ;Hsync waiter. 0390 ; 0400 COLPM0 = $D012 ;Player/Missile 0410 COLPM1 = $D013 ;Hardware color 0420 COLPM2 = $D014 ;registers. 0430 COLPM3 = $D015 0440 ; 0450 SDLSTL = $0230 ;Dlist shadow 0460 VVBLKD = $0224 ;Vblank pointer 0470 VDSLST = $0200 ;DLI pointer 0480 HPOSP0 = $D000 ;H position. 0490 IRQEN = $D20E ;IRQ enable. 0500 POKMSK = $10 ;...and shadow. 0510 NMIEN = $D40E ;NMI enable. 0520 GPRIOR = $026F ;Global priority 0530 PMBASE = $D407 ;Player base 0540 GRACTL = $D01D ;Graphic control 0550 SDMCTL = $022F ;Shadow DMA cont 0560 SKCTL = $D20F ;Serial Control 0570 RANDOM = $D20A 0580 ; 0590 ;----------------------------- 0600 ; Default Player Box Boundaries. 0610 YMIN = 40 0620 YMAX = 170 0630 XMIN = 50 0640 XMAX = 190 0650 ; 0660 ;----------------------------- 0670 ; Default Vertical positions. 0680 VP0 = YMIN+[[YMIN+YMAX]/8] 0690 VP1 = [YMIN+YMAX]/2 0700 VP2 = YMAX-[[YMIN+YMAX]/8] 0710 VP3 = [YMIN+YMAX]/2 0720 ; 0730 ;----------------------------- 0740 ; Default Horizontal positions. 0750 HP0 = [XMIN+XMAX]/2 0760 HP1 = XMAX-[[XMIN+XMAX]/8] 0770 HP2 = [XMIN+XMAX]/2 0780 HP3 = XMIN+[[XMIN+XMAX]/8] 0790 ; 0800 ;----------------------------- 0810 ; Default Player Base color. 0820 P0C = $30 0830 P1C = $C0 0840 P2C = $50 0850 P3C = $90 0860 ; 0870 ;----------------------------- 0880 ; ...and claim how many players are currently active. 0890 ACTIVE = 4 0900 ; 0910 ;----------------------------- 0920 *= $2000 0930 ; Starting at $2000, hold a place for the player number. 0940 CURRPLR 0950 .BYTE 0 0960 ; 0970 ;----------------------------- 0980 ; Remember in order, 0-1-2-3, how fast everyone should move. 0990 MEMSPEED 1000 .BYTE 0,0,0,0 1010 ; 1020 ;----------------------------- 1030 ; 1040 ; Remember in order, 0-1-2-3, how fast everyone is moving. 1050 SPEED 1060 .BYTE 0,0,0,0 1070 ; 1080 ;----------------------------- 1090 ;This is how many dots to move 1100 ;each step. Range 1-3. 1110 VSTEP 1120 .BYTE 1,1,1,1 1130 HSTEP 1140 .BYTE 1,1,1,1 1150 ; 1160 ;----------------------------- 1170 ; This is the shape that is drawn onto each player. 1180 PLRGRAF0 1190 .BYTE 0,0,0,0 1200 .BYTE $18,$3C,$7E,$FF,$18,$18,$18,$7E 1210 .BYTE $42,$7E,$5A,$24,$18 1220 .BYTE 0,0,0,0,0,0,0 1230 ; 1240 PLRGRAF1 1250 .BYTE 0,0,0,0 1260 .BYTE $FF,$FF,$7E,$7E,$3C,$3C,$18,$FF 1270 .BYTE $FF,$18,$3C,$3C,$7E 1280 .BYTE 0,0,0,0,0,0,0 1290 ; 1300 PLRGRAF2 1310 .BYTE 0,0,0,0 1320 .BYTE $3C,$18,$3C,$42,$A9,$81,$42,$24 1330 .BYTE $3C,$3C,$5A,$42,$3C 1340 .BYTE 0,0,0,0,0,0,0 1350 ; 1360 PLRGRAF3 1370 .BYTE 0,0,0,0,24,126,255,255,255,255,255 1380 .BYTE 255,255,255,255,126,24,0,0,0,0,0 1390 ; 1400 ;----------------------------- 1410 ; Current player Horizontal position while moving. 1420 HPOSITION 1430 .BYTE HP0,HP1,HP2,HP3 1440 ; 1450 ;----------------------------- 1460 ; Current Player Vertical position while moving. 1470 VPOSITION 1480 .BYTE VP0,VP1,VP2,VP3 1490 ; 1500 ;----------------------------- 1510 ; 'PDIRECTION' is where we keep track of which direction each 1520 ; player is currently moving. 1530 ; 1540 ; bit7 clear="move down" 1550 ; bit7 set="move up" 1560 ; bit6 clear="move right" 1570 ; bit6 set="move left" 1580 PDIRECTION 1590 .BYTE 0,$40,$80,$C0 1600 ; 1610 ;----------------------------- 1620 ; Another useful mem loc 1630 THISPLAYER 1640 .BYTE 0 1650 ; 1660 ;----------------------------- 1670 ; Reserve, at $6000, four pages of memory for the players's 1680 ; color memory map. 1690 PCBASE = $6000 1700 P0COLR = PCBASE 1710 P1COLR = PCBASE+$0100 1720 P2COLR = PCBASE+$0200 1730 P3COLR = PCBASE+$0300 1740 ; 1750 ;----------------------------- 1760 ; Reserve, at $7000, four pages of memory for the player 1770 ; shapes on the screen. 1780 PBASE = PCBASE+$1000 1790 P0RAM = PBASE+$0400 1800 P1RAM = PBASE+$0500 1810 P2RAM = PBASE+$0600 1820 P3RAM = PBASE+$0700 1830 ; 1840 ;----------------------------- 1850 ; Reserve space at $8000 for the television display. 1860 SCREEN = PCBASE+$2000 1870 ; 1880 ;----------------------------- 1890 ; Build a table of player shape addresses in player order. 1900 PLAYERTABLE 1910 .WORD P0RAM,P1RAM 1920 .WORD P2RAM,P3RAM,P3RAM 1930 ; 1940 ;----------------------------- 1950 ; Build a table of player color addresses in player order. 1960 CPLAYERTABLE 1970 .WORD P0COLR,P1COLR 1980 .WORD P2COLR,P3COLR,P3COLR 1990 ; 2000 ;----------------------------- 2010 ; Build a table of player color source addresses in plr order. 2020 SPLAYERTABLE 2030 .WORD P0COLG,P1COLG 2040 .WORD P2COLG,P3COLG,P3COLG 2050 ; 2060 ;----------------------------- 2070 ; Build a table of player shape source addresses. 2080 GPLAYERTABLE 2090 .WORD PLRGRAF0,PLRGRAF1 2100 .WORD PLRGRAF2,PLRGRAF3 2110 .WORD PLRGRAF3 2120 ; 2130 ;----------------------------- 2140 ; This is a short Display List. 2150 TLIST 2160 .BYTE BLANK8,BLANK8,BLANK8 2170 .BYTE LMS+MODE6+INT 2180 .WORD SCREEN 2190 ; 2200 .BYTE JMPWT 2210 .WORD TLIST 2220 ; 2230 ;----------------------------- 2240 ; Reserve obscene amounts of Z 2250 *= $80 2260 SWITCH *= *+1 2270 POINTER *= *+2 2280 ; 2290 ;----------------------------- 2300 ; DEFINE MACROS 2310 ; MACRO #1:"LDW source,memory" 2320 ; say:"Load-Word" 2330 ; This first macro will load the WORD value of a label 2340 ; into a two-byte memory location, forming a pointer. 2350 ; EXAMPLE: 2360 ; LDW SOURCE,POINTER 2370 ;...will load the LO, HI bytes that make up the label SOURCE 2380 ; into memory locations POINTER, POINTER+1. 2390 ; 2400 .MACRO LDW 2410 LDA # <%1 2420 STA %2 2430 LDA # >%1 2440 STA %2+1 2450 .ENDM 2460 ; 2470 ;----------------------------- 2480 ; MACRO #2 "NEWPAGE" 2490 ; This macro will force the program counter to the 2500 ; next higher page number, even. 2510 ; EXAMPLE: 2520 ; (program counter now $4322) 2530 ; NEWPAGE 2540 ; (program counter now $4400) 2550 ; 2560 ;Follow: *=$4322 2570 .MACRO NEWPAGE 2580 *= *&$FF00 ; *=$4300 2590 *= */$0100 ; *=$0043 2600 *= *&$FF ; *=$43 2610 *= *+1 ; *=$44 2620 *= **$0100 ; *=$4400 2630 .ENDM 2640 ;Follow: *=$4400 2650 ; 2660 ;----------------------------- 2670 *= STARTOFCODE 2680 CLD 2690 SEI 2700 LDX #$FC 2710 TXS 2720 JSR ALTINT ;Finish init. 2730 LDW TLIST,SDLSTL 2740 LDW DBLANK,VVBLKD 2750 CLI 2760 ; 2770 ; Since this demonstrations action is controlled by both 2780 ; Vertical Blank and a DLI loop no action is needed by the 2790 ; calling program. 2800 ; 2810 IDLE 2820 JMP IDLE 2830 ; 2840 ;----------------------------- 2850 ; This is where the player coloring takes place. 2860 ; 2870 NMIVEC 2880 PHA ;Pack .A and .X 2890 TXA 2900 PHA 2910 LDX #OFFSET ;Scan line start 2920 KERNAL 2930 STA WSYNC ;Wait off-screen 2940 INX ;next scan line. 2950 CPX #OFFSET+150 ;End-o-loop? 2960 BCS DLIDONE ;Branch if yes. 2970 ; 2980 ; Otherwise... 2990 LDA P0COLR,X ;Zero's color 3000 STA COLPM0 ;Stuff color 3010 LDA P1COLR,X ;And so forth. 3020 STA COLPM1 3030 LDA P2COLR,X 3040 STA COLPM2 3050 LDA P3COLR,X 3060 STA COLPM3 3070 JMP KERNAL ;Stay in loop. 3080 ; 3090 DLIDONE 3100 PLA 3110 TAX 3120 PLA 3130 RTI 3140 ; 3150 ;----------------------------- 3160 DRAWTHEM 3170 LDX #ACTIVE-1 3180 PAGAIN 3190 STX CURRPLR 3200 LDA SPEED,X 3210 BPL PAGT1 3220 ; 3230 LDA MEMSPEED,X 3240 STA SPEED,X 3250 PAGT1 3260 DEC SPEED,X 3270 LDA SPEED,X 3280 BPL PAGX 3290 ; 3300 LDA PDIRECTION,X ;Moving L/R 3310 AND #$40 ;Move left bit. 3320 BNE PAG1 ;If moving left. 3330 ; 3340 LDA CURRPLR ;Moving right, 3350 JSR MOVERIGHT ;Player right. 3360 JMP PAG2 ;Jump Up or Down 3370 PAG1 3380 LDA CURRPLR ;Moving left, 3390 JSR MOVELEFT ;Player left. 3400 PAG2 3410 LDX CURRPLR ;Player number. 3420 LDA PDIRECTION,X ;Moving U/D 3430 BMI PAG3 ;if moving up. 3440 ; 3450 LDA CURRPLR ;Moving down, 3460 JSR MOVEDOWN ;Player down. 3470 JMP PAGX ;Check next plr. 3480 PAG3 3490 LDA CURRPLR ;Player number 3500 JSR MOVEUP ;Player Up. 3510 PAGX 3520 LDX CURRPLR ;Unpack player 3530 DEX ;Count player. 3540 BPL PAGAIN ;Branch if more. 3550 ; 3560 RTS 3570 ; 3580 ;----------------------------- 3590 ;This is the Vertical Blank. 3600 DBLANK 3610 LDW NMIVEC,VDSLST 3620 JSR DRAWTHEM ;New position. 3630 ; 3640 LDX #ACTIVE-1 3650 PAGG1 3660 LDA HPOSITION,X ;Shadow pos 3670 STA HPOSP0,X ;into hardware. 3680 TXA 3690 PHA 3700 JSR DODRAW 3710 PLA 3720 TAX 3730 DEX ;count player... 3740 BPL PAGG1 ;..until finish. 3750 XITINT 3760 PLA ;Stock return. 3770 TAY 3780 PLA 3790 TAX 3800 PLA 3810 RTI 3820 ; 3830 ;----------------------------- 3840 ALTINT 3850 LDA #$C0 3860 STA IRQEN 3870 STA POKMSK 3880 STA NMIEN 3890 LDA #$11 ;Gang, priority. 3900 STA GPRIOR 3910 LDA # >PBASE ;Point/players. 3920 STA PMBASE 3930 LDA #3 ;Enable players. 3940 STA GRACTL 3950 LDA #$3E ;Reg playfield. 3960 STA SDMCTL 3970 LDA #3 ;Enable keyboard 3980 STA SKCTL 3990 ; 4000 LDX #0 4010 CCAGAIN 4020 LDA #0 4030 STA P0COLR,X ;Erase colors. 4040 STA P1COLR,X 4050 STA P2COLR,X 4060 STA P3COLR,X 4070 LDA #0 4080 STA P0RAM,X ;Erase players. 4090 STA P1RAM,X 4100 STA P2RAM,X 4110 STA P3RAM,X 4120 INX 4130 BNE CCAGAIN 4140 ; 4150 LDX #14 4160 PAGAIN1 4170 LDA PLRGRAF0,X ;Draw player. 4180 STA P0RAM+VP0,X 4190 LDA PLRGRAF1,X 4200 STA P1RAM+VP1,X 4210 LDA PLRGRAF2,X 4220 STA P2RAM+VP2,X 4230 LDA PLRGRAF3,X 4240 STA P3RAM+VP3,X 4250 ; 4260 LDA P0COLG,X ;Draw colors. 4270 STA P0COLR+VP0-4,X 4280 STA P1COLR+VP1-4,X 4290 STA P2COLR+VP2-4,X 4300 STA P3COLR+VP3-4,X 4310 ; 4320 DEX 4330 BPL PAGAIN1 4340 ; 4350 RTS 4360 ; 4370 ;----------------------------- 4380 NEWPAGE 4390 P0COLG 4400 .BYTE 0,P1C+4,P1C+6,P1C+8 4410 .BYTE P1C+10,P1C+0,P1C+2 4420 .BYTE P1C+4,$18,$16 4430 .BYTE $32,$38,$34,$52,0 4440 ; 4450 P1COLG 4460 .BYTE 0,$2C,$2A,$28 4470 .BYTE $26,$24,$22,$20,$18 4480 .BYTE $1A,$52,$54,$56,$58,0 4490 ; 4500 P2COLG 4510 .BYTE 0,P3C+2,P3C+4,P3C+6 4520 .BYTE P3C+8,P3C+10,P3C+12 4530 .BYTE P3C+14,P3C+64+12 4540 .BYTE P3C+64+10,P3C+32+8 4550 .BYTE P3C+32+6,P3C+16+4 4560 .BYTE P3C+16+2,0 4570 ; 4580 P3COLG 4590 .BYTE 0,P0C+2,P0C+4,P0C+6 4600 .BYTE P0C+8,P0C+10,$20 4610 .BYTE $C4,$24,$20 4620 .BYTE P0C+10,P0C+8 4630 .BYTE P0C+6,P0C+4,P0C+2,0 4640 .BYTE 0,0,0,0,0,0,0 4650 ; 4660 ;----------------------------- 4670 DODRAW 4680 STA THISPLAYER 4690 ASL A 4700 TAX 4710 ; 4720 ; Set POINTER to point at the current player shape. 4730 LDA PLAYERTABLE,X 4740 STA POINTER 4750 LDA PLAYERTABLE+1,X 4760 STA POINTER+1 4770 ; 4780 ; Set POINTER+2 to point at the current player color strip. 4790 LDA CPLAYERTABLE,X 4800 STA POINTER+2 4810 LDA CPLAYERTABLE+1,X 4820 STA POINTER+3 4830 ; 4840 ; The following example of self- modifying code should never 4850 ; be used whenever there is the slightest chance the code will 4860 ; wind up in ROM. I use it here because this is only a 4870 ; demonstration program. 4880 ; We pick up the source of each players colors in turn and 4890 ; physically modify the address at Label RAMPOINTER. 4900 ; 4910 LDA SPLAYERTABLE,X 4920 STA RAMPOINTER+1 4930 LDA SPLAYERTABLE+1,X 4940 STA RAMPOINTER+2 4950 ; 4960 LDA GPLAYERTABLE,X 4970 STA GRAMPOINTER+1 4980 LDA GPLAYERTABLE+1,X 4990 STA GRAMPOINTER+2 5000 ; 5010 ; Then get this players current vertical position into .Y 5020 LDX THISPLAYER 5030 LDA VPOSITION,X 5040 TAY 5050 ; Now redraw the picture. 5060 LDX #0 5070 GRAMPOINTER 5080 LDA PLRGRAF0,X 5090 STA (POINTER),Y 5100 TYA 5110 SEC 5120 SBC #4 5130 TAY 5140 ; Getting the colors through the self-modified pointer. 5150 RAMPOINTER 5160 LDA P0COLG,X 5170 STA (POINTER+2),Y 5180 CLC 5190 TYA 5200 ADC #5 5210 TAY 5220 INX 5230 CPX #20 5240 BCC GRAMPOINTER 5250 ; 5260 RTS 5270 ; 5280 ;----------------------------- 5290 ; The next four routines are all identical in operation. 5300 ; Enter with desired player in the accumulator. Try to move 5310 ; in the desired direction. If not a good move, return to 5320 ; original position and toggle the direction flag. 5330 MOVEUP 5340 TAX 5350 SEC 5360 LDA VPOSITION,X 5370 SBC VSTEP,X 5380 STA VPOSITION,X 5390 CMP #YMIN+1 5400 BCS MUX 5410 ; 5420 CLC 5430 ADC VSTEP,X 5440 STA VPOSITION,X 5450 MU1A 5460 LDA RANDOM 5470 AND #3 5480 BEQ MU1A 5490 ; 5500 STA VSTEP,X 5510 LDA PDIRECTION,X 5520 EOR #$80 5530 STA PDIRECTION,X 5540 MUX 5550 RTS 5560 ; 5570 ;----------------------------- 5580 MOVEDOWN 5590 TAX 5600 CLC 5610 LDA VPOSITION,X 5620 ADC VSTEP,X 5630 STA VPOSITION,X 5640 CMP #YMAX-1 5650 BCC MDX 5660 ; 5670 SEC 5680 SBC VSTEP,X 5690 STA VPOSITION,X 5700 MD1A 5710 LDA RANDOM 5720 AND #3 5730 BEQ MD1A 5740 ; 5750 STA VSTEP,X 5760 LDA PDIRECTION,X 5770 EOR #$80 5780 STA PDIRECTION,X 5790 MDX 5800 RTS 5810 ; 5820 ;----------------------------- 5830 MOVELEFT 5840 TAX 5850 SEC 5860 LDA HPOSITION,X 5870 SBC HSTEP,X 5880 STA HPOSITION,X 5890 CMP #XMIN+1 5900 BCS GOLX 5910 ; 5920 CLC 5930 ADC HSTEP,X 5940 STA HPOSITION,X 5950 GOL1A 5960 LDA RANDOM 5970 AND #3 5980 BEQ GOL1A 5990 ; 6000 STA HSTEP,X 6010 LDA PDIRECTION,X 6020 EOR #$40 6030 STA PDIRECTION,X 6040 GOLX 6050 RTS 6060 ; 6070 ;----------------------------- 6080 MOVERIGHT 6090 TAX 6100 CLC 6110 LDA HPOSITION,X 6120 ADC HSTEP,X 6130 STA HPOSITION,X 6140 CMP #XMAX-1 6150 BCC GORX 6160 ; 6170 SEC 6180 SBC HSTEP,X 6190 STA HPOSITION,X 6200 GOR1A 6210 LDA RANDOM 6220 AND #3 6230 BEQ GOR1A 6240 ; 6250 STA HSTEP,X 6260 LDA PDIRECTION,X 6270 EOR #$40 6280 STA PDIRECTION,X 6290 GORX 6300 RTS 6310 ; 6320 ;----------------------------- 6330 .BYTE "(c) 1985, " 6340 .BYTE "ANTIC PUBLISHING" 6350 ENDCODE 6360 *= $02E0 6370 .WORD STARTOFCODE 6380 .OPT NO LIST 6390 .END