Extending the Gigatron instruction set

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice.
HGMuller
Posts: 20
Joined: 14 May 2018, 05:46

Extending the Gigatron instruction set

Post by HGMuller » 14 May 2018, 07:26

One of the nice things about having a CPU built from TTL components is that you don't need to consider it a 'given', but can change the architecture to meet your needs. Want another index register, or a second accumulator? Just grab your soldering iron!

Of course adding new features to the architecture will also require you to add new instructions that can use these features. No use for a register that you cannot load, and store or use for generating addresses. Fortunately the original instruction set of the Gigatron is rather sparse, designed mostly for minimizing decoder logic. So at the expense of some extra logic in the instruction decoder-logic it should be possible to reporpose some of the opcodes that now are duplicats. Of course the more ambitous can also opt for completely redesigning the instruction set.

An extra addressing mode?

In my attempts so far to develop software for the Gigatron, I experience having only a single index register of each type (i.e. for low or high address byte) as a major bottleneck. Even if only to use one of the index registers as 'frame pointer', to indicate (quasi-premanently) a 'page' of local variables for a recursive routine.

The original Gigatron has addressing modes [0,D], [0,X], [Y,D], [Y,X] and [Y,X++]. The latter is a rather specialized mode only available with the OUT destination, aimed at generating video. The other modes using X or Y are only available with the A (accumulator) destination, so that indexed loading of X or Y alsways has to go through A. (Which also is a major annoyance, as it requires storing an reloading of the old A content when the purpose was to store it through the indexed mode.) The mode [0,X] is a bit limited, because it always forces the high address byte to the same value 0. So only 256 bytes of the entire memory can be reached through it. To index other memories that way requires the high byte to be in the (already overloaded) Y register.

The obvious solution in the original Gigatron architecture is to store arrays 'vertically', i.e. use Y instead of X for indexing them, so that the instruction's data field D can be used in [Y,D] to indicate the array, and Y the element in it. Downside is that this only works if the array is smaller than 128 bytes, rather than 256. With 32KB RAM Y is really only a 7-bit register!

This could be solved by replacing the mode [0,X] by [D,X], which is an 'almost backward-compatible' extension, as [0,X] could still be done by specifying D=0 in the opcode. (Only in the rare case that D is used as source for immediate data at the same time, as in STA D, [0,X] this would be imposible.) This enhancement is easy to achieve in hardware, as the second input of the high-byte address multiplexer (AH) is currently not connected (the choice between 0 and Y being made through the output-enable of the multiplexer), andd can be wired to D. Then some logic in the instruction decoder can be addedd for driving the 'select' and 'enable' inputs of this multiplexer in the newly require way.

An alternative use for this second input of AH is to wire it to X, so that a mode [X,D] can be created. From a programming point of view this would be a more useful enhancement. When arrays are stored vertically, the X registers is only rarely used. (Mostly to access large tables through [Y,X], as only few table can ly in the reach of [0,X]), so making it possible to use X as a 'second Y' greatly increases its usefulness.) With two equivalent index registers it becomes easy to shuttle blocks of data between two tables. And for most of the remaining time X can be used to define a 'stack frame' of 256 bytes, as local storage for the current instance of a recursive routine. Mode [X,D] would then be used to access local variable number D, and [0,D] to access global variable number D. This mode is not upward compatible with any of the existing adddressing modes, though. So extensive modification of the instruction decoder would be needed to fit it in the opcode map, if we don't want to sacrifice any of the other modes.

at67
Posts: 63
Joined: 14 May 2018, 08:29

Re: Extending the Gigatron instruction set

Post by at67 » 14 May 2018, 08:44

This is interesting stuff, obviously as hackers we can do whatever we like to our own individual board's instruction sets; but there is merit in discussing the idea of modified/enhanced/additional instructions to future ROM upgrades as well, (IMHO).

** removed the junk about vCPU code **

There's lots of good stuff in your post, I'll respond with a better reply when I've had a good chance to digest it properly.

