Vamiga: cputester results

Created on 5 Jan 2020  Β·  70Comments  Β·  Source: dirkwhoffmann/vAmiga

Current status (will be updated permanently):

ABCD.B πŸ‘
ADD.B πŸ‘
ADD.L πŸ‘
ADD.W πŸ‘
ADDA.L πŸ‘
ADDA.W πŸ‘
ADDX.B πŸ‘
ADDX.L πŸ‘
ADDX.W πŸ‘
AND.B πŸ‘
AND.L πŸ‘
AND.W πŸ‘
ANDSR.B πŸ‘
ANDSR.W πŸ‘ (zipped, 8 MB Fast RAM)
ASL.B πŸ‘
ASL.L πŸ‘
ASL.W πŸ‘
ASLW.W πŸ‘
ASR.B πŸ‘
ASR.L πŸ‘
ASR.W πŸ‘
ASRW.W πŸ‘

BCHG.B πŸ‘
BCHG.L πŸ‘
BCLR.B πŸ‘
BCLR.L πŸ‘
BSET.B πŸ‘
BSET.L πŸ‘
BSR.B πŸ‘
BSR.W πŸ‘
Bcc.B πŸ‘ (zipped, 8 MB Fast RAM)
Bcc.W πŸ‘ (zipped, 8 MB Fast RAM)

CHK.W πŸ‘
CLR.B πŸ‘
CLR.L πŸ‘
CLR.W πŸ‘
CMP.B πŸ‘
CMP.L πŸ‘
CMP.W πŸ‘
CMPA.L πŸ‘
CMPA.W πŸ‘
CMPM.B πŸ‘
CMPM.L πŸ‘
CMPM.W πŸ‘

DBcc.W πŸ‘
DIVS.W πŸ‘
DIVU.W πŸ‘

EOR.B πŸ‘
EOR.L πŸ‘
EOR.W πŸ‘
EORSR.B πŸ‘ OK (zipped, 8 MB Fast RAM)
EORSR.W πŸ‘
EXG.L πŸ‘
EXT.L πŸ‘
EXT.W πŸ‘

ILLEGAL πŸ‘
ILLEGAL.B πŸ‘

JMP πŸ‘
JSR πŸ‘

LEA.L πŸ‘
LINK.W πŸ‘
LSL.B πŸ‘
LSL.L πŸ‘
LSL.W πŸ‘
LSLW.W πŸ‘
LSR.B πŸ‘
LSR.L πŸ‘
LSR.W πŸ‘
LSRW.W πŸ‘

MOVEx.B πŸ‘ (zipped, 8 MB Fast RAM)
MOVEx.L πŸ‘ (zipped, 8 MB Fast RAM)
MOVEx.W πŸ‘ (zipped, 8 MB Fast RAM)

NBCD.B πŸ‘
NEG.B πŸ‘
NEG.L πŸ‘
NEG.W πŸ‘
NEGX.B πŸ‘
NEGX.L πŸ‘
NEGX.W πŸ‘
NOP πŸ‘
NOT.B πŸ‘
NOT.L πŸ‘
NOT.W πŸ‘

OR.B πŸ‘
OR.L πŸ‘
OR.W πŸ‘
ORSR.B πŸ‘
ORSR.W πŸ‘

PEA.L πŸ‘

RESET πŸ‘
ROL.B πŸ‘
ROL.L πŸ‘
ROL.W πŸ‘
ROLW.W πŸ‘
ROR.B πŸ‘
ROR.L πŸ‘
ROR.W πŸ‘
RORW.W πŸ‘
ROXL.B πŸ‘
ROXL.L πŸ‘
ROXL.W πŸ‘
ROXLW.W πŸ‘
ROXR.B πŸ‘
ROXR.L πŸ‘
ROXR.W πŸ‘
ROXRW.W πŸ‘
RTE πŸ‘
RTR πŸ‘
RTS πŸ‘

SBCD.B πŸ‘
STOP πŸ‘
SUB.B πŸ‘
SUB.L πŸ‘
SUB.W πŸ‘
SUBA.L πŸ‘
SUBA.W πŸ‘
SUBX.B πŸ‘
SUBX.W πŸ‘
SWAP.W πŸ‘
Scc.B πŸ‘

TAS.B πŸ‘
TRAP πŸ‘
TRAPV πŸ‘
TST.B πŸ‘
TST.L πŸ‘
TST.W πŸ‘

UNLK.L πŸ‘

Info

Most helpful comment

MOVEM has also previously used too many "history" entries. I'll also check it after 68010 stuff is more complete. You need to create later tests manually without "all".

