THE MACHINE SUPPLIES BLOCKS AND SAYS WHAT A DRIVE IS. It says nothing about filesystems, which is what leaves room for a system that would rather have its own - and is why the volatile bit is a fact about the hardware rather than a promise about SBFS. 0x26 what the selected drive is: bit 0, contents do not survive 0x27, 0x28 how many blocks it has --ram-disk N a drive of N blocks with memory behind it A drive of memory selects, reads, writes and has a size like any other, and a program cannot tell the difference except by how fast it was. The one thing it cannot work out for itself is that the contents are volatile, because an empty disk and a volatile disk look identical from outside. THAT BIT IS THE DIFFERENCE BETWEEN A DRIVE A SYSTEM MAY FORMAT ON SIGHT AND ONE IT MUST NOT. CosmOS formats a volatile drive it cannot read, because there was never anything on it to lose, and leaves every other unreadable drive alone - an unformatted floppy is not an invitation, it is a blank floppy. Removing that check formats somebody's blank disk, which is checked rather than asserted: cosmosBlankDisk boots with one and requires it to be refused. So CosmOS grew a format. The size comes from the drive rather than from a superblock, since a superblock states a size too and that is no use on a disk which has not got one yet. Sixteen directory blocks, 128 names, chosen rather than worked out: a scratch disk runs out of names long before room, and this machine cannot divide. The RAM disk is no faster on this emulator by default, and that is honest rather than disappointing: the emulated disk has no seek time unless asked for one. With --disk-cycles 10000 the same copy is 7.94M cycles against 8.70M, the difference being every write. run.sh takes "ram:2048" where an image name goes, which needs no removing between runs because there is nothing to remove. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
52 lines
2.1 KiB
C
52 lines
2.1 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.
|
|
|
|
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.
|
|
} 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
|