Discussion:
16-bit 80386
(too old to reply)
muta...@gmail.com
2021-03-12 10:14:12 UTC
Permalink
My new BIOS concept worked:

https://groups.io/g/hercules-380/message/139

I would now like to run 16-bit programs while
remaining in 80386 mode.

I want to use the same trick used by MVS
"continents" (see above group).

I want to allocate 128k of memory so that I am
sure I have a 64k boundary, and then load the
16-bit module into that region.

Let's say that address is 0x12340000

I will then load eax/ebx/etc with that address.

Then I want to use 80386 instructions that never
disturb the high 16 bits of registers. I believe that
means putting a lot of db x'66' and db x'67' (or
something like that) in front of a lot of instructions
to make them do 16-bit operations instead of
32-bit operations.

I then need a compiler such as IA16 to actually
generate those instructions.

Then I can run 16-bit programs at native speed.

Can anyone see any flaw in that?

This would be purely tiny memory model of course.

Thanks. Paul.
JJ
2021-03-12 13:18:53 UTC
Permalink
Post by ***@gmail.com
https://groups.io/g/hercules-380/message/139
I would now like to run 16-bit programs while
remaining in 80386 mode.
I want to use the same trick used by MVS
"continents" (see above group).
I want to allocate 128k of memory so that I am
sure I have a 64k boundary, and then load the
16-bit module into that region.
Let's say that address is 0x12340000
I will then load eax/ebx/etc with that address.
Then I want to use 80386 instructions that never
disturb the high 16 bits of registers. I believe that
means putting a lot of db x'66' and db x'67' (or
something like that) in front of a lot of instructions
to make them do 16-bit operations instead of
32-bit operations.
I then need a compiler such as IA16 to actually
generate those instructions.
Then I can run 16-bit programs at native speed.
Can anyone see any flaw in that?
This would be purely tiny memory model of course.
Thanks. Paul.
If the 16-bit code is a protected mode program, there may be a problem if it
tries to read GDT/LDT. i.e. it'll treat 32-bit descriptors as 16-bit
descriptors.
muta...@gmail.com
2021-03-12 21:43:59 UTC
Permalink
Post by JJ
If the 16-bit code is a protected mode program, there may be a problem if it
tries to read GDT/LDT. i.e. it'll treat 32-bit descriptors as 16-bit
descriptors.
I am only interested in supporting 16-bit *application*
programs. They will only using 8086 instructions plus
db '66' '67' or whatever, creating an 8086+.

BFN. Paul.
wolfgang kern
2021-03-12 18:36:11 UTC
Permalink
Post by ***@gmail.com
https://groups.io/g/hercules-380/message/139
I would now like to run 16-bit programs while
remaining in 80386 mode.
I want to use the same trick used by MVS
"continents" (see above group).
I want to allocate 128k of memory so that I am
sure I have a 64k boundary, and then load the
16-bit module into that region.
Let's say that address is 0x12340000
I will then load eax/ebx/etc with that address.
Then I want to use 80386 instructions that never
disturb the high 16 bits of registers. I believe that
means putting a lot of db x'66' and db x'67' (or
something like that) in front of a lot of instructions
to make them do 16-bit operations instead of
32-bit operations.
I then need a compiler such as IA16 to actually
generate those instructions.
Then I can run 16-bit programs at native speed.
Can anyone see any flaw in that?
This would be purely tiny memory model of course.
My OS is a PM32 but it contains and uses also LM64, PM16 and trueRM16
modules. And I use it the opposite way: all 16bit code can access 4GB.

So yes for using 32bit flat pointers also in PM16/RM16,
but NO for abusing GPregs as segment registers.
x386 offers enough options with segmenting, paging, task-switches and
VM86 and not at least BiGRealMode for mixing 16<>32bit modes.
__
wolfgang
muta...@gmail.com
2021-03-12 21:45:27 UTC
Permalink
Post by wolfgang kern
So yes for using 32bit flat pointers also in PM16/RM16,
but NO for abusing GPregs as segment registers.
x386 offers enough options with segmenting, paging, task-switches and
VM86 and not at least BiGRealMode for mixing 16<>32bit modes.
I want my 16-bit applications to run on an 8086+
processor, not just an 80386.