MOVEM zero mask is sort of edge-case but it actually exists in real world, some early crap C(?)-compilers have created it. I have seen it some early Amiga binaries but I don't think it has ever been used to generate/not generate mysterious address errors.

Actually I also didn't know this behavior until tester reported it :)

MVMEL and MVMLE = MOVEM to registers and from registers. Technically they are different instructions and need different label. (Don't ask why those labels, they already existed when I started doing UAE stuff ages ago)

All 70 comments

For reference: CHK.W (N flag is wrong):

Bildschirmfoto 2020-01-05 um 10 27 50

Disk full: you could spread the files on two disks and copy the contents of them to ram: together with the cputester

Then you should be able to start cpu tester from ramdisk

Copy df0: to ram: ALL

😎

Bildschirmfoto 2020-01-05 um 11 20 54

🀀🀀🀀

Disk full: you could spread the files on two disks

Using the RAM disk is a good idea. As I understood, Toni is also working on gzip support for the .dat files. This should solve the issue for most test cases (the dat files are heavily compressible).

Toni has built in gzip support which solves my problem πŸ‘.

Test case ANDSR fits on a single ADF now and runs just fine in vAmiga:

Bildschirmfoto 2020-01-05 um 14 03 41

cputester really pays off. I did expect issues with DIVS and DIVU, but not with LINK 🀭. Apparently, Moira writes a wrong stack frame πŸ™ˆ:

Bildschirmfoto 2020-01-05 um 13 31 13

LINK A7,#something makes no sense but it is still technically valid instruction. Note that different CPU models handle this differently. ("LINK stacked value is saved before SP is decreased by 4. Only affects pointless LINK A7,#x variant. (All models except 68040)" says my notes)

The issue with the LINK instruction was actually a simple one. In my code, I explicitly subtract 4 when register A7 is used:

template<Instr I, Mode M, Size S> void
Moira::execLink(u16 opcode)
{
    int ax   = _____________xxx(opcode);
    i16 disp = (i16)readI<S>();

    push<Long>(readA(ax) - (ax == 7 ? 4 : 0));

    writeA(ax, reg.sp);
    reg.sp += (i32)disp;

    prefetch<LAST_BUS_CYCLE>();
}

I did this, because I reimplemented what I saw in PiCiJi’s portable68000/Denise emulator. He implemented it that way.

I’ll let him know that this is wrong. A7 needs to be handled just as every other register.

And indeed. Changing line

push<Long>(readA(ax) - (ax == 7 ? 4 : 0));

to

push<Long>(readA(ax));

fixes the issue 😎.

Bildschirmfoto 2020-01-05 um 15 03 07

Finally. I've run all tests by now πŸ₯΅.

Unexpectedly, Moira only has a very few issues left:

  • ANDSR.B πŸ˜• Needs a 1.44MB disk (zip files too large)
  • BSR.W πŸ˜• Needs a 1.44MB disk (zip files too large)
  • DIVS.W 😫 FAIL
  • DIVU.W 😫 FAIL
  • EORSR.W πŸ˜• Needs a 1.44MB disk (zip files too large)
  • ORSR.W πŸ˜• Needs a 1.44MB disk (zip files too large)
  • Scc.B πŸ˜• Needs a 1.44MB disk (zip files too large)

Assuming that the five untested test suits pass, only the DIV command has issues (which should be easy to fix) πŸ˜ƒ.

Regarding the five too large test cases, I can split Scc.B into 8 separate ones (one for the 8 possible addressing modes). The others can’t be split, because they use a single addressing mode. I’ll run them inside the RAM disk tomorrow (after reading in the files from different disks). Maybe I should really add support for 1.44MB drives which would solve the issue, too. Hard-drive support is difficult I guess, so I better keep my hands away from this for the moment.

Time for a beer 🍺 …

I added quick and dirty extra option: askifmissing. if it is enabled and xxxx.dat file is not found, it asks for path and retries. Note that because there is no "this is really the last file" marker (at least not yet), it will also ask for new path even if there is no more files remaining. Empty path = exit.

Ah clever, that means when cputester reports about the missing file, dirk can swap disks in the background ... hehe😏

I appended askifmissing=1 to the end of my .ini file, but it didn’t ask me for a path. πŸ€”

What about adding something like a path variable instead of askifmissing? If a file isn't found relative to the current directory, cputester could try again by searching in path.

Anyway, I was stupid yesterday. I simply had to reduce the number of test runs from 2 to 1 to make the (zipped) test cases fit onto a single ADF πŸ™„.

I have also seperated Scc into multiple test cases by splitting them w.r.t. the applied addressing mode. By doing this, I noticed that cputester didn’t generate test cases for the PC-relative addressing modes PC16 and PC8r. Is this a bug?

askifmissing is m68k test program command line parameter ("cputest instruction.x askifmissing"). It has nothing to do with generating tests.

Scc does not support PC16/PC8r variants. (ILLEGAL test includes these)

Meanwhile DIVU and DIVS are passed, too. This means that Moira passes 100% of all tests by now πŸ₯³.

Bildschirmfoto 2020-01-06 um 12 28 00

Overall I think this is a shining example of the strength of open source software. With the existence and free availability of Musashi, portable68000 and cputester I was able to implement a working 68000 CPU within weeks. I am amazed myself about this short development time.

Next step: I will further clean up Moira and put it into a public repo on Github. Maybe others can benefit from this as well.

Thanks to everyone who helped me with this!!!

Nice. Next step is trace :)

