Jump to content
IGNORED

TI-99/4A with a Pipistrello FPGA board


speccery

Recommended Posts

From the Parsec source code it looks like it's reading from GROM into a 64(?) byte buffer in scratchpad ram where the graphics is shifted and then sent on the the VDP. I guess the answer to my question is the same as for GPL: all these instructions take so long that the read from GROM is relatively insignificant in comparison.

 

 

And I did not even know that Parsec source code is available :) Still new to the TI scene. Thanks for providing it! I wonder if anybody has done new versions of it? F18A support?

Link to comment
Share on other sites

Here's an analysis I did back in 2009 on Yahoo:

 

This struck me as interesting, so I used Classic99 to see how true it really is.

 

Parsec does indeed write and execute a small piece of scratchpad RAM every frame, from 0x83E0. However, there's a lot of code executing in the scratchpad, which does not get written repeatedly. Here's a function at >8354:

 

 

 65D0 bl @>8354
 8354 movb @>8800,@>833c(R3)
 835A inct R3
 835C jlt >8354
 835E b *R11
 8360 mov @>833c(R4),R1
 8364 src R1,0
 8366 movb R1,@>8c00
 836A inct R4
 836C jlt >8360
 836E b *R11
>8360 contains another subroutine:

 

 6714 bl @>8360
 8360 mov @>833c(R4),R1
 8364 src R1,0
 8366 movb R1,@>8c00
 836A inct R4
 836C jlt >8360
 836E b *R11
Parsec does not appear to write the scroll routine to scratchpad every frame. I tested this by adding code that would flag all executed bytes

in the scratchpad RAM, then emit debug if they were written to. After the game was up and scrolling, I breakpointed the emulator and cleared

those flags, then resumed. There was no debug emitted. When I started the game, that's when I saw the messages about data at >83Ex being

executed and written.

 

The code that ends up there, and thus gets rewritten, looks like this at game start:

 

 7F34 bl @>83e0
 83E0 movb @>9000,R10
 83E4 jmp >83e6
 83E6 jmp >83e8
 83E8 jmp >83ea
 83EA b *R11
Note those three JMPs are NOPs, so all this does is a delay. Since it's reading from >9000, this is probably just a little routine to safely get the speech status without touching the 8-bit bus. This is the only code that is written to scratchpad every frame, the rest lives there

permanently. It's only updated when it thinks it might be speaking.

 

By breakpointing on that code, it looks like Parsec has a 5-frame scroll sequence, and it writes and calls this function for every frame. The

five frames seem to be:

 

-Scroll first quarter of scenery

-Scroll second quarter of scenery

-Scroll third quarter of scenery

-Scroll fourth quarter of scenery

-Scroll stars and animate ship flame

 

https://groups.yahoo.com/neo/groups/TI99-4A/conversations/topics/62734

  • Like 3
Link to comment
Share on other sites

I've been working on my retrochallenge project. The week was busy, not much progress, but now I have TMS9918 graphics mode 1 compatible output. Kind of. This is fun, and it would be great fun to work more on this alone, but I want to get Basic running so that this would become closer to a real TI. For that I need to add GROM support to this design, I think I also am going to need VDP interrupts, and probably something that resembles a TMS9901 to get keyboard connectivity. My understanding is that the sound chip is write only, so that will be the last thing to go in. I do have actual chips that I could use for the keyboard controller and sound, but I think the TMS9901 would have trouble running at 5MHz machine cycles of the TMS99105. My understanding is that the sound chip requires wait states even with the TMS9900 although I did not check. Now that it seems the CPU, memory and "VDP" can interact stably at 5MHz I do not want to slow things down :-D

 

To be honest my "VDP" is write only at this point, but getting support for reads will not be a problem as the VDP memory is on-chip the FPGA and thus very fast. Getting the external SRAM working was harder.

 

Video here:

https://www.youtube.com/watch?v=JYpLSkfiT9E

 

