Jump to content
IGNORED

StrangeCart


speccery

Recommended Posts

51 minutes ago, PeteE said:

One trick I saw in Tursi's and Rasmus' emulators is to use a status flags lookup table for comparison to zero for every possible word or byte value, if you have enough RAM to spare to store the tables.  Another untested idea I have is instructions store a pair of values for each status flag that they modify, and later lazily compare the values when the flag is needed.  The latter would use less RAM, and could possibly use vector intrinsic like __mm_shuffle_epi32 to store multiple value pairs at once.

Thanks @PeteE, the lazy comparison is an interesting idea.
 

I have been thinking about doing some sort of static  (or dynamic) code analysis to figure out what flags are actually needed, but doing lazy analysis after the matter would be interesting.
 

I can’t store tables more than a few kilobytes, so big lookup tables 64k+ are not an option.

 

The lazy evaluator could in my case have a circular buffer of results and instructions generating them, so that when a flag is needed, it could be computed only when used, after the fact. Need to think how this could be done efficiently.

Link to comment
Share on other sites

  • 1 month later...
On 3/23/2022 at 11:50 PM, dhe said:

Any news on the StrangeCart?

Thanks for checking in. I guess I could just start shipping the current prototype boards, and continue firmware development with feedback from the community. Assuming there is still interest :) 

The current boards I have are not perfect, I think the edge connector is probably about 1mm too short since the boards are seem a bit sensitive on alignment with the cartridge port. The boards I have been testing have not damaged the TI nor the StrangeCart, but sometimes need a bit of wiggling to get proper contact. Might also be caused by oxidisation of the connector on the console side.

I have been plugging in bare boards. I have not used cartridge cases, since they would cover the buttons and LEDs and I have only done very minimal design of 3D printed parts.

This means you need be ready for a bit of an adventure. But if you're up to that, I would be very interested in feedback!

Edited by speccery
  • Like 4
  • Thanks 1
Link to comment
Share on other sites

2 hours ago, FarmerPotato said:

@speccery is Strange Cart too big to fit in a TI cartridge shell? With projects like FlashROM I made holes and slots. Maybe you can use tall buttons or right angle?

It fits into a normal shell - almost but the USB connector needs a cut. The buttons are of the type where you can mount a tall cap on, I on purpose chose those so that the buttons could be accessible if the shell has holes.

I haven’t focused on the mechanical part too much yet, since the software has required a lot of effort.

  • Like 2
  • Thanks 3
Link to comment
Share on other sites

One of the features I've wanted the StrangeCart to have is to be able to save Basic programs locally into its own Flash memory. I was thinking that this weekend I will have time to work on it. And I did, but I did not get very far.

Earlier I only handled on I/O operation: SAVE STRANGE.NAME from TI Basic. The NAME is ignored, and what this command does is that it simply saves the program into the RAM of the StrangeCart, so that it can then be executed with CALL RUN. The standard pattern of running programs thus is something like:

OLD DSK1.PROGRAM

SAVE STRANGE.L

CALL RUN

Again the filename L above is just a convenient short name, and has no meaning. Currently only one Basic program can reside in the memory of the StrangeCart.

 

I today created another device, SCD1, and it is now possible to do SAVE SCD1.PROGRAM and the program goes into the RAM of the StrangeCart as before. But right now it is not handled any differently from SAVE STRANGE.PROGRAM. My plan is to use the device name to cause the program to be saved to only RAM (STRANGE) or to RAM and flash (SCD1). 

Currently I cannot load anything from StrangeCart, i.e. OLD SCD1.NAME or OLD STRANGE.NAME do nothing (and hopefully does not crash). But I plan to make it so that OLD SCD1.NAME would cause the program with the name NAME be loaded from flash to both into the RAM of the StrangeCart and into the ordinary RAM of TI-99/4A (i.e. VDP memory for TI Basic programs).

 

This also implies that I'd need to create a simple filesystem for Flash. I sort of have that already for storing multiple cartridges. My default flash image is something like 750k and includes a bunch of cartridge images. There is SPIFFS which is used by ESP32 microcontrollers a lot, perhaps I will port that over.

  • Like 4
Link to comment
Share on other sites

  • 2 weeks later...

The first StrangeCart prototype board(s) have left the building. 

 

Due to this, I have started to build documentation for the StrangeCart at GitHub:

https://github.com/Speccery/StrangeCart-Doc

and

https://github.com/Speccery/StrangeCart-Doc/wiki

 

The latter is the Wiki, and I will move all the documentation over there as I have time to write material. I have to say that the GitHub wiki is something I should have used more, easy no frills tool is what works for me.

 

