hot dos (Developers)
> For instance, idling with sti
and hlt
, if it
> works,
What is the reason this might not work?
> may let the CPU idle until the next IRQ arrives, be it a timer,
> keyboard event, serial I/O, etc.
I was thinking about the philosophy of this. I am
tempted to replace (or raise a bug report) on the
BIOS used by Virtualbox.
But that seems a bit impractical.
But also it is unclear to me how DOS 4.0 etc could
be logically changed - correctly - ie without needing
the timer to save the day.
If there is no timer to save the day, then if I do a
BIOS request to see if there is a keystroke pending,
and then do a HLT if I have nothing, well - the
keystroke may have come in and been processed just
before I did the HLT. In which case the system will
hang waiting for an interrupt that will never come.
So it makes more sense - logically - to do this in
the BIOS instead - even if it means waiting for a
bug fix (or forking it).
I was thinking that on the other hand, if I was
waiting for input from either the serial port or
the keyboard, then it would make more sense to do
it in DOS 4.0. But that's exactly why I don't do
multitasking of any sort. I don't want any such
complication in my code. I want to get a simple
system working first. Which means you read from
the keyboard and then wait.
I do have code to wait on the serial port, but
it relies on manipulating the hardware.
; enable interrupts and then halt until interrupt hit
hltintgo:
hloop:
; I believe hlt will be interrupted by other interrupts, like
; the timer interrupt, so we need to do it in a loop
sti
hlt
cli
jmp hloop
hltinthit:
; remove return address, segment and flags from the stack as we
; do not intend to return to the jmp following the hlt instruction
; that was likely interrupted
add esp, 12
; note that interrupts will be disabled again (I think) by virtue
; of the fact that an interrupt occurred. The caller would have
; disabled interrupts already, so we are returning to the same
; disabled state.
ret
intaddr = (unsigned long)hltinthit;
/* we are interested in this interrupt */
xch = PREADB(imr);
xch &= ~(1 << (intno % 8));
PWRITEB(imr, xch);
uartEnableGPO2(&uart);
/* uartEnableModem(&uart); */
/* uartRaiseDTR(&uart); */
/* uartRaiseRTS(&uart); */
/* uartCTS(&uart); */
intdesc1 = (0x8 << 16) | (intaddr & 0xffff);
intdesc2 = (intaddr & 0xffff0000)
| (1 << 15)
| (0 << 13)
| (0x0e << 8);
disable();
G_intloc[(intno + 0xb0) * 2] = intdesc1;
G_intloc[(intno + 0xb0) * 2 + 1] = intdesc2;
uartEnableRxRDY(&uart);
hltintgo();
/* if I immediately disable UART interrupts, I can no
longer read the old pending id of RxRDY.
If I read the pending ids, RxRDY just gets reasserted,
presumably because I haven't actually read the
character yet.
If I try reading the character, a new character may
come in and I'll miss it.
So the safest thing to do is just disable interrupts
and assume that RxRDY was hit, since that was the only
thing actually enabled, and I don't bother reading the
interrupt ids. */
G_intloc[(intno + 0xb0) * 2] = old1;
G_intloc[(intno + 0xb0) * 2 + 1] = old2;
uartDisableInts(&uart);
enable();
ch = uartRecCh(&uart);
PWRITEB(0x20, 0x20);
uartDisableGPO2(&uart);
xch = PREADB(imr);
xch |= (1 << (intno % 8));
BFN. Paul.
Complete thread:
- hot dos - kerravon, 08.05.2025, 00:24
- hot dos - ecm, 08.05.2025, 00:36
- hot dos - Rugxulo, 08.05.2025, 03:22
- hot dos - kerravon, 08.05.2025, 07:24
- hot dos - rmcconne, 11.05.2025, 15:15