And some more description here:

https://hackaday.io/project/15430-rc201699-ti-994a-clone-using-tms99105-cpu

 

Like I wrote at the hackaday project log, the start screen is fake in the sense that the TMS99105 just copies it from SRAM to VDP memory, but it seems to display *roughly* correctly and that was the point of the exercise. I captured that dump with classic99 and included it in my test firmware. The VDP registers are initialized to the values indicated by classic99. Some of the registers do nothing at this point, since I don't have anything else than the graphics mode 1.

  • Like 1
Link to comment
Share on other sites

The sound chip in the 99/4A is wired up to deliver wait states, but it's unclear to me that it's not fast enough to prevent actual waits (one of the many things I still need to wire up and test). That said, there's nothing that /requires/ it, like the VDP it could just as easily run freely.

  • Like 1
Link to comment
Share on other sites

You should check the specifications of the 76489 / 94624 concerning timing. The sound generator is a surprisingly simple circuit, essentially a counter per channel that flips its output every time the counter reaches 0.

 

 

Yes it is indeed simple. I looked at the data sheet. Still it would take a few hours to build all of that into the FPGA, but that I suppose is what needs to be done. According to the data sheet, the writes to the control register take about 32 cycles (at around 4MHz). In FGPA logic terms this essentially means forever, about 800 clock cycles at 100MHz. The open collector ready output of the chip indicates when the write is complete. On the other hand I have no other devices that require the ready signal, so depending on how I am doing with time I could just wire this chip on the protoboard, and I would only need one pin from the FPGA, the chip select signal. The ready output would just need a pull up to 5V, and then it could be directly connected to the CPU's ready input. Actually I'd need also another signal for the clock of this chip.

With that I think my strategy is that I will implement it inside the FPGA if I have the time, if not I will just plug in the chip and do the wiring.

  • Like 1
Link to comment
Share on other sites

YIPPEE! I got first successful boot with original TI ROMs and GROMs!

I added a bunch of stuff today, all listed in my hackaday project log entry, and this resulted in the TMS99105 rendering this nice picture after reset!

FIRST BOOT WITH ORIGINAL TI-99/4A ROMS AND GROMS! TMS99105 and FPGA

I am very happy! Need to add TMS9901 support next to get some user input going, I'm dying to know if it would move to the next screen with a keypress!
The big problem I had initially was that the bloody original Basic ROM or GROM code corrupts the ROM. In other words, I implemented ROM as RAM, loaded from the PC. But unless the bottom 8K is write protected it does not work. So I blame TI code - of course it could a bug in my design too (how likely would that be :) ), but I seem to remember reading from somewhere that the basic does actually write to ROM.
  • Like 6
Link to comment
Share on other sites

looking nice!

 

But unless the bottom 8K is write protected it does not work. So I blame TI code - of course it could a bug in my design too (how likely would that be :) ), but I seem to remember reading from somewhere that the basic does actually write to ROM.

I tried catching this with Classic99's debugger and couldn't, at least as far as boot, start TI BASIC and run a program consisting of "10 print 1+1"

  • Like 1
Link to comment
Share on other sites

 

looking nice!

 

 

I tried catching this with Classic99's debugger and couldn't, at least as far as boot, start TI BASIC and run a program consisting of "10 print 1+1"

 

 

Thank you very much for checking! So in that case I must have a bug somewhere. This would be hardly surprising :( . Now that I think about it, and I am not as tired as last night, I probably went a bit too far there, and the comment I read about Basic writing to ROM probably was not on the TI, but on some other retrocomptuter. So my apologies to TI.

 

By the way, I am using classic99 as an important development and testing tool, loading my test code to address >6000 as a cartridge ROM, and compiling it to address >0000 for the TMS99105. xas99.py makes this super easy. I have been comparing GROM reads regarding both data and addresses to what I get on classic99, as well as VDP operations, and when I get identical results I know things are good :)

