Negative numbers in prg-rom?!

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Negative numbers in prg-rom?!
by on (#3373)
Hey all,

I've just started to to write an NES emulator. The first thing I've done is make a simple hex viewer to see the code, but I find that there are negative codes! For example, I might a "0xffffff80" randomly and if I format my output to decimal instead of hex I find actual negative numbers (ie -15). Why oh why are there negative numbers?!

Thanks for the help

(Btw, I'm using C and working off of MarioBros.nes. I am simply opening the nes file, reading in a byte, outputting that byte to another file formattted as hexidecimal with a label and then repeating)

by on (#3376)
A ROM simply contains a bunch of bits, usually organized in 8-bit units (bytes). The interpretation of the bits is up to the hardware connected to it. The NES CPU interprets bytes as opcodes, addresses , and values.

Unsigned (modulo) addition and subtraction can be used for signed addition and subtraction using two's complement representation. In this representation the high bit happens to be set for negative numbers and clear for positive numbers and zero. It can be understood by noting that adding 11 hours on an old-style clock face is the same as subtracting one hour.

Thus a byte in ROM can have a negative value if interpreted as a signed value. $ff = -1. $02 + $ff = $101. $fe = -2. $80 = -128. $7f = 127.

The 6502 doesn't have any arithmetic registers larger than 8 bits. On machines that do, there is usually an instruction to convert a signed 8-bit value to a signed 16-bit value (and larger). This is called sign extension, and simply involves copying the sign bit to all higher bits in the destination. $fe sign-extended to 16 bits is $fffe.

You're probably loading the 8-bit value from ROM into a signed 8-bit value in your program, then converting it to a 32-bit value. If you want to treat it as unsigned, mask it with 0xff.

In short, a ROM is just a collection of bits and what they mean is up to the machine that interprets it. It can contain (representations of) colors, pictures, sounds, etc.

by on (#3428)
Use unsigned char instead of char.