dirkwhoffmann / vAmiga

vAmiga is a user-friendly Amiga 500, 1000, 2000 emulator for macOS
https://dirkwhoffmann.github.io/vAmiga
Other
293 stars 24 forks source link

How to pretend being a 68EC030? #730

Closed dirkwhoffmann closed 1 year ago

dirkwhoffmann commented 1 year ago

I understand that the only differences between the 020 and 030 are not in the instruction set but in the MMU which is not useful in emulation, and data cache + burst mode which probably add nothing much in performance either in emulation, so could it be possible to have a 030 setting that would be identical to the 020 emulation save for the identification bits? So that Settlers can have map size to 8...

Originally posted by @Vweber73 in https://github.com/dirkwhoffmann/vAmiga/issues/728#issuecomment-1215777166

dirkwhoffmann commented 1 year ago

After comparing specs, I though my 68020 should be recognized as a 68EC030 if the CALLM and RETM instructions are removed. However, this is not the case. Systest still reports a 68EC020.

I've also tried WhichAmiga.exe.zip which is capable to distinguish between the 68030 and the 68EC030. However, it also reports a 020:

Bildschirmfoto 2022-08-16 um 08 27 28

Bottom line: Pretending to be a xx030 is not as easy as originally thought.

Vweber73 commented 1 year ago

Thanks for trying! I thought it was only a matter of chip identification bits? Am I mistaken?

nicolasbauw commented 1 year ago

Seems it has something to do with CACRF_WriteAllocate and CACRB_WriteAllocate flags and the cache. Found some info in:

From the 68030 doc, I can read this : The instruction cache control bits in the cache control register (CACR) of the MC68030 are in the identical bit positions as the corresponding bits as the MC68020's CACR. However, the MC68030 has additional control bits for burst enable and data cache control.

EDIT : Looks like whichamiga deducts it's an EC if the AttnFlags says it's a 030 AND testing the MMU (by testing access to 'MMU only regs' and catching illegal instructions by setting a custom Illegal Instruction vector) behaves like there's no MMU. So : the presence of additional flags in CACR AND absence of MMU registers make a 68030 an EC030.

mras0 commented 1 year ago

KS3.1 CPU detection code at $00f80c36 (KS3.1 40.68):

    MOVEQ.L #$00, D0
    MOVEC   D0, VBR
    BSET.L  #AFB_68010, D0
    MOVE.L  #CACRF_EnableI!CACRF_ClearI!CACRF_FreezeD!CACRF_ClearD, D1 ; $0a09
    MOVEC   D1, CACR
    MOVEC   CACR, D1
    BSET.L  #AFB_68020, D0
    BTST.L  #CACRB_FreezeD, D1 ; CACRB_FreezeD=9
    BEQ.B   .Not030
    BSET.L  #AFB_68030, D0
.Not030:

I.e. it tries to set some 030 only cache bits in CACR and the check if they stick (they read as 0 on a 020). So I think you should be able to fool the system into thinking you're an 030 by allowing the relevant CACR bits to be set (See MC68020UM §4.2 and MC68030UM §6.3).

BTW I don't know if there's any (evil) software that require accurate emulation of caches, but be aware that the expansion for ROM the HD controller (and debug board) probably won't work if you start emulating that (without some minor changes).

dirkwhoffmann commented 1 year ago

Ok, I see. CACR does the trick. Here is the relevant code in Musashi:

case 0x002:            /* CACR */
    /* Only EC020 and later have CACR */
    if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
    {
        /* 68030 can write all bits except 5-7, 040 can write all */
        if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
        {
            REG_CACR = REG_DA[(word2 >> 12) & 15];
        }
        else if (CPU_TYPE_IS_030_PLUS(CPU_TYPE))
        {
            REG_CACR = REG_DA[(word2 >> 12) & 15] & 0xff1f;
        }
        else
        {
            REG_CACR = REG_DA[(word2 >> 12) & 15] & 0x0f;
        }
        return;
    }

I'll port this over...

Vweber73 commented 1 year ago

Excellent! This is really appreciated. I actually can't think of any software other that Settlers that requires a 68030 to allow full options... A 68020 with boosted clock should run everything... So we are only doing this for Settlers, thanks a lot! :)

