
PROGRAM LISTING: 86-02a/MCP.M65
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
Back to previous page