BFN. Paul.
Alexey F
2021-03-13 02:32:47 UTC
Permalink
Post by ***@gmail.com
https://groups.io/g/hercules-380/message/139
I would now like to run 16-bit programs while
remaining in 80386 mode.
I want to use the same trick used by MVS
"continents" (see above group).
I want to allocate 128k of memory so that I am
sure I have a 64k boundary, and then load the
16-bit module into that region.
Let's say that address is 0x12340000
I will then load eax/ebx/etc with that address.
Then I want to use 80386 instructions that never
disturb the high 16 bits of registers. I believe that
means putting a lot of db x'66' and db x'67' (or
something like that) in front of a lot of instructions
to make them do 16-bit operations instead of
32-bit operations.
You can achieve a lot that way, but there probably are
some cases where you still need to do something
special.
Post by ***@gmail.com
I then need a compiler such as IA16 to actually
generate those instructions.
Then I can run 16-bit programs at native speed.
If the environment is 32-bit-capable anyway, there's
probably not much in making the compiler emit
proper 16-bit only code.
Doesn't gcc/as already support emitting
16-bit-mode-compatible code through those
operand and address size overrides?
See e.g. https://stackoverflow.com/q/19055647/968261

Alex
Rod Pemberton
2021-03-13 06:49:54 UTC
Permalink
On Fri, 12 Mar 2021 02:14:12 -0800 (PST)
Post by ***@gmail.com
https://groups.io/g/hercules-380/message/139
I would now like to run 16-bit programs while
remaining in 80386 mode.
Sigh, don't we all, but how do you do that
without processor support? Binary translation
was the only solution I found.
Post by ***@gmail.com
Then I want to use 80386 instructions that never
disturb the high 16 bits of registers. I believe that
means putting a lot of db x'66' and db x'67' (or
something like that) in front of a lot of instructions
to make them do 16-bit operations instead of
32-bit operations.
While that (mixed-mode code using address/operand
instruction overrides) will work for plenty of
instructions, it won't work for the different
addressing modes for 16-bit and 32-bit.

16-bit addressing modes work against 4 of 8
16-bit registers, using addition of two of the
registers: bx, bp, si, di. 32-bit addressing
modes work directly against 7 of 8 32-bit
registers: eax, ebx, ecx, edx, ebp, esi, edi.
I.e., how do you convert an address reference
against bp+si to eax? esi? or, vice-versa?

I gave an example to you in 2018 of how
code would need to be converted to work
for both modes:

;32-bit code
00000028 89FB mov ebx,edi
0000002A 8B4720 mov eax,[edi+32]

;16-bit code
00000028 89FB mov bx,di
0000002A 8B4720 mov ax,[bx+0x20]

In other words, I don't know how to fully convert
16-bit mode code to 32-bit mode code while using
only address-size/operand-size overrides due to
differences in addressing modes. This would seem
to require binary translation to perform.
--
Diplomacy with dictators simply doesn't work.
muta...@gmail.com
2021-03-13 11:41:44 UTC
Permalink
Post by Rod Pemberton
Post by ***@gmail.com
I would now like to run 16-bit programs while
remaining in 80386 mode.
Sigh, don't we all,
Oh. I didn't realize someone else wanted to do
that. Why do you want to do that?

Note that I'm only talking about tiny memory
model.
Post by Rod Pemberton
but how do you do that
without processor support? Binary translation
was the only solution I found.
We'll see.
Post by Rod Pemberton
Post by ***@gmail.com
Then I want to use 80386 instructions that never
disturb the high 16 bits of registers. I believe that
means putting a lot of db x'66' and db x'67' (or
something like that) in front of a lot of instructions
to make them do 16-bit operations instead of
32-bit operations.
While that (mixed-mode code using address/operand
instruction overrides) will work for plenty of
instructions, it won't work for the different
addressing modes for 16-bit and 32-bit.
Sorry, I was mistaken about using prefixes. I don't
think that's what I want.
Post by Rod Pemberton
16-bit addressing modes work against 4 of 8
16-bit registers, using addition of two of the
registers: bx, bp, si, di. 32-bit addressing
modes work directly against 7 of 8 32-bit
registers: eax, ebx, ecx, edx, ebp, esi, edi.
I.e., how do you convert an address reference
against bp+si to eax? esi? or, vice-versa?
In that case, I don't want to generate code that
does a bp+si. I will do two adds instead if
necessary. The final address reference will
then use eax or esi.
Post by Rod Pemberton
I gave an example to you in 2018 of how
code would need to be converted to work
;32-bit code
00000028 89FB mov ebx,edi
0000002A 8B4720 mov eax,[edi+32]
;16-bit code
00000028 89FB mov bx,di
0000002A 8B4720 mov ax,[bx+0x20]
In other words, I don't know how to fully convert
16-bit mode code to 32-bit mode code while using
only address-size/operand-size overrides due to
differences in addressing modes. This would seem
to require binary translation to perform.
Ok, maybe the problem here is that there are
insufficient 16-bit only instructions. The same
problem exists in S/370. It uses 32-bit registers,
and the only instructions you can use that only
touch the lower 16 bits is ICM (insert 1 or 2
characters) and STCM (store 1 or 2 characters).

