Jump to content

Photo

Harmony DPC+ ARM programming


28 replies to this topic

#1 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sun May 30, 2010 7:16 PM

As promised, here's the ARM code demo! I didn't finish what I wanted (the 3D projection isn't quite right), but it does show how to call ARM code, which is really all that matters.


The ARM code is written in C. You'll need to have the appropriate compiler installed. I'm on OS X and used the GCC-3.3 Toolchain found on this page. Here's the direct link to the package.

Linux/Windows users should use the one found here. You'll also need to update the Makefile. Specifics on what to change can be found at the top of main.c.


The C code is found in the custom directory.


One key thing you need to know about calling ARM Code is that the 6507 is being fed NOPs during the duration of the subroutine. This means the 6507's PC is advancing. If your code takes to long to execute, the 6507 will run past the end of cartridge space. This will crash your program. To maximize subroutine run time, have the STA CALLFUNCTION command towards the start of the 4K bank, this provices plenty of time to run an ARM function for the duration of the vertical blank. At the end of the ARM code, the 6507 is feed a JMP command to pick up after the STA CALLFUNCTION command.

Source
Attached File  DPCplus ARM code demo.zip   91.67KB   219 downloads

Binary
Attached File  DPC+ ARM Demo.bin   32KB   216 downloads

#2 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Tue May 3, 2011 8:27 PM

I've started a new DPC+ ARM project and posted the first build in my blog, under the category Frantic.

If you're interested in doing DPC+ with ARM development it might be worth your time to follow along as I expand from this initial demo to the finished game.

#3 ScumSoft OFFLINE  

ScumSoft

    Moonsweeper

  • 361 posts
  • Location:Polysorbate 60

Posted Wed May 4, 2011 4:51 PM

Very interesting, I'll definitely offload some things to the ARM now. I look forward to seeing your completed project.

#4 eshu OFFLINE  

eshu

    Chopper Commander

  • 249 posts

Posted Thu May 5, 2011 6:13 AM

As promised, here's the ARM code demo! I didn't finish what I wanted (the 3D projection isn't quite right), but it does show how to call ARM code, which is really all that matters.


The ARM code is written in C. You'll need to have the appropriate compiler installed. I'm on OS X and used the GCC-3.3 Toolchain found on this page. Here's the direct link to the package.

Linux/Windows users should use the one found here. You'll also need to update the Makefile. Specifics on what to change can be found at the top of main.c.


The C code is found in the custom directory.


One key thing you need to know about calling ARM Code is that the 6507 is being fed NOPs during the duration of the subroutine. This means the 6507's PC is advancing. If your code takes to long to execute, the 6507 will run past the end of cartridge space. This will crash your program. To maximize subroutine run time, have the STA CALLFUNCTION command towards the start of the 4K bank, this provices plenty of time to run an ARM function for the duration of the vertical blank. At the end of the ARM code, the 6507 is feed a JMP command to pick up after the STA CALLFUNCTION command.

Source
Attached File  DPCplus ARM code demo.zip   91.67KB   219 downloads

Binary
Attached File  DPC+ ARM Demo.bin   32KB   216 downloads


What happens if you STA CALLFUNCTION from zero page?

#5 eshu OFFLINE  

eshu

    Chopper Commander

  • 249 posts

Posted Thu May 5, 2011 9:07 AM

What happens if you STA CALLFUNCTION from zero page?


Thinking about it it would probably confuse the harmony about where to feed the nops, but perhaps you could run in zero page for a set time and exit out in time for the harmony to feed the jmp?

Also I can't get the demo to work in stella, I'm guessing it doesn't support custom arm code yet?

Edited by eshu, Thu May 5, 2011 9:08 AM.


#6 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu May 5, 2011 9:11 AM

That does work - but I'd only use it with the $FF version as the 10-15% interrupt overhead of $FE would be wasted since the LDA AMPLITUDE/STA AUDV0 commands it outputs would never be run.

I did an experiment of running in ZP last year with a routine that pre-fetched & cached AMPLITUDE data, and the ZP routine would update AUDV0 while the ARM code ran. Turns out you can't pre-fetch AMPLITUDE data though, it resulted in staticy music. That's why we came up with the $FE version for interrupt driven music.

The ZP routine I came up with monitors the cartridge space to see when CALLFUNCTION is done as we don't want to hand execution back to cartridge ROM if the ARM is still doing it's thing. This is done by the ldx PosObject instruction. PosObject is a subroutine I put in every single ROM bank, so if I read the first byte of PosObject and don't see #$38 then I know the ARM is still outputting NOP commands. The routine also sets the screen background to a different color if cache data ran out - I was going to use this to let me know if an ARM function ran too long.
; this routine is copied to Zero Page and runs while the ARM is busy.  
        MAC ZP_ROUTINE
        SUBROUTINE
        ; X holds how many Cache values-1
.ZP     ldy #$FF		; 2 67
        sty CALLFUNCTION	; 4 69
.ZPloop
	lda CachedAMPLITUDE,x	; 4 73
	sta WSYNC		; 3 76/0	
	sta AUDV0		; 3  3	
	dex			; 2  5	
	bpl .ZPloop		; 3  8 - branch taken
.checkARMstate			; 2  7 - branch not taken
	ldx PosObject		; 4 11
	cpx #$38		; 2 13 - check that we see a SEC command
	beq .BCcountdown	; 3 16 - branch taken
	ldx #$80		; 2 18 - error color since ARM still running
ERROR_COLOR = * - .ZP - 1	;        offset used to set error color
	stx BackgroundColor	; 3 21
	ldx #120		; 2 23 - show error color for 2 seconds
	stx BCcount		; 3 26
.BCcountdown
	ldx BCcount		; 3 29
	beq .ZPexit		; 2 31
	dex			; 2 33
	stx BCcount		; 3 36
	bne .ZPexit		; 2 38
	ldx #0			; 2 40 - black
	stx BackgroundColor	; 3 43
.ZPexit
	rts			; 6 49 - 49 = worse case path	
        ENDM

Edit: part of the message was accidentally entered as part of the code's comment. Moved it back to where it belonged.
Source
Attached File  DPCplus ARM and Music demo 2.zip   126.03KB   92 downloads

Edited by SpiceWare, Thu May 5, 2011 9:23 AM.


#7 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu May 5, 2011 9:19 AM

Also I can't get the demo to work in stella, I'm guessing it doesn't support custom arm code yet?

I don't think the release build of Stella supports it - you can use the ones that batari posted here.

Hmm - the demo crashes Stella on my system. When this demo was written we were still making a lot of changes to DPC+ and ARM support. I'll take a look at it this weekend to see if I can't fix it. In the mean time you can check out other ARM demos like the one I just posted, or follow the development of Frantic in my blog.

#8 batari OFFLINE  

batari

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

  • 6,512 posts
  • begin 644 contest

Posted Thu May 5, 2011 4:02 PM


Also I can't get the demo to work in stella, I'm guessing it doesn't support custom arm code yet?

I don't think the release build of Stella supports it - you can use the ones that batari posted here.

Hmm - the demo crashes Stella on my system. When this demo was written we were still making a lot of changes to DPC+ and ARM support. I'll take a look at it this weekend to see if I can't fix it. In the mean time you can check out other ARM demos like the one I just posted, or follow the development of Frantic in my blog.

Yes, these older demos will not work. At least two reasons for its failure is that these older demos have ARM code for the setup, and the entry points are different. If you rebuild them with the latest custom.S and lds files, they should work.

#9 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu May 5, 2011 4:33 PM

I've replaced those, but it still crashes Stella.

There were some compile errors that I fixed, but there's still a bunch of warnings that I don't remember from before. I'm using a different, and newer, compiler than I did when this was originally built.

#10 batari OFFLINE  

batari

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

  • 6,512 posts
  • begin 644 contest

Posted Thu May 5, 2011 5:47 PM

I've replaced those, but it still crashes Stella.

There were some compile errors that I fixed, but there's still a bunch of warnings that I don't remember from before. I'm using a different, and newer, compiler than I did when this was originally built.

What does the console output look like?

#11 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Fri May 6, 2011 9:25 AM

As I recall, the warnings were mostly about the macros from supercat, as well as a few regarding the matrix functions.

My plan when I look at it again this weekend is to revert to the initial, though slower, line drawing routines and see if it works as that would bypass those macros. If that doesn't help, I'd disable the 3D stuff (so the matrix functions aren't used) and test the line drawing routines by themselves.

#12 batari OFFLINE  

batari

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

  • 6,512 posts
  • begin 644 contest

Posted Fri May 6, 2011 1:45 PM

I mean the output that Stella produces in the OSX console application.

#13 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Fri May 6, 2011 2:00 PM

Ah - I don't ever run it from command line, so that never crossed my mind.

Darrell-Spices-MacBook-Pro:MacOS darrell$ ./Stella 
2011-05-06 14:57:17.448 Stella[940:903] Could not connect the action togglePallette: to target of class Menus
2011-05-06 14:57:17.450 Stella[940:903] Could not connect the action xStartPlus: to target of class Menus
2011-05-06 14:57:17.451 Stella[940:903] Could not connect the action xStartMinus: to target of class Menus
2011-05-06 14:57:17.451 Stella[940:903] Could not connect the action yStartPlus: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action yStartMinus: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action ntscPalMode: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action widthPlus: to target of class Menus
2011-05-06 14:57:17.453 Stella[940:903] Could not connect the action widthMinus: to target of class Menus
2011-05-06 14:57:17.453 Stella[940:903] Could not connect the action heightPlus: to target of class Menus
2011-05-06 14:57:17.454 Stella[940:903] Could not connect the action heightMinus: to target of class Menus
2011-05-06 14:57:17.454 Stella[940:903] Could not connect the action saveProps: to target of class Menus
write16(0x00000048,0x00000880), abort


#14 stephena OFFLINE  

stephena

    River Patroller

  • 2,539 posts
  • Stella maintainer
  • Location:Newfoundland, Canada

Posted Fri May 6, 2011 2:19 PM

Ah - I don't ever run it from command line, so that never crossed my mind.

Darrell-Spices-MacBook-Pro:MacOS darrell$ ./Stella 
2011-05-06 14:57:17.448 Stella[940:903] Could not connect the action togglePallette: to target of class Menus
2011-05-06 14:57:17.450 Stella[940:903] Could not connect the action xStartPlus: to target of class Menus
2011-05-06 14:57:17.451 Stella[940:903] Could not connect the action xStartMinus: to target of class Menus
2011-05-06 14:57:17.451 Stella[940:903] Could not connect the action yStartPlus: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action yStartMinus: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action ntscPalMode: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action widthPlus: to target of class Menus
2011-05-06 14:57:17.453 Stella[940:903] Could not connect the action widthMinus: to target of class Menus
2011-05-06 14:57:17.453 Stella[940:903] Could not connect the action heightPlus: to target of class Menus
2011-05-06 14:57:17.454 Stella[940:903] Could not connect the action heightMinus: to target of class Menus
2011-05-06 14:57:17.454 Stella[940:903] Could not connect the action saveProps: to target of class Menus
write16(0x00000048,0x00000880), abort

Not directly related to the topic at hand, but I just committed code that fixes those 'Could not connect the ...' messages.

I also plan to add better logging to Stella, so that it's visible from within the application. And I have to fix the problem of errors in ARM code causing Stella to crash. It's OK if your game crashes, but it should never cause the application itself to crash :) I believe it's just an issue of exit() being called, when what should happen is a console pops up showing you the errors.

EDIT: could someone post a ROM that caused Stella to crash, and state exactly what error is being printed? I want to get logging support added for the next release, and having a ROM that always crashes would speed things along.

#15 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Fri May 6, 2011 2:52 PM

This is the ROM that's crashing on me.
Attached File  DPC+ ARM Demo.bin   32KB   130 downloads

#16 PAC-MAN-RED OFFLINE  

PAC-MAN-RED

    Moonsweeper

  • 424 posts

Posted Fri May 6, 2011 4:43 PM

This is the ROM that's crashing on me.
Attached File  DPC+ ARM Demo.bin   32KB   130 downloads


This is what I get from running it in my work computer(when I should be working) :P :

DPC+ ARM Demo.PNG

#17 stephena OFFLINE  

stephena

    River Patroller

  • 2,539 posts
  • Stella maintainer
  • Location:Newfoundland, Canada

Posted Fri May 6, 2011 4:50 PM


This is the ROM that's crashing on me.
Attached File  DPC+ ARM Demo.bin   32KB   130 downloads


This is what I get from running it in my work computer(when I should be working) :P :

DPC+ ARM Demo.PNG

Stella 3.3 doesn't run ARM assembly code, so that's why the app isn't crashing. There's a pre-release of Stella (mentioned above) that you need for ARM support. Or you can wait another 2 weeks, when I release Stella 3.4.

#18 PAC-MAN-RED OFFLINE  

PAC-MAN-RED

    Moonsweeper

  • 424 posts

Posted Fri May 6, 2011 5:14 PM



This is the ROM that's crashing on me.
Attached File  DPC+ ARM Demo.bin   32KB   130 downloads


This is what I get from running it in my work computer(when I should be working) :P :

DPC+ ARM Demo.PNG

Stella 3.3 doesn't run ARM assembly code, so that's why the app isn't crashing. There's a pre-release of Stella (mentioned above) that you need for ARM support. Or you can wait another 2 weeks, when I release Stella 3.4.


2 WEEKS!?!? Oh alright.. I guess I can handle that. :D

Illya

#19 ScumSoft OFFLINE  

ScumSoft

    Moonsweeper

  • 361 posts
  • Location:Polysorbate 60

Posted Fri May 6, 2011 6:06 PM

There was also mention of the DPC+ DataFetchers being set in a HI/LOW fashion causing pointer errors, however in my latest test program build the issue cropped back up and all the DataFetchers are set in a LOW/HI fashion. I'll post the source here that works fine in stella but not on the Harmony cart.

Attached Files



#20 batari OFFLINE  

batari

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

  • 6,512 posts
  • begin 644 contest

Posted Fri May 6, 2011 8:31 PM

Ah - I don't ever run it from command line, so that never crossed my mind.

Darrell-Spices-MacBook-Pro:MacOS darrell$ ./Stella 
2011-05-06 14:57:17.448 Stella[940:903] Could not connect the action togglePallette: to target of class Menus
2011-05-06 14:57:17.450 Stella[940:903] Could not connect the action xStartPlus: to target of class Menus
2011-05-06 14:57:17.451 Stella[940:903] Could not connect the action xStartMinus: to target of class Menus
2011-05-06 14:57:17.451 Stella[940:903] Could not connect the action yStartPlus: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action yStartMinus: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action ntscPalMode: to target of class Menus
2011-05-06 14:57:17.452 Stella[940:903] Could not connect the action widthPlus: to target of class Menus
2011-05-06 14:57:17.453 Stella[940:903] Could not connect the action widthMinus: to target of class Menus
2011-05-06 14:57:17.453 Stella[940:903] Could not connect the action heightPlus: to target of class Menus
2011-05-06 14:57:17.454 Stella[940:903] Could not connect the action heightMinus: to target of class Menus
2011-05-06 14:57:17.454 Stella[940:903] Could not connect the action saveProps: to target of class Menus
write16(0x00000048,0x00000880), abort

You don't need to run from the command line, just run the console applications in the OSX utilities folder.

Anyway, when ARM code crashes, it will always display the offending memory access (and I've since modified it to do a full register dump, and I need to submit that code) but anyway, the problem is there is a write to flash, causing a data abort exception. Not sure why it isn't also happening in Harmony (or is it?)

#21 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 8,339 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Fri May 6, 2011 9:03 PM

Just checked the console, it has the could not connect... messages, but not the write16 abort message.

Hadn't tried it on the Harmony since posting this last year... Interesting - it runs just fine.

Attached File  DPCplus ARM code demo 2.zip   171.05KB   135 downloads

Edited by SpiceWare, Fri May 6, 2011 9:04 PM.


#22 stephena OFFLINE  

stephena

    River Patroller

  • 2,539 posts
  • Stella maintainer
  • Location:Newfoundland, Canada

Posted Mon May 9, 2011 10:24 AM

I'm working on improving the interaction between Stella and the Thumb emulation right now. The exit()'s are easy enough to fix; I just throw (and catch) an exception instead. But what should we do with it? Here's my opinion, and what I'd like to get done for the next release (in about 2 weeks):

1) all exit() in the code are changed to throw an exception, the contents of which will be the text describing the error

2) if an exception is caught, the text is shown from within the application, in a window indicating that an error has occurred

3) a choice is given to proceed with emulation of the ROM, or exit the ROM