dirkwhoffmann commented 1 year ago

but be aware that the expansion for ROM the HD controller (and debug board) probably won't work if you start emulating that

You mean because a write to one of the special registers won't be recognized any more because it's routed to the cache, right?

mras0 commented 1 year ago

You mean because a write to one of the special registers won't be recognized any more because it's routed to the cache, right?

I was more concerned about the code patching (e.g. modifying the target of library vectors), but looking at it again it's probably not really a concern with 020/030 cache sizes (probably not even 040/060).

Data caches could be an issue, but I think you should be able to handle that by just treating those areas specially (but that's a long term worry).

dirkwhoffmann commented 1 year ago

Now the 68EC030 is recognized as such 😎:

Bildschirmfoto 2022-08-17 um 10 33 15
mithrendal commented 1 year ago

🤩 Wonderful. Can’t wait to leave office space and merge this hot new stuff into the uat version of vAmigaWeb this evening…

Vweber73 commented 1 year ago

Great!!

mras0 commented 1 year ago

Good work! On a pedantic note the implementation is slightly wrong. Bits 2&3 are write only in CACR on a 020 and always read as zero (probably similar issues for 030 but I can't verify on real HW).

I.e. on a real EC020 (tested on my A1200 w/ accelerator disabled):

    moveq #-1,d0
    movec d0,cacr
    movec cacr,d0
    ;d0=$3, in current vAmiga d0=$f
mithrendal commented 1 year ago

merged it into uat version of vAmigaWeb (that one is only meant for testing)

results with selected 68020 whichamiga shows 68020 sysinfo shows 68EC020

results with selected 68030 whichamiga shows 68EC030 sysinfo crashes with a guru !!!

is that maybe because of the slightly wrong implementation which @mras0 mentioned?

Vweber73 commented 1 year ago

Whatever the problem is, it doesn't show up in Settlers, which correctly reports 68030, and max map size of 8 :)

mithrendal commented 1 year ago

then it has something to do with sysinfo .... I tried with different kickstart and with an older version of sysinfo (4.0 instead of 4.4) ... and at least it reports the 68030 now

image

well somehow ;-)

maybe it tries to do additional MMU tests and crashes ?

mras0 commented 1 year ago

maybe it tries to do additional MMU tests and crashes ?

Looks like it. Exception B (11) is Line F (FPU/MMU instruction). In this case it's a PMOVE ($F010). Found this post by Toni on EAB (a different, but related issue):

[...] most 68EC030 CPUs have MMU that is not fully working (68030 with manufacturing error in MMU marked as 68EC030) or it is disabled but MMU instructions will still execute on 68EC030, they may not execute correctly or do anything at all (and in worst case it may simply hang the CPU) but they don't cause any invalid instruction errors. For compatibility purposes emulated no-MMU 68030 has dummy MMU instruction emulation.

Probably not worth emulating if it's only for SysInfo, but if it also causes issues for WHDLoad it might be worth looking more into.

EDIT: As hack adding ________________(0xF010, NOP, MODE_IP, Word, Nop, CIMS) to Moira::createJumpTable makes sysinfo report 68030 with MMU disabled.

dirkwhoffmann commented 1 year ago

Exciting stuff. I had a brief look at the MC68851 users manual. It seems like the following opcodes correspond to MMU instructions:

1111 0000 XXXX XXXX
1111 0001 0XXX XXXX

I think it's best to map all of them to NOP if a 68EC030 is selected.

nicolasbauw commented 1 year ago

I think it's best to map all of them to NOP if a 68EC030 is selected.

According to my previous post, I'm afraid that could cause whichamiga to no longer detect it as an EC030.

dirkwhoffmann commented 1 year ago

According to my previous post, I'm afraid that could cause whichamiga to no longer detect it as an EC030.

Sorry, I missed the edit in your post. So it looks like systest and whichamiga are incompatible. Fixing one of them breaks the other.

mithrendal commented 1 year ago

Overview of current reporting

Running Moira 68020 ->Sysinfo 68EC020 ->Whichamiga 68020

Running Moira 68030 ->Sysinfo 68030 (and crashes) ->Whichamiga 68EC030

both programs report exactly the opposite (EC vs. non-EC) for each cpu. Cool ! Probably sysinfo likes to play something with MMU on non-EC CPUs and crashes …

I would say this is a good test case for pretending a MMU ... but it would be safer still to make both programs think that there is a EC version for all cpus, no?

nicolasbauw commented 1 year ago

Maybe this could help:

The translation control register configures the table lookup mechanism to be used for all table searches as well as the page size and any initial shift of logical address required by the operating system. In addition, this register has an enable bit that enables the MMU.

I don't know how sysinfo checks the MMU, but maybe, if it sees the MMU is disabled by checking this bit, that could be enough for not making it crash.

nicolasbauw commented 1 year ago

Running Moira 68020 ->Sysinfo 68EC020 ->Whichamiga 68020

From the whichamiga source : it differentiates EC and non-EC by checking the address bus width. 32 bits = 68020, 24 bits = 68EC020.

mras0 commented 1 year ago

Looking at the whichamiga source code (specially the .gogo020 part of GetMMU) I think it should be possible to handle it and sysinfo. It actually tries to setup translation tables to check if the MMU is functional. Just letting the instruction ranges Dirk posted act as NOPs makes it report "MMU in use" for me due to this test (if (sp) isn't modified it just reads a semi-random value):

    pmove.l tc,(sp)         Save tc:
    moveq   #-1,d7
    move.l  (sp),d5
    bmi .exitsuper      MMU in use!

Reporting an incorrect result might be OK (it's certainly the easiest), but otherwise having a few special cases might be worth it.

nicolasbauw commented 1 year ago

but it would be safer still to make both programs think that there is a EC version for all cpus, no?

I agree with that, the point of this particular thread is 'pretend being an EC030' after all :-) Faking an MMU with NOPs will not do that. For the EC020, limiting the address bus width should be an easy thing to do.

dirkwhoffmann commented 1 year ago

it differentiates EC and non-EC by checking the address bus width. 32 bits = 68020, 24 bits = 68EC020.

It's this code, isn't it?

_getaddrbits    bsr.b   _getvbr
    move.l  ($08,a0),-(sp)      Save Access Fault vector
    move.l  a0,-(sp)        Save VBR
    lea (.busfailure,pc),a1 Set new Access Fault vector:
    move.l  a1,($08,a0)

    lea AddrChipData,a0     16 byte chip buffer
    move.l  #$BADCAFFE,d1
    move.l  #$DEADBABE,d2
    move.l  #'lOVE',d3
    move.l  #'8biT',d4

    move.w  #256-1-1,d5
    movem.l d1-d4,(a0)
    move.l  a0,a1
.loop   add.l   #$1000000,a1

    moveq   #4-1,d0
    move.l  a0,a2
    move.l  a1,a3
.compare    cmpm.l  (a2)+,(a3)+
    dbne    d0,.compare
    tst.w   d0
    dbpl    d5,.loop

    tst.w   d5
    bpl.b   .exit           Is 32bit

    exg d1,d4
    exg d2,d3
    movem.l d1-d4,(a0)
    movem.l (a1),d5-d6/a4-a5
    movem.l d1-d4,(a1)

    moveq   #4-1,d0
    move.l  a0,a2
    move.l  a1,a3
.compare2   cmpm.l  (a2)+,(a3)+
    dbne    d0,.compare2

    movem.l d5-d6/a4-a5,(a1)

    tst.w   d0
    bmi.b   .exit           Isn't 24bit

    moveq   #24,d7

.exit
.busfproceed    move.l  (sp)+,a0        Restore VBR
    move.l  (sp)+,($08,a0)      Restore Access Fault vector
.xit    move.l  d7,d0
    rts

If I understand it correctly, accessing an address that does not fit into 24 bits causes a bus error?

nicolasbauw commented 1 year ago

Yes, it's this code. And from the specs, the 24-bit bus is indeed a difference between a EC020 and a 020.

dirkwhoffmann commented 1 year ago

Yes, it's this code. And from the specs, the 24-bit bus is indeed a difference between a EC020 and a 020.

What I don't understand is why the code is so complex. Isn't it sufficient to simply read from (or write to) to a real 32-bit address and to check if a bus fault occurs?

I also checked my hardware. I've upgraded one of my machines with a Terrible Fire board a while ago. Originally I thought it contained a 68EC020, but it does contain a real 68030. Hence, I think I won't get bus errors if I address above the 24-bit range on this machine.

alt Logic board

nicolasbauw commented 1 year ago

The 1200 has a EC020. Probably some people here own a 1200 and could do the test (I could, but last fall I had some flood damage at home and had to pack my amigas).

What I don't understand is why the code is so complex. Isn't it sufficient to simply read from (or write to) to a real 32-bit address and to check if a bus fault occurs?

When I saw this code, I was thinking the same thing : why a such complex code 'just' to check that ? There is surely a reason. I did not take the time to fully analyse this.

EDIT : contrary to the 68EC020, the 68EC030 has the full 32 bits address bus.

mras0 commented 1 year ago

On an 68EC020 the 8 most significant bits of the address are just ignored (except when it comes to the instruction cache) like on a 68000. I.e. I can read execbase just fine from $ff000004 (verified on my a1200). It makes sense that an 68EC030 would have all 32 address lines since it's just a 030 with no (or faulty) MMU.

I agree with that, the point of this particular thread is 'pretend being an EC030' after all :-) Faking an MMU with NOPs will not do that.

Found another EAB thread that discusses EC030 identification. My take away from that thread is that it's not in general possible to distinguish a normal 030 from an EC030 purely in software (a mistake that MC corrected with the 040). Arguably it would be correct to just use NOPs (probably taking the effective addressing mode into account) for MMU instructions on EC030, or even halt the CPU if such a instruction was used!

Of course that would not be very useful, and vAmiga users are probably more concerned about existing software working than the emulator being technically correct but useless :)

