Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Simulating Bits

Reply to topic
Author Message
Chris
  • Guest
Reply with quote
Simulating Bits
Post Posted: Wed Jul 07, 1999 5:16 am
Is it logical for me to simulate the use of bits by doing this in C:

typedef struct {
int bit1: 1;
int bit2: 1;
int bit3: 1;
int bit4: 1;
int bit5: 1;
int bit6: 1;
int bit7: 1;
int bit8: 1;
} FLAGS;

FLAGS RegFlags

Wouldn't that be pretty useful to do or would it lead to problems later on down the line?

Chris :o)
 
Eric
  • Guest
Reply with quote
Post Posted: Wed Jul 07, 1999 5:15 pm
Quote
> Is it logical for me to simulate the use of bits by doing this in C:

> typedef struct {
> int bit1: 1;
> int bit2: 1;
> int bit3: 1;
> int bit4: 1;
> int bit5: 1;
> int bit6: 1;
> int bit7: 1;
> int bit8: 1;
> } FLAGS;

> FLAGS RegFlags

> Wouldn't that be pretty useful to do or would it lead to problems later on down the line?

It is logical, but not the best solution for an emulator.

First, each 'int' is (at least) 16 bits, but in most casese 32 bits. so for each "emulated-bit" you are actually using 16 (or more) bits of real memory.

Second, there's no way to modify more than one bit at a time. Each bit has to be individually accessed. In the Z80 this can be bad since so many instruction modify many different flags.

Most emulator authors use C/C++'s BIT-WISE logic operands to manipulate bits. You would declare your RegFlags as type CHAR (which is 8-bits). Then, you would use the & and | operators to manipulate individual bits.

For example if I wanted to SET bit 5 of the RegFlags (whatever flag is in bit 5 I don't know, but it's not important,) I would do: (RegFlags | 0x10). The vertical bar in C is the bit-wise OR operation. I'm ORing RegFlags with a bit-mask for bit 5. This will SET bit 5 and leave the other's untouched. To RESET bit 5 do: (RegFlags & 0xEF).

This method has the benefit that multiple bits can be SET and RESET simultaneously.

Certainly you will be able to correctly implement an emulator with your method above, it just may to be as fast as it could be.

Eric
 
Chris
  • Guest
Reply with quote
Hum...So...
Post Posted: Wed Jul 07, 1999 8:11 pm
Quote
> It is logical, but not the best solution for an emulator.

> First, each 'int' is (at least) 16 bits, but in most casese 32 bits. so for each "emulated-bit" you are actually using 16 (or more) bits of real memory.

> Second, there's no way to modify more than one bit at a time. Each bit has to be individually accessed. In the Z80 this can be bad since so many instruction modify many different flags.

> Most emulator authors use C/C++'s BIT-WISE logic operands to manipulate bits. You would declare your RegFlags as type CHAR (which is 8-bits). Then, you would use the & and | operators to manipulate individual bits.

> For example if I wanted to SET bit 5 of the RegFlags (whatever flag is in bit 5 I don't know, but it's not important,) I would do: (RegFlags | 0x10). The vertical bar in C is the bit-wise OR operation. I'm ORing RegFlags with a bit-mask for bit 5. This will SET bit 5 and leave the other's untouched. To RESET bit 5 do: (RegFlags & 0xEF).

> This method has the benefit that multiple bits can be SET and RESET simultaneously.

> Certainly you will be able to correctly implement an emulator with your method above, it just may to be as fast as it could be.

> Eric

So there's functions or keywords to manipulate bits in bytes? What I really want to do is simply
use register F as a byte and manipulate each bit during an instruction. But, to figure out the bit
value contained in F, I would save the value to a temporary variable, shift all the bits left or right
a certain amount of times until I'm left with the bit value and then I would check it and so on. Now
I know there's an easier way.

Chris :o)
 
Limbs a Flyin'
  • Guest
Reply with quote
Re: Hum...So...
Post Posted: Thu Jul 08, 1999 6:30 am


Quote
> > Most emulator authors use C/C++'s BIT-WISE logic operands to manipulate bits. You would declare your RegFlags as type CHAR (which is 8-bits). Then, you would use the & and | operators to manipulate individual bits.

the & op is what you are wanting

Quote
> So there's functions or keywords to manipulate bits in bytes? What I really want to do is simply
> use register F as a byte and manipulate each bit during an instruction. But, to figure out the bit
> value contained in F, I would save the value to a temporary variable, shift all the bits left or right
> a certain amount of times until I'm left with the bit value and then I would check it and so on. Now
> I know there's an easier way.

> Chris :o)


flag & 0x01 : if the lsb (least significant bit) from the byte "flag" is '1', then when we AND it with a constant which has its lsb as 1 (no other bits in the constant are set to 1) then you get a result of 1.


so if you want to test each bit idividualy, from lsb to most (most significant)

flag & 0x01
flag & 0x02
flag & 0x04
flag & 0x08
flag & 0x10
flag & 0x20
flag & 0x40
flag & 0x80

or for multiple bits at once, eg say the two lsb's;

flag & 0x03

or the lsb and the msb

