123 lines
4.4 KiB
C
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
|