Jump to content
IGNORED

Calling homebrew writers: read this.


MrPix

Recommended Posts

4 minutes ago, splendidnut said:

That's not completely true... Example: The PPU inside of the NES is of similar architecture to the TMS9918 and derivatives (separate RAM, data, address buses) and has no built-in hardware light gun support.  Light gun processing is done mainly in software using different techniques.  One method of detection involves flashing a white filled box in each individual sprite location on a black screen.  Each sprite gets its own separate frame, so that the frame number in which light is detected corresponds to the sprite.  If light is detected, then that sprite is hit.

 

Works great on CRTs... but things like frame lag cause issues on LCDs.

I remember those systems back in the day. Suitable for some uses, but not really ideal in fast gameplay. 

One system I worked with on the BBC micro whited the top half of the screen, then lit quarters then 8ths, then did the same vertically, so it could get down to a 1/64th of the screen in typically 6 scans. .12 of a second. Another system that knew exactly where the raster was in drawing could do it in two frames.

A poster above pointed out that you could use the video sync directly (with a counter) and I didn't consider this option to extract timing info. Unfortunately, on the CV a cart doesn't have access to those lines unless you pass the video through the cart externally - which I have never seen.

Either way, it's an interesting discussion and deserves its own thread, but I think it's out of scope for a simple paged memory cart.

Link to comment
Share on other sites

8 minutes ago, splendidnut said:

Agreed... I was just doing a simple fact check/fact correction.  Sorry for derailing the thread.

That's an alternate method of doing the light gun support though it does make the screen "blink".  It also may not be as practical on the TMS, since its hardware is not optimized for wiping out the playfield (only) and then putting it back.  Both of those would likely be full screen writes.

Link to comment
Share on other sites

Oh, no, I encourage it. These ideas and suggestions lead to new open source hardware/add-ons!

I've been working (mostly unsuccessfully) on porting CP/M 3 to the Adam and adding in support for bitmap graphics to use a full on video card. The potential is amazing... But, it requires me to play to a lot of my weaknesses, and not just my strong suit of PCB design. That came about because of an off-topic but still very interesting comment.

Right now I am looking at the really quite underperforming SGM(1/2) and thinking how reasonable it might be to design and build an expansion cart for the CV to add a lot of Adam functionality, VGA high res deep color output, Adam ROMs/expansions, more RAM, etc. etc. It's just thinking though in part due to the current lay-off, and a drop off in my side business and a small "I really need a proper pick and place machine, desperately" issue - I do have enough orders already to completely pay for the machine but in the current business climate, nobody's going to lend me the money to get it even with good credit. :/ 

Anyone want to buy me this for Christmas? :P :D 

Link to comment
Share on other sites

5 hours ago, digress said:

I assume that was using 8kb banks? 

Correct, 16,384 banks. ;)

1 hour ago, MrPix said:

If you'd like to share your paging scheme I could make mine 100% backwards compatible with yours, and then give you my extra functionality documentation. It would be good if different products had some kind of compatibility.

Also, if you'd like some help redesigning your board to be cleaner, I'd be happy to help. Just PM me. I really like how you hid the JTAG port behind the IC.

Appreciate that! You can actually see my evolution of understanding on that board - pins from the edge connector to the CPLD were early, pins from the CPLD to the flash were later. But I was under time pressure and didn't go back to redo the first half. Right now I still have almost 200 of them so a redesign is lower priority than a new product. ;)

 

The paging scheme used on the TI is not ColecoVision compatible - the TI uses a write to cartridge space to set an 8k bank. Frankly my plan for the Coleco test probably wouldn't be well loved - I was going to use one select line for paging 8k, and 16k fixed. Since I haven't taken it over to Coleco yet there's no need to feel restricted.

 

Link to comment
Share on other sites

1 hour ago, ChildOfCv said:

That's an alternate method of doing the light gun support though it does make the screen "blink".  It also may not be as practical on the TMS, since its hardware is not optimized for wiping out the playfield (only) and then putting it back.  Both of those would likely be full screen writes.

Nah, you can use the blanking bit for that - one register write will blank the display.

Link to comment
Share on other sites

38 minutes ago, Tursi said:

Appreciate that! You can actually see my evolution of understanding on that board - pins from the edge connector to the CPLD were early, pins from the CPLD to the flash were later. But I was under time pressure and didn't go back to redo the first half. Right now I still have almost 200 of them so a redesign is lower priority than a new product. ;)

Well, if you decide to port to other platforms and want a new PCB for those... ;)

38 minutes ago, Tursi said:

The paging scheme used on the TI is not ColecoVision compatible - the TI uses a write to cartridge space to set an 8k bank. Frankly my plan for the Coleco test probably wouldn't be well loved - I was going to use one select line for paging 8k, and 16k fixed. Since I haven't taken it over to Coleco yet there's no need to feel restricted.

In which case there's much more fun and interesting ways to do it, since you have room to implement a full 16-bit address decoder. The CPLD/FPGA has access to all reads/writes across the entire memory map on the address and data buses. A few signals on the control bus aren't available, but can either be deduced or are irrelevant. Either way, it means you can do the paging from within unused areas of the Z80A IO area that happen to also be backward compatible with Adam internal RAM expansion. This means you don't have to leave any holes in one of your ROM pages, and can page all four pages in a CV/Adam with ROM or SRAM and give the SRAM read and write access without the read/write line.

I'd be happy to PM you about this and some other ideas I have, where my hardware and your coding skills might overlap to make something deliciously compelling. :) 

  • Like 1
Link to comment
Share on other sites

3 minutes ago, MrPix said:

In which case there's much more fun and interesting ways to do it, since you have room to implement a full 16-bit address decoder. The CPLD/FPGA has access to all reads/writes across the entire memory map on the address and data buses. A few signals on the control bus aren't available, but can either be deduced or are irrelevant. Either way, it means you can do the paging from within unused areas of the Z80A IO area that happen to also be backward compatible with Adam internal RAM expansion. This means you don't have to leave any holes in one of your ROM pages, and can page all four pages in a CV/Adam with ROM or SRAM and give the SRAM read and write access without the read/write line.

"A few"?  Try none.  All you get is 15 of the 16 address lines, the 8 data lines, +5, gnd, shield gnd, and 4 ROM bank selects lines.

You can glean that ROM space is being accessed by the presence of any of those select lines, and that will always be expected to be a read since ROM can't be written.  Anything lower than ROM space will not signal you at all when any of the address lines or data are valid.  You also won't know whether it's a read or a write.  Finally, you won't know whether it's memory or port read/write.

 

You could designate certain address as write-only addresses, within your ROM space of course.  Then whenever you get a select for that area and the address bits are correct, you can read the data lines instead of driving them.  But that's about the best you can hope for.

Link to comment
Share on other sites

2 hours ago, ChildOfCv said:

That's an alternate method of doing the light gun support though it does make the screen "blink".  It also may not be as practical on the TMS, since its hardware is not optimized for wiping out the playfield (only) and then putting it back.  Both of those would likely be full screen writes.

Yeah, the TMS9918a chip is too slow to do large screen update.  However to avoid risking VRAM corruption and raster beam screen tears, you can change the name table address from 0x1800 to 0x1c00 to blank the screen in an instance(Make sure to fill that screen with blank char tile). And then change the name table address back to 0x1800 to make the background element appear again.   Change the sprite's color to white, or optional have a solid square block version of it in 0x3000, so you can change sprite address to point at 0x3000. 

example:

delay(1);
screen(name_table2,name_table2);
delay(1);
*change 1 object's sprite(s) to white others black*
*logic to see if light gun return a 1*
delay(1);

