Jump to content
IGNORED

Gopher2600 (continuing development on Github)


JetSetIlly

Recommended Posts

9 minutes ago, SpiceWare said:

 

All the drivers use MAM mode 2 for driver itself for performance reasons. The driver code is running in RAM, which does not trigger the bug.

 

Yes.

 

9 minutes ago, SpiceWare said:

In DPC+ projects the game's code sets MAM 1 to prevent the crashing.  From Stay Frosty 2:

 

Right. This might be where my confusion has arisen. Many DPC+ARM ROMs I have seen do as you describe. However, there are some which do not.

 

For example, the ROM I have of DK Arcade (link below) does not do this.

 

So are we saying that this ROM may crash on the hardware if it triggers the bug?

 

 

Either way, I understand now.

 

9 minutes ago, SpiceWare said:

In BUS, CDF, and CDFJ the driver's code sets MAM to 1 before it calls main(), so main() no longer changes it.

 

9 minutes ago, SpiceWare said:

As of CDFJ+ the driver no longer sets MAM because the bug is not a factor in the newer boards.  I think, but am not sure, that @johnnywc has a one-off build of the CDFJ which does not change MAM to 1.

 

Right. So it remains in MAM mode 2. That tallies with what I've read in the Turbo demo thread.

 

Let me summarise my understanding:

 

1. The DPC+ driver does not change the MAM mode from mode 2

    1a) The Thumb program must therefore change to MAM mode 1 or risk a crash

    1b) The Thumb program must change back to MAM mode 2 before exit

2. The CDF and CDFJ drivers handle the MAM changes (so the Thumb program doesn't have to)

3. The CDFJ+ driver leaves MAM in mode 2

 

 

Thanks.

 

Link to comment
Share on other sites

Thanks for the detailed feedback, Darrell.

35 minutes ago, SpiceWare said:

All the drivers use MAM mode 2 for driver itself for performance reasons. The driver code is running in RAM, which does not trigger the bug.

I have a question regarding Turbo. Could the timing critical code be moved to RAM? Does the schema allow this. Even with MAM 2, this will save some CPU time.

 

Also, is there some documentation (e.g. address ranges used) which helps an emulator to determine if code or data are in RAM or flash?

 

Link to comment
Share on other sites

8 minutes ago, JetSetIlly said:

For example, the ROM I have of DK Arcade (link below) does not do this.

 

So are we saying that this ROM may crash on the hardware if it triggers the bug?

 

With DPC+ using the custom ARM code is not required.  I did a quick test of DK Arcade and it's running 6507 code in bank 0, which suggests its not using ARM code (or using so little that's its been fully tested and doesn't trigger the bug).

 

903124593_ScreenShot2021-06-18at10_58_05AM.thumb.png.50c8e1123b61e268decb4135626a06ac.png

 

 

From  DPC+ARM - Part 6, DPC+ Cartridge Layout, emphasis added:

Quote


 Cart Layout.png

 

DPC+ Driver


The DPC+ Driver is the ARM code that the Harmony/Melody runs in order to emulate a DPC+ coprocessor.
 
The 6507 in the Atari has no access to the driver.
 
While the driver is located in ROM, it is copied into RAM when the Harmony/Melody first powers up. This is because the code runs faster when located in RAM and the extra speed is required in order for the coprocessor emulation to keep up with the Atari.
 
Bank 0
 
When using custom ARM code, it must start in bank 0. While we'll be writing our custom ARM code in C, it is possible to write it using ARM assembly language.
 
The 6507 can select bank 0 by accessing memory location $FFF6*, though when using custom ARM code it's not recommended to also use bank 0 for 6507 code. If the ARM code is large enough, this same recommendation holds true for banks 1 thru 4.
 
Bank 1

 

...

 

 

 

10 minutes ago, JetSetIlly said:

Let me summarise my understanding:

 

1. The DPC+ driver does not change the MAM mode from mode 2

    1a) The Thumb program must therefore change to MAM mode 1 or risk a crash

    1b) The Thumb program must change back to MAM mode 2 before exit

