Paul Edwards
2023-04-11 11:18:14 UTC
Hi.
As far as I can tell from testing, the BIOS INT 14H doesn't
work on most real hardware I have tried (computers made
maybe 10 years ago that still have a serial port).
So I am gearing up to replace that with 80386 PM32 code.
I have some comms routines for MSDOS (pdcomm) that I
wrote decades ago, but I want to do it a different way this time.
Less sophisticated, but more straightforward.
And designed for a single-tasking system with only one
CPU enabled (PDOS/386).
Most of the code can be done in C, but the last bit I want
to do in assembler.
Prior to hitting the assembler, I will have installed the
new interrupt address (which is assembler code, gotint,
below).
I'm just trying to confirm the sequence in the final assembler.
outb port1, transmit_byte
outb port2, tbemask ; enable transmit buffer empty (only)
xxx:
hlt ; this could get interrupted by timer interrupts and
; then processing continues so we need a jmp
jmp xxx
gotint: ; this is the interrupt address installed by C caller
outb port2, oldmask ; restore previous interrupt mask (everything disabled)
add esp, 12 ; we don't return to the previous instruction, which was hlt
; instead we skip over the return address, segment and flags
ret ; return to C caller which will do the EOI or whatever
; via separate calls to individual simple assembler functions
; like outportb()
Note that this was inspired by something similar I wrote
for S/370.
It's basically quite minimal assembler and straightforward.
There is a loop in the assembler, which I didn't have in my
old routines, but it's not really processing logic.
After transmit is working I'll try a variation of the above for receive.
I especially don't know if these two need to be swapped:
outb port1, transmit_byte
outb port2, tbemask ; enable transmit buffer empty (only)
I don't want to miss an interrupt. I want the order to
guarantee that I will get the interrupt. ie if I have already
attempted to write the transmit byte, will the interrupt
pend until I enable it, or will it be skipped?
Or is the other way around? If I haven't enabled interrupts
will it just transmit the byte and not bother interrupting?
Assume that the transmit is very fast, or the CPU is very
slow, so that there is a gap between the two outb
instructions where a decision is made on whether to
interrupt or not.
Thanks. Paul.
As far as I can tell from testing, the BIOS INT 14H doesn't
work on most real hardware I have tried (computers made
maybe 10 years ago that still have a serial port).
So I am gearing up to replace that with 80386 PM32 code.
I have some comms routines for MSDOS (pdcomm) that I
wrote decades ago, but I want to do it a different way this time.
Less sophisticated, but more straightforward.
And designed for a single-tasking system with only one
CPU enabled (PDOS/386).
Most of the code can be done in C, but the last bit I want
to do in assembler.
Prior to hitting the assembler, I will have installed the
new interrupt address (which is assembler code, gotint,
below).
I'm just trying to confirm the sequence in the final assembler.
outb port1, transmit_byte
outb port2, tbemask ; enable transmit buffer empty (only)
xxx:
hlt ; this could get interrupted by timer interrupts and
; then processing continues so we need a jmp
jmp xxx
gotint: ; this is the interrupt address installed by C caller
outb port2, oldmask ; restore previous interrupt mask (everything disabled)
add esp, 12 ; we don't return to the previous instruction, which was hlt
; instead we skip over the return address, segment and flags
ret ; return to C caller which will do the EOI or whatever
; via separate calls to individual simple assembler functions
; like outportb()
Note that this was inspired by something similar I wrote
for S/370.
It's basically quite minimal assembler and straightforward.
There is a loop in the assembler, which I didn't have in my
old routines, but it's not really processing logic.
After transmit is working I'll try a variation of the above for receive.
I especially don't know if these two need to be swapped:
outb port1, transmit_byte
outb port2, tbemask ; enable transmit buffer empty (only)
I don't want to miss an interrupt. I want the order to
guarantee that I will get the interrupt. ie if I have already
attempted to write the transmit byte, will the interrupt
pend until I enable it, or will it be skipped?
Or is the other way around? If I haven't enabled interrupts
will it just transmit the byte and not bother interrupting?
Assume that the transmit is very fast, or the CPU is very
slow, so that there is a gap between the two outb
instructions where a decision is made on whether to
interrupt or not.
Thanks. Paul.