Jump to content
IGNORED

More Than 4k For DPC+ Graphics?


Cybearg

Recommended Posts

It's a shame that, with how much detail DPC+ allows, you're limited to just the 4k of the final bank for all sprite and playfield data. Is there any way to increase that amount or to allow sprite and/or playfield data to be spread across different banks?

 

Also, did RevEng ever make a version of DPC+ that takes advantage of ROMS greater than 32k?

Link to comment
Share on other sites

The DPC+ bankswitch format, which bB DPC+ uses, is defined as a 32K image containing:

  • 3K of ARM code (the DPC+ driver)
  • six 4K banks for code
  • one 4K bank for graphic data
  • 1K of ARM data (note frequencies for music generation)

It can't be any larger, or any smaller. It's possible a new version of the DPC+ bankswitching format could be done for Harmony Encore, though I suspect it'll be a long time before that would happen.

 

The 4K of graphic data does end up in RAM as RAM is significantly faster for the ARM code to access than ROM. That extra speed is required in order for DPC+ to work. You could use the DPC+ copy feature to manipulate what's in RAM in order to utilize more than 4K of graphics - I do that in my games, though I use C code instead of the DPC+ copy feature to do the copying. In order to do this in bB would require an understanding of how bB uses DPC+ bankswitching, so that's not something I could help you with. batari mentions how to use the copy feature here (along with the fill feature).

  • Like 2
Link to comment
Share on other sites

ScumSoft posted an Assembly function that is supposed to do this sort of thing:

            MAC COPY2RAM
.source      SET {1}
.destination SET {2}
.amount      SET {3}
.mode        SET {4}

            LDA #<.destination
            STA DF0LOW
            LDA #(>.destination) & $0F
            STA DF0HI

            lda #<.source
            sta PARAMETER ;byte pointer increments on write
            lda #((>.source) & $0f) | (((>(.source)) / 2) & $70)
            sta PARAMETER
            lda #0        ;Using DataFetcher #0
            sta PARAMETER
            lda #.amount  ;256 bytes copy max
            sta PARAMETER
            lda .mode
            sta CALLFUNCTION
            ENDM

Now, is this actually complete, or is PARAMETER just pseudo-code? I don't see what PARAMETER and CALLFUNCTION refer to.

 

Also, how do I know exactly which RAM locations to overwrite? That is, if I have a number of sprite and playfield definitions, how can I tell which location needs to be swapped out?

 

Also, does the entirely of that 4k of graphics ROM get copied to 4k of RAM in one go, or does it get copied over in smaller chunks as it's referenced?

Link to comment
Share on other sites

PARAMETER and CALLFUNCTION are DPC+ registers. They're defined in DPCplus.h

 

The .amount is a single byte, so you can copy from 0-255 bytes. It's possible that passing 0 means "copy 256", though I don't know for sure.

 

As for locations to swap out, you'll need somebody familiar with bB's usage of DPC+ to tell you that.

Link to comment
Share on other sites

Thanks for the information! I'll look into it.

Anything come of this?

 

You could do what I do and make playfield pixels in data statements, thus using the ROM batari Basic banks for the data and leaving the graphics bank free for other things.

 

Also is it easy to "Tell virtual Player3 to use Player0's color?" and save space there? I thought you were looking into that also.

Link to comment
Share on other sites

Also is it easy to "Tell virtual Player3 to use Player0's color?" and save space there? I thought you were looking into that also.

On this, and on getting both sprite and color data shared between sprites, I have a question...

 

Here is an example of my current set-up:

.L0129 ;  on frame goto __Stand __Stand __Stand __Stand __WalkA __WalkB __WalkA __WalkC

	LDX frame
	LDA .L0129jumptablehi,x
	PHA
	LDA .L0129jumptablelo,x
	PHA
	RTS
.L0129jumptablehi
	.byte >(.__Stand-1)
	.byte >(.__Stand-1)
	.byte >(.__Stand-1)
	.byte >(.__Stand-1)
	.byte >(.__WalkA-1)
	.byte >(.__WalkB-1)
	.byte >(.__WalkA-1)
	.byte >(.__WalkC-1)
.L0129jumptablelo
	.byte <(.__Stand-1)
	.byte <(.__Stand-1)
	.byte <(.__Stand-1)
	.byte <(.__Stand-1)
	.byte <(.__WalkA-1)
	.byte <(.__WalkB-1)
	.byte <(.__WalkA-1)
	.byte <(.__WalkC-1)
.
 ; 

.__Stand
 ; __Stand

.L0130 ;  player0:

	LDX #<playerL0130_0
	STX player0pointerlo
	LDA #((>playerL0130_0) & $0f) | (((>playerL0130_0) / 2) & $70)
	STA player0pointerhi
	LDA #30
	STA player0height
.
 ; 

I wonder, though, instead of that on...goto using pointers to branch, could I instead have the player0: code just reference a table of hi and lo pointers to the graphics data itself? This way, all it would take would be a duplicate of those 6 lines of ASM and using the same sprite pointer table to allow sprite data to be easily shared across all sprites. without ever having to re-define sprites.

 

