Jump to content

Photo

Harmony DPC+ programming


89 replies to this topic

#1 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sun May 23, 2010 12:32 PM

With the release of BIOS 1.05, the Harmony cartridge now supports programs with custom bank switch routines. DPC+ is the first to be released.

DPC+ expands upon the capabilities of the DPC chip found in Pitfall II. The original DPC supported two 4K banks and 2K of Display Data (holds graphics and other data). DPC+ expands that to six 4K banks and 4K of Display Data and adds some new features such as "Fast Fetcher" mode. Some DPC features are not supported by the DPC+ (mostly those not used by Pitfall II).


This demo shows off all the features of DPC+, with the exception of custom ARM code. I plan to release that demo next weekend. For in depth information on the features, read the comments at the start of DPCplus.asm as well as the comments in DPCplus.h.

Your code should result in a 29K BIN file. It should then be merged with DPC+.arm, which contains the custom bank switching code, to result in a 32K BIN file. When merging, the DPC+.arm file must come first.

With the exception of custom ARM code, Stella also supports DPC+ so you can test and debug your programs via Stella. Use version 3.1.2 or higher.

This code includes 6 demos, one for each 4K bank. Use GAME SELECT to cycle between the demos.

Demo 0 - Data Fetcher Demo
  • Shows how to use the Data Fetchers in both "Windowed" and "non-windowed" modes.
  • Joystick moves sprite, fire button changes image (unless qualified, "joystick" refers to the left joystick)
  • DPC+ demo.bin.png
Demo 1 - Music Demo
  • Joystick disables voices via fire, right and/or down
  • Right Joystick selects waveforms. Fire, up, down, left, right
  • sprites are used to display the amplitude in real time
  • DPC+ demo.bin_6.png
Demo 2 - Fractional Data Fetcher Demo
  • Draws an asymmetrical playfield where the playfield data is repeated over multiple lines
  • Joystick up/down controls the fractional increment amount
  • DPC+ demo.bin_2.png
Demo 3 - Random Number Demo
  • Shows off the 32 bit random number generator
  • Joystick left to select prior set of random numbers
  • Joystick right to select next set of random numbers
  • Fire to reset the generator to the initial random seed
  • DPC+ demo.bin_3.png
Demo 4 - Data Writer Demo
  • Unlike the DPC cartridge, the DPC+ Display Data ends up in RAM and can be modified at run time.
  • Joystick to move snowman - notice when he moves on/off screen he is masked to smoothly enter/exit the display. (compare with Demo 0)
  • Fire to flip snowman - this shows the difference between DFxWRITE and DFxPUSH.
  • DPC+ demo.bin_4.png
Demo 5 - Fast Fetch Demo
  • Shows how to enable "Fast Fetch" mode, which overloads LDA # allowing you to read DPC+ registers in 2 cycles instead of 4
  • 29 TIA updates every 2 scanlines.
  • use both joysticks to move helicopters
  • DPC+ demo.bin_5.png

DPC+ Demo source code
Attached File  DPCplus Demo.zip   36.32KB   498 downloads

DPC+ Demo, ready for Harmony and Stella
Attached File  DPC+ demo.bin   32KB   536 downloads

#2 e1will OFFLINE  

e1will

    Moonsweeper

  • 347 posts

Posted Mon May 24, 2010 8:38 AM

This sounds really neat, I'm looking forward to playing around with this.

--Will

#3 yuppicide OFFLINE  

yuppicide

    I am the Black Knight. Give me your money!

  • 6,933 posts
  • Location:New Jersey

Posted Tue May 25, 2010 7:10 AM

Looks awesome!

#4 RevEng OFFLINE  

RevEng

    River Patroller

  • 4,724 posts
  • Bitnik
  • Location:Canada

Posted Tue May 25, 2010 8:48 AM

This is very exciting stuff! I'm also looking forward to getting my hands dirty with it!

#5 MausGames OFFLINE  

MausGames

    Dragonstomper

  • 897 posts
  • Location:MO, USA

Posted Tue May 25, 2010 11:09 AM

Thanks for posting this, it's really interesting to see what it can do.

#6 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • Topic Starter
  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Wed May 26, 2010 12:16 PM

And I'm looking forward to seeing what y'all come up with :)

I may not finish what I planned for the ARM code demo, but I will release it this weekend anyway as it does show what you need to know.

Also, don't ignore this demo if you're waiting for the forthcoming ARM Code Demo as the ARM Code Demo will assume you're already familiar with this demo. Oh, and "ARM Code" really means C Code.

#7 MausGames OFFLINE  

MausGames

    Dragonstomper

  • 897 posts
  • Location:MO, USA

