Files
AnachronautandClaude Opus 5 de1857f5f7 Record every pad, not the one that happened to be first
The first recording ever made with this came back 1,766 frames of nothing.
It recorded pad NOUGHT and the controller was somewhere else - which pad
one lands on is an accident of the host, the same accident that made Lunar
Porter read all four in the first place - and a flight flown for the
purpose was lost to it.

So every pad is or-ed into the byte. A demo is a record of what somebody
DID, and on a machine one person is playing the number it arrived on is
not part of that. It plays back on pad nought, where --pad puts the first
file given, and any program that reads more than one pad reads them or-ed
anyway for exactly the same reason.

--record-pad takes one file now rather than filling pads in turn, because
there is nothing left for the second one to mean.

The check for it plays a recording on pad ONE with nought holding nothing
and requires the bytes back. That is the case that was missing: the round
trip was tested and passed, on pad nought, which is the only pad it could
not have gone wrong on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
2026-09-03 14:27:58 -04:00

67 lines
2.9 KiB
C

// utility.h
// Utilities for the SplitBit CPU Emulator
// Written by Anachronaut
// 10/15/2024
#ifndef UTILITY_H
#define UTILITY_H
#include <stdint.h>
#include "io.h"
#include "cpu.h"
// Results of reading the command line.
#define OPTIONS_OK 0 // Carry on and run the program.
#define OPTIONS_HELP 1 // The user asked for help, so stop, but not because of an error.
#define OPTIONS_ERROR 2 // The command line was no good, stop and complain.
// As many as the machine has pads.
#define PAD_DRIVE_COUNT 4
typedef struct {
uint8_t debug; // Step one instruction at a time, printing the registers.
uint8_t fast; // Ignore the cycle rate and run as fast as the host allows.
unsigned long cycles; // Stop after this many cycles. Zero means run until the program halts.
unsigned long diskCycles; // How long a block move takes. Zero is instant, and the default.
// ---- The drives, in the order they were named ----
//
// --disk given more than once fills them in turn, so the first is drive 0 and the machine
// has as many as were asked for. One name is the ordinary case and reads exactly as it
// did when there could only be one.
const char *disk; // Disk image to attach, or NULL for a machine with no disk.
const char *disks[DISK_DRIVE_COUNT];
int diskCount;
// A drive of this many blocks made of memory, taking the next drive number after the
// images above. Zero for a machine without one.
unsigned long ramDisk;
uint8_t writeProtect; // Attach the disk read only, the way a tab on a floppy would.
const char *screen; // Where to save a picture of the screen when the machine stops.
const char *keyboard; // Feed the console from this file as a keyboard, not a terminal.
const char *sound; // Where to save the samples the machine made, as raw 16 bit.
// ---- A controller made of a file ----
//
// One byte a frame, each byte the buttons held during it. Voyager reads a real pad, and
// its own tests run headless with nobody holding anything - so without this the device
// would be exercised only by somebody playing, which is exactly the state the console's
// line editing was in when it broke twice in two days.
const char *pads[PAD_DRIVE_COUNT];
int padCount; // --pad given more than once fills them in turn, like --disk.
// Where to write what the controllers held, one byte a frame, in the format --pad reads.
// Every pad or-ed together, because which one a controller lands on is the host's business
// and a demo is a record of what somebody did.
const char *padRecord;
} EmulatorOptions;
uint8_t parseOptions(int argc, char *argv[], EmulatorOptions *options);
void printHelp(const char *programName);
uint8_t loadFile(const char *path, uint8_t *Program, uint8_t *Data);
void bootStrap(uint8_t *Program, uint8_t *Data);
void printRegisters(CPURegisters *cpu, uint8_t *Program, uint8_t *Data);
#endif // UTILITY_H