VOGONS


First post, by aitotat

User metadata
Rank Member
Rank
Member

I am developing my own PC-emulator and i have been trying to find and fix some bugs for weeks. 286, motherboard components, text modes and floppy controller (IDE as well but it does not work properly yet) are currently emulated. I have written my own bios for motherboard and VGA. They should contain all functions related to currently emulated hardware.

MS-DOS boots fine (several versions) and many ASCII-games also work fine. There are two games that give me trouble. They are Pac-Gal and The Queen of Hearts Maze Game. Pac-Gal sometimes doesn’t draw all characters to screen. Both of them occasionally give some error messages, like String formula too complex or Out of string space. I think that there might be bug in CPU-emulation.

I have found (and fixed) some bugs by using PC Diagnostics 95 but it does not have any CPU tests. I would like to know where i can find any similar testing utilities that might also have CPU tests.

I have another question as well. Are BIOS-functions allowed to enable interrupts? Some BIOS-functions, like INT 16h/AH=00h (keyboard, get keystroke), need to enable interrupts but what about some (possibly slow) display bios functions? Should they enable interrupts even if it is not necessary?

Reply 1 of 18, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

qemu had some sort of a testing suite, but the compiled version was for
pentium+ (the extender used it).

Some interrupts modify the flags state in a non-standard way as they return
via retf2 and not iret, but int10 definitely preserves the interrupt flag.
Check some original bios dumps/disassemblies how exactly they return,
int15 for example has some quirks with unhandled functions.

Bios functions that use some memory copying loops usually allow interrupts
during their execution, not sure if int10 would do that at some point.

Reply 4 of 18, by Davros

User metadata
Rank l33t
Rank
l33t

doesnt dos come with a diagnostic program ?

edit: msd.exe

how about this:
http://freepctech.com/rode/009.shtml

or
PC Doctor Diagnostics for DOS :
http://www-307.ibm.com/pc/support/site.wss/MIGR-4UKNJB.html

Reply 5 of 18, by aitotat

User metadata
Rank Member
Rank
Member

Thanks for help. That Diag required at least 386 for some processor tests. Many other tests worked fine on 286 and i found out that i have some bugs in RTC and keyboard emulation. I'll fix those before trying to find the CPU bug.

I would still like to know about other test utilities that would work on 286.

Reply 7 of 18, by aitotat

User metadata
Rank Member
Rank
Member

I have now fixed lot of bugs but many still remains.

I'm still testing with Diag and now i have problems with hard disk benchmark. It starts but never finishes. It seems that it polls timer tick variable from bios data area. It just never changes because interrupts are disabled.

Diag calls int 13h functions with far call instead of int instruction. My int 13h functions will always return with iret and i think this is what causes problems.

I have macros for setting and clearing any return flag. They are used at the end of bios functions that modifies flags. Here is macro for setting flag:

;--------------------------------------------------------------------
; Macro for setting bits to flag register currently in stack.
;
; SET_RET_FLAG_BITS:
; Parameters:
; %1: Bit mask ORred to flags register
; %2: Temporary register required
; %3: Number of registers pushed to stack by ISR
; Returns:
; Nothing
; Corrupts registers:
; %2
;--------------------------------------------------------------------
%macro SET_RET_FLAG_BITS 3
mov %2, bp ; Store BP to temporary register
mov bp, sp ; Copy stack pointer to BP
or WORD [bp+4+(%3*2)], %1 ; Or bit mask to flags register
mov bp, %2 ; Restore BP
%endmacro

Other registers will be popped after using that (or the other for clearing flag) macro.

Problem is likely to be solved by using retf 2. Then how about other flags? Should interrupts always be enabled (Diag seems to be expecting this)?

Reply 8 of 18, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Would it be enough to enable interrupts during the int13 routine?
As usually the int13 sector transfer routines need interrupts enabled anyways,
so the timer interrupt is/can be called during the transfers.

Reply 9 of 18, by aitotat

User metadata
Rank Member
Rank
Member

Interrupts are needed during many int 13h functions. When returned with iret, interrupts will be disabled if they were disabled when bios function was called.

Diag seems to have pushed some dummy word before calling int 13h with far call. This dummy word disables interrupts when popped with iret. Retf 2 would ignore it but then no flags would be returned to original states.

Since interrupts are needed during that bios function, it is probably safe to always return with interrupts enabled.

