The NetMD factory command set, ported from netmd-js.
Factory mode exposes the player's internal memory (RAM / EEPROM / disc cache peripheral) for reading and writing. It backs firmware patching, raw UTOC access and the display override. This is dangerous; a wrong write can brick the device. Do not use it unless you know exactly what you are doing.
Three device families need slightly different framing, modelled as a
tagged struct (:netmd, :himd, :rh1). Open one with open/1, which
authenticates and detects the variant, then use the memory and device
functions here or the higher-level operations in NetMD.Factory.Commands.
Summary
Types
Memory region to address.
How to open a memory range.
An authenticated factory interface.
Device family: base NetMD, Hi-MD, or the MZ-RH1 special case.
Functions
Authenticate the factory session.
Open, keep open, or close a memory range for access. A no-op on the MZ-RH1, which addresses memory through the peripheral instead.
Factory-transfer checksum (CRC-16/CCITT) over data.
A short device code string like "S1.600" (chip family, firmware
version, subversion).
The device code: chip type, hardware id, firmware version and subversion.
The device's firmware version as a BCD-decoded number.
EEPROM checksum with the standard seeds (0xA596 for Hi-MD).
Authenticate a factory session on an open device and detect its variant.
Read length bytes of type memory at address.
Read length bytes from the disc-cache metadata peripheral.
Set the display mode (:default or :override).
Override the display with text (a string, encoded to Shift-JIS, or raw
bytes with raw: true). At most 8 characters or 9 raw bytes.
Front-panel switch and button state.
Write data to type memory at address.
Write to the disc-cache metadata peripheral.
Types
@type error() :: NetMD.Interface.error()
@type memory_type() :: :mapped | :eeprom_2 | :eeprom_3 | 0..255
Memory region to address.
@type open_type() :: :close | :read | :write | :read_write | 0..255
How to open a memory range.
@type t() :: %NetMD.Factory{device: NetMD.Device.t(), variant: variant()}
An authenticated factory interface.
@type variant() :: :netmd | :himd | :rh1
Device family: base NetMD, Hi-MD, or the MZ-RH1 special case.
Functions
Authenticate the factory session.
@spec change_memory_state( t(), non_neg_integer(), non_neg_integer(), memory_type(), open_type(), keyword() ) :: :ok | error()
Open, keep open, or close a memory range for access. A no-op on the MZ-RH1, which addresses memory through the peripheral instead.
Factory-transfer checksum (CRC-16/CCITT) over data.
Options: as_16bit: true treats the input as little-endian 16-bit words;
seed: sets the initial value (Hi-MD memory uses 0xA596).
A short device code string like "S1.600" (chip family, firmware
version, subversion).
@spec device_code(t()) :: {:ok, %{ chip_type: byte(), hwid: byte(), version: non_neg_integer(), subversion: byte() }} | error()
The device code: chip type, hardware id, firmware version and subversion.
@spec device_version(t()) :: {:ok, non_neg_integer()} | error()
The device's firmware version as a BCD-decoded number.
EEPROM checksum with the standard seeds (0xA596 for Hi-MD).
@spec open(NetMD.Device.t()) :: {:ok, t()} | error()
Authenticate a factory session on an open device and detect its variant.
Runs the same subunit-identifier handshake as the reference for side effects, authenticates, then reads the device code to promote MZ-RH1 devices to their special interface.
@spec read(t(), non_neg_integer(), non_neg_integer(), memory_type()) :: {:ok, binary()} | error()
Read length bytes of type memory at address.
@spec read_metadata_peripheral( t(), non_neg_integer(), non_neg_integer(), non_neg_integer() ) :: {:ok, binary()} | error()
Read length bytes from the disc-cache metadata peripheral.
Set the display mode (:default or :override).
Override the display with text (a string, encoded to Shift-JIS, or raw
bytes with raw: true). At most 8 characters or 9 raw bytes.
@spec switch_status(t()) :: {:ok, [non_neg_integer()]} | error()
Front-panel switch and button state.
@spec write(t(), non_neg_integer(), binary(), memory_type()) :: :ok | error()
Write data to type memory at address.
@spec write_metadata_peripheral(t(), non_neg_integer(), non_neg_integer(), binary()) :: :ok | error()
Write to the disc-cache metadata peripheral.