// The Apple II the game runs on: a 64K RAM image holding the four FS2 // code/data chunks at their original addresses, the hires pages at // $2000/$4000, and the soft switches, keyboard latch, paddle timers, // speaker and SmartPort block device the game touches. // // Every translated routine reads and writes fs2Ram directly, so RAM is // laid out exactly as on the original machine and can be diffed // against an fs2trace dump. #ifndef MACHINE_H #define MACHINE_H #include #include #define MACHINE_RAM_SIZE 0x10000 #define MACHINE_BLOCK_BYTES 512 #define MACHINE_BLOCK_LIST 256 // entries in ReadBlockDataBuffer ($D575) #define MACHINE_LC_BANK_START 0xD000 #define MACHINE_LC_BANK_BYTES 0x1000 #define MACHINE_HIRES_PAGE1 0x2000 #define MACHINE_HIRES_PAGE2 0x4000 #define MACHINE_HIRES_BYTES 0x2000 #define MACHINE_PADDLES 2 #define MACHINE_KEY_QUEUE 32 // Milliseconds of wall-clock time per ProcessInputTick: the clock code // advances one second every eight ticks. #define MACHINE_TICK_MS 125 extern uint8_t fs2Ram[MACHINE_RAM_SIZE]; // Loading and reset ------------------------------------------------ // Load the chunk images (orig/2_f600-fbff, 3_d300-f3ff, 4_0200-25ff, // 5_6000-b3df) and the loading panel into RAM. `dir` is the project // root. Returns false on any missing file. bool machineLoadChunks(const char *dir); // Mount a ProDOS disk image and select the file (FS2.1, A2.SD1, ...) // whose blocks the game's loader reads; its index block becomes the // block list at $D575. Either argument may be NULL to keep the current // image or file. bool machineMountDisk(const char *poPath, const char *fileName); // Copy the mounted block list into $D575 (the boot loader's job). void machineInstallBlockList(void); // SmartPort ReadBlock: copy 512 bytes of physical `block` to `addr`. // Returns true on success (carry clear). bool machineReadBlock(uint16_t block, uint16_t addr); // Display ---------------------------------------------------------- // LOWSCR / HISCR soft switches. void machineLowScr(void); void machineHiScr(void); bool machinePage2Displayed(void); // TXTCLR / TXTSET ($C050 / $C051): the edit-mode overlay shows the // 40-column text page at $0400 while it runs. void machineTxtClr(void); void machineTxtSet(void); bool machineTextModeDisplayed(void); // Language card bank select ($C08B / $C083). Bank 1 swaps a private 4K // image into $D000-$DFFF; bank 2 restores the game's chunk3 bytes. void machineLcBank(int bank); // Input ------------------------------------------------------------ // KBD ($C000): latch value, bit 7 set while a key is pending. uint8_t machineReadKbd(void); // KBDSTRB ($C010): clear the latch. void machineKbdStrobe(void); // Host side: queue an Apple II key code (0..127). void machinePushKey(uint8_t key); // BUTN0/BUTN1 ($C061/$C062): bit 7 set while pressed. uint8_t machineReadButton(int index); // PTRIG ($C070): start the paddle timers. void machinePaddleTrigger(void); // PADDL0/PADDL1 ($C064/$C065): bit 7 set while the timer runs. uint8_t machineReadPaddle(int index); // Host side: paddle positions 0..255. void machineSetPaddle(int index, uint8_t value); void machineSetButton(int index, bool down); // Sound ------------------------------------------------------------ // SPKR ($C030): toggle the speaker cone. void machineClickSpeaker(void); // Host services ----------------------------------------------------- // Called by the game once per ProcessInputTick and on every page flip: // pumps host events, refreshes the window, and paces the tick rate. void machinePoll(bool tick); // Busy-wait delays (chunk3 Delay, the ATIS typing pace) as wall-clock // time; the host keeps pumping events meanwhile. void machineDelayMicroseconds(uint32_t microseconds); // Reboot request (MaybeBootDOS): the host restarts the game. void machineRequestReboot(void); bool machineRebootRequested(void); // Host callbacks installed by main.c. NULL callbacks are ignored. typedef struct MachineHostT { void (*poll)(void *userData, bool tick); void (*speaker)(void *userData); void (*delay)(void *userData, uint32_t microseconds); void *userData; } MachineHostT; void machineSetHost(const MachineHostT *host); // Add `amount` to the frame work counter $32/$33 (16-bit). void ramChargeWork(uint16_t amount); // Little-endian word helpers over the RAM image. uint16_t ramRead16(uint16_t addr); void ramWrite16(uint16_t addr, uint16_t value); #endif