hippietrail Posted September 12 Share Posted September 12 I've made some progress with my Ghidra loaders for TI-99/4A. I now have ones in progress for FIAD (V9T9), TIFILES (XMODEM), .BIN (raw files without external header), and .RPK (MAME cartridge format). So RPK files are zip archives with one XML file that's used, one or more .bin files, and usually some unused files. The .bin files all end with a letter to provide some information about them: xxxxxC.BIN - loads as CPU cartridge ROM at >6000 xxxxxD.BIN - loads as banked CPU cartridge ROM at >6000, second bank (such as Extended BASIC or AtariSoft carts) xxxxxG.BIN - loads as GROM cartridge at >6000 in GROM space xxxxx3.BIN - Classic99 extension, loads as a 379/Jon Guidry style cartridge ROM at >6000 Often each .BIN file has an internal 'standard header', but not always. In the case of Burgertime there are two bin files: phm3233c.bin and phm3233g.bin, so the first is a CPU cartridge ROM and the second is a GROM cartridge. Since they both load at >6000 I have to ask how the address space works. Is "GROM space" its own separate address space? Or is there a paging mechanism? The layout.xml file looks like this: <romset listname="burgertm" version="1.0"> <resources> <rom file="phm3233g.bin" id="gromimage"/> <rom file="phm3233c.bin" id="romimage"/> </resources> <configuration> <pcb type="standard"> <socket id="grom_socket" uses="gromimage"/> <socket id="rom_socket" uses="romimage"/> </pcb> </configuration> </romset> So you can see that all it does is say which .bin file goes in which socket (rom vs grom). Nothing about address etc. I'm not proficient at MAME's built-in debugger, but I can see that the "CPU cartridge" is in memory at >6000. I'm not sure yet how to find if or where the GROM is loaded. Does anyone know? The GROM .bin file does have a standard header but the CPU .bin file does not. It starts with >FF but is not a GRAM Kracker format. After the >FF it has one byte each from >01 to >0F and then at >6010 it appears to have an address: >6012. At >6012 it has >C80B but as the TMS9900 extension for Ghidra is currently broken I can't check if that's valid TMS9900 machine code. Does anybody know where execution begins in a cartridge file that doesn't have one of the usual formats? Or did I just fail to identify which format this is? Or is it standard that there's an execution address at >6012? Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 12 Author Share Posted September 12 Of course GROM has a separate address space! Putting all the bits of info together in my brain sadly takes more than one reading. I found the GROM at address >0000 of what MAME calls the ":gromport:single:cartridge:grom_contents" region. This doesn't match the info that says it would be at >6000 so I'm still missing something. Also, for a cartridge that has a GROM and a CPU ROM, which will be executed first? It seems that the original cartridges were GROM cartridges so that would make me think the GROM calls into the CPU ROM at some point, but of course I am probably still missing quite a lot. 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted September 12 Share Posted September 12 Sounds like the start of a most need reference. Quote Link to comment Share on other sites More sharing options...
+wavemotion Posted September 12 Share Posted September 12 Required reading: https://www.unige.ch/medecine/nouspikel/ti99/architec.htm GROM is a separate address space. The built in console GROM files are 24K and take up >0000 to >5FFF and the user/cart GROMs start at >6000 and can be 40K in size up to >FFFF (actually, you can utilize more than one GROM base... but that's probably not of great interest to the basic understanding here). The TI99 built-in 8K Console ROM will boot up figure out what's "out there". If there is something to run at GROM >6000 or if it should look to the Cart/User ROM space... etc. Quote Link to comment Share on other sites More sharing options...
Gary from OPA Posted September 12 Share Posted September 12 28 minutes ago, hippietrail said: Of course GROM has a separate address space! Putting all the bits of info together in my brain sadly takes more than one reading. I found the GROM at address >0000 of what MAME calls the ":gromport:single:cartridge:grom_contents" region. This doesn't match the info that says it would be at >6000 so I'm still missing something. Also, for a cartridge that has a GROM and a CPU ROM, which will be executed first? It seems that the original cartridges were GROM cartridges so that would make me think the GROM calls into the CPU ROM at some point, but of course I am probably still missing quite a lot. GROMs also generally only contain GPL assembly not TMS9900 assembly, so until you have a Ghidra loader that understands the GPL opcodes no point worrying about it yet, as it will not disassemble via 9900. On the TI99 the first 8k console ROM at >0000 contains a virtual cpu interpreter that decodes the GPL. The TI99 is complex beast in that it basically has two cpus each with its own 64k of address space, one real the 9900 and one virtual the GPL which is custom language that TI designed which simulates a stack based 8 bit type opcode assembly with custom commands to make using the VDP which has its own 16k of ram easier. 4 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 12 Author Share Posted September 12 1 hour ago, Gary from OPA said: GROMs also generally only contain GPL assembly not TMS9900 assembly, so until you have a Ghidra loader that understands the GPL opcodes no point worrying about it yet, as it will not disassemble via 9900. Yes this much I did already understand. I have a page or two of the GPL opcodes handy. Writing a Ghidra extension for a new processor looks a lot harder than writing a loader, but it should be possible as I believe other virtual machines are supported by Ghidra already. In the meantime I can do things like put the mnemonics in comments. But at this stage it's often just helpful to look up an opcode or two to check that I'm interpreting things correctly. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 12 Share Posted September 12 5 hours ago, hippietrail said: xxxxx3.BIN - Classic99 extension, loads as a 379/Jon Guidry style cartridge ROM at >6000 Though @Tursi’s Classic99 still honors it, the ‘3’ terminator is deprecated in favor of ‘9’ for the 379 inverted-bank implementation and ‘8’ for the 378 non-inverted-bank implementation. ...lee 2 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted September 12 Share Posted September 12 @hippietrail can you say a bit more about what we would be able to use Ghidra for when you're done? Quote Link to comment Share on other sites More sharing options...
Gary from OPA Posted September 12 Share Posted September 12 15 minutes ago, Asmusr said: @hippietrail can you say a bit more about what we would be able to use Ghidra for when you're done? Ghidra is open source reverse engineering tool mainly designed to disassemble computer languages, amazing enough it does support tms9900 except it needs to be updated, the part that loads the binary code in so you can view it. https://en.m.wikipedia.org/wiki/Ghidra It is nice piece of software designed by NSA and is free compared to the commercial IDA Pro which is similar type of tool. 3 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted September 12 Share Posted September 12 57 minutes ago, Gary from OPA said: Ghidra is open source reverse engineering tool mainly designed to disassemble computer languages, amazing enough it does support tms9900 except it needs to be updated, the part that loads the binary code in so you can view it. https://en.m.wikipedia.org/wiki/Ghidra It is nice piece of software designed by NSA and is free compared to the commercial IDA Pro which is similar type of tool. Thanks, I have also Googled it, but how would it compare to something like SkoolKit for the ZX Spectrum? 1 Quote Link to comment Share on other sites More sharing options...
Gary from OPA Posted September 12 Share Posted September 12 1 hour ago, Asmusr said: Thanks, I have also Googled it, but how would it compare to something like SkoolKit for the ZX Spectrum? Not the same class at all, -- The best we have currently for live debugging and simulating TI99 code would be Classic99 - All tho for it, would be nice if it did more in the way of displaying GPL opcode disassembly as well. Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 13 Author Share Posted September 13 13 hours ago, Lee Stewart said: Though @Tursi’s Classic99 still honors it, the ‘3’ terminator is deprecated in favor of ‘9’ for the 379 inverted-bank implementation and ‘8’ for the 378 non-inverted-bank implementation. Thank you! That's good to know. 1 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 13 Author Share Posted September 13 Ghidra is basically an advanced interactive disassembler and decompiler. So first it takes in binary executable code such as machine code for a CPU or byte code for a virtual machine such as WASM, Java bytecode, Android Dalvik bytecode, C# CIL, etc. As long as the processor is supported either with built-in support with Ghidra, or with a 3rd party extension. Then it also decompiles the executable code into C-like source code. (It doesn't have to have been originally in C and it doesn't decompile to other languages.) It's less popular than IDA, but it's free and open source, whereas IDA is expensive. Its main focus is on modern platforms but due to being open source we're free to add retro platforms. People have already added support for some of the most popular retro platforms and for most of the console gaming platforms which are newer than what I'm interested in. For many platforms there are already 'better' disassemblers. So if you're only interested in only in platform it might not interest you. But, like MAME, it supports many platforms in the same way and anybody that can code can add new support. So if you've started to feel comfortable using Ghidra on one platform it's easy to start using it on another platform even if you don't know much about its architecture. Somebody made a TMS9900 CPU extension but Ghidra has been updated a couple of times while the TMS9900 extension hasn't been updated since 2022. Nobody has made any Loader or FileSystem extensions for TI-99/4A that I know of. I'm working on Loaders and FileSystems. Loaders parse file formats of single programs to find the parameters such as which CPU and the machine code sections so that Ghidra can then disassemble and decompile it. FileSystems parse file formats that contain multiple programs, such as disk images, tape images, archive and compression file formats. Ghidra is written in Java, which is not my favourite programming language. Its extension-development tools are for Eclipse, which is my least favourite IDE. Apparently some people have got it working in other IDEs and maybe working with Kotlin, but I haven't gone down that rabbit hole yet. I only know a tiny fraction of Ghidra, both how to use it and how to program extensions for it. I'm not an expert. But as an old Z80 and 680x0 machine code and assembly programmer who is also interested in the other systems from the late '70s until the PC era, the fun of exploring is enough to keep me going so far. If anyone is keen, you're welcome to have a look at RetroGhidra on Github: https://github.com/hippietrail/RetroGhidra but I haven't done a release yet and though TI-99/4A files (not disk images yet) can be loaded, they can't yet be disassembled. You can add feature requests for other systems and file formats not on my TODO list etc. Also the TI stuff is not in GitHub yet but I can put in in a branch if anyone is interested. https://github.com/gnulnulf/Ghidra-TMS9900 I will have to look at the broken TMS9900 support later, but that looks much more complicated to work on than Loaders and FileSystems. I should at least look at it more deeply and file a bug report. (If I'm wrong and it's easier than I think then one day somebody could probably add GPL support.) 1 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 13 Author Share Posted September 13 12 hours ago, Asmusr said: Thanks, I have also Googled it, but how would it compare to something like SkoolKit for the ZX Spectrum? It's probably not as good as many of the dedicated tools that target only one platform. But also most of those tools probably disassemble but don't decompile. Decompiling can be fun because you can view pseudocode of a function whether its decompiled from an assembly language you know well or one that's totally alien to you. When I first got interested in Ghidra for old computers at the start of the pandemic I thought it would be fun to see if the ports of Manic Miner from the ZX Spectrum to other systems of the day used the same logic and algorithms. (Which I never ended up getting to.) I made several disassemblers when I was around 12 to 15 in BASIC on my ZX Spectrum and a decade later made one in C for my Amiga 2000/030. I've been interested in disassemblers ever since. 1 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 13 Author Share Posted September 13 11 hours ago, Gary from OPA said: Not the same class at all, -- The best we have currently for live debugging and simulating TI99 code would be Classic99 - All tho for it, would be nice if it did more in the way of displaying GPL opcode disassembly as well. Ghidra actually has debugging support but I've never tried to use it. I'm assuming it would work for any platform that has the loader support and cpu support. I think it's relatively new. I don't know if anyone has tried to use it with any retro platform. I would definitely watch any YouTube videos anyone made on that topic! For the Speccy I usually use RetroVirtualMachine, which is a very slick Speccy emulator with a built-in debugger. I mainly used this to make sure I was parsing the .SNA file format properly for my Speccy .SNA loader for Ghidra. But then there's MAME, which is maybe like a lowest common denominator. Like most things in MAME, its debugger is probably unintuitive and probably has quite a learning curve, but once you get to grips with it on one platform, it will work the same on every platform MAME supports. 1 Quote Link to comment Share on other sites More sharing options...
+Torrax Posted September 13 Share Posted September 13 From your description you are going to need a "GPL extension" for Ghidra to handle the GROM files. There is a GPL interpreter built into the TI-99/4A system ROMs that handles the GROM code. 1 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 13 Author Share Posted September 13 49 minutes ago, Torrax said: From your description you are going to need a "GPL extension" for Ghidra to handle the GROM files. There is a GPL interpreter built into the TI-99/4A system ROMs that handles the GROM code. My goals for now are Loaders and FileSystems and I have a hunch that while I could probably write a GPL disassembler with enough effort, I'm not sure I could write a GPL extension for Ghidra. From what I've seen of processor support they look quite arcane. But it would surely be a fun and rewarding project for the right person! There is also a chance that it might be a bit higher level than the other bytecodes Ghidra already supports which might potentially cause problems. In the meantime I can use xdg99.py to see that I've identified the right parts of a file and the right load addresses and get a vague idea what some of the code might do. 1 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 13 Author Share Posted September 13 In case anyone's interested, I've filed a bug report against the TMS9900 extension for Ghidra: https://github.com/gnulnulf/Ghidra-TMS9900/issues/1 Perhaps people who have written TI-99/4A emulators could manage to understand some of it, but it's beyond my skill and knowledge levels. Hopefully the person who developed the extension will notice in the near future. 1 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 14 Author Share Posted September 14 Good news! The author of the TMS9900 extension for Ghidra has posted a fix that works for me. I can now disassemble the machine code parts of .rpk cartridge emulator files. (Not the GPL parts of course unfortunately.) If anyone can point me towards some files that have only TMS9900 machine code and no GPL bytecode I can make sure my TIFILES, FIAD, and .bin loaders work. So far it seems most of the files I've collected are BASIC, GROMs, or game cartridge files, which I believe always have a GROM whether or not they also have some machine code. Also, are there any other formats? Note that I'm not ready to support disk image formats or cassette tape .wav files yet. 1 Quote Link to comment Share on other sites More sharing options...
HOME AUTOMATION Posted September 14 Share Posted September 14 Texas Instruments TI-99 4A [TOSEC]/Command Modules/Donkey Kong (1983)(Nintendo)(Part 1 of 2).zip Texas Instruments TI-99 4A [TOSEC]/Command Modules/Donkey Kong (1983)(Nintendo)(Part 2 of 2).zip 2 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 14 Author Share Posted September 14 (edited) 35 minutes ago, HOME AUTOMATION said: Texas Instruments TI-99 4A [TOSEC]/Command Modules/Donkey Kong (1983)(Nintendo)(Part 1 of 2).zip Texas Instruments TI-99 4A [TOSEC]/Command Modules/Donkey Kong (1983)(Nintendo)(Part 2 of 2).zip Thanks! The parsing of the .bin / standard header is working and disassembling is working. Sadly, decompiling into C/pseudocode is not working. That's up to the TMS9900 module, which the author tells me is very much still a work-in-progress. Standard header: Beginning of code as pointed to by Standard header: Edited September 14 by hippietrail better first image without comments cropped out 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 14 Share Posted September 14 2 hours ago, hippietrail said: Good news! The author of the TMS9900 extension for Ghidra has posted a fix that works for me. I can now disassemble the machine code parts of .rpk cartridge emulator files. (Not the GPL parts of course unfortunately.) If anyone can point me towards some files that have only TMS9900 machine code and no GPL bytecode I can make sure my TIFILES, FIAD, and .bin loaders work. So far it seems most of the files I've collected are BASIC, GROMs, or game cartridge files, which I believe always have a GROM whether or not they also have some machine code. Also, are there any other formats? Note that I'm not ready to support disk image formats or cassette tape .wav files yet. Two things: @ralphb’s suite of TI-99/4A cross-development tools written in Python, which include a GPL cross-assembler and a GPL disassembler, might be useful in your endeavors. My fbForth 3.0 cartridge BIN (four 8KiB banks) is all TMS9900 machine code, which you are welcome to use: Binary: fbForth300_9.bin Source listing for comparison: fbForth300.lst ...lee 1 Quote Link to comment Share on other sites More sharing options...
hippietrail Posted September 14 Author Share Posted September 14 9 minutes ago, Lee Stewart said: Two things: @ralphb’s suite of TI-99/4A cross-development tools written in Python, which include a GPL cross-assembler and a GPL disassembler, might be useful in your endeavors. My fbForth 3.0 cartridge BIN (four 8KiB banks) is all TMS9900 machine code, which you are welcome to use: Binary: fbForth300_9.bin Source listing for comparison: fbForth300.lst ...lee Thanks that could be perfect! I've already been looking at ralphb's tools, especially the GPL disassembler. I'm going to see how Ghidra goes with your Forth binary right now. I pushed all my TI-99/4A loader work to GitHub a few hours ago by the way. 2 Quote Link to comment Share on other sites More sharing options...
HOME AUTOMATION Posted September 15 Share Posted September 15 (edited) On 9/12/2024 at 5:57 AM, hippietrail said: The GROM .bin file does have a standard header but the CPU .bin file does not. It starts with >FF but is not a GRAM Kracker format. After the >FF it has one byte each from >01 to >0F and then at >6010 it appears to have an address: >6012. At >6012 it has >C80B but as the TMS9900 extension for Ghidra is currently broken I can't check if that's valid TMS9900 machine code. Does anybody know where execution begins in a cartridge file that doesn't have one of the usual formats? Or did I just fail to identify which format this is? Or is it standard that there's an execution address at >6012? On 9/12/2024 at 6:27 AM, hippietrail said: Also, for a cartridge that has a GROM and a CPU ROM, which will be executed first? It seems that the original cartridges were GROM cartridges so that would make me think the GROM calls into the CPU ROM at some point, but of course I am probably still missing quite a lot. Normally, carts have a single HEADER. If a GROM is used, that's where the HEADER, would be. A ROM would only have a HEADER, if no GROM is included. The GROM HEADER(program list), can only point execution to an address within GROM address space, where GPL code, exists. Similarly a ROM's HEADER, can only start execution within CPU address space, and MACHINE CODE, exists. GPL uses single BYTE instructions. When GPL code, is running, and needs to branch to MACHINE CODE(which can only execute from CPU space), a GPL, XML(eXecute Machine Language, >0F)instruction is used. This is followed by a single BYTE, that indicates where to start execution within CPU space. That byte is divided into two nybbles. The first nybble, indicates what TABLE(CPU, base address), is desired... Table Address Memory >0 >0D1A Console ROM >1 >12A0 " >2 >2000 Low memory expansion >3 >3FC0 " >4 >3FE0 " >5 >4010 Peripheral card ROM (or RAM) >6 >4030 " >7 >6010 Cartridge ROM/ Rambo bank (RAM) >8 >6030 " >9 >7000 Cartridge bank / Rambo bank >A >8000 Decoded as >8300 on most machines >B >A000 High memory expansion >C >B000 " >D >C000 " >E >D000 " >F >8300 Scratch-pad memory (ABOVE, taken from: https://www.unige.ch/medecine/nouspikel/ti99/gpl2.htm) The second NYBBLE, indicates what PROCEDURE(branch address), to execute... The PROCEDUREs, are single WORD entries, that indicate the final address to branch to. Thus... XML >70, will point execution to the CPU address, specified in >6010. XML >71, should point to >6012, et cetera. That all being said, it is possible to use both GROM, and ROM, HEADERS, to some advantage, in a single cart ...or at least I have. This is undocumented(a trick), and there probably is a better way to handle this. But can be less practical if one is reusing/modifying existing code. I sometimes use two HEADERS, in order to rewrite/replace the RAM bank, in MINI MEMORY. This allows to start execution in the RAM bank(without the need to modify the GPL code to include an XML), while retaining the ability of the GROM HEADER, to specify the POINTER TO SUBPROGRAM LIST, needed, for example, to add "CALL LINK" to BASIC. I used this, here, to get SNAKE SNAKE(BASIC/MINI MEMORY), to run as a cartridge. Edited September 15 by HOME AUTOMATION left out a ...), and ..., also removed some anomalous occurrences of the current time/date. 3 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 15 Share Posted September 15 On 9/14/2024 at 11:04 AM, Lee Stewart said: Two things: @ralphb’s suite of TI-99/4A cross-development tools written in Python, which include a GPL cross-assembler and a GPL disassembler, might be useful in your endeavors. My fbForth 3.0 cartridge BIN (four 8KiB banks) is all TMS9900 machine code, which you are welcome to use: Binary: fbForth300_9.bin Source listing for comparison: fbForth300.lst ...lee I think we should mention that there is a lot of 9900 code but also a significant amount of address threaded data with "dictionary" headers interleaved. It's a really good test for a diss-assembler. 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.