TL;DR Original developers of the core: Is some newer version of ao486_tool to generate autogen directory available ? I have trouble generating same content with tool from Aleksander's original repo.
Now to the actual saga. I love hacking into ao486 core. More and more I am going through the code, more respect I have to all the people who made this possible (Aleksander, Alexey, Robert and more). Because there is still some odd behaviour and compatibility problems, I thought it would be best not to complain, but to actually iron out some issues that exists with running certain programs. At first, I was to check how the CPU is detected by various programs. We do have 486, and we do have 486SX2 / 50 in CPUID code (045Bh). The trouble is, CPUID instruction was introduced fairly late, and majority of 486 processors do not have it. As such, there are a lot of programs, which either do not use CPUID instruction at all, or expect only valid output, as they have hardcoded vendor IDs. I selected memtest86+ v4.10 as demonstration of a not working program. If you run memtest86+ 4.10 on current core, you get this:
A completely not working program, which fails to even show what CPU it detected.
How is the usual (simplified) order of things to detect a CPU and its features on our FPGA CPU with program which uses CPUID ?
1) detect 486
2) detect if CPUID instruction is available (try to toggle ID bit in EFLAGS)
3) we have it ? good, use CPUID to get "MiSTer AO486" as a vendor ID (use CPUID instruction and get vendor string from EBX, EDX and ECX)
Now, if I wanted to change "MiSTer AO486" to "GenuineIntel" or "AuthenticAMD" or "CyrixInstead" or any other vendor ID, I need to modify CMD_CPUID.txt and generate autogen directory. I did some digging, the only thing which differs between original ao486 repo and ao486_MiSTer is this:
Code: Select all
diff ao486/rtl/ao486/commands/CMD_CPUID.txt ao486_MiSTer/rtl/ao486/commands/CMD_CPUID.txt 37,38c37,38 < SAVE(ebx, "ineG"); < SAVE(edx, "Aenu"); --- SAVE(ebx, "TSiM"); SAVE(edx, "A re"); diff ao486/rtl/ao486/commands/CMD_INVD.txt ao486_MiSTer/rtl/ao486/commands/CMD_INVD.txt 40c40 < always @(posedge clk or negedge rst_n) begin --- always @(posedge clk) begin 47c47 < always @(posedge clk or negedge rst_n) begin --- always @(posedge clk) begin diff ao486/rtl/ao486/commands/CMD_task_switch.txt ao486_MiSTer/rtl/ao486/commands/CMD_task_switch.txt 158c158 < always @(posedge clk or negedge rst_n) begin --- always @(posedge clk) begin 660c660 < always @(posedge clk or negedge rst_n) begin --- always @(posedge clk) begin diff ao486/rtl/ao486/commands/CMD_WBINVD.txt ao486_MiSTer/rtl/ao486/commands/CMD_WBINVD.txt 41c41 < always @(posedge clk or negedge rst_n) begin --- always @(posedge clk) begin 48c48 < always @(posedge clk or negedge rst_n) begin --- always @(posedge clk) begin
There are some minor changes only, one being change of CPUID vendor string from "GeniuneAO486" to "MiSTer AO486". At first, I tried to generate autogen directory with original sources, and used ao486_tool from original repo. It produced completely different output ! This made me wonder, what was the original files used to generate autogen, and if there is newer ao486_tool available somewhere. I changed it to "GenuineIntel", used ao486_tool from original repo and produced changed autogen directory anyway. I compiled it, and was pleasently surprised, because the core was working. Now what would happen if we run previously not working memtest86+ 4.10 with only change being vendor id "MiSTer AO486" to "GenuineIntel" ?
Oh look ! It works ! Not only it works, it correctly reads 045Bh and decode it as Intel 486SX2. What others programs say now ?
We no longer have Unknown CPU Vendor and model from chkcpu. Programs using CPUID should be fine now...
But CPUID instruction was introduced with Pentium and newer models of 486 right ? That means, all Pentium's had CPUID instruction, but not all 486 had CPUID instruction, and there is a lot of software, which do not even know, what CPUID instruction is. What is detected, if we disable CPUID detection ?
That was easy one - change behaviour of ID flag in EFLAGS register in verilog code, and remove CPUID instruction from the core. Recompile, and we are here:
Memtest is working (good), but displays Cyrix ??? as a CPU ? For that, there is a very good explanation. Before CPUID, you had to resort to CPU odd behaviour, which could differ between different vendors of 486 CPUs. Our FPGA CPU is detected as Cyrix, because detection routine try to do a 5 by 2 divison using DIV instruction and gets correct result with EFLAGS unaffected. The thing is, original Intel and AMD CPUs, against instruction set description, actually do modify some of EFLAGS. If they do, every CPU detection routine get this 486 as original Intel or AMD. But because AO486 core is correct, and does not modify EFLAGS, it is tagged as Cyrix.
The bad thing is, if you are on Cyrix, you certainly should have DIR0 and DIR1 registers, which stores Cyrix CPU ID information. So if programs detect they are on Cyrix, they expect you to have these registers. And our FPGA CPU does not have it. If programs are checking if DIR0 and DIR1 are available and are not, they identify it as a very rare Cyrix or TI 486 variant without DIR registers. If the programs try to use some Cyrix specific behaviour instructuion, it simply fails. What other programs say about this non-CPUID 486 ?
This is what programs see, if they were old enough to not know about CPUID instruction.
This is where I will end this. I am including RBF which have CPUID changed to GenuineIntel, so you can test, if your program, which was not previously running is now OK. I am mainly writing this, because I would like to dig more into 486 odd behaviour, and was wondering if there is some newer version of ao486_tool so I can generate consistent autogen directory in ao486 source. Is it possible to commit current ao486_tool to ao486_MiSTer git directory ?
Thank you for your reading