2. The CDF and CDFJ drivers handle the MAM changes (so the Thumb program doesn't have to)

3. The CDFJ+ driver leaves MAM in mode 2

 

Correct.  Do note that the risk of a crash is only on the original Harmony and Melody boards.  If you're making a new game you know it'll only be built with a new Melody board, so you could leave it in Mode 2 and just let people know it could crash on an older Harmony.

  • Like 1
Link to comment
Share on other sites

20 minutes ago, JetSetIlly said:

For example, the ROM I have of DK Arcade (link below) does not do this.

 

So are we saying that this ROM may crash on the hardware if it triggers the bug?

Maybe this has been tested, maybe not. AFAIK only old (how old is old?) Harmony carts are affected by the MAM bug.

The errata sheet says:

Quote

Under certain conditions when the MAM is fully enabled (Mode 2) code execution from internal Flash can fail. The conditions under which the problem can occur is dependent on the code itself along with its positioning within the Flash memory.

The bug seems only to occur for latched, non-sequential data in flash. Maybe the exact condition is very rare, so that no all games are affected.

 

Edit: Or it doesn't use ARM. :) 

Edited by Thomas Jentzsch
Link to comment
Share on other sites

13 minutes ago, Thomas Jentzsch said:

Thanks for the detailed feedback, Darrell.

 

You're welcome!

Quote

I have a question regarding Turbo. Could the timing critical code be moved to RAM? Does the schema allow this. Even with MAM 2, this will save some CPU time.

 

That's a good idea, though I don't know how you would go about it.

 

Quote

 

Also, is there some documentation (e.g. address ranges used) which helps an emulator to determine if code or data are in RAM or flash?

 

 

FLASH/ROM starts at 0x0

RAM starts at 0x40000000

 

The driver is the first 2K or 3K of both ROM and RAM.

Link to comment
Share on other sites

Just now, SpiceWare said:

That's a good idea, though I don't know how you would go about it.

You are the expert, not I. :) 

 

Just now, SpiceWare said:

FLASH/ROM starts at 0x0

RAM starts at 0x40000000

That's easy.

 

@JetSetIlly I suppose we won't need any assumption about what is RAM and what is flash anymore.

Link to comment
Share on other sites

22 minutes ago, SpiceWare said:

 

With DPC+ using the custom ARM code is not required.  I did a quick test of DK Arcade and it's running 6507 code in bank 0, which suggests its not using ARM code (or using so little that's its been fully tested and doesn't trigger the bug).

 

It's definitely running ARM code. So we can assume that it just so happens not to trigger the bug.

 

16 minutes ago, Thomas Jentzsch said:

You are the expert, not I. :) 

 

That's easy.

 

@JetSetIlly I suppose we won't need any assumption about what is RAM and what is flash anymore.

 

I'm assuming that the PC will never jump from one area to the other and that data read/writes are always from SRAM. I'm already measuring if the read/write is from RAM or Flash.

 

21 minutes ago, Thomas Jentzsch said:

The errata sheet says:

The bug seems only to occur for latched, non-sequential data in flash. Maybe the exact condition is very rare, so that no all games are affected.

 

Right. That's probably enough information to have a linting check in the emulator. (Probably not needed now that CDF* is availble but it's a nice feature).

 

Thanks @SpiceWare and @Thomas Jentzsch for the info and helping me think things through.

Edited by JetSetIlly
  • Like 1
Link to comment
Share on other sites

23 minutes ago, Thomas Jentzsch said:

You are the expert, not I. :) 

 

Main question is can a function be moved in memory and still work.

 

Copying the function would be fairly easy as the functions' located at &function.  Size of function not sure, perhaps there's a predefine like __func__, which returns the function's name as a char[], or just copy a block of memory large enough that you know it'll get the entire function.

 

Running the relocated function would be easy - use a function pointer.

 

Link to comment
Share on other sites

1 hour ago, Thomas Jentzsch said:

But if you reading from a fixed table, your can also be reading from flash, no?

 

Good point. Currently the assumption that access to SRAM is only made in the case of PUSH, POP and LDMIA and STMIA, which I think is reasonable. All other loads and stores are stretched for Flash memory. The current MAM mode alters that but in principle most read/writes are stretched for Flash.

 

But as you said in a previous post, the available documentation for cycle usage isn't very good, so I'm making a lot of assumptions ?

 

At the moment, I'm happy if the timings work out so that (a) existing ROMs work (or don't work) as expected and (b) that it's helpful for developing new ROMs. Which for me, means causing a screen roll or running past the end of memory if the Thumb program runs too long.

 

 

