9

I have been struggling to find a method to actually run any assembly code on my 8086 chip. I have an 8086 chip and I am trying to implement it on hardware to power up a LED or anything simple.

On Proteus's simulation, this is easy to do because Proteus offers you to write code on run directly inside the simulation.

However, in the real world, I cannot find any clue on how to do this. How to upload that ASM code on the chip in order to power up a LED or something?

Voltage Spike
  • 75,799
  • 36
  • 80
  • 208
Mora
  • 167
  • 5
  • 5
    Please edit your question to explain in more detail what circuitry you have. "*I have an 8086 chip and I am trying to implement it on hardware to power up a LED or anything simple*" says that you have an 8086 IC in front of you and nothing else. – TonyM Nov 11 '22 at 09:24
  • 9
    As others have already mentioned, you need to add memory to an 8086 before it'll be able to do anything. If you're thinking of building an 8086-based system from scratch you might consider using an 80186 instead of a "bare" 8086. The 80186 is an 8086 with many of the standard support peripherals built in which you would otherwise need to add as separate ICs in your design. Unfortunately they're not connected in exactly the same way as in the "standard" IBM-compatible PC design - so it won't run a PC BIOS. But an 80186 + some memory is all you need if you're writing your own bare ASM code. – brhans Nov 11 '22 at 15:15
  • If you like older processors, there are versions of [Intel's 8051](https://en.wikipedia.org/wiki/Intel_8051) that have memory on chip. You can upload to the internal EPROM memory. Some versions have other support circuitry, like UARTs. Could be cheaper than the modern microcontrollers. – Thomas Matthews Nov 12 '22 at 01:24
  • Thank you very much for this amazing answer. – Mora Nov 12 '22 at 05:29
  • 2
    @TonyM Yes the 8086 IC is in the only chip I have. I thought it had an internal memory. However, thanks to everyone here who helped, I know that it requires external circuitry – Mora Nov 12 '22 at 05:31

4 Answers4

34

The 8086 in itself doesn't have any memory, so you can't upload anything to it. You need to build a whole x86 computer with that chip in its core and then put a program in memory at the position the CPU fetches the first instruction, and then let the CPU run.

If you go to the Wikipedia page for the 8086 you'll see that the 8086 is missing a lot of the things built in to modern CPUs, and needs separate chips so it can clock itself, handle interrupts, have any main memory, communicate over a serial line, or in any way interface with peripherals. So, the 8086 is a very complicated starting point if you just want to build something where you can upload some program to run.

You're essentially in need of building a minimalist clone of the original IBM PC!

If you instead of a 1970's microprocessor went for a 1980s (or better, later) microcontroller, you would have a chip that has the CPU, the main memory, the permanent memory, interrupt controllers, clocking circuitry, IO controllers and serial interfaces all built in. To that you could then upload a machine code program directly.

As to what you can do to learn the software side of things while you build your IBM PC, you could use an IBM PC emulator to run the binaries that come out of your assembler. It might be easiest to instead of bare metal binaries to produce normal DOS executables in the COM format, using a C compiler or an assembler of your choice, and running it from the DOS prompt in the emulator.

Marcus Müller
  • 88,280
  • 5
  • 131
  • 237
  • Great explanation. If you want to see what's needed, have a look here: https://eater.net/6502 - Ben's using a 6502, but the requirements are very similar. – RJR Nov 11 '22 at 11:53
  • @RJR uff, that nest of (very tidy!) cabling suggests: really not something you want to build on breadboard if you value your sanity. Both for "oh, this is sooo many cables" and "oh, this is sooo many cable-board connection which individually can be a bit flimsy" reasons. The videos are very cool and instructional! I like it. – Marcus Müller Nov 11 '22 at 12:04
  • 8
    @MarcusMüller: Back in the day, it wasn't uncommon for people to build 8086 or even 68000-based systems on breadboards. Clock speeds would have been rather limited by modern standards, but the things did actually work, somehow. – supercat Nov 11 '22 at 17:27
  • @supercat no doubt about that! The computer Ben Eater built also works. It's just, as said, probably not good for your sanity :) – Marcus Müller Nov 11 '22 at 17:30
  • 1
    @supercat Yes. I personally wire-wrapped a lot and limited myself to about 4 MHz for anything I did in that way. And I never had any troubles. Beyond that I'd worry, though. – jonk Nov 11 '22 at 19:36
14

You need to attach something to the CPU memory bus at specific starting location from where the CPU can fetch program code to execute.

For the 8086, it starts executing code from memory address 0xFFFF0 after reset, that is 16 bytes below the end of the 1 megabyte address space.

As the 8086 has a 16-bit data bus, you need to have e.g. a 16-bit memory chip, or two 8-bit memory chips, programmed with the code you want to run. Flash chips are programmable, and you can simply make just enough code to allow transferring code from somewhere else to be run in the system.

Justme
  • 127,425
  • 3
  • 97
  • 261
  • that's true, the "flat" 16 bit memory bus means you can attach basically anything with a parallel address bus as program memory. – Marcus Müller Nov 11 '22 at 12:08
7

The 8086 loads an instruction from the Data memory space after it completes its power on and reset is deasserted. This instruction is the first instruction of whatever program or bootloader you want to run.

The I/O is typically a 16bit parallel ROM and the enable line from the ROM needs to be the I/O enable line from the 8086. It could be an EEPROM or whatever.

The Prentice-Hall book The Intel Microprocessors is a good resource.

I once wire wrapped an 8088, which is slightly different than an 8086. The first thing I did was wire wrap RAM and ROM chips and their enable line. Then loaded a small assembly program on the flash and test some I/O and the RAM

Toby Speight
  • 172
  • 1
  • 7
Voltage Spike
  • 75,799
  • 36
  • 80
  • 208
  • 2
    From the I/O space, really? – user253751 Nov 11 '22 at 21:18
  • I thought I could be wrong on that, it's been 15 years since I built it. The RAM had it's own line, the ROM had its own line and the I/O had it's own enable line if I remember right – Voltage Spike Nov 11 '22 at 21:46
  • 3
    The I/O space is only 64K and only used for in/out. Instructions are always read from memory, be it ROM or RAM. – mirabilos Nov 12 '22 at 01:22
  • @mirabilos: In 8086, though, I think they all used the same external bus, and being IO vs. memory address-space was via a separate pin that was asserted or not to tell devices and memory how to decode the address lines. Or am I conflating that with just MMIO vs. port IO for devices separate from RAM/ROM? Probably not, that would require something in the CPU to map different addresses to different busses. But anyway, if you do weird things with the I/O enable line, you could have the ROM be readable as both memory or I/O. To run code from it, yeah it needs to respond to memory reads. – Peter Cordes Nov 12 '22 at 04:53
  • Thank you very much for this amazing answer. – Mora Nov 12 '22 at 05:29
  • 1
    @PeterCordes, one could do tricks with the memory and I/O space but it's needlessly taking a really long way round something simple. That part of the answer as written was wrong: on reset, the 8086 executes instructions in memory space, same as usual. It starts from address FFFF:0000h. That's usually accessing an EPROM/ROM IC, no use of I/O space. The system design may do something with I/O space mapped into address space but the 8086 certainly doesn't. – TonyM Nov 12 '22 at 14:01
  • @TonyM: Oh yes, on a 2nd look at exactly what this answer is saying, that the I/O enable line should be wired to the ROM's enable line, yeah that won't work, unless the CPU's output on that pin is inverted vs. how the ROM treats it. The ROM needs to respond to memory reads. It could also respond to some range of I/O reads if you don't care about that range of ports for anything else. But that's not particularly helpful, just means you could maybe wire the ROM to always enabled. – Peter Cordes Nov 12 '22 at 23:31
  • @PeterCordes the ROM must respond to memory reads only, and at address FFFF0h which is outside of I/O space. I/O space only uses the lower 16 bits of the address bus (but, yes, it’s shared and has a separate I/O pin, which means that anything _not_ I/O (ROM, RAM) must only be enabled if the I/O enable is _not_ set). @ TonyM it is FFFF0h linear, but you get no guarantee what CS and IP are set to, could be F000:FFF0h (and this is, in fact, more frequent) or FF00:0FF0h or so… – mirabilos Nov 21 '22 at 17:14
  • @mirabilos: If you want to have all of I/O space available for I/O, yes you need the ROM to respect the enable line. But you might not need that in a minimal homebrew system built around a bare 8086 chip. You might also not use all the address lines from the CPU and allow some aliasing, like only decoding the low 16 bits so ROM responds to `0FFF0`, `1FFF0`, etc. (And some range around that, since normally you'd want more than just 16 bytes of code in ROM; the initial boot address is in the last 16 bytes of linear address space.) – Peter Cordes Nov 21 '22 at 17:24
  • @mirabilos, "*but you get no guarantee what CS and IP are set to, could be F000:FFF0h*" See Intel 8086 Family User's Manual 1979 p2-29 Table 2-4 'CPU State Following Reset'. IP=0000h, CS=FFFFh, DS/ES/SS=0000h. That leads to reset execution at FFFF:0000h i.e. FFFF0h. – TonyM Nov 21 '22 at 17:28
  • Perhaps, but it is well-known that “compatibles” don’t do that. Needs a far jump anyway… – mirabilos Nov 23 '22 at 14:01
0

If you want to go really old-school, have a bank of switches and a circuit to copy the switch state into a register, and another to copy the switch state into the RAM address specified by that register. See CONSOLE ENTRY SWITCHES on page 30 of this document for how it worked on the IBM 1130. In Load mode, Load IAR set the Instruction Address Register, while Start wrote the switch state to memory.

John Doty
  • 2,227
  • 5
  • 12
  • Would anyone want to do that, in this day and age? – TonyM Nov 13 '22 at 00:11
  • @TonyM Why not? Some people build things with vacuum tubes. – John Doty Nov 13 '22 at 00:17
  • 2
    I don't think 'Why not' needs an explanation :-) But because it was horrible 45 years ago and it'd be horrible now. Some people do build with valves but for very different reasons to this. Downvoting, I'm afraid. – TonyM Nov 13 '22 at 00:36
  • Surely you'd have two banks of switches - one for the address and one for the data byte(s)... or does the same bank of switches serve both purposes? That is to say, *first* the switches provide the address and once that address has been copied into the (address) register (presumably using one other push button or toggle switch), *then* the bank of switches then serves as the data input (to then be set at the address upon a second toggle) and so on, back and forth, ad-infinitum? If you could [edit] and elaborate upon your answer, to illustrate how it used to be done, that would be good. – Greenonline Nov 13 '22 at 00:59
  • @Greenonline, "*If you could edit...answer, to illustrate how it used to be done, that would be good*" That's not a reason for an answer on SE.EE, it's an electronics design Q&A site. That's a reason for an SE.Retrocomputing answer instead. – TonyM Nov 13 '22 at 09:30
  • Thanks for the update @JohnDoty. So, the same switches were used for both address and data. – Greenonline Nov 13 '22 at 14:09