btw, I added optional automatic gzip compression support to test generator. (Binary not yet available, need to do some testing first because of cpu emulation related changes)

πŸ™‹πŸ»β€β™€οΈToni, what does "next step is trace" mean ?

Two other aspects for the test of an CPU Emulation come to my mind ...

  • first instruction total cycle length and

  • second the bus cycle length of the intermediate read/write DMA-bus access of an instruction.

Do you maybe also have an idea or hint about this ? πŸ€“

I read this in your description text for cputester

Instruction cycle order or timing is ignored. It is not possible without extra hardware.

Currently my understanding is that it is still possible to test the first aspect with software πŸ€— as dirk did already here but the second aspect the intermediate bus access is extremely difficult to test 🀒 with software alone, ... see some thoughts here where dirk also thinks it is hardly doable in a fine grained way (search for "intermediate bus access") Maybe only possible with a thing like a logic analyser πŸ₯΄?

Trace as in Trace mode (SR T-bit). Many protections use it ("trace vector decoder") and not all cracks remove it.

Getting accurate cycle length is not possible (almost correct should be possible) in real world. Only way is to use logic analyzer (I used logic analyzer to implement accurate timing over 10 years ago or so). Another possibility is to analyze recently released fx cast core which is based on 68000 microcode. (But then you probably hardwire your emulation to 68000 only. Which can also be valid choice.)

But in my opinion instruction cycle count length can be only used to check that instruction is not totally wrong in emulation, using it to do regression testing. Order of memory accesses and positions of any possible "idle" cycles are very important because it will affect timing greatly if CPU is accessing chip ram and Agnus DMA is also active. Instruction cycle count results without any DMA contention might look nice and match documentation but don't have much common with real world situation.

Trace as in Trace mode (SR T-bit). Many protections use it ("trace vector decoder")

That's good to know. I formerly thought that the trace functionality was only used for hardware debugging. I'll put trace support on my TODO list 🀀.

Nice. Next step is trace :)

vAmiga until yesterday: 😲
Bildschirmfoto 2020-01-10 um 14 51 35

vAmiga today: πŸ₯³
Bildschirmfoto 2020-01-10 um 15 06 12
I have to admit that I didn't run all tests πŸ™„. Just a single one: OR.W with feature_sr_mask=0xa000.

I recommend also testing SR modifying instructions. (ANDSR/ORSR/EORSR,MOVE to SR,STOP,RTE).

btw, cycle count mode is coming soon. I thought it wasn't possible to have accurate enough cycle counting without custom hardware. I was wrong.

I recommend also testing SR modifying instructions.

Thanks, I will πŸ‘.

btw, cycle count mode is coming soon. I thought it wasn't possible to have accurate enough cycle counting without custom hardware. I was wrong.

cputester is already a great tool, but this one is gonna be a killer feature. I'm looking forward to get my hands on the new version 🀀.

Hi Toni,

I just downloaded the latest cputester revision (using the link on the first page of the EAB thread).

When I run it in my Windows VM, it crashes after printing the parsed options:

Bildschirmfoto 2020-01-18 um 11 31 37

If needed, I can upload the .ini file.

Does default unmodified ini also crash? Does any more log files appear if you replace mode=all with mode=or.l ? (or set verbose=2)

Default .ini file works.

It crashes when I comment out test_low_memory_start and test_low_memory_end

; Low address space limits. Real hardware must have RAM in this space. Comment out to disable.
; Start should be zero if Amiga, set to 0x0800 if Atari ST.
; Must be disabled if cycle counting, cycle count tests must only access real Fast RAM.
;test_low_memory_start=0x0000
;test_low_memory_end=0x8000

