Jump to content
IGNORED

Icy99 FPGA 99/4A


speccery

Recommended Posts

On 10/20/2020 at 12:01 PM, Willsy said:

Yes. @InsaneMultitasker and Fred Kaal helped me to work them out. 

Was that before or after napping at the Chicago Faire?  :D

 

The most common 80 column artifact 'problem' is that V9938/58 systems need registers V8-V15 initialized if you want a program to display properly in multiple environments.  One brute-force method that Gazoo and I used in the past was to clear VR8-15 then set VR0-7.   (If you set VR0-15 in ascending order with only 8 active registers, VR8-VR15 can overwrite VR0-VR7).   So typically you want to write the high 8 registers first to avoid a potential masking/wraparound problem. 

 

Edit:  See discussion here regarding detection methods for v99x8 and f18a. If you can detect the configuration that is often the better approach.  

 

 

 

  • Like 5
Link to comment
Share on other sites

Somewhat off-topic: in my exploration of different low-cost FPGA chips, I sometime ago came across the Lattice ICE40UP5K chip. It can be targeted with the open source icestrom toolchain. I ordered from Tindie two Upduino V3 boards to test these chips, I got them about a week ago after some exercises with customs.

UPduino at GitHub

I put quickly together a simple "breadboard" design (as I call it) and now have it successfully running on this tiny chip.