Edited by JetSetIlly
Link to comment
Share on other sites

The changes I've made today around cycle accuracy and how the MAM works is worth packaging up I think.

 

Summary:

- MAM now differentiates between mode 1 and 2
- MAM set according to cartridge mapper (ie. DPC+ or CDF*) [thanks @SpiceWare]
- Counting of conditional branches corrected  [thanks @Thomas Jentzsch]

 

https://github.com/JetSetIlly/Gopher2600/releases/tag/v0.12.1

 

And thanks to @Al_Nafuur for help with the Windows binary.

  • Like 3
Link to comment
Share on other sites

On 6/18/2021 at 11:20 AM, SpiceWare said:

 

I think, but am not sure, that @johnnywc has a one-off build of the CDFJ which does not change MAM to 1.

You are correct Darrel!  Chris made one for me for RobotWar so I could save 4 bytes by not having to set it during initialize. :) (I also use it for Gorf Arcade since I need the extra processing power to play voices during the game)

Link to comment
Share on other sites

  • 1 month later...

A few months ago I was talking about techniques for capturing screenshots of games that use flicker kernels. Today when I was implementing a pause feature for play-mode I was reminded that similar problems exist for the paused screen. My solution is to assume that a display is interlaced on a two-frame cycle and to continue the flicker through inference. I think the results are pretty good (video below)

 

Of course, the same problems that arise when creating screenshots also apply here. So, displays that flicker on a three frame cycle or have elements that flicker at different rates will have suboptimal results. Also, displays that have no flicker but have moving objects will "shimmer" when paused. But IMO, this is better than showing a single frame which to the eye looks to have missing elements.

 

Ideally, we would be able to detect what kind of kernel the ROM is using and use the appropriate method. However, this would involve an analysis of the pixels being pushed by the TIA I think and isn't at all trivial. But it is something to keep in mind I think.

 

 

 

 

Game is Zookeeper from @johnnywc

 

 

  • Like 4
Link to comment
Share on other sites

Quite a lot has changed in the few weeks so I've packaged up another release. Windows and Linux binaries (AMD64) on the github page.

 

https://github.com/JetSetIlly/Gopher2600/releases/tag/v0.13

 

Full change log in the link but the most significant changes are:

 

1) Better ARM/Thumb cycle counting. This still isn't 100% but I've managed to improve the accuracy considerably after chatting things through with @Thomas Jentzsch and getting some valuable feedback from @Andrew Davie.

 

More significant than cycle-counting, Andrew identified an issue that turned out to be a subtle but serious bug in the LDMIA instruction. This is now fixed along with a bug in the format 15 CMP instruction.

 

2) Support for the STM32F407VGT6 memory map. This is the ARM chip that is found in the PlusCart. This should help when developing CDFJ games that can run on that cartridge. I know @Al_Nafuur has been trying this out and has had some success.

 

3) Better ghosting effect on the TV screen. My previous bilinear filter was applied horizontally and vertically. This is wrong and created ugly artefacts, more noticeable on some ROMs that others. Using Zookeeper as an example, this is from the new version.

 

Image

 

And a close up from Hack'Em Hangly Man

 

image.thumb.png.cbfe177aaa627f078896a8aedb4e272e.png

 

If the ghosting effect is too strong, there is a slider in the CRT Preferences window (F10 in playmode) for you to adjust.

 

4) Also added is a screen roll sensitivity slider. This controls how tolerant the screen is of unsynced TV frames. Related to this is how aggressive screen "resizing" is. By this I mean the process of deciding how many scanlines are required to be displayed but no more than necessary (and it's not as easy as looking for the VBLANK signal). I've tried several strategies over the last year or so and I'm now finally satisfied with it.

 

As part of these improvements the FPS indicator (F7 in playmode) now shows more information. In addition to current FPS it will now show basic TV information including whether the screen in "unsynced".

 

image.png.8c4f6c71a765b402d01f7afe61f3337d.png

 

5) Better static disassembly and fixed symbols usage. Figuring out what bytes in a ROM is an instruction is not always straightforward without actually executing the ROM. This is now a lot better I feel but as ever I welcome feedback on this and any other issue.

 

Enjoy.

 

 

 

 

 

Edited by JetSetIlly
  • Like 5
Link to comment
Share on other sites

  • 1 month later...