I can't duplicate it but I'll debug it more later today. It isn't that important because you need to disable "low memory" anyway if you want correct cycle count results.

EDIT: Oops, I read it the wrong way (works if disabled), now I can duiplicate it :)

Should be fixed now.

In the latest revision, cputester seems to ignore my modesetting.

My config files has

; mnemonics separated by comma or all/fall.
; all = generate all CPU tests. tst = generate tst.b, tst.w and tst.l. tst.l = generate only tst.l
; fall = generate all FPU tests.
; branch = all branch instructions (branchj = non-stack only, branchs = stack using)
mode=and

but it generates tests for all instructions.

Do I have to enable cycle count checking explicitly or is it enabled by default? I haven't found an option for that.

I've also noticed that the new .ini file comes with various default settings such as

[test=IRQ]
enabled=0
mode=nop,ext,swap
feature_interrupts=1

How can I tell cputester to use one of these settings? πŸ€”

Cycle count is always enabled if 68000 (or 68010 but results are useless). m68k test program has option to either ignore included cycle counts (default) or enable it (-cycles)

Ini structure has changed, [cputest] section does not anymore generate anything. Only [test=] generate tests. Enabled=0: don't generate tests (This makes it easy to have multiple "profiles" in same ini). Changed it to enabled=1 and you'll get 68000_IRQ directory containing test data.

"Default" test is the one that m68k tester runs by default. Other test sets/groups/profiles (whatever you want to call them) need cputest < test group name >/< name of instruction or all >.

Ini structure has changed...

OK, got it.

Now, I am experiencing another problem. I created tests for TST.W, but they fails in both UAE and vAmiga. I guess it has something to do with test generation and not with the emulators.

Bildschirmfoto 2020-01-18 um 13 49 55

What I did is to shrink the test memory size to

test_memory_size=0x40000

in the .ini file to make the test case fit on a single ADF. Could it be related to that or do you think it is something else?

Do you also use new m68k tester from updated archive? I got similar problems earlier today but I can't duplicate them anymore. Please redownload and try again (also double check file date has changed because site commonly returns cached data if downloaded soon after upload)

Same problem. I downloaded the latest version from:

http://www.winuae.net/files/b/cputester.7z

File time stamps:

-rw-r--r--@   1 hoff  staff   107884 18 Jan 14:31 cputest
-rw-r--r--@   1 hoff  staff  2066432 18 Jan 14:29 cputestgen.exe
-rw-r--r--@   1 hoff  staff     6907 18 Jan 10:32 cputestgen.ini
drwxr-xr-x@   2 hoff  staff       64  8 Sep 17:12 data
-rw-r--r--@   1 hoff  staff     7547 18 Jan 10:53 readme.txt

Here is the full config file I used:

[cputest]

; CPU model (68000, 68020, 68030, 68040 or 68060).
; Always select 68020 when testing FPU instructions, even if test hardware CPU is 68040 or 68060.
cpu=68000

; CPU address space. 24-bit or 32-bit. If 24-bit, tester will assume upper 8-bits of addresses gets ignored.
cpu_address_space=24

; FPU model (empty string or 0, 68881, 68882, 68040, 68060)
; Enable only when testing FPU. Enabled FPU mode will slow down native test execution even when not testing FPU instructions.
fpu=

; Write generated instructions to standard output. Always disabled in "all" mode.
verbose=0

; Where to generate test files
path=data/

; gzip compression
; 0 = do not compress
; 1 = compress only test data files
; 2 = compress only main data files
; 3 = compress all data files
feature_gzip=0

; Low address space limits. Real hardware must have RAM in this space. Comment out to disable.
; Start should be zero if Amiga, set to 0x0800 if Atari ST.
; Must be disabled if cycle counting, cycle count tests must only access real Fast RAM.
; test_low_memory_start=0x0000
; test_low_memory_end=0x8000

; High address space limits (0x00ff8000 to 0x01000000 is complete space if 24-bit). Comment out to disable.
; Automatically disabled if 32-bit CPU and end == 0x01000000
test_high_memory_start=0x00ff8000
test_high_memory_end=0x01000000

; ROM high address space. High memory is only used for read tests, uses last 32k of ROM image file.
; high_rom=D:\amiga\roms\Kickstart v3.1 rev 40.63 (1993)(Commodore)(A500-A600-A2000)[!].rom

; main test memory start and size (real hardware must have RAM in this address space)
test_memory_start=0x860000
;test_memory_start=0x68800000
;test_memory_start=0x07800000
;test_memory_start=0x340000
;test_memory_size=0xa0000
test_memory_size=0x40000

; address where test instructions are located
; if not defined: mid point of test memory
opcode_memory_start=0x87ffa0