On another note, I also added SPIFFS to the StrangeCart firmware. It is not yet integrated with the rest of the firmware, but I have some test routines which so that it does work in principle. This means I will be able to quite easily have a small actual filesystem in the flash memory. Currently the flash memory is partitioned so that the bottom 14 megs is for the cartridge image file and top 2 megs for the SPIFFS use. The first use case I have for SPIFFS is to implement support for saving and loading BASIC programs there. That will make StrangeCart a useful standalone board for all the masses of TI BASIC programmers out there :) , without needing any other peripherals.

Edited by speccery
  • Like 6
  • Thanks 2
Link to comment
Share on other sites

I did a simple:

10 for i = 1 to 20

20 print i

30 next i

 

call run

 

Call run completes and then sends me to the next line, but doesn't print.

Is that the expected behavior?

 

>call run

>

>I can type here.

 

I did print out all the documentation - good stuff.

 

call carts - shows nothing.

 

The display after hitting enter shows:

Basic

Easy Bug

Strange Mem

 

 

Link to comment
Share on other sites

3 hours ago, dhe said:

I did a simple:

10 for i = 1 to 20

20 print i

30 next i

 

call run

 

Call run completes and then sends me to the next line, but doesn't print.

Is that the expected behavior?

 

>call run

>

>I can type here.

 

I did print out all the documentation - good stuff.

 

call carts - shows nothing.

 

The display after hitting enter shows:

Basic

Easy Bug

Strange Mem

The menu shows that at least GROM emulation works, that’s good. Did you save the program before CALL RUN with SAVE STRANGE.P? Without that the basic program is not in the memory of the strangecart and it wouldn’t work.

 

If CALL CARTS doesn’t work, it could be a connector issue, as the GROM lines are all on one side of the connector so the menu could work even if not everything is going through. I have had often weird problems like that when the connection is bad.

 

You could switch to another cartridge image by pressing the 2nd rightmost button one or more times and then resetting the computer with leftmost button. If for example Parsec works then all the connection should be good.

 

Do you have F18A installed? That’s not a requirement, but it dawned on me that I have done all my testing with one.

 

Finally, don’t hesitate to reset the board if it’s not doing what you expect. Press rightmost button to do that and then leftmost to reset the computer. 

Edited by speccery
  • Like 3
  • Thanks 2
Link to comment
Share on other sites

Was thinking about StrangeCart after seeing this video.  

 

Here is how they implemented it:  "No expansion audio is being used for this. Neither is any co-processor, decompressor, video decoding, etc. All that we are doing is loading chunks of data from the SD card into CHR-RAM and continually re-pointing the PPU at them just in time to render the video in a pixel-perfect fashion. We interleave the video writes with the audio writes and have just enough time to support full 44.2KHz PCM."

 

I wonder if StrangeCart can push video and audio into the 9918A and 9919 in something like this (rather than rom reads as all previous carts have done).  Granted, our ability to do PCM has been poor in the past, but this makes you wonder.  I don't know all the bus/technical aspects of the NES 6502 and 2A03 with this cart pushing the data to the NES compared to what StrangeCart can do... but still... shows you what's possible when you simply feed data into a cart port at near real time speed ;)

 

Probably the closest we've gotten to pushing video as much as possible was Dragon's Lair, but this was a ROM, and not a 90 something MHz ARM processor pushing data to the TI. 

 

 

 

  • Like 1
Link to comment
Share on other sites

The NES doesn't have video RAM, but uses what it calls "CHR ROM" on the cart directly, so there's no need to transfer pattern definitions... just swap the banks on the cart and you have a whole new set ready to go. We need to transfer all data to the 9918a's RAM with the CPU, so there's no way we can achieve the same sort of speed. I've been racking my brain about how we could get the 16K of VRAM directly on the bus, or at least have some sort of DMA mechanism to up the bandwidth to the VDP.

  • Like 1
Link to comment
Share on other sites

42 minutes ago, TheMole said:

The NES doesn't have video RAM, but uses what it calls "CHR ROM" on the cart directly, so there's no need to transfer pattern definitions... just swap the banks on the cart and you have a whole new set ready to go. We need to transfer all data to the 9918a's RAM with the CPU, so there's no way we can achieve the same sort of speed. I've been racking my brain about how we could get the 16K of VRAM directly on the bus, or at least have some sort of DMA mechanism to up the bandwidth to the VDP.

Why not start a separate topic about interfacing the VDP to CPU RAM? I’ve tried to work out an idea with a fast SRAM, a PLD, and some latches, but the number of chips goes up.
 

Essentially, an arbiter on very fast SRAM, that buffers the VDP address DRAM setup. It similarly buffers CPU address and allows read/write in between VDP accesses. It’s a lot of latches. 
 

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, acadiel said:

I wonder if StrangeCart can push video and audio into the 9918A and 9919 in something like this (rather than rom reads as all previous carts have done).  Granted, our ability to do PCM has been poor in the past, but this makes you wonder.  I don't know all the bus/technical aspects of the NES 6502 and 2A03 with this cart pushing the data to the NES compared to what StrangeCart can do... but still... shows you what's possible when you simply feed data into a cart port at near real time speed ;)

 

Probably the closest we've gotten to pushing video as much as possible was Dragon's Lair, but this was a ROM, and not a 90 something MHz ARM processor pushing data to the TI. 

 

I haven't looked at the video you posted yet, saving that for a bit later. What I have already done with the StrangeCart is to dynamically on the fly create a program, which only writes to the VDP memory. It does this by setting the workspace pointer to point to the VDP write port, and the just uses the load immediate (LI) instructions to write data to the VDP. This is not practical with a regular ROM based cartridge, since it would consume a ton of memory, but for the StrangeCart it works as it can render graphics as sequences of LI instructions. This is the fastest way to write data to VDP memory without modifying the console.

 

If modifications are not off the table, then what I have been thinking is to have a version of the F18A with an SPI port (synchronous serial port) with a direct cable to the StrangeCart. That would require only around five wires, and would enable multiple megabytes per second of bandwidth to video memory. I have also in my FPGA implementations of the 99/4A already tested direct memory mapping of VDP RAM, through a 256 byte window if I remember what I did a couple of years ago.

  • Like 4
Link to comment
Share on other sites

Just think of the possibilities!

 

I'm still curious in it's current form how fast SC can feed the VDP (through the CPU) with the LI instructions compared to something pulling data off of a ROM.  Are we using the same speed for both types of data exchanges in the current architecture?  Or can the SC ARM processor "feed" data faster than a ROM can?

Link to comment
Share on other sites

15 hours ago, speccery said:

What I have already done with the StrangeCart is to dynamically on the fly create a program, which only writes to the VDP memory. It does this by setting the workspace pointer to point to the VDP write port, and the just uses the load immediate (LI) instructions to write data to the VDP.

Any idea what kind of throughput you can get this way?

Link to comment
Share on other sites

Doing some back of the napkin math: it seems that an LI instruction takes 24 cycles to execute and we can do 50000 cycles per 1/60 second (VDP frame), so about 2000 LI's per frame. We need 6144 LI's per frame for a full screen monochrome image, so we should be able to achieve a little under 20fps this way.

Link to comment
Share on other sites

9 hours ago, TheMole said:

Doing some back of the napkin math: it seems that an LI instruction takes 24 cycles to execute and we can do 50000 cycles per 1/60 second (VDP frame), so about 2000 LI's per frame. We need 6144 LI's per frame for a full screen monochrome image, so we should be able to achieve a little under 20fps this way.

Any thoughts to also improve the PCM quality by feeding sound data directly the sound chip?

 

(Edit:  This is a conversion tool for sound that can provide high quality audio and target the SN76489.  From what I understand, it essentially pre-processes the sound to make it sound better vs just encoding it.)

https://github.com/maxim-zhao/pcmenc


I’m seeing new demo capabilities here with even a stock machine.  A new mega demo on stock hardware?  ?

 

An example from a SMS (which I think uses the same sound chip?)

 

 

 

  • Like 4
Link to comment
Share on other sites

We did all the math on fastest approaches years ago... In bitmap mode, you need to wait 8uS between each data write to avoid losing data. That's roughly 24 cycles - and the LI from 8-bit cartridge memory should be 24 cycles as TheMole notes - greatly helped by lack of read-before-write. That puts it right on the edge meaning it will probably work on some machines and fail on others (F18A would not have any issue, of course.) Would be fun to see what it can do though.

 

You also have to deal with the memory range. You can autogenerate the program, but you still need to insert a branch every 8k or so (or a jump every smaller amount, but the branch would cost less in the long run). You have to keep the generated instructions inside the cartridge memory space, since the address counter still increments. The longer the range you dedicate to the generated code, the less this costs.

 

The SMS (and MSX) sound chip has a major advantage over the one in the TI when it comes to samples - it can turn off the square wave generator and output a volume modulated line. The TI can't, so there will always be some added distortion. Because the TI can't turn off the square wave generator, using the pcmenc trick of stacking the logarithmic channels will produce unreliable results on our hardware - some channels will be additive, some will be subtractive, and it'll change every time you reset. (This is because the sound generator powers up in a random state, so all the counters have unpredictable values. When you set them to maximum frequency, there is no guarantee they will line up with each other.) I attempted this back when I first started working on samples, and it took me a few days to figure out why the samples looked so awful. ;)

 

It's interesting that the github page targets ColecoVision, which I am pretty sure is the same as the TI version. I wonder if they tried it there or just assumed it would work...

 

All that said, theory vs practice. Give it a shot, see how it sounds! ;)

 

 

  • Like 6
Link to comment
Share on other sites