To do what I want (16-bit programming) on S/370
will require more instructions than just ICM and
STCM. Although I've just realized that I do have
another option for S/370. I can generate instructions
that change the upper 16-bits of 32-bit registers,
but then immediately restore them to their previous
values.

On a real 16-bit S/370, those instructions will simply
do nothing.

I think I can do the same with 80386. Or maybe we
can add some 16-bit instructions to the 80386. Is
that possible?

Thanks. Paul.
Rod Pemberton
2021-03-13 18:19:40 UTC
Permalink
On Sat, 13 Mar 2021 03:41:44 -0800 (PST)
Post by ***@gmail.com
Post by Rod Pemberton
Post by ***@gmail.com
I would now like to run 16-bit programs while
remaining in 80386 mode.
Sigh, don't we all,
Oh. I didn't realize someone else wanted to do
that. Why do you want to do that?
So, I don't have to code BIOS functions for 32-bit,
as my OS isn't setup to run 16-bit code. It uses
32-bit C compilers for most of the code, so I have
no need of a 16-bit interface, except for BIOS
calls. E.g., ... for not needing to code disk
or video BIOS functions.

Or, as you said elsewhere in thread:

PE> No, I don't want to switch modes. I want to stay
PE> in 80386 protected mode, and I don't want to
PE> require OS support to do a mode change.

Ditto.
Post by ***@gmail.com
I think I can do the same with 80386. Or maybe we
can add some 16-bit instructions to the 80386. Is
that possible?
IIRC, the undocumented 80286 LOADALL instruction
was emulated for 80386, as it produced an invalid
opcode exception on later processors.

LOADALL Instruction (80286 0F 05, 80386 0F 07)
http://www.rcollins.org/articles/loadall/tspec_a3_doc.html

LOADALL (80286 0F 05)
https://www.pcjs.org/documents/manuals/intel/80286/loadall/

Undocumented OpCode LOADALL (80386 0F 07)
http://www.rcollins.org/secrets/opcodes/LOADALL.html
--
Diplomacy with dictators simply doesn't work.
Rod Pemberton
2021-03-13 18:48:02 UTC
Permalink
On Sat, 13 Mar 2021 13:19:40 -0500
Post by Rod Pemberton
On Sat, 13 Mar 2021 03:41:44 -0800 (PST)
Post by ***@gmail.com
Post by Rod Pemberton
Post by ***@gmail.com
I would now like to run 16-bit programs while
remaining in 80386 mode.
Sigh, don't we all,
Oh. I didn't realize someone else wanted to do
that. Why do you want to do that?
So, I don't have to code BIOS functions for 32-bit,
as my OS isn't setup to run 16-bit code. It uses
32-bit C compilers for most of the code, so I have
no need of a 16-bit interface, except for BIOS
calls. E.g., ... for not needing to code disk
or video BIOS functions.
PE> No, I don't want to switch modes. I want to stay
PE> in 80386 protected mode, and I don't want to
PE> require OS support to do a mode change.
Ditto.
Post by ***@gmail.com
I think I can do the same with 80386. Or maybe we
can add some 16-bit instructions to the 80386. Is
that possible?
IIRC, the undocumented 80286 LOADALL instruction
was emulated for 80386, as it produced an invalid
opcode exception on later processors.
LOADALL Instruction (80286 0F 05, 80386 0F 07)
http://www.rcollins.org/articles/loadall/tspec_a3_doc.html
LOADALL (80286 0F 05)
https://www.pcjs.org/documents/manuals/intel/80286/loadall/
Undocumented OpCode LOADALL (80386 0F 07)
http://www.rcollins.org/secrets/opcodes/LOADALL.html
From Robert Collins linked to articles (for 80286),