Posted Wed May 26, 2010 5:47 PM

I don't have a Harmony yet, so I'll have to wait to try out the demo when you post it; I hope someone can make a video.

#8 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • Topic Starter
  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon May 31, 2010 5:04 PM

It's been a week, no questions or demos to show off?

#9 MausGames OFFLINE  

MausGames

    Dragonstomper

  • 897 posts
  • Location:MO, USA

Posted Mon May 31, 2010 5:33 PM

I can't think of any ways to use any of this with bB, other than the random number generator; it would help a lot.

#10 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • Topic Starter
  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon May 31, 2010 5:55 PM

I think batari's planning on new kernels that utilize DPC+ features. One thing it would do is decrease the conflicts, ie: "if you use this feature, missile 1 is not available".

#11 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • Topic Starter
  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Sep 27, 2010 2:19 PM

I ran into an issue using DPC+ and Fast Fetch mode and wanted to give y'all a heads up:

My original code was this:

dey		; 2 24
	cpy #10		; 2 26
	bcc ExitLoop	; 2 28
	lda #<AMPLITUDE	; 2 30 load music data for next line

The code worked fine under Stella, but crashed on a real system. Turns out that when a branch command (BCC, BCS, BEQ, etc) is used, the command immediately after is always fetched even if it ends up not being used (most likely why taking a branch is 3 cycles while not taking the branch is 2 cycles). Normally it's not a problem, but when Fast Fetch mode is turned on the ARM routines see the LDA # and ends up return a Fast Fetch value even though you didn't get to the command. This leads to unexpected results, such as the crashing.

A quick fix was this:
dey		; 2 24
	cpy #10		; 2 26
	bcc ExitLoop	; 2 28
	nop		; 2 30 - CANNOT have an LDA #< immediately after a
			;        branch instruction when using Fast Fetch mode
			;        as the 6507 always fetches instruction
			;        following the branch command.
	lda #<AMPLITUDE	; 2 32 load music data for next line

Edited by SpiceWare, Mon Sep 27, 2010 2:56 PM.


#12 DavidEth OFFLINE  

DavidEth

    Star Raider

  • 62 posts

Posted Mon Sep 27, 2010 2:37 PM