v0.14 is about 10% faster on my development machine. Feedback from MacOS and Windows users also indicate noticeable improvements.

 

https://github.com/JetSetIlly/Gopher2600/releases/tag/v0.14

 

Among the changes is the addition of stereo sound. Selectable in the preferences window (F10 in playmode; in the menus in the debugger). I've also included a three point slider to indicate the amount of stereo separation (narrow, wide, discrete).

 

image.png.91b661619f28b25026a7dc4a48109dd9.png 

 

I've also improved the mono mixing as advised by @Crispy in his document "TIA Sounding Off in the Digital Domain". I've not yet tackled the other audio issue mentioned in this thread (below).

 

Also worth mentioning that these changes to the audio system seem to have fixed sound issues that @Al_Nafuur was experiencing on Windows. So if you're a Windows user and were put off by this, give it another go and see what you think!

 

I managed to break the VSYNC counter sometime between v0.12 and v0.13. This wasn't noticeable except for the effect it had on RSYNC, which is rarely seen. One particularly neat RSYNC demo is now working again as intended. The Smooth Scrolling Playfield by @eshu

 

 

Supercharger tape loading is improved and seems to be less fussy about MP3 and WAV files than before. In particular, at @Mr SQL's request, I've made sure that his KC OS can load as intended.

 

I've also added a nice notification icon to indicate when the Supercharger tape is being played. There's a similar notification for when the tape has been rewound.

 

image.png.34706aaddf8b4e5ad91176c2469ccbaa.png

 

Similarly, PlusROM cartridges will notify when there is network activity. (Both of these notifications can be turned off in the preferences window)

 

image.png.02ab50bdaea78102e0986c50ca23171c.png

 

Finally, there is support for the new Moviecart kernel. @rbairos has done some smart work improving what was already an impressive project.

 

Demo video (encoded by @Andrew Davie).

 

 

You can also see me fiddling with the CRT controls in this. The gaps you can see in the moviecart display are caused by bilinear filtering. This is my way of emulating RF ghosting sometimes seen on televisions fed by an analogue signal. They can be a bit distracting so I lowered the intensity while the moviecart was playing.

 

My TODO list isn't getting any shorted so I'll be adding to the emulator for a while yet. In the meantime, I'd be very pleased if you could all give it a go and let me know what you think.

 

 

Edited by JetSetIlly
  • Like 6
Link to comment
Share on other sites

  • 2 weeks later...
39 minutes ago, Dionoid said:

The performance has increased a lot for version 0.14. Great work, @JetSetIlly!

 

Cheers. I've got some performance improvements for the debugger in the pipeline for the next version. This has allowed me to make the rewind feature more interactive and more natural feeling. I've attached a short video below.

 

 

Simply by selecting the pixel on the screen, the emulation instantly sets itself to how it is at that *video cycle*. As of version 0.14 you can do this but it feels clunky by comparison to the development version.

 

Notice how the CPU window is showing half decoded instructions. Stepping by CPU instruction is the usual thing in a emulator/debugger, but I feel that being able to step (forwards and backwards) by color-clock is helpful. Particularly with the 2600 where the image on the screen is so closely tied to the current state of the machine.

 

Incidentally I snuck out v0.14.1 yesterday which has support for the right-side player joystick. I added this when @Al_Nafuur pointed out that he couldn't play Nukey Shay's Missile Command hack without it. Keys for the second joystick are the same as the defaults in Stella.

 

https://github.com/JetSetIlly/Gopher2600/releases/tag/v0.14.1

Edited by JetSetIlly
  • Like 3
Link to comment
Share on other sites

  • 3 weeks later...

I've added a feature to the debugger this weekend that I've wanted to add for some time. A timeline window showing information traces for the system over time.

 

For now, it is only showing traces for TV stability (the red line) and left-player input (the green line). But there's potential for lots more I think. Network / tape activity; ARM CPU load; audio activity; all sorts of things I'm sure.

 

The TV trace in particular should prove useful to help visualise and quickly find problem frames (ie. scanline count changing from frame to frame).

 

The window also doubles up as a way of rewinding to a previous state. The moving orange bar indicating what states are available.

 

The latest code is on Github for those interested. And if anyone has any ideas for how I can extend this idea, I'd love to hear them.

 

  • Like 5
Link to comment
Share on other sites

