Page 1 of 1

Teradrive Hardware Info

Posted: Thu May 31, 2018 5:17 pm
by Mask of Destiny
First, let me start with a big thanks to Nemesis and piroxilin for providing Teradrive disk images and firmware images respectively. Having easy access to software/firmware to reverse was a big help. Now for the info I've figured out:

M68K Memory Map (standard MD hardware omitted)
000000 - ??????: Boot ROM, PC memory space or cart depending on register settings
A14000: Non-standard TMSS register
AE000X: M68K side specific Teradrive regs (only 2, haven't checked mirroring yet)
AFXXXX: PC IO address space
BXXXXX: 1MB window into PC memory address space

Most of the Teradrive-specific registers are accessible from the PC IO space. They are as follows:

Key: X = writeable by both CPUS, M = writeable by M68K only, R = read-only, 1 = read-only, always 1, 0 = read only, always 0
Note that some bits marked as always 0 or always 1 may have some function that I just haven't stumbled across yet

Code: Select all

1160: XXXXXXXX
   Unclear function, must be set to $21 when booting M68K. Set to 0 by BIOS after initial MD-side boot.
1161: 11111111
1162: 110XXXX0
   Sets the base address for the memory window in the PC address space for accessing an 8KB chunk of the M68K address space
   BIOS initializes this from CMOS and defaults to $CE, if the CMOS value is invalid. This corresponds to CE00:0000 (segment notation), $CE000 (physical address)
1163: XXRRXXXX
   bit 0: Unclear function. Must be set when booting M68K
   bit 1: Enables the memory window in PC address space. Must be clear when booting M68K
   bit 4: Returns value written to AE0001 bit 0
   bit 5: Returns value written to AE0001 bit 1
1164: MXXXXXXX
   bit 0: Releases the M68K from reset and pauses the 286  when set. Puts the M68K into reset and releases the 286 when cleared
            Experimentation suggests that certain other register changes make clearing this bit ineffective, but not sure which ones.
   bit 1: 1 = Cart/expansion port mapped in at $0 on M68K side, 0 = Teradrive M68K boot ROM or PC memory
   bit 2: Controls the video switch. 0 = PC VGA, 1 = MD VDP
   bit 4: Appears to enable some sort of test mode. Behavior of 1165 and AE0003 change when this is set
   bit 6: Unclear function. Set before purposely wedging CPU (reading from VDP data port when writes are configured) on cart TMSS failure
   bit 7: Appears to be set at boot. Can't be cleared by the 286, but can by the 68K
1165: 00R0RR0R
   bit 0: Indicates PC/MD switch setting, 0 = MD boot, 1 = PC boot
   bit 2: Indicates video switch setting, 0 = "Video", 1 = "RGB"
   bit 3: Unclear. Normally 0, occasionally 1
   bit 5: Indicates MD hardware has been "unlocked" ('SEGA' has been written to $A14000)
1165(alt): RRRRRRRR
   Returns a value in a fixed sequence each time it's read (sometimes, may be impacted by other register settings). D5,7F,00,AA,55,FF,80,2A
1166: XXXXXXX0
   Low portion of M68K address visible in 8K memory window (bits 1-7 of reg = bits 13-19 of address)
1167: 0000XXXX
   High portion of M68K address visible in 8K memory window (bits 0-3 of reg = bits 20-23 of address)
Additionally there are 3 registers only accessible from the M68K address space.

Code: Select all

AE0001: XXXXRRXX
   bit 0: Value set here will be returned in AF1163 bit 4
   bit 1: Value set here will be returned in AF1163 bit 5
   bit 2: Returns state of AF1163 bit 6
   bit 3: Returns state of AF1163 bit 7
   bit 4: Appears to be used by the M68K to track whether it's the first time the 68K has been booted. Starts out 0 and is set to 1 during boot by M68K
   bit 5: Appears to be used by the M68K to track whether a cart was found during initial boot. Will refuse to unlock MD side when set
   bit 6: Set by M68K side if the cart passes the TMSS check and PC/MD mode switch is set to PC
   bit 7: Maps the PC address space at $0 when set when 1164 bit 0 is clear
AE0003: XXXXXXXX
   bits 0-3: Selects the 1MB bank visible at $B00000
AE0003 (alt): XX10XXXX
A14000: XXXXXXXX XXXXXXXX
   Unlocks 286 access to MD hardware when 'SEGA' is written to this address, Locks it when other values are read. Byte access seems to lock the M68K.
   Note that writing to this reg is not required for M68K access to the VDP like normal TMSS and the version field of the version reg is 0 on the Teradrive.
   Unsure if this is readable (definitely not byte-readable)
Switch Function:
PC/MD switch: Indicates to firmware the desired boot mode (via 1165). Resets the machine when toggled.
RGB/Video switch: Indicates to firmware whether a 15KHz mode is desired on the PC side at boot (via 1165). Controls whether composite output always contains MD video (RGB setting) or whether it is switched by 1164 like the VGA connector (Video setting).

M68K Firmware info:
The M68K boot ROM is located inside the additional mask ROM (called the ROMDISK by prioxilin, though only part of it appears to contain a disk-like structure) at offset $43000. Unclear how this ROM is accessed from the PC side or if other portions are accessible on the MD side.

The M68K firmware is responsible for displaying the SEGA logo at boot time, doing a basic TMSS check on cartridges (is 'SEGA' present at $100 or $101) and authenticating requests to unlock the hardware for the PC side. It recognizes two special header strings at $100 and has different boot behavior if they are found.
'SEGA TERA286': Mostly normal, but allows the PC to unlock the MD side even if this is present (normally a cart being present prevents PC access)
'SEGA TERA68K': Unlike a normal cart, this is booted directly after the Sega logo (normally M68K returns control the PC side after Sega logo and requires the 286 to reset it again to boot the cartridge)

I'm guessing the prototype Mega CD unit used SEGA TERA286.

The initial M68K boot code also checks for a special ISA option ROM in the $C0000 region of PC memory. This ROM must contain the text 'PRODUCED BY OR UNDER LICENSE FROM SEGA ENTERPRISES Ltd.', 0 (that zero is there to indicate a literal null byte) at an even address. If found, the 68K will jump to the offset stored at offset 4 of the 1KB chunk that the text was found in.

Unlock process:
To unlock the MD hardware from the PC side, write $21 to 1160 (probably 0 at the start of the process), $1 to 1163 (probably already set to that, but best to be safe), 0 to $1166 and $1167 (unless you have located your PRODUCED BY... text in a funny location) and then write $81 to 1164. You must have the PRODUCED BY... text at an even address in RAM before doing so or you will not gain access. As long as that text is in "conventional" memory (i.e. in the low 640KB of the PC address space), using 0 in 1166/1167 is fine. Otherwise, you must specify the upper 11 bits of the physical address that contains the text in 1166/1167. You may also do that to speed things up slightly when the text is located in conventional memory, but the speedup is negligible given the delay involved in displaying the TMSS license screen.

If you are successful, bit 5 of 1165 will now read 1 and you will be able to use 1162,1163,1166 and 1167 to access the MD hardware via the memory window mechanism, but the 68K will not be running. Puzzle Construction seems to operate in this way with game logic running on the 286, but the YM3438, MD IO and MD VDP used for the game mode and launcher (standard VGA is used for the editor screens) and the cdram utility (can backup BRAM carts to disk).

If you instead want to run code on the 68K, first unlock the MD hardware as above. Then write your initial M68K code to MD work RAM via the window mechanism. Then go through the unlock procedure again, but this time put a value from $A0-$FF inclusive in 1166/1167. This will cause the M68K Teradrive firmware to jump to $FF0100.

Unknowns:
If there is a way to let both CPUs run simultaneously (normally they are mutually exclusive)
If there is a mechanism to allow the 286 to receive MD interrupts of the M68K to receive PC interrupts
What the remaining bits in the above registers do
How the hardware knows to use offset 0x43000 for the M68K firmware (seems like a weird address for it to be hard coded)
How the rest of that additional firmware ROM is accessed

Re: Teradrive Hardware Info

Posted: Thu Aug 09, 2018 10:34 am
by Nemesis
Wow, good job with this! I always wanted to investigate this hardware more, but never found the time. It's interesting to read about how the PC and Mega Drive hardware interacts. One tip I can give, from memory if you hold one of the function keys when you power the system on (F2 I think), both the Mega Drive and PC hardware boots and runs concurrently. I think this is the key to being able to run both CPUs simultaneously. Of course, the fact this is accomplished by holding a key at boot time suggests it's managed by the bios, and therefore there's probably some kind of memory location you can poke a value into to accomplish the same thing after boot.

Re: Teradrive Hardware Info

Posted: Thu Aug 09, 2018 8:16 pm
by Mask of Destiny
Nemesis wrote:
Thu Aug 09, 2018 10:34 am
Wow, good job with this!
Thanks!
Nemesis wrote:
Thu Aug 09, 2018 10:34 am
I always wanted to investigate this hardware more, but never found the time.
Still quite a few unknowns if you suddenly find yourself with a bunch of free time :wink: Happy to share test code and/or IDA disassembly projects if that happens (though I know how hard free time can be to come by).
Nemesis wrote:
Thu Aug 09, 2018 10:34 am
Nemesis wrote:
Thu Aug 09, 2018 10:34 am
One tip I can give, from memory if you hold one of the function keys when you power the system on (F2 I think), both the Mega Drive and PC hardware boots and runs concurrently.
Very interesting, I'll have to investigate. Do you know what setting the PC/MD switch should be in for that?

Re: Teradrive Hardware Info

Posted: Wed Aug 15, 2018 6:24 pm
by piroxilin
Awesome work, dude!
This is very interesting information!
I guessed a lot about it, but many was unique :)
Thank you so much for such hard work!