My suggestion, which I think would work for existing software, would be to properly decode MMU instructions (so something like (a0)+ actually updates a0 for example), but not do anything except for pmove.l tc,EA which should clear EA. Maybe there's a few more things that are required, but that can always be fixed later. AFAIK there isn't that much software out there that pokes the MMU (I may be wrong though). Some examples to check (just off the top of my head):

dirkwhoffmann commented 1 year ago

On an 68EC020 the 8 most significant bits of the address are just ignored

Thanks for checking this!

Overall, it might be easiest to solve the issues by moving a step forward. Musashi has some kind of MMU support which can be ported over without too much effort I think (I haven't looked into the details yet, just browsed the code). After this, we'll have a "real" 68030 which will render the current 68EC030 mode obsolete.

I'll do this after finishing my current cputester work (I'm at letter C now, just managed to fix the CHK instruction).

mras0 commented 1 year ago

Thanks for checking this!

No problem, just @'me if you need something checked on my a1260 (accelerator can be switched off for EC020 stuff but then I can only run checks w/ the basic config i.e. without fast ram).

Overall, it might be easiest to solve the issues by moving a step forward. Musashi has some kind of MMU support which can be ported over without too much effort I think (I haven't looked into the details yet, just browsed the code). After this, we'll have a "real" 68030 which will render the current 68EC030 mode obsolete.

I'll do this after finishing my current cputester work (I'm at letter C now, just managed to fix the CHK instruction).

