I'm trying to write an emulator for the z80, and am wondering if there is any specific opcode layout (i.e. do all the ld instructions have a specific bit set). I've looked here but if there's an indication of a pattern, I haven't found it yet.
Is there? If there is, please give me a few examples.
You are right, there's a pattern. This page:
http://www.z80.info/decoding.htm
explains the encoding of various Z80 instructions, both documented and undocumented ones.
The ld c, d instruction, for example, is encoded as LD r[y], r[z] with the x field (the two most significant bits) of the op-code set to 1 and three-bit fields y and z (bits 3-5 and 0-2 respectively) set to 1 and 2.
To give you an example of how that can be implemented in an emulator, here's a link to my implementation of the decoder:
z80.h.
Related
I'm currently studying for an upcoming quiz in my microprocessors class and ran into a question where an XOR instruction was introduced.
I understood why the N flag was set to 1, but i'm at a loss as to why the C flagwas set to 1.
I looked everywhere online as to why or how this might have occurred, but everything related to a C flag only talked about the arithmetic portion as to why a C flag changes.
I'm using a MSP430 if that helps.
Since it is related to a homework/study preparation, I want to give you a hint.
The XOR operation can be used to add two binary numbers ;-)
Okay, so it may not be that strange, but I'm really new to Ada. In my job, I am translating legacy Ada to C, and have come across something that I haven't seen yet. I searched around, but couldn't really find it; here it is.
type Discrete_Names is ( ENUM_POS_4, --label names in an enum
ENUM_POS_5, --that evaluate to 4, 5, and 6
ENUM_POS_6); --respectively
type Discrete_Array_Type is Array (Discrete_Names) of Discrete.Does_Not_Matter
Side note—the Discrete.Does_Not_Matter just references another type in a different library.
It would be great if someone could just help me get my bearings and just figure out what is going on here.
Well, it is quite simple. In Ada arrays can be indexed by any discrete type, that is, integers, characters or enumeration types (your case). The line
type Discrete_Array_Type is Array (Discrete_Names) of Does_Not_Matter
declares Discrete_Array_Type as the type of an array that contains values of type Does_Not_Matter and it is indexed by values of type Discrete_Names.
If your doubt stems from the fact that ENUM_POS_4 has Pos equal to 4 -- so that it seems that the first index of the array is 4 and not 0 -- my suggestion is... forget about it. The compiler will take care of that. In Ada arrays can start from any index. For example, if you say
type Array_Foo is array(Positive range <>) of Characters;
Bar : Array_Foo(10..15);
Bar will be just 6 entries long (not 16) and when you access Bar(12) the compiler -- behind the scenes -- will remove the initial offset "10" to "12" so that you will access the third memory location reserved to Bar. (Actually, I think that for the sake of efficiency it will add 12 to the address of Bar diminished by 10 times the integer sizes, but this is a detail...)
My personal experience is that in cases like this you should not consider the enumerative type like a "integer in disguise" (although it will be internally represented by an integer), but like a type of its own that can be used to index an array. Let the compiler worry about the internal low-level details.
How does the 68000 internally represent instructions.
I've read that there are different types of instructions: single effective operation word format instructions, brief and full extension word format instructions. The single effective operation word instruction seems to represent the instruction and the lower 6 bits of this instruction the addressing mode and register. Does this addressing mode and register tell you if there follows a brief or full extension word format instruction, which on his turn represents the operands for the instruction. Do you know a better manual than the 68000 programming reference manual.
Thanks in advance
The actual internal representation is a combination of "microcode" and "nanocode". The 68000 has 544 17-bit microcode words which dispaches to 366 68-bit nanocode words.
While this may not be what you wanted to know, this link may provide some insights:
http://www.easy68k.com/paulrsm/doc/dpbm68k1.htm
right, on m68000 indexed modes uses the brief extension. In "Address Register Indirect with Index (8-Bit Displacement) Mode" (d8, An, Xn), the BEW is filled with D/A (if Xn is a data or address register), Xn (the register number), W/L (to threat Xn contents as 16 or 32bits), scale to 0 (see note), and the 8-bit displacement.
on other hand, other modes, like the 16bit displacement, "Address with displacement" (d16,An) , the extension is only a word with the displacement.
the note is: brief extension word - m68k doesn't support the 2bits for scale so is set to 0; scale on BEW using the scale bits, and full extensions are only suported m68020,40,-> cpus. http://etd.dtu.dk/thesis/264182/bac10_19.pdf
What does the OpenCL compiler option -cl-fast-relaxed-math do?
From reading the documentation - it looks like -cl-fast-relaxed-math allows a kernel to do floating point math on any variables - even if those variables point to the wrong data type, cause division by zero, or some other illegal behavior.
Is this correct? In what situation would this compiler option be useful?
From comments:
Enables -cl-finite-math-only and -cl-unsafe-math-optimizations. These two options provide aditional speed by removing some checks to the input values. IE: Not check for NaN numbers. However, if the input values happend to BE non normal numbers, the results are unknown. – DarkZeros
Apologies for making this my second Z80 DAA question - I have pretty much implemented this instruction now, but there is one thing I'm not sure about - is the H flag set by this instruction at all? The Z80 manual says 'see instruction', but it only mentions the flag before DAA, not after it is executed.
I set the flags as follows:
S is set if result is negative (0x80 & result equals 0x80)
Z is set if result is zero
H (not sure hence this question)
P/V is set to the parity of the result (1 if even, 0 if odd)
N is left alone
C is set if the higher nibble of the original accumulator value is modified
Other than this, the instruction seems to perform as I expect it to :-) I hope someone can clear this up for me, many thanks.
I could only find here that the half-carry/borrow flag is modified by DAA.
I recommend that this flag be set exactly as the AF (auxiliary carry) flag is set by the DAA and DAS instructions on x86 CPUs. I see no reason why there should be any difference in operation between i8080/i8085/Z80's and i8086's DAA/DAS.
The x86 DAA/DAS sets AF to 1 if it adjusts the lowest 4 bits of the accumulator by 6. If it does not adjust them, it resets AF to 0.
See the pseudo-code for DAA and DAS in the intel's (or AMD's) x86 CPU manuals.
It's a good question. Yes, H flag's behaviour is not clearly documented because it is behaviour is non-standard with DAA.
If lower nibble (least significant four bits) of A is a non base-10 number (greater than 9 like A,B,C,D,E or F) or H flag is set, 6 is added to the register. This means even if lower nibble is in 0-9 range, you can force to add 6 to A register by setting H flag.
When it comes to your question, H flag usually remains untouched in my experience but you cannot depend on that because it is said that "the effect is non-standard" which means H flag may change or may not change depending on the situation. In cases like this, you should always think H flag is affected by the DAA instruction after execution even if you see it is not affected in your tests.