maguman Posted June 10, 2008 Share Posted June 10, 2008 Hi I've been programming in 6502 for a few years, but have only recently moved onto the Atari 8-bit. (I have an 800, and its great.) I'm having a lot of fun with Mac/65, but I have hit a small snag. I wanted to look at writing some pretty simple games in assembler to familiarise myself better with the 8-bit hardware & how it works. I started with a simple joystick moving a player routine & started to work up. From what I have read, it seems that doing movement/collision testing etc is best accomplished inside a VBI routine. I grabbed a copy of the routine from Atari Roots, fixed up the glitches and it works fine. Now I want to move onto drawing playfields and detecting player-playfield collisions. My biggest issue is this. How do I draw a playfield so that both it and the player are stable at once? Just writing bytes to memory doesn't cut it - tried replacing the blanks at the start of the routine above as a simple test. Clearly something needs synching, but I am not familiar enough with the 8-bit hardware. Do I need to set up some form of DLI to set the graphics screen the way I want (and then have the screen in RAM)? Appreciate any advice/suggestions/help. Quote Link to comment Share on other sites More sharing options...
Rybags Posted June 10, 2008 Share Posted June 10, 2008 For a rudimentary game with a few PMG objects moving against a mostly static background, there should be no issue - there is heaps of time before the screen is started to be drawn for you to update everything. Although, having said that, it is entirely possible to have an "inefficient" PMG routine. Worst case scenario might be something that blanks 5x256 bytes of PMG data, then writes back each object - that would use a lot of time. Also, remember with PMG collision events that they are only triggered when the relevant part of the screen is displayed. e.g. if you position a Player around character pos. 0,0 and there's a character there, but you blank it just before that part of the screen is drawn, then there will be no collision registered. Another problem might crop up if you're doing scrolling by moving memory - if you update the screen while the beam is drawing it you can get tearing effects, blinking, flickering or blank areas. In such case, the alternative could be to have a DLI near the bottom of the display and begin your updates there instead of the VBI. Or, another alternative altogether is page-flipping/double buffering. Quote Link to comment Share on other sites More sharing options...
maguman Posted June 10, 2008 Author Share Posted June 10, 2008 Thanks Rybags. I never got as far as doing the collisions. Prior to looking into VBI, I had implemented code with collisions without a VBI, but the collision detection was far from ideal, so I switched over. Here is the code (from Atari Roots). If I just switch from writing blanks to memory to writing some other values (at line 410), I get scrolling gibberish with a 'stable' player. I was trying the simplest thing. Should I use a DLI? I didn't think I'd need to draw a static screen from inside the VBI routine (which currently just checks the joystick). 10 ; 20 ; PLAYER-MISSLE GRAPHICS ROUTINE 30 ; 40 .OPT OBJ 45 .OPT NO LIST 50 *= $5000 60 JMP START 70 ; 80 RAMTOP = $6A ;TOP OF RAM PTR 90 VVBLKD = $0224 ;INTERRUPT RTN 0100 SDMCTL = $022F ;DMA CNT. SHADOW 0110 SDLSTL = $0230 ;SDLST, LOW BYTE 0120 STICK0 = $0278 0130 PCOLR0 = $02C0 ;PLAYER COLOR 0140 COLOR2 = $02C6 ;BKG COLOR 0150 ; 0160 HPOSP0 = $D000 ;PLAYER HORZ PSN 0170 GRACTL = $D01D 0180 PACTL = $D302 ;JS PORT CNTRL 0190 PMBASE = $D407 ;PM BASE ADR 0200 SETVBV = $E45C ;ENABLE INTRPT 0210 XITVBV = $E462 ;EXIT INTERRUPT 0220 ; 0230 HRZPTR = $0600 ;HORIZ PSN PTR 0240 VRTPTR = HRZPTR+1 ;VRT PSN PTR 0250 OURBAS = VRTPTR+1 ;OUR PMBASE 0260 TABSIZ = OURBAS+2 ;TABLE SIZE 0270 FILVAL = TABSIZ+2 ;BLKFIL VALUE 0280 ; 0290 TABPTR = $B0 ;TABLE ADDR PTR 0300 TABADR = TABPTR+2 ;TABLE ADDRESS 0310 ; 0320 PLBOFS = 512 ;PLAYER BAS OFFS 0330 PLTOFS = 640 ;PLAYER TOP OFFS 0340 ; 0345 POSIZE = 10 0350 SHAPE .BYTE 0,92,92,72,255,93,28,20,54,0 0360 ; 0370 START 0380 ; 0390 ;CLEAR SCREEN 0400 ; 0410 LDA #0 0420 STA FILVAL 0430 LDA SDLSTL 0440 STA TABPTR 0450 LDA SDLSTL+1 0460 STA TABPTR+1 0470 LDA #960&255 ;BYTES PER SCRN 0480 STA TABSIZ 0490 LDA #960/256 0500 STA TABSIZ+1 0510 JSR BLKFIL 0520 ; 0530 ;DEFINE PMG VARIABLES 0540 ; 0550 LDA #0 0560 STA COLOR2 ;BLACK BKG 0570 LDA #$58 0580 STA PCOLR0 ;PINK PLAYER 0590 ; 0600 LDA #100 ;SET HORIZ PSN 0610 STA HRZPTR 0620 STA HPOSP0 0630 ; 0640 LDA #48 ;SET VERT PSN 0650 STA VRTPTR 0660 ; 0670 LDA #0 ;CLEAR OURBASE 0680 STA OURBAS 0690 STA OURBAS+1 0700 ; 0710 SEC 0720 LDA RAMTOP 0730 SBC #8 0740 STA PMBASE ;BASE=RAMTOP-2K 0750 STA OURBAS+1 ;SAVE BASE ADR 0760 ; 0770 LDA #46 0780 STA SDMCTL ;ENABLE PM DMA 0790 ; 0800 LDA #3 0810 STA GRACTL ;ENABLE PM DSPLY 0820 ; 0830 ;FILL PM RAM W/ZEROS TO CLEAR 0840 ; 0850 CLC 0860 LDA OURBAS 0870 ADC #PLBOFS&255 0880 STA TABADR 0890 STA TABPTR 0900 LDA OURBAS+1 0910 ADC #PLBOFS/256 0920 STA TABADR+1 0930 STA TABPTR+1 0940 ; 0950 SEC 0960 LDA #PLTOFS&255 0970 SBC #PLBOFS&255 0980 STA TABSIZ 0990 LDA #PLTOFS/256 1000 SBC #PLBOFS/256 1010 STA TABSIZ+1 1020 ; 1030 LDA #0 1040 STA FILVAL 1050 JSR BLKFIL 1060 ; 1070 ;DEFINE PLAYER 1080 ; 1090 PLAYER 1100 ; 1110 ;DRAW PLAYER 1120 ; 1130 JSR DRAWPL 1140 ; 1150 ;ENABLE INTERRUPT 1160 ; 1170 LDY #INTRPT&255 1180 LDX #INTRPT/256 1190 LDA #7 1200 JSR SETVBV 1210 ; 1220 INTRPT 1230 LDA #RDSTIK&255 1240 STA VVBLKD 1250 LDA #RDSTIK/256 1260 STA VVBLKD+1 1270 ; 1280 ;INFINITE LOOP 1290 ; 1300 INFIN 1310 JMP INFIN 1320 ; 1330 ;READ JOYSTICK 1340 ; 1350 RDSTIK 1360 LDA #4 1370 ORA PACTL ;SET BIT #5 1380 ; 1390 LDA STICK0 1400 CMP #$0F ;JS STRAIGHT UP? 1410 BEQ RETURN ;YES, NO ACTION 1420 ; 1430 TRYAGN 1440 CMP #$07 ;RIGHT MOVE 1450 BNE TRYAG2 1460 LDX HRZPTR 1470 INX 1480 STX HRZPTR 1490 STX HPOSP0 1500 JMP RETURN 1510 ; 1520 TRYAG2 1530 CMP #$0B ;LEFT MOVE 1540 BNE TRYAG3 1550 ; 1560 LDX HRZPTR 1570 DEX 1580 STX HRZPTR 1590 STX HPOSP0 1600 JMP RETURN 1610 ; 1620 TRYAG3 1630 CMP #$0D ;DOWN MOVE 1640 BNE TRYAG4 1650 ; 1660 INC VRTPTR 1670 JSR DRAWPL 1680 JMP RETURN 1690 ; 1700 TRYAG4 1710 CMP #$0E ;UP MOVE 1720 BNE RETURN 1730 ; 1740 DEC VRTPTR 1750 JSR DRAWPL 1760 JMP RETURN 1770 ; 1780 RETURN 1790 JMP XITVBV 1800 ; 1810 ;BLOCK FILL ROUTINE 1820 ; 1830 BLKFIL 1840 ; 1850 ;DO FULL PAGES FIRST 1860 ; 1870 LDA FILVAL 1880 LDX TABSIZ+1 1890 BEQ PARTPG 1900 LDY #0 1910 FULLPG 1920 STA (TABPTR),Y 1930 INY 1940 BNE FULLPG 1950 INC TABPTR+1 1960 DEX 1970 BNE FULLPG 1980 ; 1990 ;DO REMAINING PARTIAL PAGE 2000 ; 2010 PARTPG 2020 LDX TABSIZ 2030 BEQ FINI 2040 LDY #0 2050 ; 2060 PARTLP 2070 STA (TABPTR),Y 2080 INY 2090 DEX 2100 BNE PARTLP 2110 ; 2120 FINI 2130 RTS 2140 ; 2150 DRAWPL 2160 PHA ;SAVE ACC VALUE 2170 CLC 2180 LDA TABADR 2190 ADC VRTPTR 2200 STA TABPTR 2210 LDA TABADR+1 2220 ADC #0 2230 STA TABPTR+1 2240 ; 2250 LDA #0 2260 FILLPL 2270 LDA SHAPE,Y 2280 STA (TABPTR),Y 2290 INY 2300 CPY #POSIZE 2310 BCC FILLPL ;REPEAT TILL DONE 2320 PLA ;RESTORE ACC VAL 2330 RTS Quote Link to comment Share on other sites More sharing options...
kenfused Posted June 10, 2008 Share Posted June 10, 2008 (edited) 0430 LDA SDLSTL 0440 STA TABPTR 0450 LDA SDLSTL+1 0460 STA TABPTR+1 SDLSTL doesnt point to the screen data, it points to the display list that tells the program how to draw the screen. Random data stored there will probably put all kind of random graphics modes on the screen. locations 88 and 89 (decimal) should point to a screen that was created by the OS. Edited June 10, 2008 by kenfused Quote Link to comment Share on other sites More sharing options...
Rybags Posted June 11, 2008 Share Posted June 11, 2008 +1 use locations $58,$59 to find the screen memory. And, you can't be 100% reliant on them either, because if you have a text-windowed graphics mode, they are also used to address the text window when it's accessed. So, the best bet is to open the screen, and immediately copy the screen pointer somewhere before you start doing anything else. Quote Link to comment Share on other sites More sharing options...
maguman Posted June 11, 2008 Author Share Posted June 11, 2008 Ack & thanks for the help. Missed the display list vs screen memory address thingo. I think I will go and change my name to Mr G Oat. If it is setting up a blank display list (effectively), then I should be able to set up any other one (e.g. a screen in Graphics mode 3) and then point to screen memory with something useful to plot. I am only after static (non-scrolling) screens, so that should about do it. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.