speccery Posted October 7, 2016 Author Share Posted October 7, 2016 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? Quote Link to comment Share on other sites More sharing options...
Tursi Posted October 8, 2016 Share Posted October 8, 2016 Just wondering if GROM is 30 times slower than ROM how Parsec manages to display the scrolling graphics, which is stored in GROM AFAIK, at a reasonable speed? It also takes four frames to scroll that screen. It's not THAT fast. 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted October 8, 2016 Share Posted October 8, 2016 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 bytesin 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 therepermanently. 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 3 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 8, 2016 Author Share Posted October 8, 2016 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 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. 1 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted October 8, 2016 Share Posted October 8, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted October 8, 2016 Share Posted October 8, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 9, 2016 Author Share Posted October 9, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 9, 2016 Author Share Posted October 9, 2016 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! 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. 6 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 9, 2016 Author Share Posted October 9, 2016 And the usual link: https://hackaday.io/project/15430-rc201699-ti-994a-clone-using-tms99105-cpu 2 Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted October 9, 2016 Share Posted October 9, 2016 (edited) Excellent progress! If it boots, I suspect you will be able to do a lot more once the keyboard input is in place. . . Edited October 9, 2016 by Ksarul 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted October 10, 2016 Share Posted October 10, 2016 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" 1 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 10, 2016 Author Share Posted October 10, 2016 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. 2 Quote Link to comment Share on other sites More sharing options...
Tursi Posted October 10, 2016 Share Posted October 10, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
kl99 Posted October 10, 2016 Share Posted October 10, 2016 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! 2 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 10, 2016 Author Share Posted October 10, 2016 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. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted October 10, 2016 Share Posted October 10, 2016 The 9901 is also a really simple circuit, unlike the mystery that was all about it (caused by a lack of information). See tms9901.cpp in MAME. 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted October 11, 2016 Share Posted October 11, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 11, 2016 Author Share Posted October 11, 2016 The 9901 is also a really simple circuit, unlike the mystery that was all about it (caused by a lack of information). See tms9901.cpp in MAME. Yes, I have built a circuit which uses TMS9901 driven by TMS9995. So it is very simple indeed. Quote Link to comment Share on other sites More sharing options...
speccery Posted October 11, 2016 Author Share Posted October 11, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 14, 2016 Author Share Posted October 14, 2016 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 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted October 14, 2016 Share Posted October 14, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted October 15, 2016 Share Posted October 15, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 15, 2016 Author Share Posted October 15, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 15, 2016 Author Share Posted October 15, 2016 And that indeed was it! FINALLY! Update at hackaday! Tursi, thanks again! So now I have new problems - interrupt gets stuck unlike with my test code - but that's fine 4 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 16, 2016 Author Share Posted October 16, 2016 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... 7 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.