; number of test rounds
; registers are re-randomized after each round if not in target ea mode.
test_rounds=2

; test word or long odd data access address errors (68000/010 only)
; 0 = do not generate address errors
; 1 = include address errors
; 2 = only generate test instructions that generate address errors
feature_exception3_data=0

; test branches to odd addresses
; same options as above
feature_exception3_instruction=0

; Use static effective address instead of random EA.
; Multiple values supported (max 8), separated by commas.
; Useful for bus error and address error testing
; Disables above exception3 modes.
; If odd value and 68000/010: skip all tests that don't cause address error
; Supports 68000 addressing modes only.
; If instruction only has destination EA, source Areg, Dreg or immediate is generated.
feature_target_src_ea=
feature_target_dst_ea=

; addresses where test instruction is located, use for bus error prefetch testing
; automatically enables RP bus error mode, data read bus errors are skipped.
;feature_target_opcode_offset=90,92,94,96,98,100,102,104

; Memory region that generates bus error (both read and write).
; Must be inside any test memory region.
; Can be used to verify bus errors if ea above is inside this memory region.
feature_safe_memory_start=
feature_safe_memory_size=
; R = data read only bus error
; W = data write only bus error
; P = prefetch bus error
; empty or RWP = both.
; if enabled, all tests that don't generate matching bus error are skipped.
feature_safe_memory_mode=

; user stack modes
; 0 = normal even stack
; 1 = odd stack (original stack + 1)
; 2 = odd stack and skip all tests that didn't generate address error exception
; 3 = take stack from feature_target_opcode_offset
feature_usp=0

; exception vector bus error/address error test
; 0: normal
; non-zero: replace exception vectors with this value (except vectors 2 and 3)
;feature_exception_vectors=0x0007321

; CCR/FPU status flags mode
; 0 = all combinations (32 CCR loops, 256 FPU loops)
; 1 = all zeros and all ones only (2 CCR loops, 32 FPU loops)
; Xcc type instruction (Bcc, DBcc etc) always forces all combinations mode
feature_flags_mode=1

; SR min interrupt mask
; Amiga: can be zero.
; Atari ST: should be 4 or larger.
; Skips all tests that would set lower interrupt mask.
feature_min_interrupt_mask=0

; Interrupt test
; If enabled, interrupt request is set before test.
; Tests all INTREQ bits one by one. Compatible with cycle count mode.
; Amiga only
feature_interrupts=0

; SR extra mask.
; 0x8000 = T1
; 0x4000 = T0 (68020-68040)
; 0x2000 = S
; 0x1000 = M (68020-68060)
; Other bits are ignored.
; For example 0xa000 adds 3 extra test rounds: S=1/T1=0, S=0/T1=1 and S=1/T1=1
; For example 0x8000 adds 1 extra test round: T1=1
; Note: instructions that generate privilege violation exception will automatically add extra S=1 round.
feature_sr_mask=0x0000

; generate loop test: label: <test instruction> dbf dn,label
; value: 0 = disabled, >0 = number of loops
feature_loop_mode=0
feature_loop_mode_register=7

; 68020+ addressing modes (this makes test files much larger if other addressing modes are also enabled)
; currently does not generate any reserved mode bit combinations.
feature_full_extension_format=0

; empty = all addressing modes (feature_full_extension_format=1 enables 68020+ modes)
; Dreg, Areg, Aind, Aipi, Apdi, Ad16, PC16, Ad8r, PC8r, absw, absl, imm.
; Ad8rf and PC8rf = 68020+ full extension only. For example "Aind,Aipi,imm"
; Note: FPU source EA is considered destination EA.
feature_addressing_modes_src=
feature_addressing_modes_dst=

; Limit test instruction size
; B = byte, W = word, L = long, empty = no size limit
feature_instruction_size=

; mnemonics separated by comma or all/fall.
; all = generate all CPU tests. tst = generate tst.b, tst.w and tst.l. tst.l = generate only tst.l
; fall = generate all FPU tests.
; branch = all branch instructions (branchj = non-stack only, branchs = stack using)
mode=

; test groups
; use key=* to restore default value

[test=Default]
enabled=1
mode=tst.w

[test=IRQ]
enabled=0
mode=nop,ext,swap
feature_interrupts=1

[test=AE_SRC]
enabled=0
feature_target_src_ea=0x87fff1,0x7111
feature_target_dst_ea=
mode=all

[test=AE_DST]
enabled=0
feature_target_src_ea=
feature_target_dst_ea=0x87fff1,0x7111
mode=all