** better reply **
In my attempts so far to develop software for the Gigatron, I experience having only a single index register of each type (i.e. for low or high address byte) as a major bottleneck. Even if only to use one of the index registers as 'frame pointer', to indicate (quasi-premanently) a 'page' of local variables for a recursive routine.
I came across somewhat similar issues when I was writing native code for blits/sprites, my initial attempts required using page zero as an intermediate buffer between source and destination native code blits. Combine this with a generic save background, draw sprite, restore background blit/sprite type architecture and I started to hit performance, (and SYS timing), limits very quickly.
The original Gigatron has addressing modes [0,D], [0,X], [Y,D], [Y,X] and [Y,X++]. The latter is a rather specialized mode only available with the OUT destination, aimed at generating video.
[Y,X++] can also write to RAM as well, it's fantastic for blasting data embedded into the native instructions into RAM, (using DD,[Y,X++]), (it's how I achieved my pacman blinky sprite demo), and you can do it at almost one byte per clock cycle, (with a small amount of setup time required per row of data).

If you replace your ROM with RAM, (which I am in the process of doing), you can not only change the ROM routines trivially, but you can also store data, (bitmaps, sprites, generic), together with their copy/blit routines; i.e. the data and the associated code that moves it around are stored together within the harvard architecture memory. When you need data copied to RAM in a hurry, you simply supply a destination address and call the corresponding routine that has the data embedded within it. Whether this routine is a generic memory copy or a sprite handler, or a background restoring blitter is all hidden within the data and it's code.

Eventually I plan on completely removing all the bit banging code from the ROM, using an FPGA to emulate the RAM and ROM and video mode and allow the native code to run at close to 100% speed. I personally want to code in native code at full speed, that's my end goal.
The obvious solution in the original Gigatron architecture is to store arrays 'vertically', i.e. use Y instead of X for indexing them, so that the instruction's data field D can be used in [Y,D] to indicate the array, and Y the element in it. Downside is that this only works if the array is smaller than 128 bytes, rather than 256. With 32KB RAM Y is really only a 7-bit register!

This could be solved by replacing the mode [0,X] by [D,X], which is an 'almost backward-compatible' extension, as [0,X] could still be done by specifying D=0 in the opcode. (Only in the rare case that D is used as source for immediate data at the same time, as in STA D, [0,X] this would be imposible.) This enhancement is easy to achieve in hardware, as the second input of the high-byte address multiplexer (AH) is currently not connected (the choice between 0 and Y being made through the output-enable of the multiplexer), andd can be wired to D. Then some logic in the instruction decoder can be addedd for driving the 'select' and 'enable' inputs of this multiplexer in the newly require way.
Apart from the corner case instruction that you mention this sounds like a feasible solution, if the instruction is not currently used in ROM v1 and is unlikely to be used, then making the hardware modifications you mentioned might be the answer.
An alternative use for this second input of AH is to wire it to X, so that a mode [X,D] can be created. From a programming point of view this would be a more useful enhancement. When arrays are stored vertically, the X registers is only rarely used. (Mostly to access large tables through [Y,X], as only few table can ly in the reach of [0,X]), so making it possible to use X as a 'second Y' greatly increases its usefulness.) With two equivalent index registers it becomes easy to shuttle blocks of data between two tables. And for most of the remaining time X can be used to define a 'stack frame' of 256 bytes, as local storage for the current instance of a recursive routine. Mode [X,D] would then be used to access local variable number D, and [0,D] to access global variable number D. This mode is not upward compatible with any of the existing adddressing modes, though. So extensive modification of the instruction decoder would be needed to fit it in the opcode map, if we don't want to sacrifice any of the other modes.
This architecture really isn't missing much, but two index registers being able to be configured simultaneously as source and destination are a big one. As you suggest, [X,D] combined with [Y,D] as an indexing pair would make native code efficiency and performance increase substantially, throw an [X++,D] in there as well while you're at it and we have an architecture that would have destroyed all 8bit and 16bit architectures of a comparable time period.

HGMuller
Posts: 20
Joined: 14 May 2018, 05:46

Re: Extending the Gigatron instruction set

Post by HGMuller » 16 May 2018, 19:46

Well, since X is a counter [X++,D] should also be easy to realize. The main question is which opcodes to repurpose. Currently multiple addressing modes are only found on instructions with ACCU as destination, and to a lesser extent with OUT. In that design it would make sense to only add new modes to the ACCU instruction group. The current opcode map has a lot of redundancy in this group, as instructions that use bus mode D, IN or ACCU (and thus ignore the memory and its mode altogether) all appear 4 times.