Basically it's a minimal TMS9900 system, consisting of:

  • TMS9900 processor core (my verilog version) running at 12MHz
  • TMS9902 UART (this is @pnr's design, also verilog version)
  • A slightly modified EVMBUG ROM to support 9600 bps 8N1 serial format. This is a 8K ROM.
  • 32K RAM

I haven't done any extensive testing, but hey, if it runs the processor core and provides a stable UART connection and is able to receive commands and does disassembly of the ROM it cannot be too far off. I am interested of this chip since it is tiny, cheap, has only 48 pins (well if you can call them that with the QFN-48 package) so it should be useable in many projects.

The aspect which makes the chip interesting for retro computing stuff is that is has on-board 128 kbytes of RAM single port RAM (in 4 blocks) as well as 16 kbytes of dual port RAM (in 32 blocks of 512 bytes). So this chip alone, with no external RAM, could be able to support TI-99/4A. The logic capacity of the chip is small, and my breadboard project already took 57% of logic cells, but it seems it might be possible to make a version of Icy99 for this one too.

  • Like 3
Link to comment
Share on other sites

7 hours ago, TheBF said:

This is cool.

Is the 9902 connected to the USB port?

I have a kernel that runs over 9902.  Could I make it work with this board?

 

 

Thanks. Yes, the 9902 is connected to the USB port after the FPGA is configured. My setup is super simple, so there is just the CPU, the 9902 and memory (8k ROM in the bottom of address space, 32K RAM in the top half of the address space). The memory layout is not as in the TI-99/4A. But as this is FPGA based, one can configure the memory anyway one wants. If your kernel only needs the CPU and for example 64K RAM, it would work. I will post this “breadboard” Verilog core later today to github.

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

Continuing a bit off-topic (I have also worked on the icy99, more about that shortly).

 

I committed the first version of the small TMS9900 system into GitHub.

I seem to have forgotten how to link album picture to posts, but anyway below is a picture of the UPduino V3 board.

IMG_3674.thumb.jpg.e13208e626bfd14d0f367ab0f41cb1ed.jpg 

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

I've worked a bit more on icy99. This time I actually had time to work on it, but the bugs I was wrestling with were surprisingly difficult to identify.

My test case has been Megademo. In addition to being great to look at, it also exercises many features and is very good for uncovering bugs.

I fixed two bugs: multicolor mode, and a bug which manifests itself in the very first phase of the demo (stretch.a99). 

 

The fixes for both bugs were super simple - once I knew what to fix. Fixing the multicolor bug took probably only an hour, I was setting the pattern for shift register and the colors a little incorrectly. This was harder to find than it needed to be, since I didn't remember when reading the Verilog code that I have some states where the state machine can stay for rather long, and it processed the correct data in the first cycle, but then overwrote the correct data with bogus data on the next cycle while waiting for the bit shifter to become available. 

 

I spent way too much time wondering and fixing the bug in the stretching effect: in order to be able to understand what the heck was going on, I finally had to take UART output into use, and modify the stretch.a99 code so that it initialises the TMS9902 UART and writes hexadecimal words every now and then. So normal printf() style debugging, but in assembler. Eventually after suspecting bugs in the CPU etc I found out that the data which is streamed from memory to screen in this demo is split across multiple 8K pages (when loading from cartridge). I had bug in cartridge paging: when I extended it to 2 megabytes, I forgot to widen the page register assignment, and only 5 bits were written to the 8 bit page register. This limited the cartridge size, as seen by the TMS9900, to 256kbytes. It just so happens, that the code and a portion of the data in stretch.a99 were in the last page in that 256K region, but most of the data are in the next two 8k pages, which was above the 256K region size. So the CPU got just random data when reading them (or not random, but data from other unrelated pages) and that caused a messy display. The fix was simple, but finding the culprit probably took something like 8 hours... Well at least in the process I have improved my debugging tools.

 

At least one bug still lingers, the splitscreen3_demo.a99 uses the sprite COINC flag to get access the VDP's vertical position counter. I have already worked on this bug in the VHDL version of the code and fixed it there (yes two times the same bug seems to the charm here). It appears that my Verilog implementation of COINC works, except when the sprites bleed in from the top. In this demo effect the first vertical coordinates seem to be -2 (or 254). This should trigger COINC on the first scanline, but due to the bug COINC is never triggered, and the demo just halts. At least that is very noticeable, and the bug also manifests itself in my Verilog test bench for the VDP, so this should not be too hard to fix.

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

Keep in mind, in the 9918A sprite collision detection is *only* active when pixels are being shifted out of the four sprite shift registers, and only sprite pixels with a pattern value of '1' will trigger a collision (the fg color of the pixel does not matter, and it may be transparent).  The sprite shift registers are only active during the active display area (256x192).  Since sprites are processed on the scan line prior to where they appear, the first visible sprite Y position is 255.

  • Like 1
Link to comment
Share on other sites

8 hours ago, matthew180 said:

Keep in mind, in the 9918A sprite collision detection is *only* active when pixels are being shifted out of the four sprite shift registers, and only sprite pixels with a pattern value of '1' will trigger a collision (the fg color of the pixel does not matter, and it may be transparent).  The sprite shift registers are only active during the active display area (256x192).  Since sprites are processed on the scan line prior to where they appear, the first visible sprite Y position is 255.

Thanks, these are really good reminders! I am thinking about refactoring the sprite generator somewhat, since it's gotten a bit too complex by now.

Link to comment
Share on other sites

I think I have now fixed all bugs related to TMS9918... Well not quite. Megademo now seems to run correctly, except for the multisplit_demo.a99 which does not correctly display the splitscreen material. I think I need to check what happens with my VRAM memory address pointer when changing modes.

 

The sprite coincidence stuff now seems to work correctly. I also had a couple of other bugs, with sprite behaviour with early clock bit set (left edge) and rendering not stopping at the right edge.

 

I had a hard time finding any software to test sprite bleeding in from the left: I did not realise it before, but Extended Basic does not support setting the early clock bit: sprite coordinates range from 1 to 256, no option to set negative coordinates to test sprites partially displayed from the left. I only tested the behaviour with iverilog simulation then, and it seems to work there. I thought that at least the UFO in TI Invaders would nicely enter pixel by pixel from the left but nope, it just appears out of nowhere completely. On the right edge it does disappear and enter pixel by pixel, I guess they didn't want to spend a few more bytes to do it nicely on the left edge too.

 

And while in the topic of wondering and ranting about Extended Basic:

  • CALL SPRITE: Why the heck is the coordinate system not zero based? 1 to 256? I did not realize this before, especially when coding as a kid :)
  • Still on CALL SPRITE: what is the deal with the hash sign for sprite numbers? It seems completely superfluous syntax and only consuming valuable RAM. (After writing the entire message I realised that perhaps CALL SPRITE allows multiple sprites to be instantiated with one command, in that case the hash makes sense - but I still don't like it and the lines are very long even with one sprite declared).
  • Sprite auto motion is kinda cool, but at the end of the day seems unnecessary since Basic code anyway is not fast enough to check where the sprites are driving around. I used slow speed sprite moving for checking my TMS9918 implementation, and discovered that it does not move all the sprites at the same time. I had a whole bunch of sprites on screen with horizontal speed -1, and they did not move at the same time. Perhaps that's just because in Basic one cannot start more than one sprite at the same time (given the slow speed of Basic). Another reason why automation is not useful...
  • And why does Basic editor & listing not use the first column/columns??? Valuable screen real estate wasted!
  • This next one is a bit specific: I am using PS/2 keyboard connected to the FPGA board. To edit lines as probably everyone here knows you enter the line number and push cursor up/down to call the line for editing. Half the time I accidentally pressed enter after the line number - deleting the line. And of course there is no command line history nor undo... I have to say I miss dearly those features. User error for sure, and it comes with a hefty punishment - but not as hefty as pushing QUIT accidentally - of course no confirmation is asked, and the Basic test program is gone...

Enough ranting there.

 

The other FPGA feature I added was cursor key navigation for the on-screen display on the ULX3S board. Now hitting F1 brings the OSD up, and cursor keys can be used to navigate the SD card and load GROM and ROM data.

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

I’m quite sure I had to set the early clock bit in one of my assembly language games.

Think it was Pitfall, but memory is fading as it has been many years.

If that it’s not it it might have been my Time Pilot demo.

 

Either way, quite sure Rasmus had to set the early clock in one of his many games ?

  • Like 1
Link to comment
Share on other sites

8 hours ago, speccery said:

I had a hard time finding any software to test sprite bleeding in from the left: I did not realise it before, but Extended Basic does not support setting the early clock bit: sprite coordinates range from 1 to 256, no option to set negative coordinates to test sprites partially displayed from the left. I only tested the behaviour with iverilog simulation then, and it seems to work there. I thought that at least the UFO in TI Invaders would nicely enter pixel by pixel from the left but nope, it just appears out of nowhere completely. On the right edge it does disappear and enter pixel by pixel, I guess they didn't want to spend a few more bytes to do it nicely on the left edge too.

My game Fork is using early clock all the time a lot.

fork8.bin

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

6 hours ago, Asmusr said:

My game Fork is using early clock all the time a lot.

fork8.bin 32 kB · 1 download

Thanks @Asmusr very helpful! I had a rather spectacular bug - the early clock bit setting was not reset after sprites were done, causing the early bit to impact succeeding characters. This whole test and bug fix took only something 10 minutes. Below pictures before (with bug) and after (bug fixed). The bluish ball is partially visible on the left hand side. My 4K monitor supports PIP mode, so the HDMI coming out of ULX3S goes to my monitor and I've set the picture to bottom right hand corner.

1479940657_Forknotworking.thumb.jpg.4fb0365fc97c30ced12d01cfcb81af66.jpg with the bug :)

 

