Jump to content

Photo

Conversion of Z80 code to TMS9900


58 replies to this topic

#1 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,466 posts
  • Location:Denmark

Posted Tue Jun 13, 2017 8:54 AM

Does anyone have experience with conversion of Z80 code to TMS9900? What the best strategy, should you try to convert each instruction individually or convert at a slightly higher level? Should you use a fixed mapping of Z80 registers to 9900 registers? Are there any caveats to look out for?



#2 arcadeshopper OFFLINE  

arcadeshopper

    River Patroller

  • 2,570 posts
  • Location:Portland, Oregon USA

Posted Tue Jun 13, 2017 11:08 AM

Probably tough to do without looking at things individually.. my z80 assembler is about 25-30 years old in my brain but it's a pretty simple instruction set plus 8bit



#3 arcadeshopper OFFLINE  

arcadeshopper

    River Patroller

  • 2,570 posts
  • Location:Portland, Oregon USA

Posted Tue Jun 13, 2017 11:12 AM

Have you seen this?

 

guy converted the z80 code from dk to the 6809 in a coco  http://users.axess.c...ilight/sock/dk/he's working on pacman next..  

 

im a firm believer that if the coco can do it, we can do it better.. course they had to put 512k on the coco3 to do that, and also they have a mod player that runs in the same set up we may needs SAMS to achieve the same

 

Greg



#4 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,736 posts
  • Busy bee!
  • Location:North, England

Posted Tue Jun 13, 2017 11:15 AM

You might find this Z80 to 6502 "recompiler" useful as a starting point :-

 

http://atariage.com/...pentagram-port/

 

It has been used to convert several ZX Spectrum games over to the A8. With some manual optimisations afterwards, the games are quite playable and sometimes play faster!



#5 JamesD OFFLINE  

JamesD

    Quadrunner

  • 7,753 posts
  • Location:Flyover State

Posted Tue Jun 13, 2017 12:38 PM

Have you seen this?

 

guy converted the z80 code from dk to the 6809 in a coco  http://users.axess.c...ilight/sock/dk/he's working on pacman next..  

 

im a firm believer that if the coco can do it, we can do it better.. course they had to put 512k on the coco3 to do that, and also they have a mod player that runs in the same set up we may needs SAMS to achieve the same

 

Greg

There is a lot the CoCo 3 has the TI doesn't.
A 16 color mode where you can chose the colors with palette registers, and enough resolution capable of supporting that game without scaling the graphics.
He was able to move some stuff to shrink the vertical size.
Direct access to video RAM from the CPU.
A CPU with much shorter instruction timing.
And a DAC to play sound samples from the arcade.  That's what takes most of the RAM.
A programmable interrupt timer and fast interrupt for playing the sound samples.

Frankly, the only way you could "do it better" is with a different video chip.
The 9918 just doesn't have the resolution or palette required for that accurate of a port.
If you scale things for the TI screen, do the best you can with colors, and use lower sample rates, the TI could certainly have a more arcade accurate Donkey Kong.
 



#6 TheBF OFFLINE  

TheBF

    Moonsweeper

  • 371 posts
  • Location:The Great White North

Posted Tue Jun 13, 2017 12:47 PM

Does anyone have experience with conversion of Z80 code to TMS9900? What the best strategy, should you try to convert each instruction individually or convert at a slightly higher level? Should you use a fixed mapping of Z80 registers to 9900 registers? Are there any caveats to look out for?

 

I have not touched the Z80 for many years and I was not the guru that other people are,  but the good news is the 9900 has 16 general purpose, 16 bit registers.

 

The Z80 register set is not so general purpose! :-)

AF: 8-bit accumulator 
(A) and flag bits 
(F) carry, zero, minus, parity/overflow, half-carry (used for BCD), 
and an Add/Subtract flag (usually called N) also for BCD

BC: 16-bit data/address register or two 8-bit registers
DE: 16-bit data/address register or two 8-bit registers
HL: 16-bit accumulator/address register or two 8-bit registers
SP: stack pointer, 16 bits
PC: program counter, 16 bits
IX: 16-bit index or base register for 8-bit immediate offsets
IY: 16-bit index or base register for 8-bit immediate offsets
I: interrupt vector base register, 8 bits
R: DRAM refresh counter, 8 bits (msb does not count)

AF': alternate (or shadow) accumulator and flags (toggled in and out with EX AF,AF' )
BC', DE' and HL': alternate (or shadow) registers (toggled in and out with EXX)

So what this means is that when you translate to 9900, any 9900 register can do the jobs of these registers pretty much.

1. Except 9900 R0 cannot do indexed addressing.