*change another object to white, blank the other sprites.*
*logic to see if light gun return a 1 and check object coordinate to see if the gamer is cheating by using a lightbulb.*
delay(1);
*change another object to white, blank the other sprites.*
*logic to see if light gun return a 1 and check object coordinate to see if the gamer is cheating by using a lightbulb.*
delay(1);
screen(name_table1,name_table1);
*restore object's original colors*

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

1 minute ago, Kiwi said:

Yeah, the TMS9918a chip is too slow to do large screen update.  However to avoid risking VRAM corruption and raster beam screen tears, you can change the name table address from 0x1800 to 0x1c00 to blank the screen in an instance(Make sure to fill that screen with blank char tile). And then change the name table address back to 0x1800 to make the background element appear again.   Change the sprite's color to white, or optional have a solid square block version of it in 0x3000, so you can change sprite address to point at 0x3000. 

example:

delay(1);
screen(name_table2,name_table2);
delay(1);
*change 1 object's sprite(s) to white others black*
*logic to see if light gun return a 1*
delay(1);

*change another object to white, blank the other sprites.*
*logic to see if light gun return a 1 and check object coordinate to see if the gamer is cheating by using a lightbulb.*
delay(1);
*change another object to white, blank the other sprites.*
*logic to see if light gun return a 1 and check object coordinate to see if the gamer is cheating by using a lightbulb.*
delay(1);
screen(name_table1,name_table1);
*restore object's original colors*

Can that method work for the Graphics II mode also, or are you restricted to Graphics I?  Seems like that 768-byte name table might have space issues, depending on how big the pattern tables are.

Link to comment
Share on other sites

15 minutes ago, ChildOfCv said:

"A few"?  Try none.  All you get is 15 of the 16 address lines, the 8 data lines, +5, gnd, shield gnd, and 4 ROM bank selects lines.

You can glean that ROM space is being accessed by the presence of any of those select lines, and that will always be expected to be a read since ROM can't be written.  Anything lower than ROM space will not signal you at all when any of the address lines or data are valid.  You also won't know whether it's a read or a write.  Finally, you won't know whether it's memory or port read/write.

 

You could designate certain address as write-only addresses, within your ROM space of course.  Then whenever you get a select for that area and the address bits are correct, you can read the data lines instead of driving them.  But that's about the best you can hope for.

Let me rephrase that:

A0..14 - direct

A15 - OR the bank select lines
D0..7 - direct

For paging, if you use the Z80 IO area to get page selections, you can accurately capture the page intended regardless of read or write status because the value will always be set (write) or checked (read). Latching that will always give you the correct current page.

 

Timing when data is valid is a fun one. For this you use a PLL to sync to the basic clock cycle, and multiply by four so you can accurately tell which cycle of any transfer you're in to latch data. The memory/port issue (and refresh) is solvable the same way.

However, the CV and Adam have the expansion connector that solves all these problems :P

Link to comment
Share on other sites

Just now, ChildOfCv said:

Can that method work for the Graphics II mode also, or are you restricted to Graphics I?  Seems like that 768-byte name table might have space issues, depending on how big the pattern tables are.

Should work in graphic mode II.  The 2nd name table should be filled with tile 32, which is the space character. fill_vram(0x1c00,32,768);  screen() just change the name table address register to address 0x1c00, and make it work with getput routines.  The idea is to point to an area of the VRAM that is just blank tiles.  So it'll be 1 vdp write. 

Link to comment
Share on other sites

1 hour ago, ChildOfCv said:

You could designate certain address as write-only addresses, within your ROM space of course.  Then whenever you get a select for that area and the address bits are correct, you can read the data lines instead of driving them.  But that's about the best you can hope for.

If you assert 0 to FFFFh all subsequent accesses to the top page would be SRAM reads. If you assert 1, all accesses would be writes. The decoder and D0 working a flipflop that selects between read and write, through an AND gate where the other input is the PLL 3/4 timing signal so you know the data is stabilized. Then you can be sure it's a well timed data cycle latch and not a port cycle.

