Each instruction requires some data on which it has to operate. There are different techniques to specify data for instructions. These techniques are called addressing modes. Intel 8085 uses the following addressing modes:
In this instruction, 2400H is the memory address where data is to be stored. It is given in the instruction itself. The 2nd and 3rd bytes of the instruction specify the address of the memory location. Here, it is understood that the source of the data is accumulator.
The opcode 78H can be written in binary form as 01111000. The first two bits, i.e. 0 1 are for MOV operation, the next three bits 1 1 1 are the binary code for register A, and the last three bits 000 are the binary code for register B.
In the above program the instruction MOV A, M is an example of register indirect addressing. For this instruction, the operand is in the memory. The address of the memory is not directly given in the instruction. The address of the memory resides in H-L pair and this has already been specified by an earlier instruction in the program, i.e. LXI H, 2500 H.
An instruction of a computer is a command given to the computer to perform a specified operation on given data. In microprocessor, the instruction set is the collection of the instructions that the microprocessor is designed to execute.
I am studying the replacement of a 8085 with a Z80 (I am aware that they are not pin-compatible, the solution is to be made in a board of new design rather than on the old board). The sole reason is to reduce components whose production has ceased. Still, my goal is to be able to be compatible with hardware and software targetted at the old system.
I imagine the extended interrupt shall be replicated externally, but I don't know how to proceed with instructions 0x20 and 0x30 (RIM, SIM). Is there a way in which I could "intercept" opcodes and conditonally fed them into the Z80?
You could detect those opcodes by snooping the data bus while /M1 and /RD are active. When a RIM or SIM opcode is detected, switch the opcode to a different one using a mux between the data bus and Z80. This can't be done until the data bus stabilizes, but must be done before the end of the memory read operation (end of T2) or the Z80 will read and execute the original opcode (which is JR NZ for RIM and JR NC for SIM). If you need more time you could assert /WAIT to stretch the read cycle, but this must be done by the middle (trailing edge) of T2.
Your circuit could then feed more instruction bytes into the Z80 to make it do what you want (eg. JP to some code that emulates the RIM/SIM instruction) or send it a HALT instruction and then activate NMI to force a non-maskable interrupt.
This is bound to create some timing differences. Depending on the machine's architecture it might affect bus timing in a way that upsets other things such as the video display or DRAM refresh, or conflict with the existing interrupt system. The 8085 also has more hardware interrupt inputs that might need a different circuit and software for the Z80.
The emulated instructions will take much longer, which could be a problem for code that needs cycle accuracy (eg. tape read/write, bit-banged serial port) or execution within a maximum time frame (interrupt handlers etc.). The Z80 has different instruction timings and some flags are set differently, which could create more compatibility issues. Finally the 8085 has some undocumented instructions that some programs might be using, or they might have tricky code that relies on the CPU executing unimplemented instructions in a certain way (unlikely, but you never know...).
For these reasons I think that while handling RIM and SIM may be 'feasible', it probably won't be worth the effort unless the machine's hardware and software is unsophisticated and very tolerant of timing differences. 'Vanilla' CP/M code with only 8080 instructions would probably be fine, but for that you could just use the Z80 as is and patch the OS to handle the different instructions (perhaps by replacing RIM and SIM with RST instructions).
Doesn't seem like a very sensible reason. 'New Old Stock' and reclaimed 8085s are still available for those few boards that might need them. If you are thinking of producing new boards then you could use an FPGA with 8085 CPU core, which could be made 100% compatible as well as having enhancements. Programmable logic is the way forward for replacing out of production chips. On the other hand people who don't want their retro hardware 'sullied' by modern products probably want an original processor as well.
The 8085 has multiple priority interrupt lines with a mix of edge and level triggers as well as the 8080 style INT. The Z80 has only the 8080 style interrupt, two modes of its own (IM1 and IM2) and NMI. Thus many 8085 systems would actually need a Z80 and a full on interrupt controller and a bunch of new interrupt code
There are a bunch of signal level timing differences aside from the bus being multiplexed on the 8085 and not the Z80. Above that there are significant timing differences at the instruction level and interrupt service level.
Various 8085 signals are simply missing or different on the Z80. If you happen to need S0/S1/IOM you'll have to synthesize them from IORQ/MREQ/M1 and the timings will differ there too. It's not just the two bitbang ports.
When you look at prices if you need to replace a board running 8085 software and the 8085 software replacement cost is too high you may well be better off emulating it on a modern two dollar or less part with a load of GPIO lines for the "bus". Your board will be dramatically smaller, your power consumption go way down and even with a few 5v shifters if needed your BOM is almost certain to be vastly lower.
The simulator has two parts, an assembler (built using PEGjs) which translates 8085 assembly code to machine code and a 8085 microprocessor simulator (written in C and compiled to JS using Emscripten) which executes machine code. This web application is a graphical interface for the simulator.
Sim8085 was originally developed by Debjit Biswas. It would not be possible to improve the quality and correctness of the emulator without the bugs reported by individuals. Big thanks, to all bug reporters and contributors.
This is another quick post about an unfinished (but working) software which I wrote around 8 years ago. It is an Intel 8085 microprocessor simulator, with a text based interface. The objective was to simulate the microprocessor, along with a minimal interface which closely resembles the microprocessor kit with the 7-segment displays, hex keyboard and minimal debugging features.
In our undergraduate computer science degree, we had a few subjects on microprocessor architecture. One of the subjects focused on the Intel 8085 microprocessor architecture in great details, Intel 8086 architecture, interfacing, etc. Along with the detailed architecture, we also had to do some assembly code for 8085. It was fun because, we had to use a physical 8085 microprocessor kit with a hex keyboard and just those 7-segment displays.
To write a code in the kit, you need to scan through the memory and enter the values of the assembled code. Who assembles it? We had to do that manually. We would have a table of all the instructions and the hex value for the op-code. More essentially it is very important to know the precise operations for each instruction. What operation it performs, which registers are accessed, what memory locations are accessed and how does it change the flags.
Although we were required to use the physical 8085 microprocessor kit in the exams, but for practice, we used 8085 microprocessor simulators. There are quite a few 8085 microprocessor simulators available. One of them was provided with one of the text books. There were simulators with text interface, some with text and some with nice GUI interfaces. I used one of them, the GNUSim8085. You can find an in depth review of GNUSim8085, which I wrote for OpenSource For You long ago, also posted here: Reviewing the GNUSim8085 (v1.3.7).
The right hand side shows the flags and the register states and the present start address of the simulator, very useful for step execution and debugging. The left hand side shown the kind of 7-segment display which you will get in a basic simulator kit.
To execute a code, first enter your assembled code, then set the start address by pressing s and then press x to execute. The previous image shows a step execution scenario (press z). In this case the simulator disassembles the machine code and displays the presently being executed code and the next one.
In the test machine state file dirty_test, I wrote and assembled a bubble sort code in 8085 and loaded it into 0x4200 location. The input list for the list to be sorted is in 0x0000. The first number in the list indicates the length of the list, then the actual numbers to be sorted follows. The bubble sort code sorts the list at 0x0000o and stores the result list in 0x07d0.
Go through the README file, as it has a description and I also have uploaded a file with three demo codes which you can run immediately. Play with the features if you want, and if you are able to break anything, please comment.
As I was in the middle of the year, and I could not allow much time to be invested on this, I gave myself a good 14 days to get the first version running. When I finished this, I thought that although it works as planned, but as it was not complete, therefore I thought to post this in my blog once I implement the TODOs for the second iteration (which never happened). After a few years I put that in github.
Download it as zip or clone repository. Execute make, run from present directory ./dirty or do make install as root. Note you need to have ncurses-devel, else build will fail. For Fedora/RedHat/OpenSuSe/CentOS do a dnf install ncurses-devel.
The struct _instruction_set holds all the information related to the instructions. Each entry for the array of structures struct _instruction_set instruction_set indicates the description of an instruction, which is needed. The way struct _instruction_set instruction_set was initialised is key. The description of an instruction is ordered in the array of struct _instruction_set instruction_set in the order of their op-code values. This will enable us to use the op-code to directly fetch the related information about the instruction.
c80f0f1006