Cool! Though maybe you want to consider adding basic support for 040/060 while you're at it? Very few instructions were added after 020/030 (mostly it was removing features/integrating MMU/FPU). To be honest I haven't used MMU features much directly, but if MC68851 is very different from 040/60 integrated MMUs I think supporting the latter (and ignoring 030 for now) would be better long term.

Good luck with the CPU tester effort. I saw your EAB post regarding it, but I can't get it to work with the latest version of the WinuUAE source code (got it compiling, but doesn't work), so it's probably best to stick with version you're using.

Vweber73 commented 1 year ago

I was the first one to push for 020 and 030 support, reason being software support:

1) There are some non aga games that require 020 instructions to work, e.g. Dungeon Master 2; 2) Some games offer more features with a 020 or 030 processor, e. g. Settlers will give you max map size 5 with a 68000, 7 with a 020, and 8 with 030 and up, without actually using the extra instructions.

But now we are talking 040/060 emulation (or fake emulation) with MMU support. Might be interesting for the intellectual challenge, but is there any practical interest from a compatibility point of view? I can't think of any game or even software that will give you more features with a 040/060 than with a 030 (other than the clock speed which is not an issue in emulation) , even the 030 is kind of weird for Settlers, a 020 should be enough... As for the MMU, I can't think of a usage for that, apart from running Linux on a emulated Amiga, which sounds completely useless and geeky to me... Plus I understand ready Toni earlier threads that MMU emulation is slow and complex, for almost no benefit at all...