Edited by MrPix
poke to wrong address
Link to comment
Share on other sites

24 minutes ago, MrPix said:

Let me rephrase that:

A0..14 - direct

A15 - OR the bank select lines
D0..7 - direct

For paging, if you use the Z80 IO area to get page selections, you can accurately capture the page intended regardless of read or write status because the value will always be set (write) or checked (read). Latching that will always give you the correct current page.

 

Timing when data is valid is a fun one. For this you use a PLL to sync to the basic clock cycle, and multiply by four so you can accurately tell which cycle of any transfer you're in to latch data. The memory/port issue (and refresh) is solvable the same way.

However, the CV and Adam have the expansion connector that solves all these problems :P

You have the entire address and data lines and all of the control lines and clock to watch, so no kludgy stuff.  You don't get the clock through the cartridge port either, so nothing to sync on.  Even the select lines can't be sync'd because the processor has varying numbers of T-states between instructions so even the memory access signals can't be used to sync, nor can the clock cycles following be used to check for address or data validity.

 

Z80's IO area is the same as Z80's address area.  Both OUT and a memory write will put the intended address on the address line, the intended data on the data lines, then activate WR, and the MEMQ or IORQ signal as appropriate.  A read will place the address on the address line and activate RD line and the MEMQ or IORQ as appropriate, then sample the bus on the next T state.  Timing wise, you won't know the difference without access to those 4 lines.

So yeah, the expansion port is the best way to deal with adding hardware or memory addresses, while the cartridge should have its own banking scheme that involves writes or reads of specific addresses in cartridge ROM.

Edited by ChildOfCv
Link to comment
Share on other sites

How would you feel about an extended yet compatible cartridge port/expander that goes in the expansion port. 

I'm asking because I'm working on a new extended CV replacement mainboard that can solve a lot of these issues in a backwards compatible way.

  • Thanks 1
Link to comment
Share on other sites

5 hours ago, MrPix said:

How would you feel about an extended yet compatible cartridge port/expander that goes in the expansion port. 

I'm asking because I'm working on a new extended CV replacement mainboard that can solve a lot of these issues in a backwards compatible way.

That could be interesting.  Something similar to the 7800 which can still play 2600 games, but has other pins in its connector to provide additional functionality for 7800 cartridges.

  • Like 1
Link to comment
Share on other sites

On 5/28/2020 at 3:37 PM, MrPix said:

Hey homebrewers. :D

I'm a hardware guy. I've designed a couple of options for improving the capacity of CV/Adam carts. I have a couple of options and would love to work with a couple of homebrew writers to release some much larger games with more advanced capabilities.

Option 1: 

Larger than 32K carts, using paging. 64, 128, 512K or more - a lot is possible. The extra could also be a mix of ROM and battery backed SRAM with an interesting write method and persistence of scores or play positions between games even after power cycling.

Option 2:

As above, but as a module with WiFi, to allow truly multiplayer games on different machines in different locations. This would allow all kinds of services like downloadable game libraries, team games, storing high score tables, leagues/seasons, games that auto update content over time, etc. etc. It does require a back end server, but there's so many little extras that become possible it could really expand your options over ordinary carts. Even just as a beta testing platform for private use, you can have it tell the beta tester a new version is available and 4 seconds later they're running it. This cart could also offer extended functionality for CP/M, BASIC programming, or etc. on the Adam. It would also add the option of PS/2 keyboards, bluetooth gamepads, etc. if someone else writes the drivers - I'm really a hardware guy.

Stretch goals:
More advanced sound, SGM-style functionality

If you're interested in basic concepts, we can chat here. If you're interested in co-developing something, PM me and we can sort out details.

Let's see what we can do!

MrPix

Well, if one of you people are completing these goals, keep up the good work trying this.

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