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 ›