This does not hold for STA instructions, though, as these always use the memory, an the bus just decides what to write there. For these instructions the opcodes that specify memory as the bus source have undefined effect, though, and could be used for upto 4 new modes that store ACCU. (Or with a really complex instruction decoder with a single new mode to store ACCU, D or IN; but storing IN, or D in a mode that also uses D seems hardly usefull.) It is an annoyance that STA instructions would need decoding that is different from ALU instructions, though. But perhaps we can do without the new mode(s) on STA instructions.

I am playing with the idea for a much more drastic modification, which would completely destroy the binary compatibility, but still keep virtually all useful instructions the standard Gigatron has. (But with different opcodes.) This to simplify the instruction decoder, by making the instruction set more orthogonal. I do not like it that some addressing modes cannot be used with some destination registers, because the original design has a mixed destination / addressing-mode field (and a diode matrix picking out a subset of the possible combinations). It would be more useful to have a mixed bus-mode / addressing-mode field, as some combinations of those are intrinsically useless: if the memory is not on the bus, the memory mode becomes irrelevant. So the only useful combinations in ALU instructions ACCU, IN, D or memory in various modes. This would leave room for 5 addressing modes, and all 8 data sources would then be combinable with every destination ACCU, X, Y or OUT. Of course it would require reprogramming or the ROM to use the new opcode assignments. I am still thinking about how to achieve this without 'exploding' the instruction decoder.

User avatar
marcelk
Posts: 268
Joined: 13 May 2018, 08:26

Re: Extending the Gigatron instruction set

Post by marcelk » 16 May 2018, 22:07

I'm glad we didn't optimise away the two '157 multiplexers in the high address unit. At one point we did consider to put '08 quad AND gates there instead, but we felt that would destroy too much tweaking potential.

(We were also a bit afraid of the higher fan-out on boards with bipolar transistors. Although the kit versions cheat a bit with FETs for reduced power consumption (good when feeding from USB ports). With those the fan-out is not so much of a concern. But we always wanted to preserve the ability to work with bipolars. That is the second reason we kept those '157s in there. And the '240 for that matter.)

HGMuller
Posts: 20
Joined: 14 May 2018, 05:46

Re: Extending the Gigatron instruction set

Post by HGMuller » 17 May 2018, 18:55

A tentative redesign:

IR5-7 keep the meaning they have now: primarily selecting ALU function, or generating the jump (!J) and store (!W) signals.
IR3-4 select the destination register, i.e. IR2 will be decoupled from the 3->8 decoder, so that this effectively becomes a 2->4 decoder. The outputs will directly drive the various load-enable lines of the registers (ACCU, X, Y and OUT), rather than first being combined through a diode matrix. The enables of ACCU and OUT will continue to be ORed with W to suppress their loading on store instructions.
IR0-2 are now available to select bus source and memory-address source in a non-orthogonal way. The low-address multiplexer will be controlled by IR0, to select X or D. The high-address multiplexer will select X or Y through its select input SH, and can additionally be forced to 0 through its output-enable EH. The way this is done depends on instruction group: the branch instructions will always force a 0, as they only need to use the RAM in the mode [0,D]. Other instructions only force a 0 in half the cases, controlled by IR2. So EH = !J & IR2.

The store instructions will always select Y as high address. Other instructions (i.e. ALU instructions, as branchess force the output to zero irrespective of selection) will alternate X and Y as specified by IR1. So SH = !W & IR1. This will result in the following RAM addressing:

Code: Select all

IR0-2    ALU    ST     Bcc     bus decoder
 0       Y,X    Y,X    0,X        ACCU
 1       Y,D    Y,D    0,D         IN
 2       X,X    Y,X    0,X         D
 3       X,D    Y,D    0,D        ACCU
 4       0,X    0,X    0,X        ACCU
 5       0,D    0,D    0,D         IN
 6       0,X    0,X    0,X         D
 7       0,D    0,D    0,D        ACCU
