Closed hak-foo closed 9 months ago
Thank you!
I did a bit of rework to this code, see: https://github.com/skiselev/8088_bios/commit/99e874d2816cfb0c3ea54ddc142a90cfaa1d1762 A few questions and comments:
Let me try to clarify the comments on the V20. When I tested, I saw some of the ports FFF0 and above were letting you write and read back, but not all, so I described it as "scattered". I guess I was interpreting the FDC responding as the CPU. :/
The V40 datasheets define a specific meaning for ports FFF0 and above, even though it appears to accept writes down to FFE0, so I figured these are less likely to be a problem than trying to write to a register that has an intended use.
On the NMI mask, looking at the schematic (https://github.com/homebrew8088/8088-PC-Compatible/blob/main/Schematics/4%20Slot%20Main%20Board.pdf), it seems like it was designed to use bit 5 of port 0x61 (which seems to be I/O check enable on a normal PC) as NMI Enable. Since there's no parity or 8087 support, and it seems like the only thing that actually routes to the NMI circuit is "I/O Check" on the ISA bus, this may be a "cheat" there.
Regarding the RTC, the HB8088 does not have a "official" RTC. I used spark2k06's board, which was apparently intended for the Micro8088, but which was available configured with different port numbers when I ordered it. So I figured it was possible that other people would also have that same RTC, but not at port 0x70. I ordered mine as 2A0, probably because a lot of the XT-era cards used ports above 100 and it "seemed" vacant when I ordered.
Thanks for clarifications!
I am still wondering if there are other ways to detect V40 without poking the I/O ports. There is an old thread here, but I don't see anything but a request to identify V40 CPU: https://forum.vcfed.org/index.php?threads/cpu-fpu-detection-program-routines.27198/
Another thing is here, again, it says that "V40 and V50 detection method is known but not implemented." https://github.com/MobyGamer/TOPBENCH/blob/master/CPU215/DOC/TMI0SDGL.DOC
I am still wondering if there are other ways to detect V40 without poking the I/O ports.
Back decades ago when I worked at Qualitas on 386MAX, we had endless trouble identifying stuff like this, and in particular there were motherboards that controlled the A20 Gate in their own ways. We poked a lot of ports.
One time this resulted in bricking some customer motherboards that had Flash BIOSes, and hadn't fully decoded their I/O ports.
@hak-foo I have a suggestion regarding V40 detection: As I said earlier, since most ISA cards only decode 10 lower bits of the address, so the 0xFFF0-0xFFFF I/O port range would be mapped to the FDC addresses at 0x3F0-0x3F7 and COM1 UART addresses at 0x3F8-0x3FF. With that being said, FDCs normally don't implement port 0x3F6. So perhaps 0xFFF6 port can be used for V40 detection instead of 0xFFE0 . It looks that 0xFFF6 maps to WCY2 register in V40. I think only lower 4 bits of that port are used, so I am not sure if V40 would store all the bits. To be on the safe side, I'd just modify these 4 bits. Something like:
mov dx,0FFF6h
in al,dx
mov ah,al ; store the original value in AH
xor al,0Fh ; invert lower 4 bits
out dx,al
in al,dx
xor al,0Fh ; invert again (should get the original value)
cmp al,ah
jne .not_v40
out dx,al ; write the original value
in dx,al
cmp al,ah ; compare again
jne .not_v40
jmp .v40
.not_v40:
I finally got a chance to test the proposed change. It seems to work on my machine with both the V20 and V40 CPU cards. There is a typo in the sample code (IN AL, DX instead of DX, AL) but otherwise it makes sense.
The code I was working with didn't have a .v40 label for that code path, so I just built a similar block like .not_v40 to fall through to.
pop dx
mov si, msg_cpu_nec_v40
call print
jmp .cpu_freq
On a conceptual level, I think the pokes to FFF6 look benign. On a V20, we can assume that FFF6 -> 3F6 falls into the gap of the FDC and doesn't do anything important. On a V40, we initialize to FFF6 to 01 (zero-wait DMA and 1WS refresh, but refresh is disabled), and the toggled version would be 0E (3WS DMA, 2WS refresh), which seems like it would be even safer timing if the test didn't clean up after itself for some reason.