Page 2 of 3

Re: Assembling Gigatron the hard way

Posted: 28 Apr 2019, 16:13
by pythag
I wasn't aware of the branch delay slot, nor the Youtube videos! I'll go and listen / learn....

Your Youtube link was broken - were you referring to the Hack42 Lecture?

Re: Assembling Gigatron the hard way

Posted: 28 Apr 2019, 16:19
by pythag
Okay, so looking at the schematics a low on PL should cause it to load the PC from the Bus, so PL being low means take the branch.... so why does my simulation show a low in PL yet not jump.... Looks like I've made some other silly mistake in modifying the simulator code.....

Re: Assembling Gigatron the hard way

Posted: 28 Apr 2019, 19:06
by pythag
Thanks for the video link - both really interesting and really useful!

It's certainly helped me understand more about the branch control logic.

Back at the problem in hand - my low PL line on the breadboard is because the CO line from the ALU is low during the BCC instruction.... there are so many possibilities for the cause of it - I just need to go through and eliminate them one at a time.

At least I've pretty much confirmed there are no faults in the instruction decoder, which if I'm honest is where I assumed the fault was most likely to be.

Re: Assembling Gigatron the hard way

Posted: 28 Apr 2019, 20:06
by pythag
So getting closer and learning more at the same time (which was the original aim of this!)

I bit the bullet and wired up the AC register outputs to the Arduino so I could monitor them... this immediately revealed a stuck-at-one bit (AC4)... This was quickly traced to a misplaced wire.

The subsequent run then helped explain why I was seeing PL low in the cycle I expected it to be high in the simulation... it wasn't exactly related to the branch delay slot, but simply that I hadn't taken the concept of the CLK2 pulse into account on the simulator, so some signals appeared a cycle out.

The latest run reveals there are still further problems - although I suspect these are actual memory read mismatches.

Run results below for anyone playing along at home:

(again ignore the contents of the 'DATA' register in the real thing - I'm using those inputs to monitor other signals of interest at the time).

Code: Select all

ld(0b0000);				# OUT = 0x0
                                                                                
Clock cycle:1  ROM Lookup: IR:0 D:0                                             
                                                                                
ROM ADR:0001 BUS:00 (000000000) Data:80 (010000000)                             
IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]                   
Y:00 (000000000) AC:00 (000000000) YL:0 XL:0 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
PC:1 IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]              
D:00 AC:FF (011111111) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:1                              
---------------                                                                 
ld(syncBits^hSync, OUT)		# OUT = 0x80

Clock cycle:2  ROM Lookup: IR:18 D:80                                           
                                                                                
ROM ADR:0002 BUS:80 (010000000) Data:A0 (010100000)                             
IR:18 [ins:0-LD  00011 mod:6-1101 bus-0000-ROM W:0 J:0 LD:1 ]                   
Y:00 (000000000) AC:00 (000000000) YL:0 XL:0 EH:1 EL:1 OL:0 LD:1 PL:1 PH:1      
                                                                                
PC:2 IR:18 [ins:0-LD  00011 mod:6-1101 bus-0000-ROM W:0 J:0 LD:1 ]              
D:80 AC:00 (000000000) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:0 LD:1 PL:1 PH:1 CO:0 AC7:0                              
---------------                                                                 
ld(syncBits, OUT)               	# OUT = 0xC0

Clock cycle:3  ROM Lookup: IR:18 D:C0                                           
                                                                                
ROM ADR:0003 BUS:C0 (011000000) Data:A0 (010100000)                             
IR:18 [ins:0-LD  00011 mod:6-1101 bus-0000-ROM W:0 J:0 LD:1 ]                   
Y:00 (000000000) AC:00 (000000000) YL:0 XL:0 EH:1 EL:1 OL:0 LD:1 PL:1 PH:1      
                                                                                
PC:3 IR:18 [ins:0-LD  00011 mod:6-1101 bus-0000-ROM W:0 J:0 LD:1 ]              
D:C0 AC:00 (000000000) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:0 LD:1 PL:1 PH:1 CO:0 AC7:0                              
---------------                                                                 
ld(1); 					# AC = 1

