Skip to content

Instantly share code, notes, and snippets.

@ddevault
Created August 21, 2012 22:51
Show Gist options
  • Save ddevault/8fec3ca6b9b9054e1e2f to your computer and use it in GitHub Desktop.
Save ddevault/8fec3ca6b9b9054e1e2f to your computer and use it in GitHub Desktop.
DCPU-16 Firmware Proposal

DCPU-16 Firmware

The following are unofficial modifications to the specification that describe how the firmware should work.

The provided code assumes that the eventual disk drive specifications match the HMD2043 media drive specifications from a technical standpoint.

The DCPU-16 comes paired with 512 words of ROM that are only used while booting up the device. This ROM contains the user-flashable firmware, which is loaded with a default firmware as described below.

Upon booting, the DCPU-16 loads the firmware into memory at address zero and then boots normally. The ideal mechanism for accomplishing this can be found here.

Rationale

The rationale for this proposal is to provide a means for users to easily work with the DCPU-16. It would enable users to easily load programs, distribute programs, and reliably use their devices, while staying in canon. Programs, kernels, operating systems, and the like, could all be distributed via disks instead of manually reflashing the device each time.

The Future

A potential direction to take this idea is to establish different kinds of hardware that are all compatible with each other. For instance, this one boot loader could potentially load an OS from a disk, from a hard drive, from a network connection - so long as they all have the same hardware ID and compatible interrupts.

Default Firmware

The following code would work well for the default firmware. Its goal is very simple - to copy the boot sector of the installed disk to memory and execute it. If a disk is present, it will simply boot with no error. If a disk is not present and an LEM 1802 is not present, it will fail to boot and hang. If a disk is not present and an LEM 1802 is present, it will fail to boot and display a message to the user.

A pre-assembled binary of this firmware is available for download here. The code is designed to be able to assemble on most assemblers, but it was developed using organic and tomato.

:init
    ; Move the firmware 0x200 words over before continuing
    SET I, 0
    SET J, 0x200
:move
    IFE I, 0x200
        SET PC, load
    STI [J], [I]
    SET PC, move
:init_end

.org init_end+0x200
:load
    ; Enumerate devices
    HWN I
:device_loop
    SUB I, 1
    IFE I, 0
        SET PC, device_complete
    HWQ I
    IFE A, 0x4cae
        IFE B, 0x74fa
            SET [io_hmd], I
    IFE A, 0xF615
        IFE B, 0x7349
            SET [io_lem], I
    SET PC, device_loop
:device_complete
    IFE [io_hmd], 0xFFFF
        SET PC, error_nodrive
    ; Check for disk
    SET A, 0
    HWI [io_hmd]
    IFE B, 0
        SET PC, error_nodisk
    ; Check for supported media
    SET A, 0xFFFF
    HWI [io_hmd]
    IFE B, 0xFFFF
        SET PC, error_badmedia
:copy_boot
    ; Copy the boot sector
    ; READ SECTORS
    SET A, 0x10
    ; Start at sector 0
    SET B, 0
    ; Read one sector
    SET C, 1
    ; Copy to 0x0000
    SET X, 0
    HWI [io_hmd]
    IFN A, 0
        SET PC, error_readerr
    ; Finally, boot
    SET PC, 0

; Error handlers
:error_nodrive
    ; hang forever if there is no screen
    IFE [io_lem], 0
        SET PC, hang
    JSR map_screen
    SET I, msg_nodrive
    SET PC, print_err

:error_nodisk
    ; hang forever if there is no screen
    IFE [io_lem], 0
        SET PC, hang
    JSR map_screen
    SET I, msg_nodisk
    SET PC, print_err

:error_badmedia
    ; hang forever if there is no screen
    IFE [io_lem], 0
        SET PC, hang
    JSR map_screen
    SET I, msg_badmedia
    SET PC, print_err
    
:error_readerr
    ; hang forever if there is no screen
    IFE [io_lem], 0
        SET PC, hang
    JSR map_screen
    SET I, msg_readerr
    SET PC, print_err

:map_screen
    SET A, 0
    SET B, 0x8000
    HWI [io_lem]
    SET PC, POP
; Prints the error message at [I]
:print_err
    SET J, 0x8000
:print_err_loop
    IFE [I], 0
        SET PC, hang
    SET C, [I]
    BOR C, 0xF000
    STI [J], C
    SET PC, print_err_loop
    
:hang
    SET PC, hang
    
; Error messages    
:msg_nodisk
    dat "INSERT DISK AND REBOOT", 0
:msg_nodrive
    dat "ATTACH HMD2043 AND REBOOT", 0
:msg_badmedia
    dat "UNRECOGNIZED MEDIA FORMAT       REPLACE DISK AND REBOOT", 0
:msg_readerr
    dat "DRIVE READ ERROR", 0
    
; Reserved memory
:io_hmd
    dat 0xFFFF
:io_lem
    dat 0xFFFF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment