How did the 8086 interface with the 8087 FPU coprocessor?
The 8087 has many instructions. Too many it seems to be encoded as part of the 8086 instructions. How did the Intel 8086 interface with an Intel 8087 FPU that a user added?
Consider the following x86 assembly code sample:
// c = a + b;
fld DWORD PTR [rbp-0xc] // a;
fadd DWORD PTR [rbp-0x8] // b;
fstp DWORD PTR [rbp-0x4] // c;
The instructions fld
, fadd
, and ftsp
I assume are not hardwired into the 8086 circuit. So are they psuedo instructions that the assembler subsequently converts to command/data instructions for the 8086 to pass onto the 8087 appropriately?
For example fld
might be encoded as command 0
and for data the value of rbp-0xc
is encoded which the 8087 would know is an address in memory holding the value it needs? And then a sequence of OUT
instructions are used by the 8086 to send the command and data to the 8087?
instruction-set floating-point 8086
add a comment |
The 8087 has many instructions. Too many it seems to be encoded as part of the 8086 instructions. How did the Intel 8086 interface with an Intel 8087 FPU that a user added?
Consider the following x86 assembly code sample:
// c = a + b;
fld DWORD PTR [rbp-0xc] // a;
fadd DWORD PTR [rbp-0x8] // b;
fstp DWORD PTR [rbp-0x4] // c;
The instructions fld
, fadd
, and ftsp
I assume are not hardwired into the 8086 circuit. So are they psuedo instructions that the assembler subsequently converts to command/data instructions for the 8086 to pass onto the 8087 appropriately?
For example fld
might be encoded as command 0
and for data the value of rbp-0xc
is encoded which the 8087 would know is an address in memory holding the value it needs? And then a sequence of OUT
instructions are used by the 8086 to send the command and data to the 8087?
instruction-set floating-point 8086
Related question on StackOverflow: stackoverflow.com/questions/42543905/…
– Ross Ridge
1 hour ago
add a comment |
The 8087 has many instructions. Too many it seems to be encoded as part of the 8086 instructions. How did the Intel 8086 interface with an Intel 8087 FPU that a user added?
Consider the following x86 assembly code sample:
// c = a + b;
fld DWORD PTR [rbp-0xc] // a;
fadd DWORD PTR [rbp-0x8] // b;
fstp DWORD PTR [rbp-0x4] // c;
The instructions fld
, fadd
, and ftsp
I assume are not hardwired into the 8086 circuit. So are they psuedo instructions that the assembler subsequently converts to command/data instructions for the 8086 to pass onto the 8087 appropriately?
For example fld
might be encoded as command 0
and for data the value of rbp-0xc
is encoded which the 8087 would know is an address in memory holding the value it needs? And then a sequence of OUT
instructions are used by the 8086 to send the command and data to the 8087?
instruction-set floating-point 8086
The 8087 has many instructions. Too many it seems to be encoded as part of the 8086 instructions. How did the Intel 8086 interface with an Intel 8087 FPU that a user added?
Consider the following x86 assembly code sample:
// c = a + b;
fld DWORD PTR [rbp-0xc] // a;
fadd DWORD PTR [rbp-0x8] // b;
fstp DWORD PTR [rbp-0x4] // c;
The instructions fld
, fadd
, and ftsp
I assume are not hardwired into the 8086 circuit. So are they psuedo instructions that the assembler subsequently converts to command/data instructions for the 8086 to pass onto the 8087 appropriately?
For example fld
might be encoded as command 0
and for data the value of rbp-0xc
is encoded which the 8087 would know is an address in memory holding the value it needs? And then a sequence of OUT
instructions are used by the 8086 to send the command and data to the 8087?
instruction-set floating-point 8086
instruction-set floating-point 8086
asked 3 hours ago
Jet BlueJet Blue
6801615
6801615
Related question on StackOverflow: stackoverflow.com/questions/42543905/…
– Ross Ridge
1 hour ago
add a comment |
Related question on StackOverflow: stackoverflow.com/questions/42543905/…
– Ross Ridge
1 hour ago
Related question on StackOverflow: stackoverflow.com/questions/42543905/…
– Ross Ridge
1 hour ago
Related question on StackOverflow: stackoverflow.com/questions/42543905/…
– Ross Ridge
1 hour ago
add a comment |
1 Answer
1
active
oldest
votes
The opcodes in your list are all only 16 bits (plus the extra bytes for address calculation) and you'll notice that they all begin (in hex) with Dx
where x >= 8. This is because, to the 8086, any instruction whose first byte has the bit pattern 11011xxx
was deemed to be an 8087 coprocessor instruction.
When the 8086 encountered a floating point opcode, it would do all the stuff to calculate the effective address and fetch the byte at that address and then it would just carry on.
Meanwhile the 8087 reads all the same instructions as the 8086 and when it encountered an instruction destined for it (i.e. that started with 11011xx
), it would simply read the data bus at the right time to get the first byte i.e. when the 8086 was fetching the data. For multi-byte reads it would also read the address bus and then take control of the memory bus after the 8086 read cycle and read the remaining bytes pointed to by the address using direct memory access (DMA). For writes, it would ignore the data bus, read the address and then use DMA to write the data.
The only direct connections between the 8086 and 8087 were a few control lines, some to synchronise the prefetch queues of the 8086 and the 8087 - so the 8087 would know exactly when the 8086 was executing floating point instructions - and one so that the 8086 could tell when the 8087 had finished the last instruction and was ready for the next. There was a special instruction in the 8086 called wait
that would simply cause the 8086 to wait until the 8087 signalled it was not busy on this line.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "648"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f9173%2fhow-did-the-8086-interface-with-the-8087-fpu-coprocessor%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The opcodes in your list are all only 16 bits (plus the extra bytes for address calculation) and you'll notice that they all begin (in hex) with Dx
where x >= 8. This is because, to the 8086, any instruction whose first byte has the bit pattern 11011xxx
was deemed to be an 8087 coprocessor instruction.
When the 8086 encountered a floating point opcode, it would do all the stuff to calculate the effective address and fetch the byte at that address and then it would just carry on.
Meanwhile the 8087 reads all the same instructions as the 8086 and when it encountered an instruction destined for it (i.e. that started with 11011xx
), it would simply read the data bus at the right time to get the first byte i.e. when the 8086 was fetching the data. For multi-byte reads it would also read the address bus and then take control of the memory bus after the 8086 read cycle and read the remaining bytes pointed to by the address using direct memory access (DMA). For writes, it would ignore the data bus, read the address and then use DMA to write the data.
The only direct connections between the 8086 and 8087 were a few control lines, some to synchronise the prefetch queues of the 8086 and the 8087 - so the 8087 would know exactly when the 8086 was executing floating point instructions - and one so that the 8086 could tell when the 8087 had finished the last instruction and was ready for the next. There was a special instruction in the 8086 called wait
that would simply cause the 8086 to wait until the 8087 signalled it was not busy on this line.
add a comment |
The opcodes in your list are all only 16 bits (plus the extra bytes for address calculation) and you'll notice that they all begin (in hex) with Dx
where x >= 8. This is because, to the 8086, any instruction whose first byte has the bit pattern 11011xxx
was deemed to be an 8087 coprocessor instruction.
When the 8086 encountered a floating point opcode, it would do all the stuff to calculate the effective address and fetch the byte at that address and then it would just carry on.
Meanwhile the 8087 reads all the same instructions as the 8086 and when it encountered an instruction destined for it (i.e. that started with 11011xx
), it would simply read the data bus at the right time to get the first byte i.e. when the 8086 was fetching the data. For multi-byte reads it would also read the address bus and then take control of the memory bus after the 8086 read cycle and read the remaining bytes pointed to by the address using direct memory access (DMA). For writes, it would ignore the data bus, read the address and then use DMA to write the data.
The only direct connections between the 8086 and 8087 were a few control lines, some to synchronise the prefetch queues of the 8086 and the 8087 - so the 8087 would know exactly when the 8086 was executing floating point instructions - and one so that the 8086 could tell when the 8087 had finished the last instruction and was ready for the next. There was a special instruction in the 8086 called wait
that would simply cause the 8086 to wait until the 8087 signalled it was not busy on this line.
add a comment |
The opcodes in your list are all only 16 bits (plus the extra bytes for address calculation) and you'll notice that they all begin (in hex) with Dx
where x >= 8. This is because, to the 8086, any instruction whose first byte has the bit pattern 11011xxx
was deemed to be an 8087 coprocessor instruction.
When the 8086 encountered a floating point opcode, it would do all the stuff to calculate the effective address and fetch the byte at that address and then it would just carry on.
Meanwhile the 8087 reads all the same instructions as the 8086 and when it encountered an instruction destined for it (i.e. that started with 11011xx
), it would simply read the data bus at the right time to get the first byte i.e. when the 8086 was fetching the data. For multi-byte reads it would also read the address bus and then take control of the memory bus after the 8086 read cycle and read the remaining bytes pointed to by the address using direct memory access (DMA). For writes, it would ignore the data bus, read the address and then use DMA to write the data.
The only direct connections between the 8086 and 8087 were a few control lines, some to synchronise the prefetch queues of the 8086 and the 8087 - so the 8087 would know exactly when the 8086 was executing floating point instructions - and one so that the 8086 could tell when the 8087 had finished the last instruction and was ready for the next. There was a special instruction in the 8086 called wait
that would simply cause the 8086 to wait until the 8087 signalled it was not busy on this line.
The opcodes in your list are all only 16 bits (plus the extra bytes for address calculation) and you'll notice that they all begin (in hex) with Dx
where x >= 8. This is because, to the 8086, any instruction whose first byte has the bit pattern 11011xxx
was deemed to be an 8087 coprocessor instruction.
When the 8086 encountered a floating point opcode, it would do all the stuff to calculate the effective address and fetch the byte at that address and then it would just carry on.
Meanwhile the 8087 reads all the same instructions as the 8086 and when it encountered an instruction destined for it (i.e. that started with 11011xx
), it would simply read the data bus at the right time to get the first byte i.e. when the 8086 was fetching the data. For multi-byte reads it would also read the address bus and then take control of the memory bus after the 8086 read cycle and read the remaining bytes pointed to by the address using direct memory access (DMA). For writes, it would ignore the data bus, read the address and then use DMA to write the data.
The only direct connections between the 8086 and 8087 were a few control lines, some to synchronise the prefetch queues of the 8086 and the 8087 - so the 8087 would know exactly when the 8086 was executing floating point instructions - and one so that the 8086 could tell when the 8087 had finished the last instruction and was ready for the next. There was a special instruction in the 8086 called wait
that would simply cause the 8086 to wait until the 8087 signalled it was not busy on this line.
edited 2 hours ago
answered 2 hours ago
JeremyPJeremyP
4,65011528
4,65011528
add a comment |
add a comment |
Thanks for contributing an answer to Retrocomputing Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f9173%2fhow-did-the-8086-interface-with-the-8087-fpu-coprocessor%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Related question on StackOverflow: stackoverflow.com/questions/42543905/…
– Ross Ridge
1 hour ago