Re: Teradrive Hardware Info

Posted: Mon Jun 10, 2024 10:19 pm
by RetroSwim
I'm loath to drag up a ~6 year old thread, but I've started to put together some demos based on the information in this thread.

https://github.com/RetroSwimAU/TeradriveCode

So if there is any more information, test code, annotated disassembly etc that you guys could share, I'd be most grateful.

I have successfully
- Played a VGM file (badly) using MD's PSG from the PC side
- Wrote to IO ports and VGA memory from the MD side (booped the PC speaker, displayed code on POST analyzer, displayed colourful mode 03h text), and toggle PC/MD video using the joypad.
(These two demos are what's currently in the git repo)

What I'm still working on
- Draw some graphics on VGA and do a palette cycle animation (chunky mode 13h should be easy), all from 68000 code. Currently done without any PC BIOS software interrupts, all using VGA registers. I have this partially working.
- Maybe a better featured VGM player with PSG and Yamaha support. Thinking of trying to patch SBVGM.
(These efforts aren't committed yet, but I've shifted to SGDK over writing 68K asm, for my sanity haha)

I have one burning question, and hopefully one of you three legends are still about to share your wisdom!

I don't quite understand the 'PRODUCED BY...' stuff. Setting the 1166/67 registers affects how the PC sees MD memory, how does that impact where the 68000 looks for the string in PC memory? This might be academic, because simply having that string in my EXE file somewhere seems to 'just work', as described, since the 68000 searches PC's 640KB @ $00000-$A0000 (I guess $B00000-$BA00000 in MD space??).

I can't thank you (Mask, Nemesis, piroxilin) enough for the work you did!

Re: Teradrive Hardware Info

Posted: Thu Jun 13, 2024 8:26 am
by Mask of Destiny
RetroSwim wrote:
Mon Jun 10, 2024 10:19 pm
So if there is any more information, test code, annotated disassembly etc that you guys could share, I'd be most grateful.
So I actually figured out a bit more since I originally wrote this post. Here are the registers with an updated description

Code: Select all

1160: XXXXXXXX
   Selects an 8 KiB page from the extra firmware ROM that contains the kanji font, menu ROMDISK and 68K side boot firmware
 1163: XXRRXXXX
   bit 0: Enables extra firmware ROM on 68K side
   bit 1: Enables the memory window in PC address space. Must be clear when booting M68K
   bit 4: Returns value written to AE0001 bit 0
   bit 5: Returns value written to AE0001 bit 1
 1164: MXXXXXXX
   bit 0: Releases the M68K from reset and pauses the 286  when set. Puts the M68K into reset and releases the 286 when cleared
            Experimentation suggests that certain other register changes make clearing this bit ineffective, but not sure which ones.
   bit 1: 1 = Cart/expansion port mapped in at $0 on M68K side, 0 = Teradrive M68K boot ROM or PC memory
   bit 2: Controls the video switch. 0 = PC VGA, 1 = MD VDP
   bit 3: dual boot bit (see notes on how bit 3, 1 and 0 work together)
   bit 4: Appears to enable some sort of test mode. Behavior of 1165 and AE0003 change when this is set
   bit 6: Unclear function. Set before purposely wedging CPU (reading from VDP data port when writes are configured) on cart TMSS failure
   bit 7: Appears to be set at boot. Can't be cleared by the 286, but can by the 68K
   Values written by BIOS
      80 - pc mode
      81 - firmware boot
      8A - dual boot
      07 - cart boot
   Effective combinations of bits 3, 1, 0 (X = don't care)
      11X = dual boot
      011 = cart boot
      X01 = 68K firmware boot
      X00 = pc mode
1165: 00R0RR0R
   bit 0: Indicates PC/MD switch setting, 0 = MD boot, 1 = PC boot
   bit 2: Indicates video switch setting, 0 = "Video", 1 = "RGB"
   bit 3: Indicates a DTACK timeout for 286 access to 68K bus. 1 indicates timeout occurred since last read. Cleared on read
   bit 5: Indicates MD hardware has been "unlocked" ('SEGA' has been written to $A14000)
Dual boot mode is pretty limited since the 68K has no access to any PC side hardware and the only way to communicate are via the 4 bits in AE0001/1163 (2 for each direction).

The secondary firmware ROM is mapped on the 286 side in the same 8KiB window used for access to the 68K address space. Whenever the 286 is running and 1163 bit 1 is clear, the ROM is mapped in this window instead of the selected window into the 68K address space. The 8KiB page selected by 1160 is also used to select the address of the 68K boot firmware inside the ROM; however, only the last 4KiB of the page is mapped on the 68K side when doing 68K firmware boot.

One other little detail is that it's actually possible to access a single page of the 68K's address space even when things have not been unlocked from the 68K side. When the 68K side is locked and the low four bits of 1166 are 0, then you can access the IO area ($A10000) through the memory window. The upper 4 bits of 1166 and all the bits of 1167 seem to have no effect. This is used by the BIOS to support MD controllers.

I think that basically covers the main unknowns I listed in my original post. Though what bit 4 of $1164 is still somewhat mysterious. I am curious if there's some way to receive PC side interrupts on the 68K as well. No evidence this is supported, but it would be useful.
RetroSwim wrote:
Mon Jun 10, 2024 10:19 pm
I don't quite understand the 'PRODUCED BY...' stuff. Setting the 1166/67 registers affects how the PC sees MD memory, how does that impact where the 68000 looks for the string in PC memory? This might be academic, because simply having that string in my EXE file somewhere seems to 'just work', as described, since the 68000 searches PC's 640KB @ $00000-$A0000 (I guess $B00000-$BA00000 in MD space??).
So 1166/67 are normally used to control what address the memory window is looking at; however, these registers are readable and writeable by both CPUs (though not simultaneously) and there don't appear to be any dedicated communication registers for transferring data between the 286 and 68K. So the firmware is just abusing these two registers to transfer a parameter from the 286 to the 68K for the "firmware boot" mode. When that parameter is 0, the 68K side firmware just scans all of PC conventional memory via the address ranges you list and by setting AE0003 to 0 so the first megabyte of PC address space is in the window. When the parameter is non-zero it's expected to contain 11-bits of the address where the string is located. Specifically the value written to $1167 is written to $AE0003 to select a physical 1MiB page of the 286's address space and then the 7 bits of $1166 (bit 0 is forced to 0 in hardware) select a 512 byte region within that 1MiB page (i.e. the byte is shifted left by 8 to make a 16-bit offset from $B00000). For all practical purposes, you can just put a 0 in here and not worry about it though unless you're doing something exotic.

There are a few special values though. As noted values from $A0-$FF inclusive are used for booting the 68K from data written to its RAM. $FFC is used to lock the MD hardware. $FFA does the same but displays the Sega logo first. $FF8 instructs the firmware to lock up the 68K. I think $FFE is used to instruct the 68K to check the cart for TMSS (i.e. is SEGA at $200) and boot it if successful.

Hope that helps.

Re: Teradrive Hardware Info

Posted: Fri Jun 14, 2024 1:49 am
by RetroSwim
That all helps a lot, thank you!!

I've nearly got my "68K doing PC stuff" demo to a state where I'm happy to call it done for now. I've set up a simple mode 13h screen with palette cycling.

Since I can't get interrupts from the PC side, I can't wait for Vblank (as far as I know) to do VGA register writes, so there are artifacts. Also the VGA memory is filled one byte at a time, so the initial draw is slow, but overall I feel it works well to demonstrate the capabilities.

Thank you for reaching out on Youtube as well. All this knowledge is very much appreciated. Once I've finished my two demos and released them, I'd like to write this all up for future tinkerers, like on one of the various Mega Drive wikis.

Edit: Being able to execute code on the 286 from a MegaDrive program would be killer, but doesn't seem possible. Yeah?

The TeraDrive's VGA BIOS seem to have custom int 10h routines that choose 15kHz-compatible VGA-equivalent modes when the rear switch is set to 'VIDEO', whereas my 68K code sets all the VGA registers directly, so I don't get this effect.

It's kind of crazy, the care and attention that went into this super niche machine.

Re: Teradrive Hardware Info

Posted: Fri Jun 14, 2024 6:30 am
by Mask of Destiny
RetroSwim wrote:
Fri Jun 14, 2024 1:49 am
Since I can't get interrupts from the PC side, I can't wait for Vblank (as far as I know) to do VGA register writes, so there are artifacts.
Looking at the WD90C10 documentation, it looks like you can read the vertical retrace status from bit 3 of IO port $3DA (or $3BA if $3CC/$3C2 bit 0 is 0, but that seems to just be for MDA emulation or something).
RetroSwim wrote:
Fri Jun 14, 2024 1:49 am
Edit: Being able to execute code on the 286 from a MegaDrive program would be killer, but doesn't seem possible. Yeah?
Well it's not straightforward at least. You can write to PC memory though. The main problem is figuring out how to get the code you write to run after you give control back to the 286. Probably the most reliable way to do that would be to hook some interrupt handler and then make sure the interrupt is enabled at the chipset level. This isn't foolproof since you can't control CPU-level interrupt masking, but it probably works fine in practice.
RetroSwim wrote:
Fri Jun 14, 2024 1:49 am
The TeraDrive's VGA BIOS seem to have custom int 10h routines that choose 15kHz-compatible VGA-equivalent modes when the rear switch is set to 'VIDEO', whereas my 68K code sets all the VGA registers directly, so I don't get this effect.
Yeah, if you want that you'll need to program a 15 kHz mode manually. Probably easiest thing to do is use the int 10h routines from the 286 and see what values get put in the CRTC registers

Re: Teradrive Hardware Info

Posted: Thu Jul 18, 2024 11:53 am
by RetroSwim
Thanks again for all your invaluable info!!

And yes, on my deep-dive into BIOS-less VGA programming, I found how to "poll" for when the VGA CRTC is in a blanking period. That was a load of fun to wrap my head around!!

The result of my several late nights can be found here :lol: https://github.com/RetroSwimAU/TeradriveCode

The binaries for both sides are in the v0.5 tagged release.