And after fixing by resetting the early clocks after done with sprites:

1193995429_Forkworking.thumb.jpg.e9bc38646899d080dac244f8e85f6331.jpg

 

 

  • Like 2
Link to comment
Share on other sites

  • 3 weeks later...

A bit more progress, now I finally added sound support to the icy99 (for the ULX3S FPGA board). This of course makes a big difference to the gaming experience. There is still some more low hanging fruit, support for 1M AMS is probably next. For file system support it seems that the easiest way to get going is to just integrate the TIPI interface.

 

I was planning to make this weekend a video of the current state of the project, but ran out of time, hopefully in the next few days.

 

In case anyone is interested, I noticed that at Mouser they have some ULX3S boards in stock. These are with smaller 12F FPGA - with the open source tools this can be used as 25F, Lattice 12F and 25F chips are the same by their own tools don't enable one to use the 12F as 25F). I am using the 85F boards for development, but people in the ULX3S community have told me that the design works also on the 12F boards.

 

Since the icy99 uses a very modest 25MHz clock speed, and I have been targeting four boards in the beginning, the design should be fairly portable. I haven't in a while synthesised versions for other boards, but I plan to pretty soon do that. I also want to give porting this to the MIST a go.

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

11 hours ago, speccery said:

Since the icy99 uses a very modest 25MHz clock speed, and I have been targeting four boards in the beginning, the design should be fairly portable. I haven't in a while synthesised versions for other boards, but I plan to pretty soon do that. I also want to give porting this to the MIST a go.

 

