While I've been making assemblers in the past, this one proved quite difficult. You'll remember from one of the previous logs, that the instructions can be arranged within 8-instruction blocks in almost arbitrary ways. But the actual sequence becomes important for flow control and optimization of (conditional) jumps. Above that, each 8-instruction block must end with a jump to the following block, and sometimes a slot in a block stays unused because there is a multi-word instruction or instruction sequence that can not be distributed over two blocks.
The goal was, that the assembly programmer doesn't have to concern himself with the above subtleties, and that the assembler program does all this. Now in a 'normal' assembler, the instructions have very less interaction with each other. That's totally different now.
But now that the struggle to do automatic instruction sequencing by the assembler has almost been completed, an inconvenience in the design came to the surface of my mind. That is the memory access system.
The proposed system has two models, the linear and the object model. This forms a kind of two-dimensional memory system with the A0-A15 address on one axis, and the page-or-displacement value on the other axis. If a language like C would do memory allocation, using the Kobold system, that would mean that memory would be allocated in two dimensions. This would imply a lot of complications.
So I decided to change to a more common model, while keeping most of the advantages of the 'old' system. The schematic of the old model is still available as version 20191011.
NEW MEMORY MODEL
In the new memory model, the object system has become a part of the linear model. It is almost the same as in the Kobold-one.
The address of an operand is formed by:
- A0: from address register. Is high for byte-access to the MSB of a word.
- A1 - A4: from address register, OR'ed with the four displacement bits
- A5-A15: from the address register
- A16-A19: 4 bits from the page register that belongs to the address register
An instruction can have a 4-bit displacement that is OR'ed to bit A1 - A4 of the above address. The result determines the position of a memory operand.
The address of the next instruction is constructed as follows:
- A0 is always zero, because an instruction is a word.
- A1, A2, A3 come from the NNN bits in the current instruction
- A4 - A15 come from address register A0 (PC, program counter)
- A16 - A19 come from the page register of the program counter
You see that the lowest four bits of the program counter are not used to address the next instruction. That opens the possibility to store a copy of the program page in those four bits. This gives us the same more-than 64K jump capability as in the old model, for instance for return address storage:
- The PC is moved to a dataregister, and the subroutine stores it in the stack frame
- At return, the stored address is written to the program counter, and to the page register of the program counter, at the same time! As before, the return address is always in the same instruction slot.
- So now the page register has correct contents, because that was previously stored in A0 - A3. And A4 - A15 will be used to fetch the instruction, together with the page (A16 - A19).
And, also, a jump or call is still able to reach all memory positions without a near-or-far mechanism.
The schematic is now updated. The log Addressing modes was also updated.