The right-most column indicates what data source the bus decoder would select if it were enabled. Note that the RAM is not in the list; this will be selected by disabling the bus decoder. Again it depends on the instruction group how this is done. Store instructions will always enable the bus decoder, as they use the RAM for writing, an thus cannot use it as a data source. This means they can store ACCU with modes [Y,X], [Y,D], [0,X] and [0,D], as in the original Gigatron. But immediate data D can only be stored with modes [Y,X] or [0,X]. The modes that use D have been sacrificed here, as the double use of D would hardly ever make them useful. Finally the input port can be stored through modes [Y,D] or [0,D] only.

The branch instructions could select the RAM in cases 3 and 7, (i.e. for mode [0,D]; note case 4-7 must be repetitions of 0-3 for another branch condition). But to simplify decoding we select it instead in the cases 0, 1, 4 and 5, thus sacrificing the (rather silly) branching on IN. This creates the new mode [0,X] on all branch instructions, which seems more useful.

Finally, the ALU instructions select RAM in cases 0-5. This adds the mode [X,D] to the original instruction set, plus the the useless mode [X,X], thus making the largest sacrifice so far: there is no longer any way to use IN as source for the ALU. The only instructions that can still use IN are store instructions, an any reading of the input port would have to first copy the value to memory, and then use that memory location as source in an ALU instruction. To me this seems acceptable: IN is a 'slow device', the Gigatron is not suitable as video frame grabber, and reading the input every msec (i.e. every 6000 instructions) is already quite fast. So the single extra cycle this would take doesn't seem worth added decoder complexity to eliminate it. As it is the RAM output-enable signal OE can be derived as !W & (!IR1 | !J & !IR2). A single 74xx00 qua NAND gate (or a 74xx04 hex inverter plus some of the many diodes we save by removing the addressing-decoder matrix) should be able to handle this.

Auto-incrementing of X is handled in the same way as in the original Gigatron: some of the modes with OUT destination using X addressing will cause the increment. This gives the following opcode map:

Code: Select all

           00                      c0               e0
   +----------------+-----+-------------------+-------------+
00 | ld [y,x]       | ... | st ac,[y,x]       | jmp y,[x]   |
01 | ld [y,$dd]     | ... | st in,[y,$dd]     | jmp y,[$dd] |
02 | ld [x,x]       | ... | st $dd,[y,x]      | jmp y,$dd   |
03 | ld [x,$dd]     | ... | st ac,[y,$dd]     | jmp y,ac    |
04 | ld [x]         | ... | st ac,[x]         | bgt [x]     |
05 | ld [$dd]       | ... | st in,[$dd]       | bgt [$dd]   |
06 | ld $dd         | ... | st $dd,[x]        | bgt $dd     |
07 | ld ac          | ... | st ac,[$dd]       | bgt ac      |
08 | ld [y,x],x     | ... | st ac,[y,x],x     | blt [x]     |
09 | ld [y,$dd],x   | ... | st in,[y,$dd],x   | blt [$dd]   |
0a | ld [x,x],x     | ... | st $dd,[y,x],x    | blt $dd     |
0b | ld [x,$dd],x   | ... | st ac,[y,$dd],x   | blt ac      |
0c | ld [x],x       | ... | st ac,[x],x       | bne [x]     |
0d | ld [$dd],x     | ... | st in,[$dd],x     | bne [$dd]   |
0e | ld $dd,x       | ... | st $dd,[x],x      | bne $dd     |
0f | ld ac,x        | ... | st ac,[$dd],x     | bne ac      |
10 | ld [y,x],y     | ... | st ac,[y,x],y     | beq [x]     |
11 | ld [y,$dd],y   | ... | st in,[y,$dd],y   | beq [$dd]   |
12 | ld [x,x],y     | ... | st $dd,[y,x],y    | beq $dd     |
13 | ld [x,$dd],y   | ... | st ac,[y,$dd],y   | beq ac      |
14 | ld [x],y       | ... | st ac,[x],y       | bge [x]     |
15 | ld [$dd],y     | ... | st in,[$dd],y     | bge [$dd]   |
16 | ld $dd,y       | ... | st $dd,[x],y      | bge $dd     |
17 | ld ac,y        | ... | st ac,[$dd],y     | bge ac      |
18 | ld [y,x++],out | ... | st ac,[y,x++]     | ble [x]     |
19 | ld [y,$dd],out | ... | st in,[y,$dd]     | ble [$dd]   |
1a | ld [x,x++],out | ... | st $dd,[y,x++]    | ble $dd     |
1b | ld [x,$dd],out | ... | st ac,[y,$dd]     | ble ac      |
1c | ld [x],out     | ... | st ac,[x]         | bra [x]     |
1d | ld [$dd],out   | ... | st in,[$dd]       | bra [$dd]   |
1e | ld $dd,out     | ... | st $dd,[x]        | bra $dd     |
1f | ld ac,out      | ... | st ac,[$dd]       | bra ac      |
   +----------------+-----+-------------------+-------------+