I'd like some feedback on #2 and #3. Specifically for #2, adding a full trace of the Thumb internals would be nice. Batari mentioned some code to do this; patches are welcome. As for #3, do we even offer a choice to proceed with the ROM, or simply exit it after the first error?

Finally, any other lingering patches/bugfixes for ARM stuff should be done in the next week or so, if you want it included in version 3.4.

#23 batari OFFLINE  

batari

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

  • 6,512 posts
  • begin 644 contest

Posted Mon May 9, 2011 7:54 PM

I'm working on improving the interaction between Stella and the Thumb emulation right now. The exit()'s are easy enough to fix; I just throw (and catch) an exception instead. But what should we do with it? Here's my opinion, and what I'd like to get done for the next release (in about 2 weeks):

1) all exit() in the code are changed to throw an exception, the contents of which will be the text describing the error

2) if an exception is caught, the text is shown from within the application, in a window indicating that an error has occurred

3) a choice is given to proceed with emulation of the ROM, or exit the ROM

I'd like some feedback on #2 and #3. Specifically for #2, adding a full trace of the Thumb internals would be nice. Batari mentioned some code to do this; patches are welcome. As for #3, do we even offer a choice to proceed with the ROM, or simply exit it after the first error?

Finally, any other lingering patches/bugfixes for ARM stuff should be done in the next week or so, if you want it included in version 3.4.