[test=BERR_SRC]
enabled=0
feature_safe_memory_start=0x880000
feature_safe_memory_size=0x80000
feature_safe_memory_mode=R
feature_target_src_ea=0x87fffc,0x87fffd,0x87fffe,0x87ffff,0x880000,0x880001,0x880002,0x880003,0x880004
feature_target_dst_ea=
mode=all

[test=BERR_DST]
enabled=0
feature_safe_memory_start=0x880000
feature_safe_memory_size=0x80000
feature_safe_memory_mode=R
feature_target_src_ea=
feature_target_dst_ea=0x87fffc,0x87fffd,0x87fffe,0x87ffff,0x880000,0x880001,0x880002,0x880003,0x880004
mode=all

Your ini marks "high memory" as RAM which probably isn't true (it is KS ROM space normally). Either comment it out or add matching ROM image.

Archive also updated, generator got stuck if both low and high ram was disabled.

Your ini marks "high memory" as RAM which probably isn't true

Yes, that wasn't true. Commenting test_high_memory_xxx out does the trick.

Now, the test passes in UAE and vAmiga:

Bildschirmfoto 2020-01-18 um 16 53 34

To verify, I did introduce a timing error into my CPU emulation code:

template<Instr I, Mode M, Size S> void
Moira::execTst(u16 opcode)
{
    int rg = _____________xxx(opcode);

    u32 ea, data;
    if (!readOp<M,S>(rg, ea, data)) return;

    reg.sr.n = NBIT<S>(data);
    reg.sr.z = ZERO<S>(data);
    reg.sr.v = 0;
    reg.sr.c = 0;

    sync(4);
    prefetch<LAST_BUS_CYCLE>();
}

The sync(4) causes 4 extra cycles that are wrong. Unfortunately, the test still passes in vAmiga. But it should fail now, shouldn't it?

Did you have -cycles command line parameter? Cycle counting is not enabled by default (it would be quite annoying). It is listed in cputest help output.

Did you have -cycles command line parameter?

Nope πŸ™„

One more note: currently reported expected cycle count is total of following: test instruction + possible nop + illegal instruction. Which is a bit confusing but it is side-effect how tester works. All tests end to some exception and exception stacking needs to be cycle counted.

OK, I'm making progress... step by step... cycle counting is now enabled...

But the test, as I have created it, passes neither in vAmiga nor in UAE:

UAE: 🀭

Bildschirmfoto 2020-01-18 um 17 28 34

vAmiga (1st run): 😲

Bildschirmfoto 2020-01-18 um 17 30 22

vAmiga (2nd run): 😳

Bildschirmfoto 2020-01-18 um 17 31 07

Some relativistic time dilation effect maybe πŸ€”.

Hint: DFF006 needs to be accurate. Value in parenthesis has following structure: xxxxyyyy zzzzzzzz. x = DFF006.W when test started. yyyy = DFF006.W test end. zzzzzzz = DFF004.L before test started, slightly before DFF006.W was read. (This is needed to detect possible vertical wrap around). Note that first is XX01.