"By manipulating the descriptor cache base
registers, you can access the entire address
space without switching to protected mode.
In other words, by using LOADALL, you can
access memory above 1Mb from real mode."

Sound familiar? (Hint: unreal mode)

"The 286 LOADALL is described in a 15-page
Intel-confidential document. The document
describes in detail how to use the instruction,
and also describes many of its possible
uses. LOADALL can be used to access extended
memory while in real mode, and to emulate
real mode while in protected mode."

Sound familiar? (Hint: V86 mode or unreal mode)


The pcjs.org link has a print-to-pdf
feature at the bottom, allowing you to get
the 15-page 80286 LOADALL document as a pdf,
which has quotes like:

"The protected mode 80286 can be extended
to emulate iAPX 86 real mode programs with
LOADALL. In real mode, LOADALL can provide
addressability to the other 15 Mbytes of
the 286 physical address space."

"An iAPX 86/88 program using real mode
addressing can be executed in protected
mode with full protection between it and
other programs."

"The LOADALL instruction allows a protected
mode 80286 to provide a simulated iAPX 86/88
interrupt table to iAPX 86/88 programs."
--
Diplomacy with dictators simply doesn't work.
Rod Pemberton
2021-03-13 18:58:04 UTC
Permalink
On Sat, 13 Mar 2021 03:41:44 -0800 (PST)
Post by ***@gmail.com
I think I can do the same with 80386. Or maybe we
can add some 16-bit instructions to the 80386. Is
that possible?
As for extending the instruction set, the BIOS
emulates 286 LOADALL (0F 05), NTVDM uses
C4 C4 xx xx sequences for a small API, DOSBox
uses FE 38 for a callback, Virtual PC uses
0F 3F xx xx and 0F C7 C8. I'm assuming all of
these are trapped via invalid opcode exception
or general protection faults. VMWare traps
a special I/O port sequence.
--
Diplomacy with dictators simply doesn't work.
muta...@gmail.com
2021-03-13 11:43:29 UTC
Permalink
Post by Alexey F
Post by ***@gmail.com
Let's say that address is 0x12340000
I will then load eax/ebx/etc with that address.
Then I want to use 80386 instructions that never
disturb the high 16 bits of registers. I believe that
means putting a lot of db x'66' and db x'67' (or
something like that) in front of a lot of instructions
to make them do 16-bit operations instead of
32-bit operations.
You can achieve a lot that way, but there probably are
some cases where you still need to do something
special.
Sorry, I think I was barking up the wrong tree here.
I want 32-bit address references, not 16-bit, for my
16-bit programs.
Post by Alexey F
Post by ***@gmail.com
I then need a compiler such as IA16 to actually
generate those instructions.
Then I can run 16-bit programs at native speed.
If the environment is 32-bit-capable anyway, there's
probably not much in making the compiler emit
proper 16-bit only code.
I want to be able to take my small programs to an
8086+ or 8080+ or whatever processor it was that
could only access 64k. While still being able to run,
in 80386 protected mode, on an 80386.

BFN. Paul.
wolfgang kern
2021-03-13 13:41:22 UTC
Permalink
Post by ***@gmail.com
I want to be able to take my small programs to an
8086+ or 8080+ or whatever processor it was that
could only access 64k. While still being able to run,
in 80386 protected mode, on an 80386.
I don't understand your problem ... doesn't VM86 all what you want ?

while an 32bit PM OS run on a 80386 it needs just three entries in the
GDT for code, data and stack for a 16bit limited playground.
__
wolfgang
muta...@gmail.com
2021-03-13 14:12:01 UTC
Permalink
Post by wolfgang kern
Post by ***@gmail.com
I want to be able to take my small programs to an
8086+ or 8080+ or whatever processor it was that
could only access 64k. While still being able to run,
in 80386 protected mode, on an 80386.
I don't understand your problem ... doesn't VM86 all what you want ?
No, I don't want to switch modes. I want to stay
in 80386 protected mode, and I don't want to
require OS support to do a mode change.

BFN. Paul.
Loading...