I did this in the past with my Piñata collection. In Fixer Fenix, Wrecker Ron can re-use sprites between his left and right side, cutting out any duplication of sprite data. To do this, I had to use a tweaked bit of ASM:

 asm

setRalph
	LDX ralphstate
	LDA ralphLlo,x
	STA player0pointerlo
	LDA ralphLhi,x
	STA player0pointerhi
	LDA ralphRlo,x
	STA player1pointerlo
	LDA ralphRhi,x
	STA player1pointerhi
	LDA #17
	STA player0height
	STA player1height
end

... which referenced a table of sprite data pointers:

ralphLlo
	.byte <ralphStandA
	.byte <ralphClimbA
	.byte <ralphClimbB
	.byte <ralphPoundA
	.byte <ralphPoundB

ralphLhi
	.byte >ralphStandA
	.byte >ralphClimbA
	.byte >ralphClimbB
	.byte >ralphPoundA
	.byte >ralphPoundB

ralphRlo
	.byte <ralphStandA+1
	.byte <ralphClimbB+1
	.byte <ralphClimbA+1
	.byte <ralphPoundB+1
	.byte <ralphPoundA+1

ralphRhi
	.byte >ralphStandA
	.byte >ralphClimbB
	.byte >ralphClimbA
	.byte >ralphPoundB
	.byte >ralphPoundA

... which in turn referenced the actual sprite data:

 if (<*) < 90
	repeat (90-<*)
	.byte 0
	repend
	endif
ralphStandA
	.byte 0
	.byte  %00111100
	.byte  %00011110
	.byte  %11101111
	.byte  %11010111
	.byte  %11110111
	.byte  %11101111
	.byte  %11101111
	.byte  %11101111
	.byte  %11111111
	.byte  %01111110
	.byte  %00011111
	.byte  %00000101
	.byte  %00001111
	.byte  %00000101
	.byte  %00000000
	.byte  %00000000
 if (<*) > (<(*+16))
	repeat ($100-<*)
	.byte 0
	repend
	endif
 if (<*) < 90
	repeat (90-<*)
	.byte 0
	repend
	endif
ralphClimbA
	.byte 0
	.byte  %00000000
	.byte  %00011110
	.byte  %11101111
	.byte  %11010111
	.byte  %11110111
	.byte  %11101111
	.byte  %11101111
	.byte  %11101111
	.byte  %11111111
	.byte  %01111111
	.byte  %00011111
	.byte  %00000111
	.byte  %00001111
	.byte  %00000101
	.byte  %00000000
	.byte  %00000000
 if (<*) > (<(*+16))
	repeat ($100-<*)
	.byte 0
	repend
	endif
 if (<*) < 90
	repeat (90-<*)
	.byte 0
	repend
	endif
ralphClimbB
	.byte 0
	.byte  %00111100
	.byte  %00011110
	.byte  %00001111
	.byte  %00000111
	.byte  %00000111
	.byte  %00001111
	.byte  %00001111
	.byte  %00001111
	.byte  %01111111
	.byte  %11111111
	.byte  %11111111
	.byte  %11100111
	.byte  %11101111
	.byte  %11110101
	.byte  %11010000
	.byte  %11100000
 if (<*) > (<(*+16))
	repeat ($100-<*)
	.byte 0
	repend
	endif
 if (<*) < 90
	repeat (90-<*)
	.byte 0
	repend
	endif
ralphPoundA
	.byte 0
	.byte  %00111000
	.byte  %00111000
	.byte  %00111100
	.byte  %00111100
	.byte  %00111000
	.byte  %00111000
	.byte  %00111000
	.byte  %00111001
	.byte  %00111010
	.byte  %00111110
	.byte  %00011111
	.byte  %00000101
	.byte  %01111111
	.byte  %11111111
	.byte  %11111111
	.byte  %10001111
 if (<*) > (<(*+16))
	repeat ($100-<*)
	.byte 0
	repend
	endif
 if (<*) < 90
	repeat (90-<*)
	.byte 0
	repend
	endif
ralphPoundB
	.byte 0
	.byte  %00000000
	.byte  %00000000
	.byte  %00000000
	.byte  %11100000
	.byte  %11100000
	.byte  %11110000
	.byte  %11110000
	.byte  %11100001
	.byte  %11100010
	.byte  %11111110
	.byte  %01111111
	.byte  %00000101
	.byte  %01111111
	.byte  %11111111
	.byte  %11111111
	.byte  %10001111

...changing what otherwise would have required sprite definitions for both player0 and player1 into just single sprite definitions, saving a LOT of space. This would work the same for color data.

 

However, those were with 4k games, where I could just add that sprite data at the end of the .bas file in asm...end statemetns and I was fine. In DPC+, I apparently can't directly put the necessary sprite code into the last bank because that's off-limits. Furthermore, the pointers seem a lot more complicated.

 

Is there a way that I CAN include the sprite data to be added in the final bank? Would it just simply involve modifying the includes file to add the sprite.asm file after the bB.asm file? Would there be complications in using tables of pointers in this way for DPC+ sprite data?

 

Also, what are the limitations of using these kinds of pointers? Can you actually create pointers and pointer-pointers using this table >pointer <pointer notation?

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