work on network encoding and documenting eventual component interfaces

This commit is contained in:
2026-04-05 01:04:24 +02:00
parent e3959a24da
commit dad8e34cca
6 changed files with 467 additions and 33 deletions

140
TODO.md
View File

@@ -2,8 +2,7 @@
- implement the RAID merger algorithm (merges multiple drives or filesystems together into a bigger config)
- write a tester OS, basically a menu with tests to run
- tmpdrive
- tmpfs (reork the whole thing)
- tmpfs (rework the whole thing)
- device info
- userdata support
@@ -49,7 +48,7 @@ Not everything OC has (as a few of them are really MC-centered) but most of it.
- `microphone` component, allows reading audio from nearby sources
- `tape_drive` component, compatible with Computronics
- `cd_drive` to work with CDs (can be read-only, write-only or read-write)
- `serial` component, for serial communications with other devices (USB?)
- `serial` component, for serial communications with other devices (see Serial)
- `iron_noteblock` component
- `colorful_lamp` component
- OpenSolidState flash storage
@@ -67,3 +66,138 @@ NOTE: we're mostly bottlenecked by the architecture (typically a Lua VM) and the
- make signals use a circular buffer instead of a simple array
- use more arenas if possible
# Unique components
Subject to change, still being discussed with the other NeoFlock members.
## Serial
The `serial` component would have the methods:
- `read(len: integer): string`, to read data
- `write(data: string): boolean`, to send data
- `isConnected(): boolean`, to check if the port is currently connected
- `setProtocol(protocol: string): string`, sets the protocol string of our port, which may be truncated.
- `getProtocol(): string`, gets the currently registered protocol of our port. Default is `raw`.
It would also push the following signals:
- `serial_connected(portAddress: string, protocol: string)`, when connected
- `serial_protocol(portAddress: string, protocol: string)`, when other side changed protocol mid-connection.
- `serial_disconnected(portAddress: string)`, when the port is disconnected
- `serial_data(portAddress: string, amount: integer)`, when new data is available (and how much)
## Radio
For very large-distance telecommunications. Frequency is in Hz.
The `radio_controller` component, which enables listening to connected radio towers
- `isOpen(): boolean`, whether listening is enabled
- `open(): boolean`, to open for listening
- `close(): boolean`, to close the listener
- `setRange(minimum: number, maximum: number): boolean`, sets the frequency range we listen for.
- `getRange(): number, number`, gets the frequency range we listen for.
The `radio_tower` component, which actually receives and sends the waves
- `isEmitter(): boolean`, whether this tower can, in fact, send radio waves
- `minFrequency(): number`, the minimum frequency it can detect and transmit
- `maxFrequency(): number`, the maximum frequency it can detect and transmit
- `getFrequencyResolution(): integer`, how many frequencies can be listened for in that range. The frequencies sent to the controller are rounded to one of
these
- `getRangeOf(frequency: number): number`, to get the maximum range for a given frequency
- `maxPacketSize(): integer`, to get the maximum size that can be sent at once, typically 32KiB.
- `getBaseFrequency(): number`, gets the base frequency of radio communications, typically 100 kHz.
- `emit(frequency: number, data: string): boolean`, to emit a radio packet on a given frequency. The frequency must be in range, and will be rounded to one
within resolution
Radio waves travel at a (likely configurable) speed and have extremely large range on lower frequencies.
They can also have bit flips.
The range and speed are based off the frequency range. Given base frequency f0, base energy cost e0, base range r0, we can compute energy cost e, range r of a
given frequency f using:
- `r = r0 / (f / f0)`
- `e = e0 * (f / f0)`
When one is received, it will push:
- `radio_message(localControllerAddress: string, localTowerAddress: string, distance: number, frequency: number, data: string)`, where frequency is rounded to
within the resolution of the tower. It does ensure the frequency is within the controller range and the controller is open. Data may be corrupted by bit flips.
Distance is in meters. As you can notice, there is no sender address. It is the responsibility of the protocol to identify and verify senders.
## VT
A generic virtual terminal. Like a GPU + screen, but with no VRAM.
Has a 256-color palette representing ANSI 256 colors.
Subsequently, colors 0-15 represent ANSI escape colors.
The entire palette is editable.
The `vt` component has:
- `getResolution(): integer, integer`, to get the resolution. Cannot be changed
- `getDepth(): integer`, to get the color depth. Cannot be changed
- `getColor(index: integer): integer`, to get a color
- `setColor(index: integer, color: integer): integer`, sets a color and returns the old one. Characters who's colors were table indexes would be updated
- `setForeground(color: integer, fromTable?: boolean)`, sets a foreground color, optionally as a table index
- `getForeground(): integer, integer?`, returns what the foreground color was, and the palette index if applicable
- `setBackground(color: integer, fromTable?: boolean)`, sets a background color, optionally as a table index
- `getBackground(): integer, integer?`, returns what the background color was, and the palette index if applicable
- `set(idx: integer, data: string): boolean`, to write to the screen's unicode buffer. While `data` is UTF-8, the buffer stores codepoints. Pretend
the terminal does an internal conversion from UTF-8 to UTF-32
- `getColorOf(idx: integer): integer, integer, integer?, integer?`, to get the foreground color, background color, and palette indexes of a tile
- `get(idx: integer, len: integer): string`, to get the contents of part of the VT's unicode buffer, encoded as UTF-8
It also pushes the signals of keyboards and screens (no precise) for using input.
The unicode buffer is a 0-indexed buffer of codepoints alongside the color data. When writing to the unicode buffer, it also writes to the color buffer.
If `x` and `y` are 0-indexed, then `x + y * width` is the index in the buffer
## CD drives
The `cd_drive` component has:
- `hasDisk(): boolean`, to check whether a disk is in the drive
- `isReadonly(): boolean`, to check where the drive is read-only (often is)
- `isDiskErasable(): boolean`, to check whether the disk is erasable, which requires support from both the disk and the drive
- `tell(): integer`, current 0-indexed byte offset into the disk
- `seekTo(position: integer): boolean`, seek to a current 0-indexed byte offset in the disk
- `moveBy(delta: integer): boolean`, move the current position by some amount of bytes (+/-), can wrap around
- `maxReadSize(): integer`, to return the maximum size of a read
- `read(len: integer): string`, to read some data. Does wrap around
- `write(data: string): boolean`, to write some data. Does wrap around.
It also pushes the signals:
- `cd_added(driveAddress: string)`, for when a disk is added
- `cd_removed(driveAddress: string)`, for when a disk is removed
### Writing to non-erasable drives
Instead of erroring out, it instead ORs the bits between what was there and what is written. This means you can still write the initial contents,
as the CD starts out 0'd, but subsequent writes are likely to corrupt previous.
### CDs vs tape
Tape is slow. CDs are fast.
Tape is always fully writable. CDs may not always be erasable.
Tape has high capacity, CDs do not.
### CDs vs unmanaged floppies
CDs are slower for random reads as they have no cache.
## LED
The `led_matrix` component has:
- `getResolution(): integer, integer`, gets the resolution of the LED matrix.
- `getIntensity(x: integer, y: integer): number`, gets the intensity of an LED.
- `setIntensity(x: integer, y: integer, intensity: number): number`, sets the intensity of an LED and returns the old one.
Intensity is between 0 (off) and 1 (full brightness).
An LED matrix has really high call budget, thus it is ideal for frequency updating status updates.
## Speaker
TODO: interface
## Microphone
TODO: interface
## OLED/IPU
TODO: interface