fs2port/port/include/machine.h

123 lines
4.4 KiB
C

// 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 <stdbool.h>
#include <stdint.h>
#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