2. And the PC can't be accessed directly on 9900. (uses Branch, and jumps)

3. No shadow registers but you can BLWP to a new workspace if you need that kind of function.

 

The bad news is you have to re-write everything and that means you need to understand what the Z80 code is doing.

And you won't want to do some of the "tricks" that coders do on the Z80 because they don't make sense on a 9900.

There is probably no short cut unless someone created an AI recently to do the translation.

 

 

My 2 cents

 

BF



#7 JamesD OFFLINE  

JamesD

    Quadrunner

  • 7,753 posts
  • Location:Flyover State

Posted Tue Jun 13, 2017 1:25 PM

To go from the Z80 to 9900, I'd write a program to do a rough translation to start.
The better the program, the less work you have to do.
If it were good enough, you could run a peephole optimizer on the results for a pretty good starting point.
 



#8 matthew180 OFFLINE  

matthew180

    River Patroller

  • 2,408 posts
  • Location:Castaic, California

Posted Tue Jun 13, 2017 1:39 PM

The 8-bit CPUs are their own breed.  Going from Z80 to 6809, or something like that you might try a somewhat 1:1 translation.  But there is going to be a lot of code in there dealing with larger values in 8-bit chunks, and done in a very 8-bit way.  Most of the 8-bit CPUs did not have divide (and sometimes not even multiply), and routines were written to specifically multiply and divide by specific values, i.e. divide by 7, multiply by 11, etc.  The 8-bit CPUs were also pretty crafty with stack use, and many of them have bulk block transfer instructions and such.

 

Weeding all of that out and trying to do a direct translation would be a lot harder IMO, and you would end up with a really big and slower program.  Due to the extreme architecture differences, I would say you need to look at the original code at a higher functional level.



#9 TheBF OFFLINE  

TheBF

    Moonsweeper

  • 371 posts
  • Location:The Great White North

Posted Tue Jun 13, 2017 2:33 PM

The 8-bit CPUs are their own breed.  

 

Yes, this is what I meant by "tricks".  The 8 bit CPU guys know and use tons of unique features of the chips that are meaningless on another CPU.

 

BF



#10 JamesD OFFLINE  

JamesD

    Quadrunner

  • 7,753 posts
  • Location:Flyover State

Posted Tue Jun 13, 2017 4:02 PM

On the Z80, most "tricks" like multiplication for address calculation are easy enough to identify.
Game logic is unique and much more difficult to figure out.  Especially when combined with hardware you aren't familiar with.
For the most part, the weirdest  thing you will run across is moving things around in registers to where the you can actually use certain opcodes.

The 6502... well... you probably need some 6502 programming experience at an advanced level to figure some of it's tricks out.
You end up doing some odd things to make code fast.
But if you are looking at a 70s arcade game, there are probably a lot fewer tricks than something from a personal computer in 1985.
Your biggest issues porting from a computer will probably be hardware.  Atari display lists, etc...
Porting from the Acorn Atom would be much simpler since it doesn't have fancy hardware to worry about.

 

680X assembly is pretty straitforward compared to the other two.  
If you are porting an arcade game from the 6809, you are looking at more complex titles though.
Williams, etc... which also have blitters, etc...
 


Edited by JamesD, Tue Jun 13, 2017 4:15 PM.


#11 JamesD OFFLINE  

JamesD

    Quadrunner

  • 7,753 posts
  • Location:Flyover State

Posted Tue Jun 13, 2017 4:15 PM

The 8-bit CPUs are their own breed.  Going from Z80 to 6809, or something like that you might try a somewhat 1:1 translation.  But there is going to be a lot of code in there dealing with larger values in 8-bit chunks, and done in a very 8-bit way.  Most of the 8-bit CPUs did not have divide (and sometimes not even multiply), and routines were written to specifically multiply and divide by specific values, i.e. divide by 7, multiply by 11, etc.  The 8-bit CPUs were also pretty crafty with stack use, and many of them have bulk block transfer instructions and such.

 

Weeding all of that out and trying to do a direct translation would be a lot harder IMO, and you would end up with a really big and slower program.  Due to the extreme architecture differences, I would say you need to look at the original code at a higher functional level.

Only the Motorola 6801/6803/6809 and Hitachi 6303/6309/64180(z180) have multiply, and only the 6309 has a divide.
I've ported code between Z80, 6803, 6502, and 6809.
Direct translations aren't that bad, and it can get you up and running quickly.
But you'll have to go back and optimize the code.
You don't need to move things around in registers, or to swap things in and out of memory so much on the 9900.
 



#12 matthew180 OFFLINE  

matthew180

    River Patroller

  • 2,408 posts
  • Location:Castaic, California

