Skip to content
Nakazoto edited this page Dec 7, 2023 · 27 revisions

Almost There!

This is a collection of entries that are close to meeting the guidelines, but not quite there. There is some epic code in here, and perhaps you can get it running on a unique machine to bring it up fully! Entries are in alphabetical order.

Quick links:

Apple II Bally Astrocade Intel 8088 Intel x86 Assembly
NES Oscilloscope (Analog) Sega SG-1000 T-962A Reflow Oven

Apple II

The Apple II itself is not exactly a rare or unique machine, but I'm a sucker for a fully kitted out original machine. An early Apple II with Sanyo VM-2409 and proper disk drive (essentially recreating the original Apple II ad from 1977) could definitely find a place! If you happen to have this exact setup, Mouse over on the Discord has written some excellent code that could work on it!

Bally Astrocade Home Console

The Bally Astrocade is defintiely a weird/unique system, and it absolutely can "Hellorld!" However, we don't quite have the original hardware at hand. Commander Dave over on the Discord modified some original code by Adam Trionfo on the who runs the https://ballyalley.com/ website and the Bally Astrocade discussion group at https://groups.io/g/ballyalley, among other interesting things.

Code:

INCLUDE "HVGLIB.H"
        ORG    $2000    ; First byte of Cartridge
        DB     "U"      ; User System Sentinel 
        DW     MENUST   ; Next menu link
        DW     PRGNAM   ; Address of title for program
        DW     PRGST    ; Jump here if prog is selected
; Main Program
PRGST:  DI
        SYSTEM (INTPC) 
        DO     (SETOUT)
        DB     $B0        ; Vertical Blanking Line
        DB     $2C        ; Left/Right Color Boundary
        DB     $08        ; Interrupt Mode
        DO     (COLSET)
        DW     COLTAB     ; Color Table
        DO     (FILL)
        DW     NORMEM     ; Destination
        DW     4000D      ; Bytes to move
        DB     $00        ; Background color
        DO     (STRDIS)
        DB     0          ; X coordinate
        DB     0          ; Y coordinate
        DB     $0C        ; Options
        DW     STRING     ; Address of string to display
        EXIT
LOOP:   NOP
        JP     LOOP       ; Infinite loop
; Color Table #1
COLTAB: DB     $00        ; Color 3 Left  - Black
        DB     $5A        ; Color 2 Left  - Red
        DB     $77        ; Color 1 Left  - Yellow
        DB     $07        ; Color 0 Left  - White
        DB     $00        ; Color 3 Right - Black
        DB     $5A        ; Color 2 Right - Red
        DB     $77        ; Color 1 Right - Yellow
        DB     $07        ; Color 0 Right - White
PRGNAM: DB     "DISPLAY STRING"
        DB     $00        ; End String
STRING: DB     "HELLORLD!"
        DB     $00        ; End string
        ORG    $2FFF
        DB     $00        ; Last byte of 4K Cart
        END

Intel 8088 (and compatibles)

The Microcomputer we all know and love - it simply needs no introduction, Intel's very own 8088. This code here is designed to be run as a (floppy) boot-sector, about as bare metal as reasonably possible. We start at 0x7C00 for our text segment, while poking the (color) VGA memory at 0xB800 directly. The padding until offset 0x1FD is truncated and is simply followed by the magic boot-sector byte 0x55AA.

Write this to your own floppy for some boot time shenanigans!

Code:

a1 2b 7c 8e c0 31 ff 31 c0 ab 81 ff d0 07 7e f9
be 21 7c bf c6 07 b4 0f ac ab 3c 00 75 fa eb fe
f4 48 45 4c 4c 4f 52 4c 44 21 00 00 b8 00 00 00

Assembly:

          org 0x7C00                     ; bootsector is copied to 7C00 by BIOS

          mov ax, [VGAMEM]               ; set the top of VGA memory
          mov es, ax                     ; copy into the segment register
          xor di, di                     ; we will be using ES:DI for writing
          
          xor ax, ax                     ; clear AX
CLS:      stosw                          ; copy AX to ES:DI, inc DI
          cmp di, 0x7D0                  
          jle CLS                        ; are we less than 80*25?

          mov si, MESSAGE                ; string start byte pointer
          mov di, 0x7C6                  ; start at row 12, col 71
          mov ah, 0xF                    ; set color 7, high intensity
PRINTS:   lodsb                          ; load byte from SS:SI into AL, inc SI
          stosw                          ; copy AX to ES:DI, inc DI

          cmp al, 0                      
          jne PRINTS                     ; have we printed the entire string?

DONE:     jmp DONE
          hlt                            ; end

MESSAGE:  db "HELLORLD!",0               ; message to display
VGAMEM:   dw 0xB800                      ; top of (color) VGA Textmode 

          times 0x1FE - ($ - $$) db 0    ; pad a maximum of 510 bytes          
          dw 0xAA55                      ; place magic bootsector token

          times 0xB3E00 - ($ - $$) db 0  ; pad to 720KB

8088

Intel x86 Assembly

Like the 8088, this is for x86 based machines and written by the very capable Alice. It's great code, just looking for a unique machine or homebrew to run on!

Code:

org 0x7c00
bits 16