Clock cycle:4  ROM Lookup: IR:0 D:1                                             
                                                                                
ROM ADR:0004 BUS:01 (000000001) Data:80 (010000000)                             
IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]                   
Y:00 (000000000) AC:01 (000000001) YL:0 XL:0 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
PC:4 IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]              
D:01 AC:00 (000000000) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:0                              
---------------                                                                 
st([memSize], Y)			# Y = &memSize (1 as it happens), so Y = 1, Also RAM[1] = AC

Clock cycle:5  ROM Lookup: IR:D6 D:1                                            
                                                                                
ROM ADR:0005 BUS:01 (000000001) Data:22 (000100010)                             
IR:D6 [ins:6-ST  11111 mod:5-1111 bus-0010-AC  W:1 J:0 LD:1 ]                   
Y:00 (000000000) AC:01 (000000001) YL:0 XL:0 EH:1 EL:1 OL:1 LD:1 PL:1 PH:1      
                                                                                
PC:5 IR:D6 [ins:6-ST  11111 mod:5-1111 bus-0010-AC  W:1 J:0 LD:1 ]              
D:01 AC:01 (000000001) X:00 Y:01                                                
YL:0 XL:0 EH:1 EL:1 OL:1 LD:1 PL:1 PH:1 CO:0 AC7:0                              

Writing 1 to address 1                                                          
---------------                                                                 
ld(255)					# AC = 255

Clock cycle:6  ROM Lookup: IR:0 D:FF                                            
                                                                                
ROM ADR:0006 BUS:FF (011111111) Data:88 (010001000)                             
IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]                   
Y:00 (000000000) AC:FF (011111111) YL:0 XL:0 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
PC:6 IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]              
D:FF AC:01 (000000001) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:0                              
---------------                                                                 
xora([Y,0])					# AC = XOR(RAM[Y<<8+0],AC) - So store the inverse of what is in RAM at Y<<8+0 in AC

Clock cycle:7  ROM Lookup: IR:69 D:0                                            
                                                                                
ROM ADR:0007 BUS:C0 (011000000) Data:A8 (010101000)                             
IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]                   
Y:00 (000000000) AC:CF (011001111) YL:0 XL:0 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
PC:7 IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]              
D:00 AC:FF (011111111) X:00 Y:01                                                
YL:1 XL:1 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:1                              

Read 0 from 256                                                                 
---------------                                                                 
st([Y,0])					# RAM[Y<<8+0] = AC - Write the inverse of the existing value to RAM at Y<<8+0

Clock cycle:8  ROM Lookup: IR:CA D:0                                            
                                                                                
ROM ADR:0008 BUS:CF (011001111) Data:28 (000101000)                             
IR:CA [ins:6-ST  11111 mod:2-0110 bus-0010-AC  W:1 J:0 LD:1 ]                   
Y:00 (000000000) AC:CF (011001111) YL:0 XL:0 EH:0 EL:1 OL:1 LD:1 PL:1 PH:1      
                                                                                
PC:8 IR:CA [ins:6-ST  11111 mod:2-0110 bus-0010-AC  W:1 J:0 LD:1 ]              
D:00 AC:FF (011111111) X:00 Y:01                                                
YL:1 XL:1 EH:0 EL:1 OL:1 LD:1 PL:1 PH:1 CO:0 AC7:1                              

Writing 255 to address 256                                                      
---------------                                                                 
st([0])					# RAM[0] = AC - Store a copy of this inverted value in RAM[0]

Clock cycle:9  ROM Lookup: IR:C2 D:0                                            
                                                                                
ROM ADR:0009 BUS:CF (011001111) Data:08 (000001000)                             
IR:C2 [ins:6-ST  11111 mod:0-1110 bus-0010-AC  W:1 J:0 LD:1 ]                   
Y:00 (000000000) AC:CF (011001111) YL:0 XL:0 EH:1 EL:1 OL:1 LD:1 PL:1 PH:1      
                                                                                