Technical reason: when DFF006.W horizontal position is 0 or 1 (actually 1 can't be read because it is
refresh cycle but it won't cause problems here), vertical part contains previous line value. Vertical is increased when hpos becomes 2. This is not documented.

System must be PAL. NTSC is not supported.

btw, that there are about 6 instructions that also need to be 100% accurate (check readme.txt) because DFF006.W read can't be immediately before/after or it would mess up CCR contents.

I can't duplicate WinUAE difference (tested using last official version)

Hint: DFF006 needs to be accurate.

OK, that explains the negative cycle count in vAmiga.

I can't duplicate WinUAE difference (tested using last official version)

Strange. When I run it again, I get a similar error, but not the same error:

Bildschirmfoto 2020-01-18 um 17 28 34

Here is the config I was using:

Bildschirmfoto 2020-01-18 um 17 57 43
Bildschirmfoto 2020-01-18 um 17 58 13
Bildschirmfoto 2020-01-18 um 17 58 33

Ah, there is chance tester itself gets loaded to "slow ram" which would mess up timing (Agnus DMA is disabled during tests but chip ram refresh can still steal cycles). Under KS 1.x $c00000 RAM has higher priority than real fast ram.

Ah, there is chance tester itself gets loaded to "slow ram" which would mess up timing

Yes, this is likely to happed. I start cputester from a bootable disk in s/startup-sequence. Can I force AmigaDos to load cputester into FastRam when the disk boots?

Why not just disable slow ram completely? (chip ram + 8M fast ram only) Or use fastmemfirst in WB disk but I don't think it is worth the trouble..

Why not just disable slow ram completely?

Mission accomplished πŸ₯³. With SlowRam disabled, the tests runs just fine in UAE:

Bildschirmfoto 2020-01-18 um 18 34 20

I am curious to see how vAmiga will perform. Obviously, I need to fix VHPOSR first...

You can also "cheat": implement word size register somewhere in memory space that counts cpu cycles and call cputester with -cyclecnt

(for example -cyclecnt 0xf00000 if cyclecouter is located at 0xf00000), this replaces use of dff006. Address must have normal fast ram access timing.

btw, cputester small update: reported cycle count is now separated in to instruction part and exception part.

Making progress...

Test case TST.W with the old version of vAmiga (v0.55, faulty VPOSR):

Bildschirmfoto 2020-01-19 um 10 04 49

Test case TST.W with the latest and greatest code changes 😎:

Bildschirmfoto 2020-01-19 um 10 03 07

All I had to do was to fix the implementation of Agnus::peekVHPOSR() according to your remarks above:

Agnus::peekVHPOSR()
{
    // 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
    // V7 V6 V5 V4 V3 V2 V1 V0 H8 H7 H6 H5 H4 H3 H2 H1

    if (pos.h > 1)
        return BEAM(pos.v, pos.h) & 0xFFFF;

   if (pos.v == 0)
       return BEAM(isLongFrame() ? 312 : 313, pos.h) & 0xFFFF;

    return BEAM(pos.v - 1, pos.h) & 0xFFFF;
}

Next step will be to test the other instructions as well...

Excellent tool 😎. It just told me that I've got a timing problem in MOVE <ea>,SR.

Bcc.b and Bcc.w are good though.

Now I'm getting into trouble interpreting the result:

Bildschirmfoto 2020-01-19 um 13 54 16

I understand that vAmiga is consuming too many cycles here, but how exactly do I have to interpret the numbers written in parenthesis (46+34)?

Update: vAmiga triggers an unexpected trace exception here.

Does same test pass without -cycles?

(x + y) means: y = cycles taken by "exit" exception. x = cycles taken by test instruction(s).

It probably is trace related (moving #$ffff to SR), trace not getting disabled when illegal instruction starts (some exceptions clear it). Trace is a special case in cycle counting, whatever exception comes first will stop cycle counting. Most likely illegal instruction was generated (as expected) and then trace started immediately (which is not correct in this situation).

It probably is trace related

Yes, it's trace related. I've generated another test case with trace flag / supervisor flag settings and ignored cycle counting. The test fails, because the wrong exception is executed in vAmiga. Instead of triggering a privilege violation, it triggered a trace exception.

trace not getting disabled when illegal instruction starts

Nailed it. I did clear the trace flag, but I didn't clear the internal action flag which is used to trigger the trace exception handler at the right time.

Thank you so much for all the good advice. That saved me a lot of debugging time πŸ‘.

Bildschirmfoto 2020-01-19 um 16 37 37

Hi Toni,

I just computed tests for the TRAP instruction with T flag enabled. In UAE, I get the following error:

Bildschirmfoto 2020-01-20 um 23 14 34

Do you have an idea what could go wrong here?

It is tester bug, it seems some exception + trace combinations don't work correctly yet.

Fix will need to wait because currently I am adding 68010 cycle count support and there are some non-trivial changes needed to support it properly.

Fix will need to wait

No worries. I'll be busy for a while testing the other instructions. BTW, vAmiga displays the exact same error as UAE which I interpret as a good sign. And if cycle checkin is disabled, the test passes (which is definitely a good sign).

There is also an issue with the test of the JMP instruction (with and without cycle counting). I get an error in UAE when the supervisor flag is set:

Bildschirmfoto 2020-01-22 um 15 56 14

Oups, I now got an "ahist overflow" 🀭

Bildschirmfoto 2020-01-22 um 17 01 58

maybe just an overwhelming overflow of stunning, compelling, cool, new and modern testing stuff which is constantly being added by toni to cputester, breaking with everything which the world has seen before 🀀🀀🀀... see definition of ahistorical

It's the MVMLE.L instruction. The overflow also happens if this test is created alone.

Very cool 😎. cputester showed me that my MOVEP implementation is wrong. Moira falsely triggered an address error when an odd address was given.

Same for MOVEM. Moira always triggered an address error when an odd address was specified. But the address error does not trigger if the register mask is 0 (I never thought about the case somebody could (theoretically) use this command with a zero 0 reg mask, because it doesn't make sense).

It's the MVMLE.L instruction. The overflow also happens if this test is created alone.

what a strange instruction I never have seen it ... I wonder how many of these seldom seen instructions are actually being used by compilers when they compile to asm. I bet they only use a subset of all possible instructions. Is this the difference between RISC and CISC processors? CISC processors developers tend to invent special seldom used instructions. Maybe they had in mind to substitute a code sequence of the more common instructions in order to save some memory space ??? πŸ€”

MOVEM has also previously used too many "history" entries. I'll also check it after 68010 stuff is more complete. You need to create later tests manually without "all".

MOVEM zero mask is sort of edge-case but it actually exists in real world, some early crap C(?)-compilers have created it. I have seen it some early Amiga binaries but I don't think it has ever been used to generate/not generate mysterious address errors.

Actually I also didn't know this behavior until tester reported it :)

MVMEL and MVMLE = MOVEM to registers and from registers. Technically they are different instructions and need different label. (Don't ask why those labels, they already existed when I started doing UAE stuff ages ago)

Interesting. The Motorola ref manual states that only bits 0 - 4 have a meaning in the lowest word of the address error exception stack frame.

Bildschirmfoto 2020-01-23 um 10 26 03

Apparently, this is not the case. For two different test cases, the expected value is $4ed2 and $4ef2, respectively:

Bildschirmfoto 2020-01-23 um 10 16 12

Bildschirmfoto 2020-01-23 um 10 20 32

Both values differ in bit 5, so this bit must have a meaning, too. Some undocumented feature of the M68000? πŸ€”

This should be the place where UAE computes the "mystery word" located at the lowest stack frame address.

        if (nr == 2 || nr == 3) {
            // 68000 address error
            uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
            mode |= last_writeaccess_for_exception_3 ? 0 : 16;
            mode |= last_notinstruction_for_exception_3 ? 8 : 0;
            // undocumented bits seem to contain opcode
            mode |= last_op_for_exception_3 & ~31;

So it seems that a part of the opcode shows up in the upper bits (5 - 15). Uhhhh, who could have expected that? 🀭

Address error frame is full of undocumented behaviors.. I/N bit don't always work as documented, opcode field sometimes contain current, sometimes next opcode and probably more..

But as I said previously, no one cares. Except tester :)

opcode field sometimes contain current, sometimes next opcode

Hmm, yes, I just stumbled across this:

Bildschirmfoto 2020-01-23 um 15 27 31

I think I jeopardise my plan to make address error handling 100% correct and move on... since it's not really relevant to Amiga emulation, it really doesn't seem to be worth the effort.

UAE shows a cycle mismatch when testing the JMP instruction in combination with address errors and cycle counting:

Bildschirmfoto 2020-01-24 um 06 52 43

I already checked the mem config: 512 KB Chip + 0 KB Slow + 8 MB Fast

Yeah, it is already known and fixed. JMP and JSR EA calculation is a special case (no normal prefetches) and EA calculation time was done after address error check.

After doing some top-level GUI refinements, I am finally back at cycle counting 🀀.

I am having some weird issue with the latest cputester version though (I guess my configuration is wrong, but I don't know why). My problem is that I cannot get cputester to run if SlowRam is disabled. Running with SlowRam enabled, it runs just fine:

Bildschirmfoto 2020-04-13 um 11 17 01

But with SlowRam disabled, it eventually freezes. I don't know why this happens, because (I think) I configured it to place the tests in FastRam, only πŸ€”. Here are the relevant parts of my config:

test_memory_start=0x860000
test_memory_size=0x40000
opcode_memory_start=0x87ffa0

[test=Default]
enabled=1
test_rounds=2
mode=jmp

I am running UAE 4.3.0 with Chip = 512KB, Slow = 0KB, Fast = 8MB

Found it. It was an issue with my script that didn't update the ADF properly...

Now I am running into issue with the JMP instruction again. With latest cputester, it still fails in UAE when address errors are combined with cycle count checking:

Bildschirmfoto 2020-04-13 um 11 53 22

Mem config: 512 KB Chip + 0 KB Slow + 8 MB Fast

Yeah, it is already known and fixed. JMP and JSR EA calculation is a special case (no normal prefetches) and EA calculation time was done after address error check.

Ist the fix part of cputester or part of UAE? In the latter case, it's clear that the test fails, because 4.3.0 came out earlier.

It is UAE fix.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dirkwhoffmann picture dirkwhoffmann  Β·  3Comments

dirkwhoffmann picture dirkwhoffmann  Β·  3Comments

emoon picture emoon  Β·  4Comments

dirkwhoffmann picture dirkwhoffmann  Β·  3Comments

Gianmarco72 picture Gianmarco72  Β·  4Comments