// utility.h // Utilities for the SplitBit CPU Emulator // Written by Anachronaut // 10/15/2024 #ifndef UTILITY_H #define UTILITY_H #include #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