PC:9 IR:C2 [ins:6-ST  11111 mod:0-1110 bus-0010-AC  W:1 J:0 LD:1 ]              
D:00 AC:FF (011111111) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:1 LD:1 PL:1 PH:1 CO:0 AC7:1                              

Writing 255 to address 0                                                        
---------------                                                                 
xora([Y,0])					# AC = XOR(RAM[Y<<8+0],AC) - XOR with the inverted value, so we should end up with zero in RAM (and AC as it also gets stored there too).

Clock cycle:10  ROM Lookup: IR:69 D:0                                           
                                                                                
ROM ADR:000A BUS:CF (011001111) Data:E0 (011100000)                             
IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]                   
Y:00 (000000000) AC:00 (000000000) YL:0 XL:0 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
PC:10 IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]             
D:00 AC:FF (011111111) X:00 Y:01                                                
YL:1 XL:1 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:1                              

Read 255 from 256                                                               
---------------                                                                 
bne(pc())					# IF AC!=0 loop

Clock cycle:11  ROM Lookup: IR:EC D:A                                           
                                                                                
ROM ADR:000B BUS:0A (000001010) Data:A3 (010100011)                             
IR:EC [ins:7-BCC 01010 mod:3-1111 bus-0000-ROM W:0 J:1-cond LD:1 ]              
Y:00 (000000000) AC:00 (000000000) YL:0 XL:0 EH:1 EL:1 OL:1 LD:1 PL:0 PH:1      
                                                                                
PC:11 IR:EC [ins:7-BCC 01010 mod:3-1111 bus-0000-ROM W:0 J:1-cond LD:1 ]        
D:0A AC:00 (000000000) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:1 LD:1 PL:0 PH:1 CO:0 AC7:0                              
---------------                                                                 
Clock cycle:12  ROM Lookup: IR:69 D:0                                           
                                                                                
ROM ADR:000A BUS:FF (011111111) Data:88 (010001000)                             
IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]                   
Y:80 (010000000) AC:FF (011111111) YL:0 XL:0 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
PC:12 IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]             
D:FF AC:00 (000000000) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:0                              
---------------                                                                 
Clock cycle:13  ROM Lookup: IR:EC D:A                                           
                                                                                
ROM ADR:000B BUS:0A (000001010) Data:BB (010111011)                             
IR:EC [ins:7-BCC 01010 mod:3-1111 bus-0000-ROM W:0 J:1-cond LD:1 ]              
Y:00 (000000000) AC:FF (011111111) YL:0 XL:0 EH:1 EL:1 OL:1 LD:1 PL:0 PH:1      
                                                                                
PC:13 IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]             
D:00 AC:FF (011111111) X:00 Y:01                                                
YL:1 XL:1 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:1                              
---------------                                                                 


I hope nobody minds me posting updates... if you can't share the journey and excitement of chasing down problems in what can only be described as a big-mess-of-wires then what's the internet for!!!

Re: Assembling Gigatron the hard way

Posted: 29 Apr 2019, 07:08
by pythag
So the instruction I'm sticking on now is cycle 7:

Code: Select all

Clock cycle:6  ROM Lookup: IR:0 D:FF                                            
                                                                                
ROM ADR:0006 BUS:FF (011111111) Data:88 (010001000)                             
IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]                   
Y:00 (000000000) AC:FF (011111111) YL:0 XL:0 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
Writing 1 to address 1                                                          
PC:6 IR:00 [ins:0-LD  00011 mod:0-1110 bus-0000-ROM W:0 J:0 LD:0 ]              
D:FF AC:01 (000000001) X:00 Y:01                                                
YL:1 XL:1 EH:1 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:0                              
---------------                                                                 
Clock cycle:7  ROM Lookup: IR:69 D:0                                            
                                                                                
ROM ADR:0007 BUS:C0 (011000000) Data:A8 (010101000)                             
IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]                   
Y:00 (000000000) AC:CF (011001111) YL:0 XL:0 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
PC:7 IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]              
D:00 AC:FF (011111111) X:00 Y:01                                                
YL:1 XL:1 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:1                              
---------------                                                                 
So in cycle 6 (ld 255) we see the AC register go to 0xFF as expected.

