-
Two birds with one stone
05/21/2017 at 16:01 • 2 commentsAn Atari joystick will do as input device for the games I have in mind. But the breadboard computer has the potential to run a BASIC. For that, keyboard input would be great. USB is out of the question, and even PS/2 looks a bit involved. A simple matrix keyboard would be a better starting point.
Also, at some point I'll need an enclosure to keep dust out and to be able to bring it to places.
Today, I might have stumbled upon the solution for both problems.
[ Edit: to the millions of voices that suddenly cried out in terror: it had a broken PLA chip ]
-
Homebrew CPU webring
05/21/2017 at 08:40 • 0 commentsMy breadboard TTL color computer is now included in David R. Brooks' Homebrew CPU webring. How cool is that!
In the meantime I have figured out how to mix video with application code. Next week we'll have a 5-day holiday, and if there are some rainy days in there I expect to get some animated output from this thing by then.
-
First video out
05/13/2017 at 18:23 • 0 commentsIt seems I have reached the base camp. The el-cheapo 7-inch LCD monitor on the right is connected to the output port of my breadboard TTL computer. The computer is now running at 6.3MHz and runs a software loop that generates a VGA test signal. The colors look a bit off, and still not all wiring is done and tidied up, but the mountain top is definitely in sight.
As far as I can check with the oscilloscope, the signals are behaving nicely according to the VGA industry standard 640x480 at 60Hz. Yellow is the vertical sync and light blue is the horizontal sync.
The disassembly of the code:
0000 0009 ld $09 ; setup for 10 lines vertical front porch 0001 a001 suba $01 ; next line in vertical blank 0002 c200 st [$00] 0003 0200 nop 0004 0008 ld $08 ; entry point for starting a new frame, inside the first hsync 0005 ec05 bne $05 0006 a001 suba $01 0007 0200 nop 0008 18c0 ld $c0,out ; end of first hsync in frame 0009 0055 ld $55 000a ec0a bne $0a 000b a001 suba $01 000c 0100 ld [$00] 000d ec01 bne $01 000e 1880 ld $80,out ; new hsync start 000f 000a ld $0a 0010 ec10 bne $10 0011 a001 suba $01 0012 18c0 ld $c0,out ; hsync end 0013 0054 ld $54 0014 ec14 bne $14 0015 a001 suba $01 0016 1840 ld $40,out ; vsync start 0017 0200 nop 0018 0200 nop 0019 0200 nop 001a 1800 ld $00,out ; hsync during vsync 001b 000a ld $0a 001c ec1c bne $1c 001d a001 suba $01 001e 1840 ld $40,out ; hsync end 001f 0056 ld $56 0020 ec20 bne $20 0021 a001 suba $01 0022 1800 ld $00,out ; hsync during vsync 0023 000a ld $0a 0024 ec24 bne $24 0025 a001 suba $01 0026 1840 ld $40,out ; back porch 0027 0054 ld $54 0028 ec28 bne $28 0029 a001 suba $01 002a 18c0 ld $c0,out ; 33 lines black 002b 0200 nop 002c 0200 nop 002d 0020 ld $20 002e 1880 ld $80,out 002f a001 suba $01 0030 c200 st [$00] 0031 0009 ld $09 0032 ec32 bne $32 0033 a001 suba $01 0034 18c0 ld $c0,out 0035 0055 ld $55 0036 ec36 bne $36 0037 a001 suba $01 0038 0100 ld [$00] 0039 ec2f bne $2f 003a 1880 ld $80,out 003b 000a ld $0a 003c ec3c bne $3c 003d a001 suba $01 003e 18c0 ld $c0,out 003f 0055 ld $55 0040 ec40 bne $40 0041 a001 suba $01 0042 0200 nop 0043 00e0 ld $e0 0044 1880 ld $80,out 0045 a001 suba $01 0046 c200 st [$00] 0047 0009 ld $09 0048 ec48 bne $48 0049 a001 suba $01 004a 18c0 ld $c0,out 004b 0004 ld $04 004c ec4c bne $4c 004d a001 suba $01 004e 18d5 ld $d5,out ; first colors 004f 0003 ld $03 ; 9 clock delay 0050 ec50 bne $50 0051 a001 suba $01 0052 18d7 ld $d7,out ; second color bar 0053 0003 ld $03 0054 ec54 bne $54 0055 a001 suba $01 0056 18dd ld $dd,out ; third color bar [...snip...] 008a 18ea ld $ea,out ; last color bar 008b 0003 ld $03 008c ec8c bne $8c 008d a001 suba $01 008e 18c0 ld $c0,out ; back to black (front porch) 008f 0200 nop 0090 0100 ld [$00] 0091 ec45 bne $45 ; repeat for 480-256 = 224 lines 0092 1880 ld $80,out ; hsync start 0093 a001 suba $01 0094 c200 st [$00] 0095 0009 ld $09 0096 ec96 bne $96 0097 a001 suba $01 0098 18c0 ld $c0,out ; hsync end 0099 0004 ld $04 009a ec9a bne $9a 009b a001 suba $01 009c 18ea ld $ea,out ; second half of screen (256 lines) 009d 0003 ld $03 009e ec9e bne $9e 009f a001 suba $01 [...snip...] 00e1 0008 ld $08 00e2 fc04 bra $04 ; to new frame 00e3 c200 st [$00]
-
Fibonacci
05/11/2017 at 00:33 • 2 commentsWith the ALU verified and the RAM connected, today the breadboard determined that the first 8-bit Fibonacci number is 144.
0000 0000 ld $00 ; outer loop 0001 c200 st [$00] ; a=0 0002 0001 ld $01 ; b=1 0003 fc0a bra $0a 0004 0200 nop ; (pipelining) 0005 0100 ld [$00] ; inner loop 0006 c202 st [$02] ; tmp=a 0007 0101 ld [$01] 0008 c200 st [$00] ; a=b 0009 8102 adda [$02] 000a c201 st [$01] ; b+=tmp 000b 1a00 ld ac,out ; emit next Fibonacci number 000c f405 bge $05 ; repeat if bit7 is still 0 000d 0200 nop ; (pipelining) 000e fc00 bra $00 ; start over again 000f 0200 nop ; (pipelining)
The inner loop runs 12 times (1, 1, 2, 3, 5, .... 89, 144). The entire thing takes 110 cycles. Both are exactly as expected. It can be done faster but I didn't optimise the assembly to maintain my sanity.
I also hooked up a cute little MCP100-475 to the program counter reset line. This gives a controlled reset during power up. The circuit is now 90% wired. Only the high memory address control and some diodes are missing for full functionality.
-
74LS377 for speed
05/06/2017 at 13:34 • 5 commentsThe project uses '377 chips for the accumulator and output registers instead of the more obvious '273. The difference is pin 1. In the '273 this is a reset pin and we don't need that. In the '377 this is a (negative) enable pin, and that is very useful. It simplifies the control logic in the case of consecutive loads. To see why, consider the timing diagram:
The '377 can be wired directly to the clock on pin 11 and to the register address decoder on pin 1. If we were to use the '273, we only have pin 11. But if that is connected to the decoder, as in the middle case, consecutive loads don't work: only the last load will give a positive edge and therefore transfer a value. The earlier load values are missed. This is not good for the accumulator and for output, as each value can be important.
To make the '273 work, you need to put the logical OR of CLK and /EN on pin 11, so you get two edges. But the control logic doesn't have spare OR gates available, so that would cost an additional 74LS32 chip. Either that, or it would cost speed, because you can simulate the effect in software with NOP instructions. But then we are also stuck with half the horizontal resolution for the video signal. Not nice.
For the other registers these considerations don't hold and they can keep using the '273.
Today my order of '377 IC's has arrived, so the project can continue.
-
Ground control
05/02/2017 at 11:15 • 2 commentsThis is the glitch I was still contemplating yesterday:
It isn't a EEPROM timing issue after all. Low signals into the instruction decoder just weren't always low enough. The culprit turned out to be the IR register's ground pin:
Signals look much better with that sorted out:
Next is the verification of the ALU.
-
First program run
05/02/2017 at 00:23 • 2 commentsInstead of wiring up the whole thing it is better to do a minimalistic wiring that allows basic testing before proceeding. It is possible to write simple programs without using RAM, X, Y and the EA unit, so those are still left out. Today the first program is running:
The test program is doing 7 simple load instructions followed by a jump back to address 0. Because the system is pipelined, the instruction in memory immediately behind the jump instruction (at address 8, or 1000 in binary) also gets executed, yielding a cycle of 9. The assembly looks like this:
address | encoding | | opcode | | | operand | | | | V V V V 0000 0000 ld $00 0001 0001 ld $01 0002 0002 ld $02 0003 0003 ld $03 0004 0004 ld $04 0005 0005 ld $05 0006 0006 ld $06 0007 fc00 bra $00 0008 0008 ld $08
I put in a slower oscillator so that it easier for me to interpret the timing. For now, 1 µs = 1 clock tick. The scope in the photo traces ROM address line 3, bus line 0 and the decoding output for "ld" and "jump". You can't actually observe the data passing through the ALU here and entering the AC register. That can only be fully tested once the 74LS377's have arrived and they are still on the boat from China.
-
The Zen of breadboard wiring
04/27/2017 at 22:30 • 0 commentsWell over 50% wired now. I start to appreciate the invention of the PCB.
-
Condition codes
04/23/2017 at 21:00 • 5 commentsDuring jump, the ALU is wired to calculate "-AC". Only the carry out is looked at. The negation result itself is not used and discarded.
What's the use of this? Well, only in case of all-zero bits, "-AC" overflows the ALU, setting its carry-out line. So in this case the carry out acts as a zero indicator (Z). If we also look at bit 7 of AC, we also know if AC is negative or positive. The combination of these two signals makes all condition codes possible:
With this, a single 74153 chip can decode the condition code from the opcode, compare it to the contents of AC, and determine if a jump is needed.
-
Control unit design
04/16/2017 at 18:13 • 0 commentsIf you want to have a fighting chance of ending up with a small design, the instruction set follows the control unit and not the other way around. While writing the assembler I found that I had overlooked something in my original 4 or 5 IC design. I didn't want to proceed with anything else until this was settled. So back to the drawing board. I managed to solve everything within 5 chips, but still with a somewhat limited repertoire for conditional jumps: still only BPL and BMI were present. Doable, but not nice. After some puzzling, I figured I could get a complete conditional jump set with just one additional 74153 IC. I think the benefits outweigh the extra IC, so it is in for now. The clock will have to move over to another place on the breadboard, because this will take up the whole upper right board.
Designing the control unit turned out to be a bigger challenge than I had anticipated. I will let it rest for a couple of days. If I don't find any new oversights in that time, this is what it will look like. The instruction set follows from this, more on that another time.
[ Edit: Only one real issue found since writing this: the write instructions had unintended side effects. Also some of the wired logic was wrong, fixed that. We now use the '138 instead of '155, and AC/OUT must become '377 instead of '273. With that it still fits in 6 chips, although the wired AND remains a bit of a wart. ]