Results from running EX on a real Z80 board last night:
A>ex
Z80 instruction exerciser
Undefined status bits NOT taken into account
ld hl,(nnnn)..................( 16) cycles OK
ld sp,(nnnn)..................( 16) cycles OK
ld (nnnn),hl..................( 16) cycles OK
ld (nnnn),sp..................( 16) cycles OK
ld (<ix,iy>+1),nn.............( 32) cycles OK
ld (<ix,iy>-1),nn.............( 32) cycles OK
ld <bc,de>,(nnnn).............( 32) cycles OK
ld <ix,iy>,(nnnn).............( 32) cycles OK
ld <ix,iy>,nnnn...............( 32) cycles OK
ld a,<(bc),(de)>..............( 44) cycles OK
ld a,(nnnn) / ld (nnnn),a.....( 44) cycles OK
ldd<r> (1)....................( 44) cycles OK
ldd<r> (2)....................( 44) cycles OK
ldi<r> (1)....................( 44) cycles OK
ldi<r> (2)....................( 44) cycles OK
ld <b,c,d,e,h,l,(hl),a>,nn....( 64) cycles OK
ld (nnnn),<bc,de>.............( 64) cycles OK
ld (nnnn),<ix,iy>.............( 64) cycles OK
ld <bc,de,hl,sp>,nnnn.........( 64) cycles OK
ld (<ix,iy>+1),a..............( 64) cycles OK
ld (<ix,iy>-1),a..............( 64) cycles OK
ld (<bc,de>),a................( 96) cycles OK
ld a,(<ix,iy>+1)..............( 128) cycles OK
ld a,(<ix,iy>-1)..............( 128) cycles OK
ld (<ix,iy>+1),<h,l>..........( 256) cycles OK
ld (<ix,iy>-1),<h,l>..........( 256) cycles OK
ld <h,l>,(<ix,iy>+1)..........( 256) cycles OK
ld <h,l>,(<ix,iy>-1)..........( 256) cycles OK
<set,res> n,(<ix,iy>+1).......( 448) cycles OK
<set,res> n,(<ix,iy>-1).......( 448) cycles OK
ld <b,c,d,e>,(<ix,iy>+1)......( 512) cycles OK
ld <b,c,d,e>,(<ix,iy>-1)......( 512) cycles OK
ld (<ix,iy>+1),<b,c,d,e>......( 1,024) cycles OK
ld (<ix,iy>-1),<b,c,d,e>......( 1,024) cycles OK
<inc,dec> bc..................( 1,536) cycles OK
<inc,dec> de..................( 1,536) cycles OK
<inc,dec> hl..................( 1,536) cycles OK
<inc,dec> ix..................( 1,536) cycles OK
<inc,dec> iy..................( 1,536) cycles OK
<inc,dec> sp..................( 1,536) cycles OK
bit n,(<ix,iy>+1).............( 2,048) cycles OK
bit n,(<ix,iy>-1).............( 2,048) cycles OK
<inc,dec> a...................( 3,072) cycles OK
<inc,dec> b...................( 3,072) cycles OK
<inc,dec> c...................( 3,072) cycles OK
<inc,dec> d...................( 3,072) cycles OK
<inc,dec> e...................( 3,072) cycles OK
<inc,dec> h...................( 3,072) cycles OK
<inc,dec> l...................( 3,072) cycles OK
<inc,dec> (hl)................( 3,072) cycles OK
ld <bcdehla>,<bcdehla>........( 3,456) cycles OK
cpd<r>........................( 6,144) cycles OK
cpi<r>........................( 6,144) cycles OK
<rlca,rrca,rla,rra>...........( 6,144) cycles OK
<inc,dec> (<ix,iy>+1).........( 6,144) cycles OK
<inc,dec> (<ix,iy>-1).........( 6,144) cycles OK
<set,res> n,<bcdehl(hl)a>.....( 6,912) cycles OK
neg...........................( 16,384) cycles OK
add hl,<bc,de,hl,sp>..........( 35,840) cycles OK
add ix,<bc,de,ix,sp>..........( 35,840) cycles OK
add iy,<bc,de,iy,sp>..........( 35,840) cycles OK
aluop a,nn....................( 45,056) cycles OK
bit n,<b,c,d,e,h,l,(hl),a>....( 49,152) cycles OK
<daa,cpl,scf,ccf>.............( 65,536) cycles OK
<adc,sbc> hl,<bc,de,hl,sp>....( 71,680) cycles OK
aluop a,(<ix,iy>+1)...........(229,376) cycles OK
aluop a,(<ix,iy>-1)...........(229,376) cycles OK
aluop a,<b,c,d,e,h,l,(hl),a>..(753,664) cycles OK
shf/rot (<ix,iy>+1)...........( 416) cycles OK
shf/rot (<ix,iy>-1)...........( 416) cycles OK
<rrd,rld>.....................( 7,168) cycles OK
<ini,outi,ind,outd><,r>.......( 65,536) cycles ERROR **** crc expected:aafb6d5c found:498ee92f
shf/rot <b,c,d,e,h,l,(hl),a>..( 6,784) cycles OK
ld <bcdexya>,<bcdexya>........( 6,912) cycles OK
ld <ixh,ixl,iyh,iyl>,nn.......( 32) cycles OK
<inc,dec> ixh.................( 3,072) cycles OK
<inc,dec> ixl.................( 3,072) cycles OK
<inc,dec> iyh.................( 3,072) cycles OK
<inc,dec> iyl.................( 3,072) cycles OK
aluop a,<ixh,ixl,iyh,iyl>.....(376,832) cycles OK
Some failure detected.
CP/M V2.2C
A>
Dr_Acula said...
Results from running EX on a real Z80 board last night:
Thank you! It's what I also get, except that the ini/outi stuff even manages to make the break trigger and print register dumps.
This group of opcodes can't be tested in a system where some of the ports return meaningful results.
And there's still another bug lurking, despite EX giving me 100%
The indication is that some games just hang on the TRS80.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Be aware that EX does not test all instructions. EX, EXX, jumps, calls and a bunch of other stuff. It assumes some level of operation in order to run at all. There is a companion test called PRELIM that should be successful prior to running EX. PRELIM will basically crash and burn if anything is wrong with some basic ops.
You probably need to find all the ops EX does not test and have a good look at them to catch the TRS80 problem. Perhaps adding more ops to EX with checksums from a real Z80 is the way to go.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
heater said...
Be aware that EX does not test all instructions. EX, EXX, jumps, calls and a bunch of other stuff. It assumes some level of operation in order to run at all. There is a companion test called PRELIM that should be successful prior to running EX. PRELIM will basically crash and burn if anything is wrong with some basic ops.
You probably need to find all the ops EX does not test and have a good look at them to catch the TRS80 problem. Perhaps adding more ops to EX with checksums from a real Z80 is the way to go.
That may be worth trying. It's not only the TRS80, also Wordstar has a strange bug. So we can assume it's not one of the Z80 only opcodes, as Wordstar is 8080 only.
The TRS80 games are a good indication of working undocumented opcodes, because many of them use these.
Among the games that behave strange there is Bable Terror 2, where the player's graphics when you move down is garbled.
I'm not sure if EX tests all possible _values_ for all opcodes, so when checking e.g. <aluop> <nn> and nn isn't all bytes from $00 to $ff, then there still could be an error in the code despite the CRC being ok for the tested range.
Oops - wrong thread for trs80.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
One more bug spotted and squashed to death:
The DJNZ opcode was decrementing B but not limiting it to a byte. Thus if a DJNZ loop was started with B=0, which is perfectly legal (it executes 256 times then) it would on yaz80 execute 2^32 times, which naturally takes ... a little longer.
This also cures some of the hanging games in TRS80, so I'll update that one as well.
Wordstar still not working right.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
You are right. EX does not cover all possible values of all operands in its tests. If you look into the EX source at the test definitions you will see that it has bit masks and counters that are used to generate a bunch of test cases by changing various bits in the instruction or operands. I imagine that whoever defined those masks and counters was aiming at covering as many corner cases as possible. Like checking carry is generated when a result of an addition is just about big enough but not when it is one less.
One could of course add more test cases by putting more ones in those mask and counter fields and regenerating the check sums on a real chip. The run time goes through the roof though.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
You are right. EX does not cover all possible values of all operands in its tests. If you look into the EX source at the test definitions you will see that it has bit masks and counters that are used to generate a bunch of test cases by changing various bits in the instruction or operands. I imagine that whoever defined those masks and counters was aiming at covering as many corner cases as possible. Like checking carry is generated when a result of an addition is just about big enough but not when it is one less.
One could of course add more test cases by putting more ones in those mask and counter fields and regenerating the check sums on a real chip. The run time goes through the roof though.
That's what I fear. I have one candidate class of opcodes that may be not 100%: ADD/ADC/SUB/SBC. MAME's Z80 core does the overflow detection differently and I don't know, if the way you did it, and which I copied, is really equivalent.
MAME's Z80 compares the sign change of the operation against a sign difference (or no sign difference for SUB/SBC) of operand and argument and makes the P/V flag set if both are different... this is way more complicated then what you have: a carry to bit 8 (or 16 in word ops) also sets the overflow, which is then toggled if the aux' bit 7 (or 15) is set.
In MAME's case it is:
result = newval - oldval; (result ^ oldval ^ $80) & (result ^ newval) & $80 = P/V for ADD or ADC without carry
result = newval - oldval - 1; (result ^ oldval ^ $80) & (result ^ newval) & $80 = P/V for ADC with carry
result = oldval - newval; (result ^ oldval) & (oldval ^ newval) & $80 = P/V for SUB, CP or SBC without carry
result = oldval - newval - 1; (result ^ oldval) & (oldval ^ newval) & $80 = P/V for SBC with carry
It has 64K tables of flag results for the 4 operations (i.e. a flags[noparse][[/noparse]newval][noparse][[/noparse]oldval])... memory is no concern on a PC :-P
It may be that the two always give the same result. I have to write a little program to compare the two methods, because I don't see how to simplify MAME's math to what your check does.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/30/2010 11:33:36 AM GMT
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Thank you! It's what I also get, except that the ini/outi stuff even manages to make the break trigger and print register dumps.
This group of opcodes can't be tested in a system where some of the ports return meaningful results.
And there's still another bug lurking, despite EX giving me 100%
The indication is that some games just hang on the TRS80.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
You probably need to find all the ops EX does not test and have a good look at them to catch the TRS80 problem. Perhaps adding more ops to EX with checksums from a real Z80 is the way to go.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
That may be worth trying. It's not only the TRS80, also Wordstar has a strange bug. So we can assume it's not one of the Z80 only opcodes, as Wordstar is 8080 only.
The TRS80 games are a good indication of working undocumented opcodes, because many of them use these.
Among the games that behave strange there is Bable Terror 2, where the player's graphics when you move down is garbled.
I'm not sure if EX tests all possible _values_ for all opcodes, so when checking e.g. <aluop> <nn> and nn isn't all bytes from $00 to $ff, then there still could be an error in the code despite the CRC being ok for the tested range.
Oops - wrong thread for trs80.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/30/2010 9:23:13 AM GMT
The DJNZ opcode was decrementing B but not limiting it to a byte. Thus if a DJNZ loop was started with B=0, which is perfectly legal (it executes 256 times then) it would on yaz80 execute 2^32 times, which naturally takes ... a little longer.
This also cures some of the hanging games in TRS80, so I'll update that one as well.
Wordstar still not working right.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
You are right. EX does not cover all possible values of all operands in its tests. If you look into the EX source at the test definitions you will see that it has bit masks and counters that are used to generate a bunch of test cases by changing various bits in the instruction or operands. I imagine that whoever defined those masks and counters was aiming at covering as many corner cases as possible. Like checking carry is generated when a result of an addition is just about big enough but not when it is one less.
One could of course add more test cases by putting more ones in those mask and counter fields and regenerating the check sums on a real chip. The run time goes through the roof though.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
That's what I fear. I have one candidate class of opcodes that may be not 100%: ADD/ADC/SUB/SBC. MAME's Z80 core does the overflow detection differently and I don't know, if the way you did it, and which I copied, is really equivalent.
MAME's Z80 compares the sign change of the operation against a sign difference (or no sign difference for SUB/SBC) of operand and argument and makes the P/V flag set if both are different... this is way more complicated then what you have: a carry to bit 8 (or 16 in word ops) also sets the overflow, which is then toggled if the aux' bit 7 (or 15) is set.
In MAME's case it is:
result = newval - oldval; (result ^ oldval ^ $80) & (result ^ newval) & $80 = P/V for ADD or ADC without carry
result = newval - oldval - 1; (result ^ oldval ^ $80) & (result ^ newval) & $80 = P/V for ADC with carry
result = oldval - newval; (result ^ oldval) & (oldval ^ newval) & $80 = P/V for SUB, CP or SBC without carry
result = oldval - newval - 1; (result ^ oldval) & (oldval ^ newval) & $80 = P/V for SBC with carry
It has 64K tables of flag results for the 4 operations (i.e. a flags[noparse][[/noparse]newval][noparse][[/noparse]oldval])... memory is no concern on a PC :-P
It may be that the two always give the same result. I have to write a little program to compare the two methods, because I don't see how to simplify MAME's math to what your check does.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/30/2010 11:33:36 AM GMT