Skip to content
Tech News
← Back to articles

Programming the Gigatron

read original more articles
Why This Matters

The article highlights the programming capabilities of the Gigatron, a retro-inspired microcomputer, showcasing its instruction set and how it can be programmed using simple commands. This demonstrates the ongoing relevance of low-level programming and hardware understanding in the era of advanced processors, inspiring both hobbyists and professionals to explore computing fundamentals.

Key Takeaways

Programming the Gigatron

CPU

CPU instructions

gtemu.c

hi

# 00 # 20 # 40 # 60 # 80 # a0 # c0 # e0 ---+-----------------------+---------------------------+---------------------------+---------------------------+---------------------------+---------------------------+--------------------------+--------------------------------- 00 # A = oper # A &= oper # A |= oper # A ^= oper # A += oper # A -= oper # RAM[oper] = oper # PC = (Y>>8)|oper 04 # A = oper # A &= oper # A |= oper # A ^= oper # A += oper # A -= oper # RAM[X] = oper # if (A < 0) PC = hi(PC)|oper 08 # A = oper # A &= oper # A |= oper # A ^= oper # A += oper # A -= oper # RAM[(Y>>8)|oper] = oper # if (A > 0) PC = hi(PC)|oper 0c # A = oper # A &= oper # A |= oper # A ^= oper # A += oper # A -= oper # RAM[(Y>>8)|X] = oper # if (A != 0) PC = hi(PC)|oper 10 # X = oper # X = A & oper # X = A | oper # X = A ^ oper # X = A + oper # X = A - oper # RAM[oper] = oper; X = A # if (A == 0) PC = hi(PC)|oper 14 # Y = oper # Y = A & oper # Y = A | oper # Y = A ^ oper # Y = A + oper # Y = A - oper # RAM[oper] = oper; Y = A # if (A <= 0) PC = hi(PC)|oper 18 # OUT = oper # OUT = A & oper # OUT = A | oper # OUT = A ^ oper # OUT = A + oper # OUT = A - oper # RAM[oper] = oper # if (A >= 0) PC = hi(PC)|oper 1c # OUT = oper; X++ # OUT = A & oper; X++ # OUT = A | oper; X++ # OUT = A ^ oper; X++ # OUT = A + oper; X++ # OUT = A - oper; X++ # RAM[(Y>>8)|X++] = oper # PC = hi(PC)|oper 01 # A = RAM[oper] # A &= RAM[oper] # A |= RAM[oper] # A ^= RAM[oper] # A += RAM[oper] # A -= RAM[oper] # RAM[oper] = undef # PC = (Y>>8)|RAM[oper] 05 # A = RAM[X] # A &= RAM[X] # A |= RAM[X] # A ^= RAM[X] # A += RAM[X] # A -= RAM[X] # RAM[X] = undef # if (A < 0) PC = hi(PC)|RAM[oper] 09 # A = RAM[(Y>>8)|oper] # A &= RAM[(Y>>8)|oper] # A |= RAM[(Y>>8)|oper] # A ^= RAM[(Y>>8)|oper] # A += RAM[(Y>>8)|oper] # A -= RAM[(Y>>8)|oper] # RAM[(Y>>8)|oper] = undef # if (A > 0) PC = hi(PC)|RAM[oper] 0d # A = RAM[(Y>>8)|X] # A &= RAM[(Y>>8)|X] # A |= RAM[(Y>>8)|X] # A ^= RAM[(Y>>8)|X] # A += RAM[(Y>>8)|X] # A -= RAM[(Y>>8)|X] # RAM[(Y>>8)|X] = undef # if (A != 0) PC = hi(PC)|RAM[oper] 11 # X = RAM[oper] # X = A & RAM[oper] # X = A | RAM[oper] # X = A ^ RAM[oper] # X = A + RAM[oper] # X = A - RAM[oper] # RAM[oper] = undef; X = A # if (A == 0) PC = hi(PC)|RAM[oper] 15 # Y = RAM[oper] # Y = A & RAM[oper] # Y = A | RAM[oper] # Y = A ^ RAM[oper] # Y = A + RAM[oper] # Y = A - RAM[oper] # RAM[oper] = undef; Y = A # if (A <= 0) PC = hi(PC)|RAM[oper] 19 # OUT = RAM[oper] # OUT = A & RAM[oper] # OUT = A | RAM[oper] # OUT = A ^ RAM[oper] # OUT = A + RAM[oper] # OUT = A - RAM[oper] # RAM[oper] = undef # if (A >= 0) PC = hi(PC)|RAM[oper] 1d # OUT = RAM[(Y>>8)|X++] # OUT = A & RAM[(Y>>8)|X++] # OUT = A | RAM[(Y>>8)|X++] # OUT = A ^ RAM[(Y>>8)|X++] # OUT = A + RAM[(Y>>8)|X++] # OUT = A - RAM[(Y>>8)|X++] # RAM[(Y>>8)|X++] = undef # PC = hi(PC)|RAM[oper] 02 # /*nop*/ # /*nop*/ # /*nop*/ # A = 0 # A *= 2 # A = 0 # RAM[oper] = A # PC = (Y>>8)|A 06 # /*nop*/ # /*nop*/ # /*nop*/ # A = 0 # A *= 2 # A = 0 # RAM[X] = A # if (A < 0) PC = hi(PC)|A 0a # /*nop*/ # /*nop*/ # /*nop*/ # A = 0 # A *= 2 # A = 0 # RAM[(Y>>8)|oper] = A # if (A > 0) PC = hi(PC)|A 0e # /*nop*/ # /*nop*/ # /*nop*/ # A = 0 # A *= 2 # A = 0 # RAM[(Y>>8)|X] = A # if (A != 0) PC = hi(PC)|A 12 # X = A # X = A # X = A # X = 0 # X = 2*A # X = 0 # RAM[oper] = A; X = A # if (A == 0) PC = hi(PC)|A 16 # Y = A # Y = A # Y = A # Y = 0 # Y = 2*A # Y = 0 # RAM[oper] = A; Y = A # if (A <= 0) PC = hi(PC)|A 1a # OUT = A # OUT = A # OUT = A # OUT = 0 # OUT = 2*A # OUT = 0 # RAM[oper] = A # if (A >= 0) PC = hi(PC)|A 1e # OUT = A; X++ # OUT = A; X++ # OUT = A; X++ # OUT = 0; X++ # OUT = 2*A; X++ # OUT = 0; X++ # RAM[(Y>>8)|X++] = A # PC = hi(PC)|A 03 # A = IN # A &= IN # A |= IN # A ^= IN # A += IN # A -= IN # RAM[oper] = IN # PC = (Y>>8)|IN 07 # A = IN # A &= IN # A |= IN # A ^= IN # A += IN # A -= IN # RAM[X] = IN # if (A < 0) PC = hi(PC)|IN 0b # A = IN # A &= IN # A |= IN # A ^= IN # A += IN # A -= IN # RAM[(Y>>8)|oper] = IN # if (A > 0) PC = hi(PC)|IN 0f # A = IN # A &= IN # A |= IN # A ^= IN # A += IN # A -= IN # RAM[(Y>>8)|X] = IN # if (A != 0) PC = hi(PC)|IN 13 # X = IN # X = A & IN # X = A | IN # X = A ^ IN # X = A + IN # X = A - IN # RAM[oper] = IN; X = A # if (A == 0) PC = hi(PC)|IN 17 # Y = IN # Y = A & IN # Y = A | IN # Y = A ^ IN # Y = A + IN # Y = A - IN # RAM[oper] = IN; Y = A # if (A <= 0) PC = hi(PC)|IN 1b # OUT = IN # OUT = A & IN # OUT = A | IN # OUT = A ^ IN # OUT = A + IN # OUT = A - IN # RAM[oper] = IN # if (A >= 0) PC = hi(PC)|IN 1f # OUT = IN; X++ # OUT = A & IN; X++ # OUT = A | IN; X++ # OUT = A ^ IN; X++ # OUT = A + IN; X++ # OUT = A - IN; X++ # RAM[(Y>>8)|X++] = IN # PC = hi(PC)|IN

