This evening I closed the I/O loop on the machine. That is wrote an assembly program that firstly echos out some text and numerals to the console. Then accepts input to the console and echos it back out. The basic I/O loop. Getting my head around it gradually. This works both in the simulator and in the FPGA in the T-35 in the S-100 machine. The FPGA code is now available here FPGA CODE
! N
! $ COMBINED - ASCII nibble output: "HELLO WORLD" + "01234567" + ECHO POLL
! PR(ON) MR(ON) EW(ON) FS(ON)
! X ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 )
! Y ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 )
! MMAN
;
; Encoding: standard 8-bit ASCII, split into two 4-bit nibbles per character.
; Each 24-bit word holds 2 ASCII chars packed as:
; [high_nibble_A:4][00:2][low_nibble_A:4][00:2][high_nibble_B:4][00:2][low_nibble_B:4][00:2]
; The ALS 2 between COAs consumes the 2 zero padding bits.
;
; Flow: MAIN_LOOP_1 (text) -> MAIN_LOOP_2 (digits) -> ECHO_POLL
;
; ECHO_POLL: polls X19 via DIA. X19=1 -> data ready.
; Reads Y via DIB, splits byte into two nibbles, outputs via COA.
; Loops back to poll for next character.
; ================================================================
; H LOOP (ch54)
; ================================================================
ORG 54, 000
DATA 77777777 ; s000: live CLA written here before entry
COA 1 @?NEXT ; s001: high nibble of char A
; s002: dead
ORG 54, 003
ALS 2 @?NEXT ; s003: consume 2 zero padding bits
COA 1 @?NEXT ; s004: low nibble of char A
; s005: dead
ORG 54, 006
ALS 2 @?NEXT ; s006: consume 2 zero padding bits
COA 1 @?NEXT ; s007: high nibble of char B
; s010: dead
ORG 54, 011
ALS 2 @?NEXT ; s011: consume 2 zero padding bits
COA 1 @?NEXT ; s012: low nibble of char B
; s013: dead
ORG 54, 014
TRA 54,017 @000 ; s014: jump to return slot
ORG 54, 017
DATA 77777777 ; s017: return TRA written here before entry
; ================================================================
; TEXT STRING (ch02, s000-s006) "HELLO WORLD"
; ================================================================
ORG 02, 000
DATA 20402024 ; s000: H(48) E(45)
DATA 20602060 ; s001: L(4C) L(4C)
DATA 20741000 ; s002: O(4F) ' '(20)
DATA 24342074 ; s003: W(57) O(4F)
DATA 24102060 ; s004: R(52) L(4C)
DATA 20200000 ; s005: D(44) NUL(00)
DATA 77777777 ; s006: sentinel
; ================================================================
; CONSTANTS (ch02, s020-s024)
; ================================================================
ORG 02, 020
DATA 00000001 ; s020: constant 1
DATA 00050000 ; s021: Sp-adjust for text
TRADATA 00,?MAIN_AFTER_COA_1 ; s022: return TRA for text H-loop
TRADATA 00,?MAIN_AFTER_COA_2 ; s023: return TRA for digit H-loop
DATA 00230000 ; s024: Sp-adjust for digits
; ================================================================
; DIGIT STRING (ch04, s000-s004) "01234567"
; ================================================================
ORG 04, 000
DATA 14001404 ; s000: '0'(30) '1'(31)
DATA 14101414 ; s001: '2'(32) '3'(33)
DATA 14201424 ; s002: '4'(34) '5'(35)
DATA 14301434 ; s003: '6'(36) '7'(37)
DATA 77777777 ; s004: sentinel
; ================================================================
; SCRATCH (ch50)
; ================================================================
ORG 50, 011
DATA (9 << 20) | (1 << 12) | (1 << 7) | 0 ; s011: CLA ch02,s000
DATA (9 << 20) | (1 << 12) | (2 << 7) | 0 ; s012: CLA ch04,s000
; ================================================================
; MAIN (ch00) [](https://gitlab.com/mixotricha/d-17b-computer/-/tree/main/T35_D17b?ref_type=heads)
; ================================================================
ORG 00, 000
?MAIN_LOOP_1
CLA 50,011 @?NEXT ; s000: load text live CLA
STO 54,000 @?NEXT ; s001: write to H pos 0
ADD 02,021 @?NEXT ; s002: Sp-adjust for text
STO 00,007 @?NEXT ; s003: patch MAIN_FETCH_1 (007-2=005)
; s004: dead
ORG 00, 005
?MAIN_FETCH_1
CLA 02,000 @?NEXT ; s005: fetch text word (patched each iter)
TMI 00,?MAIN_LOOP_2 @?NEXT ; s006: sentinel -> done with text
CLA 02,022 @?NEXT ; s007: load return TRA 1
STO 54,017 @?NEXT ; s010: write to H pos 017
TRA 54,000 @?NEXT ; s011: enter H-loop
?MAIN_AFTER_COA_1
CLA 50,011 @?NEXT ; s012: reload text live CLA
ADD 02,020 @?NEXT ; s013: advance sector +1
STO 50,013 @?NEXT ; s014: -> ch50,s011 (lag 013-2=011)
TRA 00,?MAIN_LOOP_1 @?NEXT ; s015
?MAIN_LOOP_2
CLA 50,012 @?NEXT ; s016: load digit live CLA
STO 54,000 @?NEXT ; s017: write to H pos 0
ADD 02,024 @?NEXT ; s020: Sp-adjust for digits
STO 00,025 @?NEXT ; s021: patch MAIN_FETCH_2 (025-2=023)
; s022: dead
ORG 00, 023
?MAIN_FETCH_2
CLA 04,000 @?NEXT ; s023: fetch digit word (patched each iter)
TMI 00,?MAIN_HPR @?NEXT ; s024: sentinel -> done
CLA 02,023 @?NEXT ; s025: load return TRA 2
STO 54,017 @?NEXT ; s026: write to H pos 017
TRA 54,000 @?NEXT ; s027: enter H-loop
?MAIN_AFTER_COA_2
CLA 50,012 @?NEXT ; s030: reload digit live CLA
ADD 02,020 @?NEXT ; s031: advance sector +1
STO 50,014 @?NEXT ; s032: -> ch50,s012 (lag 014-2=012)
TRA 00,?MAIN_LOOP_2 @?NEXT ; s033
?MAIN_HPR
TRA 06,000 @035 ; s034: jump to echo poll loop
; ================================================================
; ECHO POLL LOOP (ch06)
; Polls X19 via DIA. X19=1 -> data ready.
; Reads byte from Y via DIB, outputs as two COA nibbles.
; Loops indefinitely.
;
; X tape format (19 bits, X19 leftmost):
; X19=1 (ready): X ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 )
; X19=0 (waiting): X ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 )
;
; Y tape format (24 bits, Y24 leftmost, Y1 rightmost):
; ASCII byte in Y1-Y8, MSB(Y8) to LSB(Y1).
; Example 'A' (0x41): Y ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 )
; ================================================================
ORG 06, 000
?ECHO_POLL
DIA @?NEXT ; s000: X1-X19 -> A(1-19)
ALS 5 @?NEXT ; s001: X19 -> A(24)
TMI 06,006 @?NEXT ; s002: A(24)=1 -> data ready, jump to READY
TRA 06,000 @?NEXT ; s003: not ready, loop
; s004: dead
; s005: dead
ORG 06, 006
?ECHO_READY
DIB @?NEXT ; s006: Y1-Y24 -> A, byte in A(1-8)
ALS 20 @?NEXT ; s007: octal 20 = 16 decimal: byte -> A(17-24)
; s010: dead (COA internal shift)
COA 1 @?NEXT ; s011: high nibble out
; s012: dead
COA 1 @?NEXT ; s013: low nibble out
; s014: dead
TRA 06,000 @?NEXT ; s015: loop back to poll
! M MEMORY EXEC(9999) MR(ON) K(RUN)
! PR(OFF)
!
Not sure how many people could fire this up right now since maybe 5 people in the world have an S-100 with the T35 board. But will fire up in the simulator but the simulator loads in data and isn’t dynamic so you will just see it loop around on the same test character. Unfortunately it wont fit in a FireAnt unless I move the drum memory out to a physical device that emulates it ( under serious consideration ) … but it would fit quite happily into other FPGA’s the same size as the T-35 that you have a uart hooked up to.
I should say I now think the implementation in the FPGA is solid enough that I could begin back stepping out blocks into physical cards which is my plan.
And yes I will absolutely be writing some implementation of …
Shall we play a game? Y/N How about Global Thermonuclear War? Wouldn’t you prefer a good game of chess? NO! Let’s play Global Thermonuclear War. Fine…