Could you please consider also the MiSTer (Terasic DE10-Nano board) platform? At the moment is the best choice for the retrocomputing and it's an open plaftorm (if compared to Mist/Mistica that are not open source). Moreover, due to additional power of the chipset could be the right solution for implementing additional stuff (e.g. Geneve).

 

Link to comment
Share on other sites

22 hours ago, tmop69 said:

 

Could you please consider also the MiSTer (Terasic DE10-Nano board) platform? At the moment is the best choice for the retrocomputing and it's an open plaftorm (if compared to Mist/Mistica that are not open source). Moreover, due to additional power of the chipset could be the right solution for implementing additional stuff (e.g. Geneve).

 

Yes I am thinking about MiSTer too. My primary hesitance about it is simply that I still have all the parts in a box and I haven't put mine together. I have done test synthesis (of another core) for the MIST, so I know working with that is not a problem, but haven't done the same yet with MiSTer. It should not be a problem either, but haven't tried out the toolchain.

 

Having said that, for something like the Geneve the other platforms are also easily capable enough. As one example, the Lattice 25F can support the Commodore Amiga Minimig core on the Flea FPGA Ohm board.

  • Like 2
Link to comment
Share on other sites

I've worked a bit on integrating TIPI support into icy99. I am now at the point where the next step would be to simply connect the around 8 wires between the FPGA board and Raspberry Pi. So getting into an exciting phase.

 

So far this integration has been interesting for many reasons:

  • I know (or I should say knew) almost nothing about the TIPI, except that it runs on the Pi and connects via SPI bus (implemented with a CPLD) with the 99/4A. By the same token, I have never operated the TIPI.
  • It is interesting that the TIPI is also a Verilog design, and there are not many of these for the 99/4A :)
  • As such, it was an interesting exercise to connect these two blocks together. Basically connecting a peripheral intended for the TI-99/4A to a TI-99/4A. Basically simple but a good reminder that my signals within the FPGA are not the same as one one would find on a regular TI-99/4A. A couple of major differences: for one, as is usual with FPGA designs, my design is fully synchronous and running from a single 25MHz clock. Everything occurs in sync with this clock. I don't have a multiple phase clock. Secondly I don't have the exact signals one normally finds on a TMS9900: I don't have #MEMEN (instead synchronous RD and WR signals, and #MEMEN can simply be generated with NOT (RD OR WR)), and I have an actual CRUOUT which is not multiplexed with A15. A third difference is that there are no three state bidirectional buses: there are separate data read and data write buses (with the exception of the bus connecting to off-chip SDRAM, which is a bidirectional data bus). The fourth difference is coding style, but this is a matter of taste.

I have TIPI software installed on a PI 3B+, and I can connect via ssh to it, so that part should be ok. On the 99/4A side the TIPI DSR is loaded, so not much remains - in theory. In practice I want to reserve at least a few hours to work and debug on this in one go, as I don't expect this to just magically start working - although it could happen :) 

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

On 11/24/2020 at 11:47 AM, BeeryMiller said:

I'm not sure which DSR you are using, but keep in mind Matt's DSR code has some conditional assemblies on whether it is running under emulation or not in the tipi-io.a99 and the vdp-io.a99 code besides the change in ports.

 

Beery

Those emulation conditionals have nothing to do with running the current TIPI emulation with js99er. Forgot they even existed... Now that we have js99er integration, I should remove the debris in the DSR completely. It was for mocking responses when stepping through the DSR code in classic99.

 

---

SPI? That wasn't intentional. But yes it is really close to SPI where the PI is the master, and I do slave-select oddly. I probably could have saved months if I had read the SPI specification.

  • Like 1
Link to comment
Share on other sites

I am happy to report that TIPI works well with icy99. I am actually very impressed with the functionality that TIPI brings to the table - with very little effort on my part. I have just scratched the surface, and I am using just DSK1 and DSK2 support for now. But this TIPI + icy99 combination is a bit of game changer for me. I can now focus with good conscious on some of the cool things I want to add, now that disk support is already there. As was briefly mentioned in the Facebook discussion at the TI99ers group, I want to add 1M SAMS memory support and also GRAM support while at that.

 

And then there are other things, such as expanding VRAM to 64K and adding support for extended attributes in the VDP. And I should slow the system down to original speed, if I can somehow resist the urge to make the system go very fast. With the TIPI support and 1MB of RAM it feels like having much more CPU power would be cool again... Unlike with my first EP994A core, I haven't this time around focused on the TMS9900 core performance too much. I just ran a simple extended Basic test program, and it runs at 4x speed on the icy99 compared to the real iron, so plenty fast, but nowhere close to the 30x performance with my first implementation. The icy99 CPU core is a little faster per clock, but it runs without a cache, with SDRAM, and at a quarter of the clock speed.

 

I need to tidy up the cabling by rearranging the pins on the FPGA side, so that I can just use a flat ribbon cable. My video (linked in the above message) explains the setup better, but the picture here shows the cabling arrangement, which is unnecessarily flaky. Here icy99 is running TurboForth in 80 column mode.

IMG_3807.thumb.jpg.d4476051c4d6e74bc1e0860f215736b7.jpg

  • Like 6
Link to comment
Share on other sites

6 hours ago, speccery said:

I am happy to report that TIPI works well with icy99. I am actually very impressed with the functionality that TIPI brings to the table - with very little effort on my part. I have just scratched the surface, and I am using just DSK1 and DSK2 support for now. But this TIPI + icy99 combination is a bit of game changer for me. I can now focus with good conscious on some of the cool things I want to add, now that disk support is already there. As was briefly mentioned in the Facebook discussion at the TI99ers group, I want to add 1M SAMS memory support and also GRAM support while at that.

 

And then there are other things, such as expanding VRAM to 64K and adding support for extended attributes in the VDP. And I should slow the system down to original speed, if I can somehow resist the urge to make the system go very fast. With the TIPI support and 1MB of RAM it feels like having much more CPU power would be cool again... Unlike with my first EP994A core, I haven't this time around focused on the TMS9900 core performance too much. I just ran a simple extended Basic test program, and it runs at 4x speed on the icy99 compared to the real iron, so plenty fast, but nowhere close to the 30x performance with my first implementation. The icy99 CPU core is a little faster per clock, but it runs without a cache, with SDRAM, and at a quarter of the clock speed.

 

I need to tidy up the cabling by rearranging the pins on the FPGA side, so that I can just use a flat ribbon cable. My video (linked in the above message) explains the setup better, but the picture here shows the cabling arrangement, which is unnecessarily flaky. Here icy99 is running TurboForth in 80 column mode.

IMG_3807.thumb.jpg.d4476051c4d6e74bc1e0860f215736b7.jpg

Is that also an R PI 400 in the background?  

  • Like 1
Link to comment
Share on other sites

22 hours ago, jedimatt42 said:

SPI? That wasn't intentional. But yes it is really close to SPI where the PI is the master, and I do slave-select oddly. I probably could have saved months if I had read the SPI specification.

You probably were referring to my comment on it being SPI. At the time I assumed it was SPI. On closer inspection there is also a parity bit, so this is not your SPI. SPI comes in may flavors, depending on which clock edge data is shifted out and sampled by the receiver. I also note that there are multiple shift registers in the design. I haven't looked at the Rasberry Pi code yet, but I assume the code is just bit banging the data. I need to push to Github my Verilog changes to the code, but I should clean up the code a little first.

Link to comment
Share on other sites

7 hours ago, ti99iuc said:

Wow! I can feel the power!  ????
 

You could not create something like the SpeedUp Mod but managed by icy99?
Something like a switch to set the speed you want use?

:) Yes, for sure a switch could be added. I am going to add a hotkey for that. I already use F1 to pull up the overlay screen for ROM loading, so perhaps F2 should pull up a configuration screen.

  • Like 2
Link to comment
Share on other sites

4 hours ago, TheBF said:

Is that also an R PI 400 in the background?  

Well spotted, I was thinking that somebody will recognize it. I am a bit of Raspberry Pi fan, I attach here a picture of Pis on my desk as well as a family photo of the ones on the shelf. Some are missing from these pictures, I seem to have hoarded a few of these over the years... For example I have (most of the time) in my work bag a Pi 4 with a SSD drive with icy99 development environment, you never know when inspiration hits.

 

IMG_3809.thumb.jpg.925fd01c6adf236869f604264f72203b.jpg

The family photo :) 

IMG_3810.thumb.jpg.761daf43f55839a020f4c781ecee5ff1.jpg

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