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 ›