[Edit] There are still some things I don't like in this design. The ALU instructions all did get the new mode [X,D], (and destinations X and Y can now use all modes), but the store instructions don't have it. This is a consequence of the store instructions having to specify a data source in addition to an addressing mode, which leads to a shortage of opcodes, as it also continues to specify a destination. The latter is needed to keep supporting the 'accidental' side-effect loads of X or Y.

Even the original design ran into this restriction, and solved it by sacrificing the OUT destination as a side effect on stores, an repurpose the opcodes for implementing the [y,x++] mode on stores without side effects. (Which was convenient, as the ALU instructions with destination OUT also supported this mode.) From the POV of the opcode map it would be logical to reassign other opcodes of the store group with the (suppressed) OUT destination as well: instructions like st ac,[y,$dd] there are now duplicats. So it would be nice if this could be replaced by st ac,[x,$dd]. This would complicate the decoding of the SH signal, which chooses between X an Y as high-address source: it shoul no longer always force Y as a source on store instructions, but make an exception for this one mode/destination combination. (So SH = IR1 & (!W | dest == OUT & src == 3), requirig some extra NAND gates.)

HGMuller
Posts: 20
Joined: 14 May 2018, 05:46

Re: Extending the Gigatron instruction set

Post by HGMuller » 20 May 2018, 21:05

Iteration 2

For simplifying decoder logic, it turned out to be better to invert the meaning of IR2. In addition, rather than selecting X as high address on ALU instructions whenever IR1 was high, it turns out to be more convenient to do this only when IR1 and IR0 are both high. This takes only one extra diode (as IR1 was involved in a wired AND anyway), and replaces the useless mode [X,X] by a duplicat of [Y,X] (equally useless on ALU instructions, but, as we shall see below, useful for stores).

The advantage is that forcing high address = Y (i.e. SH = 0) needs no longer make a distinction between store and ALU instructions, but only between OUT and other destinations. The list of modes then becomes:

Code: Select all

IR0-2   address       bus
       OUT  other   ST    ALU
 0     0,X   0,X   ACCU   RAM
 1     0,D   0,D    IN    RAM
 2     0,X   0,X    D      D
 3     0,D   0,D   ACCU   AC
 4     Y,X++ Y,X   ACCU   RAM
 5     Y,D   Y,D    IN    RAM
 6     Y,X++ Y,X    D     RAM
 7     Y,D   X,D   ACCU   RAM
 
This means the instructions that store ACCU will support mode [X,D] instead of [Y,D] when the 'side-effect' destination is X or Y. (But in the original Gigatron they supported neither of those.) The mode [Y,X] is thus present twice, which is useless for ALU instructions, but allows store instructions to store either immediate data or the accumulator with this mode. The mode [X] has a similar duplication, but in ALU instructions the duplicat occurs when the RAM is deselected, and the immediate data is used as source instead.

On instructions that specify destination OUT and mode 4 or 6 the X register can then be incremented, to provide the mode [Y,X++] instead of [Y,X] for reading data from memory, or for storing D or ACCU, just like in the original Gigatron. Because writing to specified destinations ACCU and OUT is suppressed in store instructions, these encodings would be equivalent, except that they now specify the difference between [Y,X] and [Y,X++] for storing D or ACCU, and between [Y,D] and [X,D] for storing ACCU. So all six memory modes will be available for plain store instructions.

New opcode map

Code: Select all

           00                      c0               e0
   +----------------+-----+-------------------+-------------+