I'll get my code to you when I get home (if I remember...) My code shows the register values, the addresses, values, and other things, and I enhanced the "valid" memory regions (currently, it doesn't return exceptions in some cases when it should.)

A trace of the instructions leading up to the error would be fairly simple. Each instruction includes optional text that is printed when DBUG and DISP are set to 1. You could modify these somehow to show a disassembly backward from the PC if needed, or just create a new method that returns the appropriate text.

#3 sounds like a good idea. While the ROM may not run right from there, it might be useful for debugging.

#24 ScumSoft OFFLINE  

ScumSoft

    Moonsweeper

  • 361 posts
  • Location:Polysorbate 60

Posted Tue May 10, 2011 10:27 PM

Okay I've figured out why LOW/HI works and yet the demo I posted doesn't.

On the Harmony cart you cannot just update the LOW DataFetcher pointer over and over like I do before updating the HI on Carry set, both have to be written to consecutively in the LOW/HI order.

So to patch this for now, I just rewrite the HI pointer after updating the LOW. This adds cycle overhead to my loops which update the sprites since I have to update the pointers to the next scanline in ScreenRAM space.

But at least this mystery has been solved for now :D

@batari, would this be correctable in a firmware update? I am guessing once DFxLOW is written to, the next write expects the HI value? I would much rather update the LOW pointer a few times and retain the HI pointer values till I need them updated, rather than having to write LOW/HI every time LOW needs updated.