Posted Tue Jun 13, 2017 4:17 PM

The 6809 is pretty bad-ass and the pinnacle of the 8-bit CPUs IMO.  When I was doing the Williams SoC I had to learn some 6809 assembly to know where my system was failing.  It was pretty cool to watch it all come up and run.  If Rasmus is doing an arcade title, he will have a bigger problem with the amount of ROM and RAM the machines had available to them.



#13 apersson850 OFFLINE  

apersson850

    Moonsweeper

  • 436 posts

Posted Tue Jun 13, 2017 4:18 PM

I've just used the Zilog Z80 a little, in a Festo industrial controller, actually. But I've used the predecessor Intel 8085 quite a lot. Almost everything the 8085 could do, the TMS 9900 can do in an easier way. Frequently several instructions were used to do arithmetic with more bits than the basic eight, functions the 9900 often can do in one single instruction.

You need to implement a stack, but that's easy enough using a register and the indirect (with autoincrement) addressing modes.



#14 JamesD OFFLINE  

JamesD

    Quadrunner

  • 7,753 posts
  • Location:Flyover State

Posted Tue Jun 13, 2017 4:38 PM

I've just used the Zilog Z80 a little, in a Festo industrial controller, actually. But I've used the predecessor Intel 8085 quite a lot. Almost everything the 8085 could do, the TMS 9900 can do in an easier way. Frequently several instructions were used to do arithmetic with more bits than the basic eight, functions the 9900 often can do in one single instruction.

You need to implement a stack, but that's easy enough using a register and the indirect (with autoincrement) addressing modes.

You won't see a huge amount of stack usage on games.  The main use is during interrupts.
I'd bet most other stack saves could be implemented just by copying to an unused register on the 9900, and interrupts could be handled with their own register file.

Yeah, you can do things in fewer instructions.  That's why you go back and optimize or use a peephole optimizer on an automated translation.
The peephole optimizer could even be ripped off from SDCC.

You have to start somewhere.

One thing to watch out for, condition codes work differently between some CPUs



#15 apersson850 OFFLINE  

apersson850

    Moonsweeper

  • 436 posts

Posted Tue Jun 13, 2017 5:00 PM

No, perhaps not in games, as they are frequently optimized for speed and nothing else. When writing code for the 9900, I frequently used a lot of subroutines, since I don't consider it worth saving a few microseconds in execution if I instead can save minutes or hours in code design and maintenance. But I'm a professional in embedded programming, so I'm used to look at the total cost and time spent to get the code executed. That includes the whole software development cycle. Since my software typically control machines, nobody cares about how much margin there is, if it's just fast enough. But the do care if it takes another week to get it done.

Of course I do speed optimizing too, but that's frequently on the level of designing the right things to be done with the proper tasks having the correct priorities and cycle times. And taking hardware buffers and such stuff into account, to prevent lockups from happening due to buffered items blocking other things from being processed. It's quite different from considering saving a few clock cycles by avoiding a subroutine call.



#16 artrag OFFLINE  

artrag

    Dragonstomper

  • 708 posts

Posted Wed Jun 14, 2017 12:43 PM

I've ported code between Z80 and 6502, but I've no idea of how different is the 9900.

From what I see the 9990 is fully 16bit and quite far from the z80 architecture.

 

If you go for a "dumb" instruction replacement, I see that you have to:

- emulate in software the stack system of the Z80 (the 9900 does not have it), while the Z80 uses it for subroutines, for saving registers, and sometimes to have fast 16bit access to data areas

- emulate alternative register sets, probably using different workspaces

- emulate the bit manipulation and testing instructions with their huge system of direct and indirect accesses 

There are also very uncommon instructions for nibble rotation and BCD math that could result hard to port.

 

Moreover, the flag system is quite complex: not all instructions affect the flags and you could have that the result of an operation is preserved in the flags for many instructions before being used by a jump instruction.

 

If you need working code, a dumb instruction replacement could be done using a modern macro assembler. Probably you can replace each instruction by macros accepting the same parameters allowed by the z80 equivalent and customise the body of the macro as a large switch dealing with each case according to the parameter passed. It would need a lot of work, but it is for sure doable.

Anyway, if you need efficient code, you will need to optimize manually the result, unless you are so brave to develop directly a compiler able to do the translation and the peephole optimization.

In this latter case the work would be even bigger... all depends on what you want to do and how many times you will use this "translator"


Edited by artrag, Wed Jun 14, 2017 3:25 PM.


#17 InsaneMultitasker OFFLINE  

InsaneMultitasker

    Stargunner

  • 1,731 posts