main:
    cli
    cld
    xor ax, ax
    mov ds, ax
    mov ah, 0x0e
    mov si, string

loop:
    lodsb
    or al, al
    jz hltloop
    int 0x10
    jmp loop

hltloop:
    hlt
    jmp hltloop

string:
    db 'Hellorld!',0

times 510-($-$$) db 0
dw 0xAA55

NES (Nintendo Entertainment System)

The Nintendo Entertainment System, or NES, isn't exactly a rare machine, they sold millions of them, but the coding work that coopstools did is very impressive! Unfortunately, we have a pretty hard and fast rule that emulators don't quite count, but I did want to showcase his work, because it's awesome.

To quote: My code can be found here (please note this is on the hellorld branch). There is a .mov file included that shows it being run on an fceux NES emulator.

Now, the NES has no concept of ASCII or any letters. So, to display a character, you first need to program in the letters. Each character is a sprite, and below is an excerpt from the creation of those sprites.

  .byte $F8, $cc, $c6, $c6, $c6, $cc, $f8, $00	; D ($03)
  .byte $00, $30, $20, $21, $21, $23, $06, $7c

  .byte $ff, $ff, $c0, $fc, $fc, $c0, $ff, $ff  ; E ($04)
  .byte $00, $00, $00, $00, $00, $00, $00, $00

  .byte $c3, $c3, $c3, $ff, $ff, $c3, $c3, $c3	; H ($07)
  .byte $00, $00, $00, $00, $00, $00, $00, $00

  .byte $c0, $c0, $c0, $c0, $c0, $c0, $ff, $ff	; L (0b)
  .byte $00, $00, $00, $00, $00, $00, $00, $00

  .byte $7e, $e7, $c3, $c3, $c3, $c3, $e7, $7e	; O ($0e)
  .byte $00, $00, $00, $00, $00, $00, $00, $00

  .byte $fe, $c6, $c6, $f8, $dc, $ce, $c6, $00	; R ($11)
  .byte $00, $39, $21, $07, $20, $20, $21, $63

The sprites and their location are then stored in rom. They are defined by their Y position, the character they display, the color pallet they will use (a sprite can only be 3 colors), and their X position.

hellorld: 
        ; Y  CHR  ATTR   X
  .byte $60, $07, $00, $68 ; 00-03 H
  .byte $60, $04, $00, $71 ; 04-07 E
  .byte $60, $0b, $00, $7a ; 08-0b L
  .byte $60, $0b, $00, $83 ; 0c-0f L
  .byte $60, $0e, $00, $8c ; 10-13 O
  .byte $69, $11, $00, $7a ; 14-17 R
  .byte $69, $0b, $00, $83 ; 18-1b L
  .byte $69, $03, $00, $8c ; 1c-1f D
  .byte $69, $1a, $00, $95 ; 20-23 !

In the startup code, the sprite are pulled out of ROM and into memory ($0200 through $02ff are the available addresses for usable memory at run time.)

  ldx #$00
@next_sprite:
  lda devexp, x
  sta $0200, x
  inx
  cpx #$20
  bne @next_sprite

And finally, there is an interrupt setup for each screen refresh that runs the code to pull the sprite info out of memory and send it to the graphics chip (PPU) through the register at $2004:

  ldx #$00 	; Set SPR-RAM address to 0
  stx $2003 ; store value in X in location $2003
@loop:
  lda $0200, x 	; Load the sprite info
  sta $2004
  inx
  cpx #$20 ; end of sprite memory
  bne @loop

This all comes together to produce the following image:

The rest of the code is either associated with startup, or with moving the sprites around the screen. I know the true hellorld would exclude the movement, but it's an NES. How could I not include some interactive element?

Oscilloscope (analog)

An analog oscilloscope isn't a computer but it does have a CRT and thus it can display Hellord. This series of coordinates was painstakingly made by hand-tracing points in Inkscape and then cleaning it up in a spreadsheet. When converted to WAV sample data and connecting the analog output to the X-Y inputs on an oscilloscope the vector graphic is displayed.

Hellord displayed on oscilloscope

More details and the actual file on eDoc2020's project page. David, you are free to copy it to your repo if desired.

-Dave: Unfortunately, the links appear to be broken and the repository linked doesn't appear to exist. Once we hunt down the right links, I'll move this over to "All the Things!"

Sega SG-1000

The Sega SG-1000 is the predecessor the famous Master System and rocks the venerable Zilog Z80 with a TMS9918 VDP. Seatsafetyswitch over on the Discord got fired up about writing some assembly for it and came up with this masterpiece! The assembly could potentially run on a Master System or Genesis if, and I quote, "you're willing to get really weird with it." I'm 100% on-board if someone wants to get "weird" with it and get some Hellorld! on a Genesis!

Code:

It's actually too long to paste here in its entirety, but check out the full Assembly file by clicking here!

T-962A Reflow Oven

This was a recent submission, unfortunately, it's missing a whole lot of extra information to make it a good fit. If this was your submission, please update with some information on the machine, the code and a bit more story of how you managed to get a reflow oven to display "Hellorld!"

Recently completed a custom controller for this oven, based on an STM32F405VGT6 ARM Cortex M4 microcontroller. It drives a Samsung KS0108 128x64 LCD, with custom written GUI code.

PXL_20231114_095211749