00 |*ld [x],x       | ... |*st ac,[x],x       |*jmp y,[x]   |
01 | ld [$dd],x     | ... | st in,[$dd],x     | jmp y,[$dd] |
02 | ld $dd,x       | ... |*st $dd,[x],x      | jmp y,$dd   |
03 | ld ac,x        | ... | st ac,[$dd],x     | jmp y,ac    |
04 |*ld [y,x],x     | ... |*st ac,[y,x],x     |*bgt [x]     |
05 |*ld [y,$dd],x   | ... |*st in,[y,$dd],x   | bgt [$dd]   |
06 |(ld [y,x],x)    | ... |*st $dd,[y,x],x    | bgt $dd     |
07 |*ld [x,$dd],x   | ... |*st ac,[x,$dd],x   | bgt ac      |
08 |*ld [x],y       | ... |*st ac,[x],y       |*blt [x]     |
09 | ld [$dd],y     | ... | st in,[$dd],y     | blt [$dd]   |
0a | ld $dd,y       | ... |*st $dd,[x],y      | blt $dd     |
0b | ld ac,y        | ... | st ac,[$dd],y     | blt ac      |
0c |*ld [y,x],y     | ... |*st ac,[y,x],y     |*bne [x]     |
0d |*ld [y,$dd],y   | ... |*st in,[y,$dd],y   | bne [$dd]   |
0e |(ld [y,x],y)    | ... |*st $dd,[y,x],y    | bne $dd     |
0f |*ld [x,$dd],y   | ... |*st ac,[x,$dd],y   | bne ac      |
10 | ld [x]         | ... | st ac,[x]         |*beq [x]     |
11 | ld [$dd]       | ... | st in,[$dd]       | beq [$dd]   |
12 | ld $dd         | ... | st $dd,[x]        | beq $dd     |
13 | ld ac          | ... | st ac,[$dd]       | beq ac      |
14 | ld [y,x]       | ... | st ac,[y,x]       |*bge [x]     |
15 | ld [y,$dd]     | ... | st in,[y,$dd]     | bge [$dd]   |
16 |(ld [y,x])      | ... | st $dd,[y,x]      | bge $dd     |
17 |*ld [x,$dd]     | ... |*st ac,[x,$dd]     | bge ac      |
18 |*ld [x],out     | ... |(st ac,[x])        |*ble [x]     |
19 | ld [$dd],out   | ... |(st in,[$dd])      | ble [$dd]   |
1a | ld $dd,out     | ... |(st $dd,[x])       | ble $dd     |
1b | ld ac,out      | ... |(st ac,[$dd])      | ble ac      |
1c | ld [y,x++],out | ... | st ac,[y,x++]     |*bra [x]     |
1d |*ld [y,$dd],out | ... |(st in,[y,$dd])    | bra [$dd]   |
1e |(ld [y,x++],out)| ... | st $dd,[y,x++]    | bra $dd     |
1f |*ld [x,$dd],out | ... | st ac,[y,$dd]     | bra ac      |
   +----------------+-----+-------------------+-------------+
     asterisk indicates new instruction
     parentheses indicate duplicats
New control signals

The orthogonal encoding of the destination register will liberate 11 diodes an 4 pull-up resistors by disbanding the diode matrix, instead connecting the load-control lines directly to the outputs of the mode decoder (which for !XL and !YL was already the case, and for the precursors of !OL an !LD requires a wire bridge). These components will then be used in the now more complex derivation of the address-multiplexer and bus-access control signals. The modification will require one extra 74xx00 (quad 2-input NAND gate) IC.

!AE = !BA0 & !BA3 (instead of !BA2, BA meaning the outputs of the bus-access decoder). This requires 2 diodes and one pull-up.
!DE = !BA2 (instead of !BA0)
!IE = !BA1 (instead of !BA3), the latter two just rewiring pins to different PCB holes.
!OE = !(!BAE) (instead of !BA1, BAE meaning the enable input of the bus-access decoder). This requires an inverter.
IX = INV_A_OUT & BA3 & IR2 (instead of INV_A_OUT). This requires 3 diodes and a pull-up.
SH = IR0 & IR1 & !(INV_A_OUT & W). (Now wired to ground, on U32 and U33.) This requires a NAND gate, 3 diodes and a pull-up.
EL = IR0 (instead of decoded by the diode matrix), just a rewiring.
EH = !(IR2 & !J) (instead of decoded from the diode matrix). This requires a NAND gate.
!BAE = !W & !(IR1 & EH). This requires a NAND gate, 2 diodes, and a pull-up.