In cycle 7 (xora([Y,0])) our AC register ends up at 0xCF instead of 0xFF.

I'm trying to understand what this instruction is supposed to do... (I'm afraid it's not as obvious to me as you might think).

The mod part of IR decodes to 0x2 so that means store in the AC register (with the high address coming from Y).
The bus part of the IR decodes to 0x01 so that means the 'B' part of the operation comes from RAM

So this means AC=XOR(RAM[Y<<8+D],AC)

As D is 0 in our case and Y is 1 this means read from RAM from address 256 and XOR it with what is already in the AC register (0xFF)? At this point though address 256 hasn't been written?

Re: Assembling Gigatron the hard way

Posted: 29 Apr 2019, 07:21
by marcelk
The mem test tries if it can write to some memory locations. For that you must first know what's there. It also tries to be non-destructive, so at the end of the loop the original value gets written back.

Re: Assembling Gigatron the hard way

Posted: 29 Apr 2019, 08:39
by pythag
So... Mostly for my own benefit here is the totally annotated version:

Code: Select all

ld(0b0000);				# OUT = 0x0
ld(syncBits^hSync, OUT)			# OUT = 0x80
ld(syncBits, OUT)               	# OUT = 0xC0

ld(1); 					# AC = 1
st([memSize], Y)			# Y = &memSize (1 as it happens), so Y = 1, Also RAM[1] = AC
ld(255)					# AC = 255
xora([Y,0])				# AC = XOR(RAM[Y<<8+0],AC) - So store the inverse of what is in RAM at Y<<8+0 in AC
st([Y,0])				# RAM[Y<<8+0] = AC - Write the inverse of the existing value to RAM at Y<<8+0
st([0])					# RAM[0] = AC - Store a copy of this inverted value in RAM[0]
xora([Y,0])				# AC = XOR(RAM[Y<<8+0],AC) - XOR what is in RAM at Y<<8+0 with the inverted value stored in AC, so we should end up with zero in AC
bne(pc())				# IF AC!=0 loop
Is this correct?

Re: Assembling Gigatron the hard way

Posted: 29 Apr 2019, 09:47
by pythag
Hmmm... This is very suspicious....

Code: Select all

xora([Y,0])					# AC = XOR(RAM[Y<<8+0],AC) - So store the inverse of what is in RAM at Y<<8+0 in AC

Clock cycle:7  ROM Lookup: IR:69 D:0                                            
                                                                                
ROM ADR:0007 BUS:C0 (011000000) Data:A8 (010101000)                             
IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]                   
Y:00 (000000000) AC:CF (011001111) YL:0 XL:0 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1      
                                                                                
PC:7 IR:69 [ins:3-XOR 01001 mod:2-0110 bus-0001-RAM W:0 J:0 LD:0 ]              
D:00 AC:FF (011111111) X:00 Y:01                                                
YL:1 XL:1 EH:0 EL:1 OL:1 LD:0 PL:1 PH:1 CO:0 AC7:1                              
As the data on the bus at this point is 11000000 it suggests that's what happened to be in that RAM location.
AC then ends up with 11001111.... I wonder if the wires 4/5 and 6/7 have been swapped somewhere....

Re: Assembling Gigatron the hard way

Posted: 29 Apr 2019, 10:18
by marcelk
pythag wrote: 29 Apr 2019, 08:39

Code: Select all

xora([Y,0]) # AC = XOR(RAM[Y<<8+0],AC) - XOR with the inverted value, so we should end up with zero in RAM (and AC as it also gets stored there too).
Is this correct?
Almost. xora doesn't write to RAM. Only st can write to RAM.

The mem test also tests some/most of the ALU. My 74F board had a shorted pin 7 of U20, and failed the memory test due to that.

Re: Assembling Gigatron the hard way

Posted: 29 Apr 2019, 10:28
by pythag
Yes, of course (I even wrote that in pseudo code then managed to read my own pseudo code wrong!!!!).

I've updated my previous post so if anyone in the future happens to read this thread they don't get confused by my mistakes!