I did some real world tests with the StrangeCart demos I have written in the past. My code divides the transfer of each frame into four blocks, since the 8K ROM area is not enough for a full monochrome frame (one frame is 768 cells of 8 bytes each, 6144 bytes). Each LI instruction requires 4 bytes but the payload is only 1 byte. Furthermore, I have reserved in this demo the first 512 bytes of the cartridge area for setup code, and the remaining 7.5 K are for the LI stream. The amount to be transferred is computed by the fill level of the ROM, but I checked it lands at 239+239+239+51 cells. Again, each cell is 8 bytes of payload, which when converted to LI instructions is 32 bytes.

I used the high resolution timer of the MCU to measure some times, at 150MHz MCU clock:

  • Generation of LI instructions programmatically for 239 cells: 182 microseconds (this rounds to zero compared to the other numbers below)
  • Launching the TMS9900 (some handshaking) about 40 microseconds
  • Waiting the TMS9900 to run the code 15521 microseconds (for 239 cells, 1912 LI instructions+handshake at the end)
  • The last transfer takes 3319 microseconds (for 51 cells)

Thus the transfer of one frame takes approximately 3*15521+3319 = 49882 microseconds, which translates to 20 fps.

 

In my demo I render the next frame during the first transfer of 239 cells, i.e. while the TMS9900 is working through the LI instructions. This means clearing a frame buffer on the MCU side, and rendering the frame. There's a whole lot of floating point math that goes into a frame, and it takes 20420 microseconds to render a frame at 150MHz. Thus in my case the TMS9900 has to wait a little before before the MCU is ready, and in practice I reach 15.75 fps. The measured bandwidth is 111506 bytes per second to VDP memory due to this. 

 

To round these numbers into something a bit easier: render time (MCU) 20 ms, transfer time of 239 cells 15ms, transfer time of 51 cells 3 ms. Since the render time exceeds transfer time by 5 ms, I am not reaching maximum performance in my demo. This could be trivially fixed by breaking the rending of a frame into two or three parts, and doing part of the rendering during the following transfers.

Edited by speccery
  • Like 4
Link to comment
Share on other sites

10 hours ago, ti99iuc said:

this is just my first homemade attempt to build a cart with a label for this powerful cartridge - Thanks @speccery I really like it.

 

Thanks @ti99iuc looks very nice indeed! I realise I forgot to send you the button covers, but I see you have already found something! I am curious - did you get the board working in the case? The reason I'm asking is that I have been pretty much only testing the bare boards, and I am still not completely that in these prototypes the edge connector is exactly the way it should be. I think I have four TI-99/4As now, but I primarily only use the two of them which have F18As.

 

I need to come up with something that enables me to use one with the original VDP. For that purpose I have built two RGB2HDMI boards (the ones which use Raspberry PI), but I have not yet used one with the TI, I think it may need some extra work to support TMS9929 (I think that's what's in my computers, need to check). I have tried to reduce clutter on my desk, and that has meant using a HDMI monitor with multiple inputs, and an USB capture dongle with VGA to HDMI adapter. So from F18A to VGA-to-HDMI, from there USB capture :) 

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

We had a bank holiday here, so I set aside some time to make a “getting started” type video for the StrangeCart. The video work started well, but as I was recording and tried to demonstrate some simple things in Basic I got weird behavior. 
 

I have made a fair amount of firmware updates, and I spent extensive amount of time debugging a seemingly simple problem. It turns out that interprocessor communication bugs take a long time to identify, fixing is easy once I knew what was wrong. 
 

Anyway, although I have some good material I was not able to make the video. The next few days are going to be very intensive at work and then I have two back to back trips, so likely no time with the TI for the next week and a half. Sigh.

 

The software is getting quite complex. I should refactor some more code from C into C++.
I am also thinking that I will soon need a more comprehensive simulation for the whole system to be able to work on it without the TI *and* be able to have breakpoints (across all CPUs). That made me think that the firmware actually already has my TI emulator linked in… hmm. I could potentially run the firmware on the StrangeCart including the TI side for debugging… more seriously I should port the whole thing to my Mac or Linux, so that I could use debugging tools from 2022 to work on this.

With built in emulation this indeed is becoming quite strange :) 

  • Like 6
Link to comment
Share on other sites

19 hours ago, speccery said:

We had a bank holiday here, so I set aside some time to make a “getting started” type video for the StrangeCart. The video work started well, but as I was recording and tried to demonstrate some simple things in Basic I got weird behavior. 

Well it appears the problems I were having could be fixed in three steps, each taking a fixed amount of time (rare when developing software):

1. Pull out the cartridge (2 seconds)

2. Clean the edge connector with IPA (30 seconds)

3. Reinsert the cartridge (5 seconds)

Done. Need to spend more time with testing though :) 

  • Like 4
  • Haha 1
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...