On 9/16/2021 at 1:56 PM, JetSetIlly said:

Supercharger tape loading is improved and seems to be less fussy about MP3 and WAV files than before. In particular, at @Mr SQL's request, I've made sure that his KC OS can load as intended.

This is fantastic for developing cycle accurate SuperCharger code in Gopher guaranteed run on a real SuperCharger.

 

Stella and some emulated BIOS stubs have pitfalls and can run fakeout code that does not work on genuine SuperCharger hardware and gets locked in a loading loop at contest time. Not the best choice for pro quality development particularly with Audacity raising the bar on the classics :) 

 

On 9/16/2021 at 1:56 PM, JetSetIlly said:

I've also added a nice notification icon to indicate when the Supercharger tape is being played. There's a similar notification for when the tape has been rewound.

How do you know when the tape is rewound? Do you mean when it stops? On real hardware KC OS runs on an an endless mobius strip (one minute answering tape) that loops with no beginning and no end. It would be cool to see a programmer inspired like @Andrew Davie add a line-in to PlusCart to make it as powerful as the Cuttle cart, adding the SD card was an interesting but useless modification like having two SD cards installed since there is already static RAM present to store offline ROM's.

 

One of the emerging FPGA Atari consoles with a refreshingly new all black design is already sporting an analog line-in for loading from cassette which may make it more compatible with real SuperCharger hardware goodness than a classic console and modern multicart solution, particularly if the FPGA job uses the real SuperCharger BIOS gold code like Gopher.

     

Link to comment
Share on other sites

1 hour ago, Mr SQL said:

This is fantastic for developing cycle accurate SuperCharger code in Gopher guaranteed run on a real SuperCharger.

 

Stella and some emulated BIOS stubs have pitfalls and can run fakeout code that does not work on genuine SuperCharger hardware and gets locked in a loading loop at contest time. Not the best choice for pro quality development particularly with Audacity raising the bar on the classics :) 

 

How do you know when the tape is rewound? Do you mean when it stops?

 

The tape "plays" and "stops" and "rewinds" automatically when the 6507 requires it.

 

This is my current strategy:

 

1) Tape will play when address 1ff9 (or any of the cartridge mirrors) is read. The RAM write bit must also be set for the tape to start playing.

 

2) Tape will stop when address fa1a (specifically) is read. This is the point in the BIOS at which the program jumps to VCS RAM (at address 0x00fa) and the loaded program begins.

 

3) Rewinding: The "tape" is just a sound file (the emulator supports most WAV and MP3 files) so "playing" is nothing more than keeping track of how much of the file has been read and moving that progress pointer along every CPU cycle. "Rewinding" therefore, is just a case of resetting the progress pointer to zero when the end of the file has been reached.

 

 

An interesting question is: can you turn those signals I've described above into hardware? Somebody might have already done this but I wonder if you could have a Commodore 64 type cassette recorder than started and stopped automatically when the above conditions are met? But that's a question for the electronics experts.

Link to comment
Share on other sites

5 minutes ago, JetSetIlly said:

 

The tape "plays" and "stops" and "rewinds" automatically when the 6507 requires it.

 

This is my current strategy:

 

1) Tape will play when address 1ff9 (or any of the cartridge mirrors) is read. The RAM write bit must also be set for the tape to start playing.

 

2) Tape will stop when address fa1a (specifically) is read. This is the point in the BIOS at which the program jumps to VCS RAM (at address 0x00fa) and the loaded program begins.

 

3) Rewinding: The "tape" is just a sound file (the emulator supports most WAV and MP3 files) so "playing" is nothing more than keeping track of how much of the file has been read and moving that progress pointer along every CPU cycle. "Rewinding" therefore, is just a case of resetting the progress pointer to zero when the end of the file has been reached.

 

 

An interesting question is: can you turn those signals I've described above into hardware? Somebody might have already done this but I wonder if you could have a Commodore 64 type cassette recorder than started and stopped automatically when the above conditions are met? But that's a question for the electronics experts.

Very cool, for number 3 I think there may be an advantage with Gopher being able to move the seek mechanism independently to the target program while the SuperCharger must go file by file sequentially loading each one until it encounters the target program.

 

The TRS-80 had a motor control you could use to turn the cassette recorder on. The ADAM Family Computer could rewind and forward the tape too.

 

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