Jump to content
IGNORED

Simple VBI/PM graphics question?


maguman

Recommended Posts

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 

Link to comment
Share on other sites

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 by kenfused
Link to comment
Share on other sites

+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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...