Atari Assembly Language Game
A descriptive paragraph that tells clients how good you are and proves that you are the best choice that they’ve made.
This page explains how to create a simple game using Atari Basic 800/XL/XE. For easier reference I have created a listing of the code first following how the program works.
MAC/65 variables
10 ;*********************************
20 ;******** DEADMAN Part 1 *********
30 ;
40 .OPT NO LIST
50 ; CREATED 7/25/07
60 ; NEW CHANGES: 8/13/12
70 ;
80 ;Player missile move routine
90 ;Using a redefined char set
100 ;in GRAPHICS 1
110 ;
120 ;DM1.m65
130 *= 32768
140 JMP demo
150 ;
160 COLOR0 = $02C4
170 COLCRS = $55
180 ROWCRS = $54
190 ATACHR = $02FB
200 STORE1 = $CC
210 STOCOL = $CD
220 ;
230 ;VBI registers
240 ;
250 COLBK = $D01A
260 BMIEN = 54286
270 WSYNC = 54282
280 SETVBK = $E45C
290 XITVBK = $E462
300 SYSVBV = $E45F
310 INTL = 512
320 INTH = 513
330 ;
340 CHSET = 57344
350 CHBAS = $02F4
360 NEWADR = 20480
370 TABLEN = 1024
380 MVSRCE = 176 ;ZERO PTR
390 MVDEST = MVSRCE+2 ;DITTO
400 CHRADR = MVDEST+2 ;DITTO
410 ;
420 LENPTR = 24576 ;Another pointer
430 RAMCHR = LENPTR+2 ;DITTO
440 ;
450 ICHID = $0340
460 ICDNO = $0341
470 ICCOM = $0342
480 ICSTA = $0343
490 ICBAL = $0344
500 ICBAH = $0345
510 ICPTR = $0346
520 ICPTH = $0347
530 ICBLL = $0348
540 ICBLH = $0349
550 ICAX1 = $034A
560 ICAX2 = $034B
570 CIOV = $E456
580 ;other equates needed
590 YLoc = 204 ;in adr. for Y
600 XLOC = 206 ;to remb. X pos
610 YLOC2 = 208
620 XLOC2 = 210
630 YLOC3 = 94
640 INITX2 = 1540
650 INITY2 = 1541
660 INITY3 = 1542
670 INITX = $D0 ;initial X val
680 INITY = $D1
690 ;INITY2 = $D2
700 STOTOP = $0100 ;temp. storage
710 STICK = $D000 ;hardw. STICK(0)
720 ;HPOSP0 = $D000 ;horz. pos P0
730 HPOSM0 = 53252 ;missile 0
740 HPOSM1 = 53253 ;missile 1
750 HPOSM2 = 53254 ;missile 2
760 HPOSM3 = 53255 ;missile 3
770 HITCLR = 53278 ;PMG collisions
780 ;
790 GRAFP1 = 53262 ;Player 2 to player collisions
800 GRAFP2 = 53263 ;Player 3 to player collisions
810 GRAFP3 = 53264 ;Joystick trigger 0 (644)
0820 ;
830 RAMTOP = $6A ;TOP OF RAM PTR
840 VVBLKD = $0224 ;INTERRUPT RTN
850 SDMCTL = $022F ;DMA CNT. SHADOW
860 SDLST = $0231 ;SDLST. LOW BYTE
870 STICK0 = $0278
880 PCOLR0 = $02C0 ;PMG COLOR
890 COLOR2 = $02C6 ;BKG COLOR |
900 HPOSP0 = $D000 ;PMG HORZ PSN
910 GRACTL = $D01D
920 PACTL = $D302 ;JS PORT CNTRL
930 PMBASE = $D407 ;PM BASE ADR
940 SETVBV = $E45C ;ENABLE INTRPT
950 XITVBV = $E462 ;EXIT INTERRUPT
960 HRZPTR = $BC00 ;HORIZ PSN PTR
970 VRTPTR = HRZPTR+1 ;VRT PSN PTR
980 OURBAS = VRTPTR+1 ;OUR PMBASE
990 TABSIZ = OURBAS+2 ;TABLE SIZE
1000 FILVAL = TABSIZ+2 ;BLKFIL VALUE
1010 TABPTR = $B0 ;TABLE ADDR PTR
1020 TABADR = TABPTR+2 ;TABLE ADDRESS
1030 PLBOFS = 512 ;PMG BAS OFFS
1040 PLTOFS = 640 ;PMG TOP OFFS
1050 DLICOL .DS 1
1060 COLMSK .DS 1
1070 GENER .DS 2
1080 DISP = 0
1090 X1 .DS 100
1100 C1 .DS 1
1110 ROOM .DS 1
1120 SCR .DS 1 1130 SCORE .DS 1 1140 LEVEL .DS 1 1150 MULTCOL .DS 1
1160 DIR .DS 1
1170 ENMYPOS .DS 1 ;ENEMY Y POSITION
1180 SAVEINY .DS 1
1190 SAVELCY .DS 1
1200 BALLY .DS 1 ;BALL'S Y POS.
1210 JMPRANGE .BYTE 0
1220 MESG .SBYTE "I FIGURED IT OUT!"
Delay loop
1240 ;Rainbow DLI. Multicolor plyr.
1250 ;
1260 SLOWDN
1270 LDY #200
1280 LDX #10
1290 CNTSLW DEX
1300 BNE CNTSLW
1310 INY
1320 BNE CNTSLW
1330 RTS
Clear the graphics screen
1340 CLRSCR
1350 LDA #125
1360 JSR COLOR
1370 LDA #0
1380 LDX #0
1390 LDY #0
1400 JSR PLOT
1410 RTS
check which room player is in
1420 CHKROOM
1430 JSR CLRSCR ;clear screen
1440 LDA ROOM
1450 CMP #30
1460 BEQ RM30
1470 CMP #31
1480 BEQ RM31
1490 CMP #32
1500 BEQ RM32
1510 RTS
subroutine to draw the rooms
1520 RM30
1530 JSR DRWLEVEL
1540 JSR LAD1
1550 RTS
1560 RM31
1570 JSR DRWLEVEL
1580 JSR LAD2
1590 RTS
1600 RM32
1610 JSR DRWLEVEL
1620 RTS
draw rooms on the graphics 1 screen
The code below actually draws the Graphics rooms you see in the above screenshots. First we store a random value in memory location 705 for the color. Then we set the display list in lines 1660-1780. Lines 1720-1970 draw the complete screens. I will explain one part so the rest will make sense. In line 1720 we initialize a Y loop to draw the top part of the screen. The LDA SCLINE1,Y is reading from an SBYTE data storage area to draw the top half of the screen. The STA 37952,Y plots it into screen memory. The Y is looped with DEY until it returns to zero again. This allows 256 bytes to be draw to the screen. The rest of the code continues to draw down the screen until everything is done.
1630 DRWLEVEL
1640 LDA 53770 ;get a random number
1650 STA 705
1660 TOSCR
1670 ; LDA #LST&255
1680 ; STA 560
1690 ; LDA #LST/256
1700 ; STA 561
1710 ;
1720 LDY #0
1730 GTLN1 LDA SCLINE1,Y
1740 STA 37952,Y
1750 DEY
1760 BNE GTLN1
1770 LDY #0
1780 GTLN2 LDA SCLINE2,Y
1790 STA 38192,Y
1800 DEY
1810 BNE GTLN2
1820 LDY #0
1830 GTLN3 LDA SCLINE3,Y
1840 STA 38432,Y
1850 DEY
1860 BNE GTLN3
1870 LDY #0
1880 GTLN4 LDA SCLINE4,Y
1890 STA 38632,Y
1900 DEY
1910 BEN GTLN4
1920 LDY #40
1930 GTLN5 LDA SCLINE5,Y
1940 STA 38872,Y
1950 DEY
1960 BNE GTLN5
1970 RTS
Calculate the Game Score
The code below (GETLEVEL) draws the score that is seen in the game. It works by converting ASCII characters to a number format. The numbers are created in the 1’s, 10’s, and 100’s place to make up the complete digits. The SCORE, SCORE+1, etc is used to keep track of the score as it increases. Lines 2460-2660 are used to plot the numbers in the correct place in screen memory.
1980 GETLEVEL
1990 PHA
2000 SED
2010 LDA LEVEL
2020 CLC
2030 ADC #1
2040 STA LEVEL
2050 CLD
2060 JSR SHOWGEN
2070 PLA
2080 ; LDY #0
2090 RTS
2100 SHOWSCORE
2110 PHA
2120 SED
2130 JSR SLOWDN
2140 LDA SCORE
2150 CLC
2160 ADC #1
2170 STA SCORE
2180 LDA SCORE+1
2190 ADC #0
2200 STA SCORE+1
2210 LDA SCORE+2
2220 ADC #0
2230 STA SCORE+2
2240 CLD
2250 JSR SHOWGEN
2260 PLA
2270 LDY #0
2280 RTS
2290 SHOWLEV
2300 LDY #14
2310 LDX #80
2320 LDA LEVEL+1
2330 JSR BCD
2340 LDA LEVEL
2350 JMP BCD
2360 RTS
2370 SHOWGEN
2380 LDY #14
2390 LDX #80
2400 LDA SCORE+1
2410 JSR BCD
2420 LDA SCORE
2430 JMP BCD
2440 RTS
2450 ;
2460 BCD
2470 PHA
2480 SEC
2490 ROR A
2500 LSR A
2510 LSR A
2520 LSR A
Write out the Game Score
Now that our accumulator contains the score data, we can write it out to screen memory from 37944, 38024, and 38037.
2530 ; STA 37944,Y
2540 STA 38024,Y
2550 LDA LEVEL
2560 STA 38037,Y ;store num in 1's place
2570 INY
2580 PLA
2590 AND #15
2600 ORA #16
2610 ; STA 37944,Y
2620 STA 38024,Y
2630 LDA LEVEL+1
2640 STA 38037,Y ;store num in 10's place
2650 INY
2660 RTS
Activate the vbis (Vertical Blank Interrupts)
The code below creates the smooth animation of the moving ball and flowing stream as seen in the game.
2670 VBI
2680 PHA
2690 TXA
2700 PHA
2710 ;
2720 ;river animation
2730 ;
2740 BGSHFT
2750 LDY #16
2760 SHFRT LDA (CHRADR),Y
2770 LSR A ;divide result by 2
2780 BCC STORE
2790 CLC
2800 ADC #128 ;add 128 to answer
2810 STORE STA (CHRADR),Y
2820 INY
2830 CPY #24 ;get next 24 chars
2840 BNE SHFRT
2850 ;
2860 ;CHECK DIRECTION OF ENEMY
2870 ;
2880 FLIP1
2890 LDA #255
2900 STA 53261
2910 STA 53262
2920 ; JSR MKANIM
2930 ; JSR BALLVELDWN