If we use a NAND gate with one input tied to Vcc for the inverter this requires 4 NAND gates, in addition to reusing R4 and 10 of the 11 diodes.

Summary of architecture changes

enhancements:
  • All ALU and store instructions support a new addressing mode [x,$dd].
  • ALU instructions with X, or Y as destination now also support modes [x], [y,x] and [y,$dd].
  • ALU instructions with OUT as destination now also support modes [x] and [y,$dd].
  • Store instructions that load X or Y as side effect now also support modes [x] and [y,x] when storing immediate data or the accumulator, and mode [y,$dd] when storing IN.
  • Branch instructions now support mode [x].
new limitations:
  • ALU instructions can no longer use IN as data source.
  • Branches can no longer use IN as branch address.
  • Storing of IN is only possible with mode [$dd].
  • Instructions that use D both as data and (low) address no longer exist.
  • The instructions that stored undefined data no longer exist,
  • Quirky instructions that incremented X without using it for address through the mode [y,x++] no longer exist.

HGMuller
Posts: 20
Joined: 14 May 2018, 05:46

Re: Extending the Gigatron instruction set

Post by HGMuller » 21 May 2018, 17:43

Schematic of the modified bus-access decoder:
giga7.png
giga7.png (28.38 KiB) Viewed 1211 times

User avatar
marcelk
Posts: 268
Joined: 13 May 2018, 08:26

Re: Extending the Gigatron instruction set

Post by marcelk » 23 May 2018, 18:23

More ideas to win speed for your Hackatron Grand Master (HGM):
  1. Hookup a different type of output device so you don't need to worry about VGA signals (LCD or OLED display with I2C or SPI)
  2. Faster chips :-)

HGMuller
Posts: 20
Joined: 14 May 2018, 05:46

Re: Extending the Gigatron instruction set

Post by HGMuller » 24 May 2018, 19:41

marcelk wrote:
23 May 2018, 18:23
Hookup a different type of output device so you don't need to worry about VGA signals (LCD or OLED display with I2C or SPI)
Or a teletype! (Through 300 baud RS232.) Then you can use paper tape for permanent storage of programs. :o

With RS232 you can also connect to the PC COM ports, an run a terminal program there.

tocksin
Posts: 16
Joined: 22 Jun 2018, 14:12

Re: Extending the Gigatron instruction set

Post by tocksin » 13 Jul 2018, 13:58

What about something a little less intrusive? I'd hate to become incompatible with the current instruction set with all of the work people are doing developing the software. What if we just replace the instructions which are currently unusable? Specifically, the store instructions which write to RAM. So, when IR1,IR0 = 01 and /W = 0

My thought was the same as yours - let's create an [X,D] memory access mode to aid in block memory copies. But we only change the above modes. So we disable reading from memory on these instructions, and instead read from AC. And when we do this, we select the upper memory address byte to be the X register. This is a fairly simple change.

We break into the /OE line and make the /newOE = /OE or W. So it will go low normally unless there's also a store command.
We need an extra control line to tell us when we are overriding the normal command which would be /OVERRIDE = (/OE or /W).
We break into the /AE line and make the /newAE = /AE and /OVERRIDE. So it will go low normally and if we are overriding the old command. I'm pretty sure you can't mix wired-ANDs and wired-ORs, so we may need an extra chip here.

Connect the X register to the unused multiplexer input next to the Y input. Then route the inverted /OVERRIDE line to the select pin. So whenever you would normally do a store [Y,X] or [Y,D], now you store [X,X] or [X,D].

So now you do block memory copies by doing a LD [Y,D] to AC, then do a ST [X,D] from AC. Easy-peasy for two wired gates, one extra AND chip, and using the extra inverter while maintaining full reverse compatibility. We could further discuss doing [X++,D] instead to aid in block copies by putting the /OVERRIDE pin into the IX line for one extra diode. So what would you rather have? st AC->[X,D] or st AC->[X++,D] ?

Post Reply