Posted Wed Jun 14, 2017 4:35 PM

somewhere in my library is a copy of Gary's (OPA)  Z80 simulator that ran on the Geneve in TI (GPL) mode.  Sadly, my copy no longer works as I suspect some bit-rot affected critical code along the way. 

 

I do remember playing Penguin Adventure and though it was a little slower than native hardware, it was playable.    The five or six included cartridge dumps were from the Coleco if I recall correctly.


Edited by InsaneMultitasker, Wed Jun 14, 2017 4:36 PM.


#18 InsaneMultitasker OFFLINE  

InsaneMultitasker

    Stargunner

  • 1,731 posts

Posted Thu Jun 15, 2017 11:23 AM

I was able to grab a few screenshots via emulation. 

Attached File  gene0007.png   4.67KB   1 downloadsAttached File  gene0008.png   3.51KB   1 downloadsAttached File  gene0010.png   16.2KB   1 downloads

 


Edited by InsaneMultitasker, Thu Jun 15, 2017 11:39 AM.


#19 mizapf OFFLINE  

mizapf

    River Patroller

  • 2,588 posts
  • Location:Germany

Posted Thu Jun 15, 2017 2:17 PM

Sachen gibt's ... (expression of surprise, hard to translate)

 

Is that in the 9640News collection? Filename?



#20 matthew180 OFFLINE  

matthew180

    River Patroller

  • 2,408 posts
  • Location:Castaic, California

Posted Thu Jun 15, 2017 2:23 PM

Sachen gibt's ... (expression of surprise, hard to translate)

...

 

"Holy Shit!" perhaps? ;)



#21 mizapf OFFLINE  

mizapf

    River Patroller

  • 2,588 posts
  • Location:Germany

Posted Thu Jun 15, 2017 3:32 PM

"Holy Shit!" perhaps? ;)

 

Yes, somewhat. The whole saying is "Sachen gibt's, die gibt's gar nicht", lit. "things there are which just can't be". :) Not an exclamation, more like a question to oneself.



#22 InsaneMultitasker OFFLINE  

InsaneMultitasker

    Stargunner

  • 1,731 posts

Posted Thu Jun 15, 2017 3:39 PM

Sachen gibt's ... (expression of surprise, hard to translate)

 

Is that in the 9640News collection? Filename?

 

Ummmm, no, it is not in the 9640News collection. ;)

 

I was only aware of one other person who had a copy.  I don't even know if Gary has the files any more.  I had written notes on the disk sleeve indicating MDOS 1.08 or earlier was required to properly run the program.  Sadly, when last I tried to run it, I could get no further than the option screen, as pressing '1' causes a spectacular lockup.  I had no good debug resources to investigate the problem back then, so I put the files in storage.  

 

PM me if you want to look into this and I'll send you the disk image.



#23 artrag OFFLINE  

artrag

    Dragonstomper

  • 708 posts

Posted Thu Jun 15, 2017 3:42 PM

Does it run as an interpreter of the z80 code or does it "compile" the z80 assembly ? What are the ram requirements to run the emulator? 

If it was an interpreter, I would be the  definitive proof that a translator from z80 to 9990 can work at reasonable speed. 

Naturally, doing a PC tool processing a coleco rom or an msx to give a TI99/4A game, would be astonishing.


Edited by artrag, Thu Jun 15, 2017 3:43 PM.


#24 InsaneMultitasker OFFLINE  

InsaneMultitasker

    Stargunner

  • 1,731 posts

Posted Thu Jun 15, 2017 4:30 PM

I suspect that Gary modified the Colecovision BIOS to use the TI-based video ports and sound ports.  The cartridge files seem to be loaded into GRAM pages, which would suggest byte-wise reading and interpretation of the cartridges. However, since the Geneve has 64K visible RAM at any given time, it is possible the cartridges are loaded into GRAM first, then moved into CPU RAM.  I know that the next screen you would see is a variation of MENU, which makes perfect sense given OPA's involvement with the Horizon RAMdisk ROS and MENU code.  I don't know how the Z80 code is handled, it is probably interpreted on the fly.



#25 JamesD OFFLINE  

JamesD

    Quadrunner

  • 7,753 posts
  • Location:Flyover State

Posted Fri Jun 16, 2017 12:26 AM

Emulation isn't that difficult, there was even an 8080 emulator on the Apple II back in the late 70s.

There is a Spectrum and a CP/M emulator for the Atari, and a CP/M emulator for OS-9 on the CoCo.
You can even run multiple copies of the emulator at once on OS-9.
It's just like writing an emulator on a PC... only slower.
I wouldn't expect something like that to compile to native code.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users