Interesting -- that must be how FE-style bankswitching works on Robot Tank then? Hardware on the cart itself sees if an opcode being fetched is a JSR or RTS and behaves accordingly. How do you tell fetching a JSR opcode (or in your case, LDA #imm) apart from just a normal data read?

(Is the source code to the Harmony BIOS available? The 1.05 download I tried only had a bunch of .arm binary files)

-Dave

#13 eshu OFFLINE  

eshu

    Moonsweeper

  • 282 posts

Posted Mon Sep 27, 2010 2:43 PM

Interesting -- that must be how FE-style bankswitching works on Robot Tank then? Hardware on the cart itself sees if an opcode being fetched is a JSR or RTS and behaves accordingly. How do you tell fetching a JSR opcode (or in your case, LDA #imm) apart from just a normal data read?

(Is the source code to the Harmony BIOS available? The 1.05 download I tried only had a bunch of .arm binary files)

-Dave


I think FE bankswitching just works by switching on any access to $FE

The main program is stored in one bank and all subroutines in the other. The stack pointer is set to $FF at startup and any jsr will push values to $FF and $FE
the rts will then pull values from $FE and $FF.

Edited by eshu, Mon Sep 27, 2010 3:05 PM.


#14 DavidEth OFFLINE  

DavidEth

    Star Raider

  • 62 posts

Posted Mon Sep 27, 2010 3:11 PM

[quote name='eshu' date='Mon Sep 27, 2010 12:43 PM' timestamp='1285620211' post='2103247']
[/quote]

I think FE bankswitching just works by switching on any access to $FE

The main program is stored in one bank and all subroutines in the other. The stack pointer is set to $FF at startup and any jsr will push values to $FF and $FE
the rts will then pull values from $FE and $FF.
[/quote]

But I thought that the cartridge is never going to see any access to $FE. In other words, bit 12 of the address line of the 6507 is wired to the "cartridge select" line?

-Dave

#15 eshu OFFLINE  

eshu

    Moonsweeper

  • 282 posts

Posted Mon Sep 27, 2010 3:17 PM

I think FE bankswitching just works by switching on any access to $FE

The main program is stored in one bank and all subroutines in the other. The stack pointer is set to $FF at startup and any jsr will push values to $FF and $FE
the rts will then pull values from $FE and $FF.


But I thought that the cartridge is never going to see any access to $FE. In other words, bit 12 of the address line of the 6507 is wired to the "cartridge select" line?

-Dave


I'm a lot better at software than hardware, so take this with a pinch of salt - but I think that is just how most carts are wired to access the (EP)ROM chips in the cart, I think the whole address bus is exposed on the cart port...

#16 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • Topic Starter
  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Sep 27, 2010 3:57 PM

(Is the source code to the Harmony BIOS available? The 1.05 download I tried only had a bunch of .arm binary files)

I've not seen the source for the Harmony BIOS, I don't think batari has released it.

With stephena's and batari's help, I did the implementation of DPC+ in Stella. It supports all but the ability to run custom ARM code. You can get that from here, look for the files CartDPCPlus.hxx and CartDPCPlus.cpp in src/emucore/.

#17 supercat OFFLINE  

supercat

    Quadrunner

  • 6,401 posts

Posted Mon Sep 27, 2010 5:45 PM

I think FE bankswitching just works by switching on any access to $FE


I've read varied descriptions of how it works. To really find out, one would have to do something like design a board which would feed address/data values to a cart with particular timings and see the result. From some descriptions, it sounded as though the FE cart might be sampling one of the data bits some time after an 01Fx access. Doing that with the proper timing would allow one to JSR/RTS between banks arbitrarily (the cycle following the second stack access will be the MSB of the next code address).

#18 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,666 posts
  • begin 644 contest

Posted Thu Sep 30, 2010 5:02 PM

I ran into an issue using DPC+ and Fast Fetch mode and wanted to give y'all a heads up:

My original code was this:

dey		; 2 24
	cpy #10		; 2 26
	bcc ExitLoop	; 2 28
	lda #<AMPLITUDE	; 2 30 load music data for next line

The code worked fine under Stella, but crashed on a real system. Turns out that when a branch command (BCC, BCS, BEQ, etc) is used, the command immediately after is always fetched even if it ends up not being used (most likely why taking a branch is 3 cycles while not taking the branch is 2 cycles). Normally it's not a problem, but when Fast Fetch mode is turned on the ARM routines see the LDA # and ends up return a Fast Fetch value even though you didn't get to the command. This leads to unexpected results, such as the crashing.

A quick fix was this:
dey		; 2 24
	cpy #10		; 2 26
	bcc ExitLoop	; 2 28
	nop		; 2 30 - CANNOT have an LDA #< immediately after a
			;        branch instruction when using Fast Fetch mode
			;        as the 6507 always fetches instruction
			;        following the branch command.
	lda #<AMPLITUDE	; 2 32 load music data for next line

The above was due to a bug in DPC+ ARM code, and it has been fixed. I have some other improvements I intend to add to the ARM code, and I'll post a new version once those are in place.

Interesting -- that must be how FE-style bankswitching works on Robot Tank then? Hardware on the cart itself sees if an opcode being fetched is a JSR or RTS and behaves accordingly. How do you tell fetching a JSR opcode (or in your case, LDA #imm) apart from just a normal data read?

(Is the source code to the Harmony BIOS available? The 1.05 download I tried only had a bunch of .arm binary files)

-Dave

I'd expect that the FE hardware is as simple as possible, and looking for opcodes is not simple for an 80's cart. Essentially, it grabs bit 5 of the PCH from the stack, which actually occurs at $01FF, or possibly just even-numbered addresses in the range $0101-$01FF (and $01FE is not an odd-numbered address, so perhaps the scheme has a misleading name.)

To work with the FE binaries, you need to invert D5 to select the bank (though the actual cart probably had the banks swapped.)

I have seen modern implementations of FE that will work with any arbitrary JSR/RTS regardless of the stack pointer, but to support the three or four existing FE games, I doubt that is necessary.

Edited by batari, Thu Sep 30, 2010 5:21 PM.


#19 supercat OFFLINE  

supercat

    Quadrunner

  • 6,401 posts

Posted Thu Sep 30, 2010 7:49 PM

I'd expect that the FE hardware is as simple as possible, and looking for opcodes is not simple for an 80's cart. Essentially, it grabs bit 5 of the PCH from the stack, which actually occurs at $01FF, or possibly just even-numbered addresses in the range $0101-$01FF (and $01FE is not an odd-numbered address, so perhaps the scheme has a misleading name.)


It would be bit 5 of the cycle following the 1FE access (could be $01FF for an RTS, or it could be the last byte of a JSR instruction). The actual bank switch needs to be delayed long enough to ensure that the operand fetch for the JSR isn't corrupted. It would seem the timing would be a little fussy. I can imagine that it might be handy, for some games, to simply switch one way on every JSR, and the other way on every RTS. That would be easy enough to do, though there are a number of ways one could do it, with differing effects for accesses other than JSR or RTS.

#20 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • Topic Starter
  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu Sep 30, 2010 9:09 PM

The above was due to a bug in DPC+ ARM code, and it has been fixed. I have some other improvements I intend to add to the ARM code, and I'll post a new version once those are in place.

Is the ability to set DPC+ registers from custom ARM code one of those improvements? That could be very handy.

#21 roland p OFFLINE  

roland p

    River Patroller

  • 2,395 posts
  • $23
  • Location:The Netherlands

Posted Sun Oct 10, 2010 1:12 AM

Is there some sort of 'Hello World' for DPC+?

#22 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • Topic Starter
  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sun Oct 10, 2010 12:02 PM

What are you looking for?

#23 roland p OFFLINE  

roland p

    River Patroller

  • 2,395 posts
  • $23
  • Location:The Netherlands

Posted Sun Oct 10, 2010 12:22 PM

What are you looking for?

I want to play around a bit with DPC. It looks very interesting and powerful. I understand that the DPC does too much to include in a hello world.

My main questions would be:
1. How do I change my source code so Stella recognises it as a DPC program? Maybe it's easier to start from a template, which includes all the banks etc.?
2. How can I use the datafetcher to display just one sprite.


Edit: maybe I should just start examining your DPCplus.asm My head was spinning the first time I read it, but maybe I can figure out what I need from it. It's just that it's a lot of code (6000+ lines) to scroll through.

#24 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • Topic Starter
  • 11,674 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sun Oct 10, 2010 3:14 PM

1 - the ROM coming out of DASM needs to be 29K, and it'll needs to be appended to the 3K DPC+.arm file (it contains the ARM code that makes it work). That's done via the CAT command in readme.txt

2 - focus on just the code in bank 0 - specifically the section that starts with the label SetFrostyShape.

SetFrostyShape:	
;----------------------------------------
; this shows how to set the Data Fetchers to draw a Sprite using a Window
; and to change the sprite colors w/out using a window
;----------------------------------------
; 	point Data Fetcher 0 to the sprite data
;	lda #<(SpriteDataPosition - HowFarDownScreen)
;	sta DF0LOW
;	lda #>(SpriteDataPosition - HowFarDownScreen)
;	sta DF0HI
	
;	set the window for Data Fetcher 0
;	lda #<(SpriteDataPosition - 1)
;	sta DF0TOP
;	lda #<(SpriteDataPosition + ImageHeight)
;	sta DF0BOT
	
; 	point Data Fetcher 1 to the color data
;	lda #<(ColorDataPosition - HowFarDownScreen)
;	sta DF1LOW
;	lda #>(ColorDataPosition - HowFarDownScreen)
;	sta DF1HI 

	; if Y is negative then we need to compensate
	; else the data fetcher will point to the wrong page
	; and the graphics and/or color data will be incorrect
	ldx FrostyImage
	lda FrostyHeights,x
	clc
	adc FrostyY
	cmp FrostyHeights,x
	bcs NoYadjust
	lda #$FF
	.byte $2c
NoYadjust	
	lda #$0
	sta NegativeYadjust
	
	; Prep Y for the shape table
	lda FrostyImage
	asl
	tay
	
	; set Data Fetcher 0 based on Frosty's shape and Y position
	sec
	lda FrostyShapes,y
	sbc FrostyY
	sta DF0LOW
	lda FrostyShapes+1,y
	sbc NegativeYadjust
	sta DF0HI	
	
	; set the "window" the sprite is visible thru.  Use DFxDATAW to read
	; the "windowed" data.
	ldx FrostyImage		; use X to lookup height of current image
	lda FrostyShapes,y
	tay
	dey			; adjust TOP value by 1
	sty DF0TOP
	clc
	adc FrostyHeights,x
	sta DF0BOT

	; for colors we don't need to set a "window" since the sprite data
	; will be 0 and thus not visible.  Use DFxDATA to read non-windowed data
	sec
	lda #<(FrostyColors)
	sbc FrostyY
	sta DF1LOW
	lda #>(FrostyColors)
	sbc NegativeYadjust
	sta DF1HI

If you're not able to figure out by next weekend, give me a heads up and I'll see about making a templet that only shows a single sprite without any other logic to selected the image or reposition it with the joystick.

#25 roland p OFFLINE  

roland p

    River Patroller

  • 2,395 posts
  • $23
  • Location:The Netherlands

Posted Mon Oct 11, 2010 2:36 AM

Ok, I'll try it. If I can make a template I will post it, it could be handy anyway.




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users