-
Notifications
You must be signed in to change notification settings - Fork 4
Computer Trainers
This is a page dedicated to seeing "Hellorld!" run on Computer Trainers. This is an interesting classification of computers. On the surface, they seem like microcomputers, but when you look a little closer, there are some notable differences. For here though, we're classifying computer trainers as Single Board Computers (SBCs) with the keyboard and/or display integrated into the board. The keyboard doesn't, and often isn't, haveto be a full sized qwerty keyboard either. Listings are in alphabetical order.
Quick links:
Rockwell AIM-65 | Digirule 2U | Multitech MPF-1 | Multitech MPF-1P (w/ VFD) |
PROFI-5/50E | Protec PRO-83 | RCA VIP | NEC TK-80/TK-85 |
The Rockwell AIM-65 was introduced in 1978 as a 6502 trainer. Interestingly, it is quite similar to the KIM-1, only with more features and capability. Unlike most other trainers, it has a Built-in full-sized QWERTY keyboard, a 20 character alphanumeric LED display (16 segments), an integrated 20 character thermal printer, and a 20 mA current-loop serial interface that can be adapted to RS-232. With a 6502, 6522, 4kB of RAM, and five sockets for expanded ROM, it's a quite capable little machine. But can it "Hellorld!"? You betcha!
Code:
==0000
.OPT LIS, GEN, NOE
; WRITTEN FOR THE AIM-65
; BY JOHN JONES OCTOBER 2023
; ENTRY ADDRS OF USED MONITOR SUBROUTINES
; ---------------------------------------
==0000 CRLF=$E9F0
==0000 OUTALL=$E9BC
==0000 CRCK=$EA24
; MAIN PROGRAM
; ------------
; START ADDRESS
==0000
*=$0200
==0200
; OUTPUT A CR AND LF TO ACTIVE OUTPUT DEVICE
20F0E9 JSR CRLF
; LOAD #FF INTO X SO IT CAN INC FROM #00
A2FF LDX #$FF
; START OF LOOP TO LOAD AND OUTPUT MSG1 CHARS
==0205 LOOP1
; INCREMENT X
E8 INX
; LOAD X CHAR OF MSG1 INTO A
BD1702 LDA MSG1,X
; CHECK IF CHAR IS THE TERMINATING CHAR (;)
C93B CMP #';'
; IF TERMINATING CHAR DETECTED BRANCH TO PRT
F006 BEQ PRT
; OUTPUT CONTENT OF A TO DEFAULT OUTPUT DEVICE AS ASCII
20BCE9 JSR OUTALL
; JUMP BACK TO START OF LOOP
4C0502 JMP LOOP1
==0213 PRT
; OUTPUT PRINT BUFFER
2024EA JSR CRCK
60 RTS
; MESSAGE TO PRINT
; ----------------
==0217 MSG1
2048 .BYT ' HELLORLD!;'
454C
4C4F
524C
44213B
; END DIRECTIVE
; ----------------
.END
Which gives us a trifecta of output, on the hex displays, the integrated printer and on the terminal!
The Digirule 2U was a kickstarter back in 2020. It's an opensource pocket computer using a modern microcontroller to emulate a fantasy 8 bits CPU with a basic front panel interface.
As describbed by its creator "The Digirule 2U is basically an 8-bit programmable computer from the 1970's, built into a 20cm Ruler".
It's very limited, even by the 70's standard (256 bytes of address space, two groups of 8 leds for display and 8 momentary switches for input) but it's very convenient to use on the go (the whole thing fits in a pocket and is powered with a single CR2032) and pretty fun to write for.
You can also connect it to a PC (USB C) or a serial terminal and use a more advanced monitor if you prefer.
And it can of course "Hellord!" :o)
The 33 bytes program will both flash the ASCII code of each letter on the D0-D7 LEDs and send it to the serial port (if a console is connected).
Source:
; Hellorld!
; Flash the Hellorld! string in the data register leds and send it to serial port
ORG 0 ; Start of the code
speed 0x70 ; Slow down the CPU so we can see the leds flashing
copylr Hellorld,CurrentChar ; Point to the first character of Hellorld string
Loop
copylr 0,_dr ; Blank the data register (switch all leds off)
copyia CurrentChar ; Copy next character in accumulator
btstsc _z,_sr ; Test bit Z of status register, and skip 2 bytes if clear
halt ; End of program
nop ; filler
copyar _dr ; copy accumulator in the data register (Leds)
comout ; send character to serial port
incr CurrentChar ; point to the next char in the string
jump Loop ; ...and continue
Hellorld byte 'H','e','l','l','o','r','l','d','!',0
CurrentChar byte 42
END 0
If you want to load it from the serial console, here is a ready to use hexdump:
:1000000002700516200500FF0C202600FC000107E9
:10001000FFC01E20280548656C6C6F726C6421005F
:010020002AB5
:00000001FF
If you prefer to enter the program using the "front panel", here is a list of bytes to be entered starting at address 0x00:
02 70 05 16 20 05 00 FF 0C 20 26 00 FC 00 01 07 |.p.. .... &.....|
FF C0 1E 20 28 05 48 65 6C 6C 6F 72 6C 64 21 00 |... (.Hellorld!.|
And here is a video where you can see the program in action: https://youtu.be/6IpT-52ig0I
The MPF-1 was introduced in 1981 as a training board to teach the fundamentals of Z80 assembly in schools and colleges. Featuring a Z80-A running at 1.7MHz it supports 158 instructions, programmed as hex using a modest keyboard, and a 6 character 7-segment display to show various parameters about the system. It has a ROM monitor program that runs in the background. Admittedly this code does CALL the screen drawing routine, which reads in 6 bytes from an address starting at the location pointed at by register IX, with each byte broken down into binary coded segment positions. It uses a nested loop of XTHL (Stack exchange HL-HL') to slow the output to a readable speed. HELLORLD! does not fit in 6 characters, so the scroll was deemed necessary.
1800 LD IX, &184D DD 21 4D 18 ;Display register text string starts at &184D
1804 LD A, &11 3E 11 ;Length of text string
1806 LD &1820, A 32 20 18 ;Stick that into scratch memory at &1820
1809 CALL &0624 CD 24 06 ;Display what IX points to
180C CALL &1821 CD 21 18 ;CALL the pause loop
180F LD A, &1820 3A 20 18 ;Pull string position pointer in from memory
1812 DEC A 3D ;Decrease text string pointer
1813 LD &1820, A 32 20 18 ;Save it in memory
1816 JZ &1800 CA 00 18 ;If Text string pointer is zero redo from start
1819 DEC IX DD 2B ;If not, Decrease register pointer IX
181B JP &1809 C3 09 18 ;Move to next character
181E NOP 00 ;Gap
181F NOP 00 ;Gap
1820 SCRATCH MEMORY 00 ;Text string position pointer
1821 LD A, 15 3E 15 ;Speed of scroll multiplier- secondary loop (loop multiplier)
1823 LD B, A 47 ;Load value into register B
1824 LD A, 20 3E 20 ;Speed of scroll loop- primary loop counter value
1826 LD C, A 4F ;Load that value into register C. Loop will operate B*C times. One loop of C is appx 0.1s.
1827 CALL &1832 CD 32 18 ;Call the primary loop code to slow the output down.
182A DEC C 0D ;Decrease multiplier counter one time.
182B JNZ &182A C2 2A 18 ;Repeat calling the primary loop until multiplier reaches zero.
182E CALL &0624 CD 24 06 ;Call Display routine again because loop code kills screen
1831 RET C9 ;Return
1832 XTHL E3 ;Stack Exchange HL-HL' (Primary loop starts here)
1833 XTHL E3 ;Stack Exchange HL-HL'
1834 DEC B 05 ;Decrease loop counter by one
1835 CALL &0624 CD 24 06 ;Call Display routine because XTHL kills screen
1838 JNZ &1832 C2 32 18 ;Loop until loop counter reaches zero
183B RET C9 ;Return
183C TEXT 00 ;Space
00 ;Space
00 ;Space
00 ;Space
00 ;Space
00 ;Space
50 ;!
B3 ;D
85 ;L
03 ;R
BD ;O
85 ;L
85 ;L
8F ;E
37 ;H
184B 00 ;Space
00 ;Space
00 ;Space
00 ;Space
00 ;Space
1850 00 ;Space
The Starts At position is far right memory location minus six empty spaces unless you want the screen to begin with text on. Calculate the number of characters you have and put that in as Length of Text String. IX is shifted down through memory locations, which displays the "window" of 6 characters.
From the Users Guide:- the Text data can be created using this- pick the segments, allocate them a 1 in the bitwise table, calculate the value in hex and insert it in memory for it to display.
At first glance, this appears to be a very similar system to the Multitech above, but not only is the code pretty dramatically different, the hardware has some pretty dramatic differences as well, most notably, this one has a gorgeous Vacuum Fluorescent Display! The code does lean on system calls, so it is an interesting contrast to the MPF-1 shown above, which appears to be a bit more bare metal.
Code:
CALL CLEAR | F000: CD B9 09 | Clear Display
LD HL,TXT | F003: 21 14 F0 | Load pointer to text data to HL register
CALL MSG | F006: CD CA 09 | Write text at HL pointer until Carriage-Return
LD IX,DISPBF | F009: DD 21 2C FF | Load pointer to display buffer into IX register
CALL SCAN | F00E: CD 46 02 | Wait for the user to press a key
JP PRI_MPF| F011: C3 00 00 | Jump back to the start of the monitor
TXT: | F014: 48 45 4C 4C | 'HELLORLD!' and a CR in ASCII
'HELLORLD!\N'| F018: 4F 52 4C 44 |
| F01C: 21 0D |
The PROFI series of computer trainers is an interesting German made trainer based around either an 8080A or 8085A. This particular PROFI-5/50E is an 8085A machine clocked at I believe 6MHz with 8k ROM and 2k RAM. Interestingly, it has full serial capability and has a Centronics interface, but the Intersil chip, which I initially thought was the UART is actually a mega-rare 7-segment driver IC! It's a quite capable little machine and looks primed and ready to be expanded into a full-fledged computer, but in it's base state with the built in keyboard and 7-segment displays, it's the perfect trainer for "Hellorld!"
Code:
8000 01 00 83
8003 CD 60 03
8006 76
8300 76 79 38
8303 38 3F 50
8306 38 5E
The Protect Microsystems PRO-80 was released in 1981 and in 1983 was updated to the PRO-83. Finding information on this trainer is very difficult indeed as it was quite rare. The PRO-80 featured a Z80 microprocessor, 1KB of RAM (expandable up to 2KB), 1KB EPROM with the memory monitor, 2 parallel I/O ports, audio cassette interface, 16-key Hex with 8 additional keys, and a 6-position Hex display. The PRO-83 is very similar indeed, using the same display, keyboard, processor, etc.
The big question though - can it Hellorld? You bet it can!
Check a video of it running here.
Code:
[1000] 21 33 10 Start: LD HL, Data ; Point at the start of our string
[1003] 06 0e LD B, $0E ; Number of times to scroll before restarting
[1005] c5 ScrollLoop: PUSH BC ; Preserve the scroll counter
[1006] 06 10 LD B, $10 ; Number of times to redraw the display before scrolling
[1008] c5 DrawAllChars: PUSH BC ; Preserve the redraw counter
[1009] 06 06 LD B, $06 ; Increment the character pointer by 6
[100b] 23 INC HL ; (cont.)
[100c] 10 fd DJNZ $ - 1 ; (cont.)
[100e] 3e fe LD A, $FE ; Start with the right-most character
[1010] 06 06 LD B, $06 ; Iterate 6 times
[1012] d3 48 DrawNextChar: OUT ($48), A ; Set enable the character
[1014] f5 PUSH AF ; Preserve the character mask
[1015] 7e LD A, (HL) ; Load the character data
[1016] d3 4c OUT ($4C), A ; Output the character data
[1018] c5 PUSH BC ; Preserve the character counter
[1019] 06 00 LD B, $00 ; Set up a delay counter
[101b] 10 fe DJNZ $ ; Delay here while the display is on
[101d] c1 POP BC ; Restore the character counter
[101e] 3e 00 LD A, $00 ; Load a blank character
[1020] d3 4c OUT ($4C), A ; Clear the current character
[1022] f1 POP AF ; Restore the character mask
[1023] 07 RLCA ; Shift to the next character to the left
[1024] 2b DEC HL ; Decrement the character pointer
[1025] 10 eb DJNZ DrawNextChar ; Do it again.
[1027] c1 POP BC ; Restore the redraw counter
[1028] 10 de DJNZ DrawAllChars ; Go back to redraw the display
[102a] c1 POP BC ; Restore the scroll counter
[102b] 05 DEC B ; Decrement the scroll counter
[102c] ca 00 10 JP Z, Start ; Done scrolling? Start over!
[102f] 23 INC HL ; Otherwise, increment the character pointer
[1030] c3 05 10 JP ScrollLoop ; And do it all again
[1033] 00 Data: DB 0x00 ; Blank
[1034] 00 DB 0x00 ; Blank
[1035] 00 DB 0x00 ; Blank
[1036] 00 DB 0x00 ; Blank
[1037] 00 DB 0x00 ; Blank
[1038] 00 DB 0x00 ; Blank
[1039] 76 DB 0x76 ; H
[103a] 79 DB 0x79 ; E
[103b] 38 DB 0x38 ; L
[103c] 38 DB 0x38 ; L
[103d] 3f DB 0x3F ; O
[103e] 50 DB 0x50 ; r
[103f] 38 DB 0x38 ; L
[1040] 5e DB 0x5E ; d
[1041] 00 DB 0x00 ; Blank
[1042] 00 DB 0x00 ; Blank
[1043] 00 DB 0x00 ; Blank
[1044] 00 DB 0x00 ; Blank
[1045] 00 DB 0x00 ; Blank
[1046] 00 DB 0x00 ; Blank
The RCA 1802 Microprocessor was introduced in the 1970's and gave rise to host of homebrew designs. The most notable was the COSMAC ELF. RCA produced a single board microprocessor system, RCA VIP, that allowed for small programming experiments in machine language and an interpretive virtual machine, Chip-8.
Looking for a unique system to implement "Hellorld", I (Mike A) realized that my 40 year old VIP + Chip-8 would make for an interesting choice. The VIP video out is pretty simple, 64 x 32 pixels (big chonkers!), and no pre-defined character set. All the characters must be part of the program, and drawn as sprites. The "Enterprise" was a canonical image for 1802 systems of the era, so I thought it would be appropriate to include.
The program (Chip-8) is written in a fairly standard assembly like form. I needed to whip up my own assembler, as I didn't like any of the multitudes available! The following is an assembler listing, but the raw hex dump follows the listing.
Code:
0x200 00e0 cls
0x202 6003 ld V0,3
0x204 6102 ld V1,2
0x206 6206 ld V2,6
0x208 a264 ld I,H
0x20a d017 drw V0,V1,7
0x20c 8024 add V0,V2
0x20e a26b ld I,E
0x210 d017 drw V0,V1,7
0x212 8024 add V0,V2
0x214 a272 ld I,L
0x216 d017 drw V0,V1,7
0x218 8024 add V0,V2
0x21a a272 ld I,L
0x21c d017 drw V0,V1,7
0x21e 8024 add V0,V2
0x220 a279 ld I,O
0x222 d017 drw V0,V1,7
0x224 8024 add V0,V2
0x226 a280 ld I,R
0x228 d017 drw V0,V1,7
0x22a 8024 add V0,V2
0x22c a272 ld I,L
0x22e d017 drw V0,V1,7
0x230 8024 add V0,V2
0x232 a287 ld I,D
0x234 d017 drw V0,V1,7
0x236 8024 add V0,V2
0x238 a28e ld I,BANG
0x23a d017 drw V0,V1,7
0x23c #
0x23c 6000 ld V0,0
0x23e 610c ld V1,12
0x240 6214 ld V2,20
0x242 a295 ld I,C1T
0x244 2256 call DRWCOL
0x246 2256 call DRWCOL
0x248 2256 call DRWCOL
0x24a 2256 call DRWCOL
0x24c 2256 call DRWCOL
0x24e 2256 call DRWCOL
0x250 2256 call DRWCOL
0x252 2256 call DRWCOL
0x254 1254 X: jp X
0x256 d018 drwcol: drw V0,V1,8
0x258 6308 ld V3,8
0x25a f31e add I,V3
0x25c d028 drw V0,V2,8
0x25e f31e add I,V3
0x260 7008 add V0,8
0x262 00ee ret
0x264 1111111f111111 H: byte 0X11,0X11,0X11,0X1F,0X11,0X11,0X11
0x26b 00000e111f100f E: byte 0X00,0X00,0X0E,0X11,0X1F,0X10,0X0F
0x272 0c040404040404 L: byte 0X0C,0X04,0X04,0X04,0X04,0X04,0X04
0x279 00000e1111110e O: byte 0X00,0X00,0X0E,0X11,0X11,0X11,0X0E
0x280 00001619101010 R: byte 0X00,0X00,0X16,0X19,0X10,0X10,0X10
0x287 01010107090907 D: byte 0X01,0X01,0X01,0X07,0X09,0X09,0X07
0x28e 04040404040004 BANG: byte 0X04,0X04,0X04,0X04,0X04,0X00,0X04
0x295 000000007f407f00 C1T: byte 0X00,0X00,0X00,0X00,0X7F,0X40,0X7F,0X00
0x29d 0000000000000000 C1B: byte 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
0x2a5 0000067fc00fc03f C2T: byte 0X00,0X00,0X06,0X7F,0XC0,0X0F,0XC0,0X3F
0x2ad 0f00000000000000 C2B: byte 0X0F,0X00,0X00,0X00,0X00,0X00,0X00,0X00
0x2b5 000000e03f003fd0 C3T: byte 0X00,0X00,0X00,0XE0,0X3F,0X00,0X3F,0XD0
0x2bd 0807183073301807 C3B: byte 0X08,0X07,0X18,0X30,0X73,0X30,0X18,0X07
0x2c5 00000101e010e040 C4T: byte 0X00,0X00,0X01,0X01,0XE0,0X10,0XE0,0X40
0x2cd 20907f00fc000ff0 C4B: byte 0X20,0X90,0X7F,0X00,0XFC,0X00,0X0F,0XF0
0x2d5 00ff0000fc040404 C5T: byte 0X00,0XFF,0X00,0X00,0XFC,0X04,0X04,0X04
0x2dd 0404fc00003fc000 C5B: byte 0X04,0X04,0XFC,0X00,0X00,0X3F,0XC0,0X00
0x2e5 00ff0000ff808080 C6T: byte 0X00,0XFF,0X00,0X00,0XFF,0X80,0X80,0X80
0x2ed 8080f01010f00000 C6B: byte 0X80,0X80,0XF0,0X10,0X10,0XF0,0X00,0X00
0x2f5 07ff0000ff000000 C7T: byte 0X07,0XFF,0X00,0X00,0XFF,0X00,0X00,0X00
0x2fd 0000000000000000 C7B: byte 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
0x305 e0ff0102fe000000 C8T: byte 0XE0,0XFF,0X01,0X02,0XFE,0X00,0X00,0X00
0x30d 0000000000000000 C8B: byte 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
0x315 00 end
Code:
200: 00 e0 60 03 61 02 62 06
208: a2 64 d0 17 80 24 a2 6b
210: d0 17 80 24 a2 72 d0 17
218: 80 24 a2 72 d0 17 80 24
220: a2 79 d0 17 80 24 a2 80
228: d0 17 80 24 a2 72 d0 17
230: 80 24 a2 87 d0 17 80 24
238: a2 8e d0 17 60 00 61 0c
240: 62 14 a2 95 22 56 22 56
248: 22 56 22 56 22 56 22 56
250: 22 56 22 56 12 54 d0 18
258: 63 08 f3 1e d0 28 f3 1e
260: 70 08 00 ee 11 11 11 1f
268: 11 11 11 00 00 0e 11 1f
270: 10 0f 0c 04 04 04 04 04
278: 04 00 00 0e 11 11 11 0e
280: 00 00 16 19 10 10 10 01
288: 01 01 07 09 09 07 04 04
290: 04 04 04 00 04 00 00 00
298: 00 7f 40 7f 00 00 00 00
2a0: 00 00 00 00 00 00 00 06
2a8: 7f c0 0f c0 3f 0f 00 00
2b0: 00 00 00 00 00 00 00 00
2b8: e0 3f 00 3f d0 08 07 18
2c0: 30 73 30 18 07 00 00 01
2c8: 01 e0 10 e0 40 20 90 7f
2d0: 00 fc 00 0f f0 00 ff 00
2d8: 00 fc 04 04 04 04 04 fc
2e0: 00 00 3f c0 00 00 ff 00
2e8: 00 ff 80 80 80 80 80 f0
2f0: 10 10 f0 00 00 07 ff 00
2f8: 00 ff 00 00 00 00 00 00
300: 00 00 00 00 00 e0 ff 01
308: 02 fe 00 00 00 00 00 00
310: 00 00 00 00 00 00
The NEC TK-80 is a trainer board using the NEC μCOM-80 (μPD8080A), a CPU that was (mostly) compatible with the Intel 8080A. Released in 1976, it was one of the first microprocessor systems easily available to the public in Japan and, though developed for engineers considering using the μCOM-80 in their products, became immensely popular with hobbyists who could afford neither more expensive systems nor the terminals that they usually required. The TK-85, released in 1980, was essentially the same but with an 8085-compatible μPD8085AC processor.
The following program is TK-80/85 Hello Program from the TK-80/TK-85 Reverse Engineering repo.
8000: 21 12 80 11 F8 83 7E B7
8008: C2 0C 80 76 12 23 13 C3
8010: 06 80 76 79 38 38 3F 50
8018: 38 5E 00