Next, I wrote a progam to parse the theloop.asm file to discover which instructions are actually used. This resulted in the following output given below. In the first column the hexadecimal instruction number, in the second column the number of times the instruction is mentioned in the file, in the third column the pseudo-C code, and in the last column the mnemonic being used in the file. $00 stands for the operand.

inst # pseudo-C mnemonic ------------------------------------------------------------- 02 586: /*nop*/ // nop 00 54305: A = oper // ld $00 01 505: A = RAM[oper] // ld [$00] 03 1: A = IN // ld in 05 26: A = RAM[X] // ld [x] 09 2: A = RAM[(Y<<8)|oper] // ld [y,$00] 0d 32: A = RAM[(Y<<8)|X] // ld [y,x] 10 1: X = oper // ld $00,x 11 27: X = RAM[oper] // ld [$00],x 12 11: X = A // ld ac,x 14 326: Y = oper // ld $00,y 15 19: Y = RAM[oper] // ld [$00],y 16 2: Y = A // ld ac,y 18 14: OUT = oper // ld $00,out 19 6: OUT = RAM[oper] // ld [$00],out 20 33: A &= oper // anda $00 21 8: A &= RAM[oper] // anda [$00] 25 2: A &= RAM[X] // anda [x] 29 2: A &= RAM[(Y<<8)|oper] // anda [y,$00] 30 9: X = A & oper // anda $00,x 40 14: A |= oper // ora $00 41 17: A |= RAM[oper] // ora [$00] 45 3: A |= RAM[X] // ora [x] 50 6: X = A | oper // ora $00,x 5d 3: OUT = A | RAM[(Y<<8)|X++] // ora [y,x++],out 60 16: A ^= oper // xora $bf 61 11: A ^= RAM[oper] // xora [$00] 69 5: A ^= RAM[(Y<<8)|oper] // xora [y,$00] 80 402: A += oper // adda $00 81 28: A += RAM[oper] // adda [$00] 82 36: A *= 2 // adda ac 85 2: A += RAM[X] // adda [x] 89 6: A += RAM[(Y<<8)|oper] // adda [y,$00] 8d 4: A += RAM[(Y<<8)|X] // adda [y,x] 90 11: X = A + oper // adda $00,x 91 1: X = A + RAM[oper] // adda [$00],x 92 2: X = 2*A // adda ac,x 95 1: Y = A + RAM[oper] // adda [$00],y a0 28: A -= oper // suba $00 a1 3: A -= RAM[oper] // suba [$00] a5 5: A -= RAM[X] // suba [x] b0 3: X = A - oper // suba $00,x c0 4: RAM[oper] = oper // st $00,[$00] c2 662: RAM[oper] = A // st [$00] c3 2: RAM[oper] = IN // st in,[$00] c6 8: RAM[X] = A // st [x] ca 6: RAM[(Y<<8)|oper] = A // st [y,$00] ce 9: RAM[(Y<<8)|X] = A // st [y,x] d2 7: RAM[oper] = A; X = A // st [$00],x d6 8: RAM[oper] = A; Y = A // st [$00],y de 27: RAM[(Y<<8)|X++] = A // st [y,x++] dc 52: RAM[(Y<<8)|X++] = oper // st $00,[y,x++] e0 314: PC = (Y<<8)|oper // jmp y,$00 e1 2: PC = (Y<<8)|RAM[oper] // jmp y,[$00] e2 13: PC = (Y<<8)|A // jmp y,ac e4 3: if (A > 0) PC = hi(PC)|oper // bgt $00 e8 14: if (A < 0) PC = hi(PC)|oper // blt $00 ec 30: if (A != 0) PC = hi(PC)|oper // bne $00 f0 10: if (A == 0) PC = hi(PC)|oper // beq $00 f4 5: if (A >= 0) PC = hi(PC)|oper // bge $00 f8 2: if (A <= 0) PC = hi(PC)|oper // ble $00 fc 497: PC = hi(PC)|oper // bra $00 fd 2: PC = hi(PC)|RAM[oper] // bra [$00] fe 612: PC = hi(PC)|A // bra ac

vCPU

vCPU instructions

... continue reading