I'm happy with good 68020 (maybe full rather than 68EC020, it might be useful someday to have more than 16MB of RAM and add Z3 memory) and fake 68EC030 emulation (I understand emulating the MMU and data cache has no practical value) and I would rather focus on doing this right than trying to do too many things with no practical value. What do you think?

dirkwhoffmann commented 1 year ago

Good luck with the CPU tester effort. I saw your EAB post regarding it, but I can't get it to work with the latest version of the WinuUAE source code (got it compiling, but doesn't work), so it's probably best to stick with version you're using.

Currently, I am using this toolchain: https://github.com/dirkwhoffmann/vAmigaTS/tree/master/cputester/HDF/tools

cputestgen.exe is a precompiled exe which I downloaded on April, 22, 2022 from the link Toni has posted in his EAB thread. cputest has been compiled locally on my machine (from the latest UAE sources).

Unfortunately, I've never managed to compile UAE in my VM.

dirkwhoffmann commented 1 year ago

Might be interesting for the intellectual challenge, but is there any practical interest from a compatibility point of view?

I understand your point, but I am pursuing a different goal. Musashi (which is one of the mostly used m68k emulation cores) somehow seems to have come to a dead end. There are a couple of pending pull requests in the main repo as well as a lot of unresponded bug reports. Unfortunately, I don’t know of any other m68k core that is as easy to use as Musashi. The UAE core seems to be tightly integrated in UAE which makes it difficult to use in other projects. I think Moira can step in here, especially because it’s not only faster than Musashi, but also more accurate. There is a big difference though: Musashi covers a whole range of processors (68000, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040 an 68040) whereas Moira is restricted to the 68000. Hence, even if 68040 support in Moira doesn’t make that much sense from an Amiga emulation perspective, other communities could benefit from it.

There is another important difference though: Musashi uses a MIT-like license whereas Moira is licensed under the GPL. Since I don’t really care about the copyleft principle here, I am thinking about switching from a GPL license to a MIT license in the future.

Vweber73 commented 1 year ago

Thanks for the exanation, very interesting! I got your point. So maybe also AGA emulation in future?

nicolasbauw commented 1 year ago

Quick note : the EC030 with additional CACR flags and no MMU (which is correctly recognized in whichamiga) does not cause problem with the AmigaOS 3.2.1 showconfig neither.

mras0 commented 1 year ago

Very nice to hear regarding the future of Moira. It already seemed to be going in that direction (hence my comments about considering what 040/060 does), but good to see spelled out. You're doing great work, but obviously there's a bit of way to go for 020+.

Maybe it would make sense to create new issues (perhaps in the Moira repo?) to track progress on different fronts (longword memory access, FPU, MMU, cache emulation, 040+, etc).

Looked more into the topic at hand (EC030), and the 030 (MC68851) MMU really takes the kitchen sink approach. They support a lot of stuff that was abandoned for 040+. Implementing the approach I mentioned earlier (MMU op = nop with EA decoding, execption for PMOVE.L tc,EA => EA=0) works for sysinfo and whichamiga as expected. WHDload doesn't work, but then again it also fails w/ 020 so probably not a MMU issue.

dirkwhoffmann commented 1 year ago

Maybe it would make sense to create new issues (perhaps in the Moira repo?) to track progress on different fronts

Yes, definitely. The Moira repo would be the proper location. Until now, I haven't opened many issues there, because it's kind of a lonely place at the moment.

dirkwhoffmann commented 1 year ago

I took a closer look at the MMU architecture. Main observations:

Bottom line: In a longer term, the following CPU models are worth to be supported in my opinion: 68000, 68010, 68020, 68030, 68040, 68EC020, 68EC030, 68EC040, 68LC040.

dirkwhoffmann commented 1 year ago

Closed as the 030/040 project is put on hold.

For reference: Commit 115f803 ist the last commit containing MMU code.