An NMI will push a value on the stack. The value depends on the instruction address at the time where NMI is given. At beginning is the memory contens unknown, and it is only possible to know the address immidiately after NMI is given (0066H). Because instructions is unknown, will it not be possible to know the address later.
The memory will need to be filled with a known value to control it.
To fill out memory with known values, is a lot of NMI's given, until all memory is filled by pushing 0067H to stack.
The value may not actualy be 0067H because some instruction is more than one byte. Jump and restarts cause another address too. After all memory is filled first time, by using a lot of NMI's, is the adress at 0066H filled with a new value. This value will in near all cases, not be an instrucition that change address (jump or restart), and at next run arround do NMI's store 0067H in all memory. If the orginal instruction at 0066H, is a two or three byte instruction, then 67H to 69H is stored at 0066H for next run arround. They are four cycle, normal load instructions, and they work too and does that 0067H is stored in all memory.
The number of cycles to fill memory is one run arround with any instruction at 0066H, and another with any four cycle instruction after changing the address at 0066H.
Any instruction at 0066H:
The 4-cycle instruction after modifying 0066H:
Total cycles of fill:
ramsize * 49 cycles.
If no oscillator is used, is the clock controlled by the PC, else is fill done by releasing clock, and running at 4MHz speed.
After filling, is all memory stored with 4 cycle load instructions, or 4 cycle NOP's, and the number of clock pulses to any instruction after NMI is known. An NMI push's the instruction address on stack, and sets the instruction pointer to 0066H. The clock is now controlled to the address that should be pushed next. It is possible to load the code by pushing values on the stack by an NMI at the address with the value that should be pushed into memory. Everytime NMI is given is instruction pointer set to 0066H by the processor. First is stackpointer unknown, and the instructions may be pushed anyplace in memory. To set stack as e.g. 400H, is 00 04 stored in memory. It does not change timing. It is importent that first push not change the timing, and only four cycle instructions is used. Next, is 00 31 stored. It change timing but it is not a problem. To store a low number as 04H, is starting with zero done by using reset before NMI is given. Memory does now contain 00 31 00 04 somewhere, and setting stack by executing all memory is done. (Running at 4MHz if external oscillator used). Since memory only contain load, nop, and the LD SP operation, is nothing else than stack loaded. Stack is now known, but the memory contain LD SP, n somewhere, and timing is not known. This is in this case handled by filling memory from address 400H and down to 001CH where bootloader is stored. The fill is done by using NMI as before, and with counting clocks. The possibility that the LD SP,n instruction was stored at 0066H is very small, even with a small memory system. It is possible to handle in code. (Unactivated code).
It is only possible to use instructions, with instruction code less than the address where the code is stored. If the stack is at top of memory, then most instructions are accessable. If memory is very small is less instructions accessable. To handle this, will it need to be loaded a bootloader. This bootloader use instructions from 0067H to 0100H+$ only, where $ is address of code to store, and the bootloader allow to be runned on a small system with 256 bytes only. (8085 + 8155 only, a two chip solution with I/O's).
The bootloader is saved into memory. It only uses instructions from 0067H to 0113H. The bootloader is stored at 0000H to 001BH and a 256 byte system use address 00H..1BH for instructions in range 0100H to 0100H+$. These instruction need to be stored before the address is used. Address is stored from top, and the instructions that use 0100H to 0113H is not in 0000H to 0013H address room.
The bootloader uses reset, and clock to store (or read) data. Operation depends on instruction at reset.
The bootloader is not critical to which value to store, and it is possible to change, modify, read etc. A15 is used to return with bit's from bootloader.
As far as I see may the methode be used for a wide range of CPU's. I have only testet it on Z80A, but more processors (8085) may be able to bootload using the methode.
The code, and the schematic, is attached to this document. Only the circuit schematic is needed. Oscillator circuit is not needed, but circuit is clocked by the PC if no oscillator circuit is used. Remember decoubling Z80 and 6116, by using capacitors under the chips if using sockets. Ack is used to indikate if oscillator circuit is used, or if all clocks is controlled by the PC.