flag & 0x81


if all this hex and bit stuff confuses you, even the standard windows calculator comes with decimal/hex/binary/octal conversions

i hope i got this all right ;)
 
Limbs a Flyin'
  • Guest
Reply with quote
whoops, small add on
Post Posted: Thu Jul 08, 1999 6:36 am
the result of ANDing gives you a bit battern,

so; (binary)

00000001 &
00000001
=
00000001





10101010 &
11110000
=
10100000

see? only if a bit is set to 1 in both variables, then it will set the relevent bit in the result

i think that should help, as long as i havent got it wrong;)
 
Eric
  • Guest
Reply with quote
Summary
Post Posted: Thu Jul 08, 1999 4:01 pm
Here's a quick summary of what Limbs a Flyin' and I have been talking about:

To TEST if a bit is set:

AND (&) the flags with a bit-mask which is all 0's except in the bit-position you want tested.
If the result is zero, the flag is reset, if the result is non-zero, the flag is set.

Example (testing SIGN bit in position 7):

(FLAGS & 0x80)

Generally, you only want to test a single flag at a time with this method. If testing more than
one bit, the result is non-zero if either flag is set. This only tells you that at least one
of the flags is set, but doesn't guarantee that both are.

To RESET a bit:

AND (&) the flags with a bit-mask which is all 1's except in the bit-positions you want RESET.
This method can be used to RESET multiple flags at once.

Example (RESETing SIGN bit in position 7 and CARRY bit in position 0):

(FLAGS & 0x7E)


To SET a bit:

OR ( | ) the flags with a bit-mask which is all 0's except in the bit-positions you want SET.
This method can be used to SET multiple flags at once.

Example (SETing SIGN bit in position 7 and CARRY bit in position 0):

(FLAGS | 0x81)


Good Luck.

Eric
 
Chris
  • Guest
Reply with quote
Re: Summary
Post Posted: Thu Jul 08, 1999 7:46 pm
Alright. Check and see if this is right...

AND
1 + 1 = 1
1 + 0 = 1
0 + 1 = 1
0 + 0 = 0

OR
1 + 1 = 0
1 + 0 = 1
0 + 1 = 1
0 + 0 = 0

Now, if I want to test a bit, I reset all of it's bits so I'm left with one? Like, if I want to test the Carry bit
which is bit 0 on my Low Endian Machine (Right to left), I should do this?

Flags & 0x01

And if I want to reset the Carry bit to zero I do this?

Flags | 0x01

And no other bits will be affected by this? I understand this method so far but am I supposed to reset the
Flags register everytime I come across an instruction that involves the flag register? Cause what if
I come across an instruction that invloves a Carry and an Overflow, then I'll be dealing with more bits?
What's the deal here?

And Thank you so much (This place is great, Zoop!)

Chris :o)
 
Eric
  • Guest
Reply with quote
Re: Summary
Post Posted: Thu Jul 08, 1999 8:31 pm

Quote
> Alright. Check and see if this is right...

No, the following are not correct.

The AND you've shown is actually OR
Quote
> AND
> 1 + 1 = 1
> 1 + 0 = 1
> 0 + 1 = 1
> 0 + 0 = 0

The OR you've shown is actually XOR (which we haven't talked about yet.)
Quote
> OR
> 1 + 1 = 0
> 1 + 0 = 1
> 0 + 1 = 1
> 0 + 0 = 0

Here are the correct tables:

AND (Bit-wise operand in C is &):

0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1

In other words, both inputs must be 1 for the output to be 1.

OR (Bit-wise operand in C is | ):

0 OR 0 = 0
0 OR 1 = 1
1 OR 0 = 1
1 OR 1 = 1

In other words, either input must be 1 for the ouput to be 1.

XOR (Bit-wise operand in C is ^ ):

0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0

In other words, the inputs must be different for the output to be 1.


Here's how you would SET CARRY in Flags: Flags = Flags | 0x01; (or you could do Flags |= 0x01;)

Here's how you would RESET CARRY in Flags: Flags = Flags & 0xFE; (or you could do Flags &= 0xFE;)

The data being ORed or ANDed with Flags in the above examples are called bit-masks.

The bit-masks for SETing and RESETing CARRY are exact inversions of each other (the same is true for any flag.)

Notice that to SET, the OR bit-mask has all bits RESET to 0 except the CARRY bit. ORing anything with 0 returns the original value (thus leaving the other bits effectively untouched) while ORing with 1 forces a 1 result (thus setting the CARRY as we want.)

Notice that to RESET, the AND bit-mask has all bits SET to 1 except the CARRY bit. ANDing anything with 1 returns the original value (thus leaving the other bits effectively untouched) while ANDing with 0 forces a 0 result (thus clearing CARRY as we want.)

You can SET or RESET as many bits as you want with a single operation. However, you can not both SET and RESET bits in a single operation, you need at least two operations: one to SET bits, and one to RESET bits. To SET more than one bit, put more 1's in the OR bit mask. To RESET more than one bit, put more 0's in the AND bit-mask.

Good luck.

Eric
 
Reply to topic



Back to the top of this page

Back to SMS Power!