# Conversion of Z80 code to TMS9900

## Recommended Posts

On the Z80, as far as I understand, if you subtract a bigger unsigned byte from a smaller one the carry bit is set:

ld a,#0xc0

sub #0xd0

jr C,label [this jump will be taken]

I don't think the carry flag works like that on the TMS9900. Is there an equivalent?

##### Share on other sites

Correct! sub a,n will set C if a<n

Be aware that some 16 instructions do not set the C flag

##### Share on other sites

When you calculate 00c0 - 00d0, the ALU effectively adds the two's complement: 00c0 + ff30 = fff0. Since the result does not exceed ffff, carry is cleared. However, when you calculate 00d0 - 00c0, you have 00d0 + ff40 = 10010 = 0010, so this means carry is set.

##### Share on other sites

This is very different from z80

The z80 ALU has proper subtraction using the carry bit as 9th or 17th bit in the operation

Only pay attention that the 16 bit add does not affect carry for compatibility with intel 8080

If you need the carry bit on 16bit operations you can use adc and sbc, but they also add and sub the previous value of the carry before affecting it.

This is the reason why you often find

And a

Sbc hl,de

Because and a resets the carry before the execution of sbc

Edited by artrag

##### Share on other sites

I don't think the carry flag works like that on the TMS9900. Is there an equivalent?

If you subtract a bigger value from a smaller one, the result is negative, so a JLT should work.

##### Share on other sites

If you subtract a bigger value from a smaller one, the result is negative, so a JLT should work.

I don't think so because >C0 - >10 = >B0, this will trigger JLT but >10 is not unsigned bigger than >C0.

I think it works to use CB followed by JL, and perform the subtraction afterwards if it's not only needed for the comparison.

##### Share on other sites

I actually did not say anything about the converse: If you subtract a bigger value from a smaller, the result is negative, but the result is also negative in other occasions, so you need something that behaves the same way in both directions (if and only if).

C0 - 10 = B0 will not trigger JLT if we understand this as 00C0 - 0010 (thinking by 16 bit). For our platform, it would have to read C000-1000 = B000, this would indeed be negative.

##### Share on other sites

Correct! sub a,n will set C if a<n

Be aware that some 16 instructions do not set the C flag

I'm still having troubles converting code that uses the C flag. Can you confirm that for sub the carry flag is set if and only if a<n and that this comparison is unsigned, i.e. 0xc0<0xd0?

##### Share on other sites

Carry is the 9th bit in the sub a,n instruction.

If the result (think it on infinite bits) is negative, the 9th bit is one. If the result is positive the 9th bit is zero.

Try

Msxpen.com

And see the 'hello word' program to have a guide

Edited by artrag

##### Share on other sites

Carry is the 9th bit in the sub a,n instruction.

If the result (think it on infinite bits) is negative, the 9th bit is one. If the result is positive the 9th bit is zero.

Try

Msxpen.com

And see the 'hello word' program to have a guide

Thanks, I'm playing with msxpen.com and I have simple question: what's the different between ld a,200 and ld a,#200? The latter is used in the disassembly I'm converting. msxpen.com accepts both notations with different results.

##### Share on other sites

#200 is hex, same as 0x200

200 is decimal

##### Share on other sites

Thanks, I'm playing with msxpen.com and I have simple question: what's the different between ld a,200 and ld a,#200? The latter is used in the disassembly I'm converting. msxpen.com accepts both notations with different results.

Motorola assembly is the same way.

#200 is hex, same as 0x200

200 is decimal

#200 is not hex, it is decimal.

Hex is represented by the prefix \$ on Motorola chips, and H postfix on the Z80, upper or lower case H h usually works depending on the assembler.

So when combined with my previous comment, ld a,200h would be load a from address 200 hex, and ld a,#200h would be load value 200 hex into a

Not only that, but a is 8 bit on the Z80 and loading a value larger than 8 bits into a should cause the assembler to generate an error

0x200 notation for hex is supported by most modern assemblers but I can't vouch for old ones.

Since this is about porting code, you just have to be aware of both forms as would a translator program.

Edited by JamesD

##### Share on other sites

Z80 is from zilog

In msxpen #200 is hex

##### Share on other sites

Z80 is from zilog

In msxpen #200 is hex

So how does it differentiate between hex and immediate addressing?

##### Share on other sites

msxopen uses the pasmo assembler.
http://pasmo.speccy.org/pasmodoc.html

##### Share on other sites

Ld a,(200) will load in a the value stored in ram at 200 decimal

Edited by artrag

##### Share on other sites

Ld a,(200)

Which is indirect addressing on other processors. Load a with the value located at the address pointed to by what is in memory address 200 and 201.

I've definitely never buying the guy that wrote Pasmo a beer.

If all you are writing is Z80 code it seems to have a lot of features., but if you spend much time going back and forth between different processors that it is likely to mess you up.

##### Share on other sites

#200 is hex, same as 0x200

200 is decimal

\$200 also seems to work in msxpen. But the code I'm converting must be using # to denote immediate addressing, because it uses things like ld hl,#table or ld a,#0xff.

##### Share on other sites

#table is a label, in some assemblers lables can start by #

Check if #0xff is a label too, it could be a quick and dirty way to name a label from a constant

Edited by artrag

##### Share on other sites

Which is indirect addressing on other processors. Load a with the value located at the address pointed to by what is in memory address 200 and 201.

I've definitely never buying the guy that wrote Pasmo a beer.

If all you are writing is Z80 code it seems to have a lot of features., but if you spend much time going back and forth between different processors that it is likely to mess you up.

The assembly has been defined by ziolg not by pasmo.

Look at this

www.zilog.com/docs/z80/um0080.pdf

##### Share on other sites

#table is a label, in some assemblers lables can start by #

Check if #0xff is a label too, it could be a quick and dirty way to name a label from a constant

No # is not part of the label, and #0xff is not a label either. I guess this has been produced using a non-standard disassembler.

##### Share on other sites

The assembly has been defined by ziolg not by pasmo.

Look at this

www.zilog.com/docs/z80/um0080.pdf

Crap... and it's even in my own code like that.

Sorry

##### Share on other sites

No # is not part of the label, and #0xff is not a label either. I guess this has been produced using a non-standard disassembler.

Hardly I can imagine to find something useful in memory at 0xFF if the bios is paged in.

Maybe it is better if you send a larger except from the source if you want a more accurate evaluation of what is doing the code

Edited by artrag

##### Share on other sites

FWIW, someone has just completed a direct translation of the arcade version of Pacman to the Coco 3.
He used a tool to help convert from the Z80 code to the 6809.
If you follow the links to the blog and look for entries for July, you will find the C source code for his tool.
Maybe you could use it as a starting point for a Z80 to 9900 translator.

##### Share on other sites

So many late late nights under my blankets with a battery torch writing Z80 code into a notebook...

Into the wee hours I'd go, looking up op-codes and turning them into hex before POKEing into memory...

I'd awaken bleary eyed and naggy to shouting parents, rudely informing me that it's time for school...

Funny, the memories that a few Z80 op-codes can invoke.

Thanks for the memories.

I'll stick with the 9900 though

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.