Classic99 is just a great piece of software!

 

Regarding my bug then, it is a good thing this is running on an FPGA, as I can take one of the available dual-port RAM blocks and make it into a trace buffer, recording bus activity. Since I know write protection of lower 8k helps, I will probably just keep recording bus interface signals at some high frequency (addresses and control signals) and stop the recording when there is a write to low 8K. I need to make that RAM available for reading from the host side. I used this technique when I built a ZX Spectrum clone. It's a bit like a built in logic analyzer.

  • Like 2
Link to comment
Share on other sites

Thank you very much for checking! So in that case I must have a bug somewhere. This would be hardly surprising :( . Now that I think about it, and I am not as tired as last night, I probably went a bit too far there, and the comment I read about Basic writing to ROM probably was not on the TI, but on some other retrocomptuter. So my apologies to TI.

There are lots of bugs in there, just apparently not that one. We've seen writing to ROM a lot on cartridges though. ;)

  • Like 1
Link to comment
Share on other sites

this is such impressive stuff. be assured that many people would benefit from the fruits of such a project. I hope you enjoy your retro challenge. all the best!

 

 

Thank you for the support Klaus! I do want to make the results available if I get this working.

 

Today was a crazy day, and I really did not have time to work on this... But I still took an hour... So the pepino FPGA board I'm using has one tactile switch. I made it behave as keyboard button "1" and expanded my test app to show that indeed again here behaviour matches classic99, when the button is pressed the CRU I/O space keyboard selection works properly, the appropriate bit follows my button. I don't have proper interrupts yet. So I push the button with Basic ROMs and GROMs loaded - and no go. Screen becomes blank after the initial screen. Okay, this could be a million things still. Working backwards on what has been the least tested area of my FPGA functionality - the GROMs. And VDP reading. If one of them fails ever so slightly, especially GROM handling, the GPL interpreter is going to get very confused and may write all over the place, including the ROM. So I need to write a test app to really test GROM access, more that a few bytes, it needs to process and test through them a million times. VDP reading I have tested a bit more, so that might work.

Link to comment
Share on other sites

Yeah, hammer on your GROM code - there are a few places in the GPL interpreter where the results of the prefetch must be correct, or it will crash.

 

Interrupts and even keyboard are not critical to the system running... early versions of Classic99 ran without interrupts and the keyboard was a software hack that just injected kscan codes into the right register based on program counter. (Of course, for your case the CRU implementation is probably easier). You can get away with implementing just the bits that are relevant to the keyboard as a start though.

  • Like 1
Link to comment
Share on other sites

Yeah, hammer on your GROM code - there are a few places in the GPL interpreter where the results of the prefetch must be correct, or it will crash.

 

Interrupts and even keyboard are not critical to the system running... early versions of Classic99 ran without interrupts and the keyboard was a software hack that just injected kscan codes into the right register based on program counter. (Of course, for your case the CRU implementation is probably easier). You can get away with implementing just the bits that are relevant to the keyboard as a start though.

 

Thanks Tursi!

 

I have implemented CRU stuff in a previous project in a FPGA, it is very easy and straightforward. I have implemented a three bit register to capture the CRU addresses >24,>26 and >28 and this implements the keyboard column capture, and reading port >0E will return a zero when column 5 is selected and the button is pushed: that's how key '1' is detected. This matches behavior on classic99 and I am pretty confident that his works. My assembler code scans all 8 columns, and the button press is reflected property only in one of them. I have implemented no other CRU functionality than the write of those three bits and the read of the eight keyboard input bits (naturally in a bit addressable fashion). The other CRU ports, when read, should return a hardcoded one bit.

 

Knowing what you wrote will save time when I have time for further work. I suppose with that I can conclude that the CRU space is not the problem. I also have not yet implemented the VDP status register, it just returns a hardcoded zero for now. I tested interrupts very simply, by driving a toggling signal to the CPU's interrupt input. I did not even check what signal it was, other than I knew it toggled on the scope. That drastically slowed down system when drawing the TI welcome screen, which to me means the CPU was spending a lot of time in the interrupt service routine. But it did complete drawing it. So that must mean that the ISR was called a lot and the CPU returned from there successfully, only to go straight back.

  • Like 1
Link to comment
Share on other sites

Very slow progress this week so far with retrochallenge and the flu does not help. Still at least I seem to have working VDP interrupts now, and more TMS9901 implemented.

 

Quick question: when the TI gets stuck in GROM search loop (building menu) does it show something on the screen - or does the screen stay completely empty? I have an empty screen now, but I think that I saw in the memory expansion project the loop situation, and I believe there was some text on the screen in that case. So I assume my issue is something else. What really bugs me is that all test code works, but Basic does not... I haven't gotten around to building a trace buffer yet.

 

On the positive side, when I compare the TMS99105 running test code to classic99 running test code at original speed, the TMS99105 is really fast. So it runs really fast everything else, except the the standard TI software that I want to run :?

 

I also spent a while suspecting that the console ROMs might not work since the TMS99105 is no TMS9900, and some of the enhancements might be incompatible. So I inserted some test code into classic99 to see if the console ROMs would use the additional flag bits that the TMS99105 has but the TMS9900 doesn't. The good (and bad) news is that the code does not accidentally use those bits. So no fundamental problem (that I know of) yet, but also no solution...

TI-99/4A with TMS99105 and FPGA

Link to comment
Share on other sites

I remember when I wrote js99er.net that BASIC didn't work to begin with. After a long time of debugging I found the reason to be that it contained a LIMI 3 instruction, which I handled incorrectly because hadn't encountered it before. But if you're not getting a menu at all I guess that's not the reason.

  • Like 1
Link to comment
Share on other sites

If it's the GROM spin loop (caused by the GROM paging code detecting multiple GROM banks but not finding a header in any of them) doesn't show anything (and the lockup is after the master title page, of course). The entire screen is filled with spaces (>20). If you disable the ability to HAVE grom bases you won't be able to trigger that bug, it can't happen no matter what happens if there's only a single GROM page.

  • Like 1
Link to comment
Share on other sites

If it's the GROM spin loop (caused by the GROM paging code detecting multiple GROM banks but not finding a header in any of them) doesn't show anything (and the lockup is after the master title page, of course). The entire screen is filled with spaces (>20). If you disable the ability to HAVE grom bases you won't be able to trigger that bug, it can't happen no matter what happens if there's only a single GROM page.

Thank you, this could be it! I do have support for multiple bases, even though only 64k is currently available for GROMs, i.e. a single bank.

Need to try it out when I have a chance.

  • Like 1
Link to comment
Share on other sites

I got Basic working!!! The TMS99105 system just flies with TI Basic - at least when compared to the original TI-99/4A. I did a video showing the benchmark. It is in the process of uploading to youtube, but boy is it slow. Real life ADSL, upstream not great.

 

You will perhaps find the video a bit lame, but I let you be the judges once it gets uploaded, hopefully before the sun freezes.

 

I built temporary keyboard support so that my PC maps it's keyboard scan codes to a 8 byte bit mask, which is sent over USB to the FPGA, and the FPGA presents the contents to the TMS99105 processor in the CRU space, as if they had been entered from a local keyboard. Crude but it works for now. And it allows me to use my mechanical keyboard with the "TI". I posted more at hackaday.

 

I have only support for VDP graphics mode 1. That's what TI Basic uses. I don't have sprites yet. That did not stop me from trying some games, with mixed results, ranging from nothing working to something working. For example TI Invaders is quite challenging when you only see the invaders and the barriers. You can see any of the bullets nor your own ship. That does not stop the invisible alien bullets from killing the ship though...

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