Edited by ScumSoft, Tue May 10, 2011 10:28 PM.


#25 batari OFFLINE  

batari

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

  • 6,512 posts
  • begin 644 contest

Posted Wed May 11, 2011 12:28 AM

Okay I've figured out why LOW/HI works and yet the demo I posted doesn't.

On the Harmony cart you cannot just update the LOW DataFetcher pointer over and over like I do before updating the HI on Carry set, both have to be written to consecutively in the LOW/HI order.

So to patch this for now, I just rewrite the HI pointer after updating the LOW. This adds cycle overhead to my loops which update the sprites since I have to update the pointers to the next scanline in ScreenRAM space.

But at least this mystery has been solved for now :D

@batari, would this be correctable in a firmware update? I am guessing once DFxLOW is written to, the next write expects the HI value? I would much rather update the LOW pointer a few times and retain the HI pointer values till I need them updated, rather than having to write LOW/HI every time LOW needs updated.

So, looking at DPC+ code, it definitely clears the HI bits when low is written. I don't remember why I did it this way but there must have been a reason at the time.

DPC+ is not in the firmware, but in the binary itself (and for things like this, I'm glad I did it this way.) So, all you need is a new DPC+.arm file to fix any issues. Here's a DPC+.arm that does not clear these bits. Let me know if there are any issues.

Attached Files

  • Attached File  DPC+.zip   1.55KB   96 downloads





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users