Many other bios functions also set or clear CF. Some does not need to enable interrupts (like Int 1Ah/AH=2h, Get RTC Time). If retf 2 is used then original IF state will be lost. Should all functions that sets/clears some flag return with interrupts always enabled and other flags undefined?

Reply 10 of 18, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

When returned with iret, interrupts will be disabled if they were disabled when bios function was called.

Yes, but if it uses int13 a lot (which is to be assumed if it's a benchmark/diag app)
the irq0 can be fired during the int13 handler, and the time advances as expected.

Reply 11 of 18, by aitotat

User metadata
Rank Member
Rank
Member

From http://www.microsoft.com/whdc/archive/Lf.mspx:
"If a ROM BIOS API is documented to modify the flags--for example, it is documented to return with the CARRY flag set or cleared--this restriction does not apply to individual arithmetic bits in the flags register. Any ROM BIOS API that is documented to modify the flags is assumed to modify all of the "arithmetic" flag bits: CARRY, AUX-CARRY, PARITY, ZEROSIGN, and OVERFLOW. The values of the other bits in the flags register must be preserved unless the API is documented to modify them."

That explains almost all i wanted to know. If interrupts are needed by bios function, it is okay to return with interrupts enabled and unneeded arithmetic flags undefined.

Now i just need to know what other bios functions are allowed to force interrupts on when returning.

Reply 13 of 18, by aitotat

User metadata
Rank Member
Rank
Member

Some int 13h functions need interrupts to be able to work and some do not. For example read and write functions need to enable interrupts and AH=8h, Get Drive Parameters does not.

What i meant before was that should all int 13h functions return with interrupts enabled or only those that really needs it?

It doesn't matter anymore since i got Diag benchmark working. It required that Int 13h/AH=8h will return with interrupts enabled (by using retf 2 instead of iret). AH=8h just reads information from bios data area so i guess this means that every int 13h function should return with interrupts enabled.

Reply 14 of 18, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

should all int 13h functions return with interrupts enabled or only those that really needs it?

None. For example the bochs bios uses a plain iret, so this'd hint at real bioses doing the same.
Check the diag app under bochs and see if it works, if it does, see my comments above,
if it doesn't, check some real bios.

Reply 15 of 18, by aitotat

User metadata
Rank Member
Rank
Member

I wrote a small program that tests if bios functions will enable interrupts.

It tests Int 11h, 12h and many 13h functions. Known values (with interrupts disabled) will be pushed to stack and loaded to flags before simulating iret with far call. Flags will be printed after bios function returns.

I tested it with my reference 286 that has AMI bios. Int 11h and 12h seems to return with iret. All Int 13h functions will always return with interrupts enabled. I will test Int 15h, 16h and 1Ah functions later.

If someone wants to try, here is the program with sources included:

Attachments

  • Filename
    biostest.zip
    File size
    3.13 KiB
    Downloads
    181 downloads
    File license
    Fair use/fair dealing exception

Reply 17 of 18, by aitotat

User metadata
Rank Member
Rank
Member

New version with more tests:
Int 15h AH=83h, AH=86, AH=88h, AH=C0h and AH=C1h
Int 16h AH=0h...3h, AH=5h, AH=9h, AH=Ah and AH=10h...12h
Int 1Ah AH=0h, AH=2h, AH=4h, AH=7h and AH=Ah

I tested it with four computers:
286 with AMI bios
486 with Award bios
Celeron with AMI bios
AthlonXP with Phoenix bios

All Int 13h functions returned with interrupts enabled on all bioses.
All Int 1Ah functions returned with interrupts enabled on all bioses.
Int 15h AH=83h, 86h and C0h returned with interrupts enabled on all bioses.
Int 16h AH=1h and 11h returned with interrupts enabled on all bioses.

286AMI returned with interrupts enabled on Int 15h AH=C1h.
Award returned with interrupts enabled on Int 15h AH=C1h and Int 16h AH=5h.
Celeron AMI returned with interrupts enabled on all tested Int 15h functions.
Phoenix returned with interrupts enabled on Int 16h AH=5h.

All other tested bios functions returned with iret so flags weren't modified.

Diag HD benchmark didn't work on bochs. It just froze just like on my bios when Int 13h returned without forcing interrupts enabled.

Attachments

  • Filename
    biostest11.zip
    File size
    4.58 KiB
    Downloads
    352 downloads
    File license
    Fair use/fair dealing exception