Fri, 12 Apr 2013 12:37:13 +0100
Make the page table volatile (it may change behind gcc's back)
philpem@18 | 1 | #ifndef _STATE_H |
philpem@18 | 2 | #define _STATE_H |
philpem@18 | 3 | |
philpem@18 | 4 | #include <stddef.h> |
philpem@18 | 5 | #include <stdint.h> |
philpem@18 | 6 | #include <stdbool.h> |
philpem@52 | 7 | #include "wd279x.h" |
philpem@112 | 8 | #include "wd2010.h" |
philpem@80 | 9 | #include "keyboard.h" |
philpem@18 | 10 | |
philpem@18 | 11 | // Maximum size of the Boot PROMs. Must be a binary power of two. |
philpem@18 | 12 | #define ROM_SIZE 32768 |
philpem@18 | 13 | |
philpem@18 | 14 | /** |
philpem@55 | 15 | * State error codes |
philpem@55 | 16 | */ |
philpem@55 | 17 | typedef enum { |
philpem@55 | 18 | STATE_E_OK = 0, ///< Operation succeeded |
philpem@55 | 19 | STATE_E_BAD_RAMSIZE = -1, ///< Bad RAM size specified (not a multiple of 512K, or less than 512K) |
philpem@55 | 20 | STATE_E_NO_MEMORY = -2, ///< Out of memory while allocating state variables |
philpem@55 | 21 | STATE_E_ROM_LOAD_FAIL = -3 ///< Error loading ROMs |
philpem@55 | 22 | } STATE_ERR; |
philpem@55 | 23 | |
philpem@55 | 24 | /** |
philpem@18 | 25 | * @brief Emulator state storage |
philpem@18 | 26 | * |
philpem@18 | 27 | * This structure stores the internal state of the emulator. |
philpem@18 | 28 | */ |
philpem@18 | 29 | typedef struct { |
philpem@18 | 30 | // Boot PROM can be up to 32Kbytes total size |
philpem@18 | 31 | uint8_t rom[ROM_SIZE]; ///< Boot PROM data buffer |
philpem@18 | 32 | |
philpem@52 | 33 | //// Main system RAM |
philpem@60 | 34 | uint8_t *base_ram; ///< Base RAM data buffer |
philpem@60 | 35 | size_t base_ram_size; ///< Size of Base RAM buffer in bytes |
philpem@62 | 36 | uint8_t *exp_ram; ///< Expansion RAM data buffer |
philpem@62 | 37 | size_t exp_ram_size; ///< Size of Expansion RAM buffer in bytes |
philpem@18 | 38 | |
philpem@52 | 39 | /// Video RAM |
philpem@52 | 40 | uint8_t vram[0x8000]; |
philpem@24 | 41 | |
philpem@52 | 42 | /// Map RAM |
philpem@142 | 43 | volatile uint8_t map[0x800]; |
philpem@26 | 44 | |
philpem@52 | 45 | //// Registers |
philpem@37 | 46 | uint16_t genstat; ///< General Status Register |
philpem@37 | 47 | uint16_t bsr0; ///< Bus Status Register 0 |
philpem@37 | 48 | uint16_t bsr1; ///< Bus Status Register 1 |
philpem@32 | 49 | |
philpem@52 | 50 | //// MISCELLANEOUS CONTROL REGISTER |
philpem@52 | 51 | bool dma_reading; ///< True if Disc DMA reads from the controller, false otherwise |
philpem@46 | 52 | uint8_t leds; ///< LED status, 1=on, in order red3/green2/yellow1/red0 from bit3 to bit0 |
philpem@46 | 53 | |
philpem@97 | 54 | bool timer_enabled; |
philpem@97 | 55 | bool timer_asserted; |
philpem@97 | 56 | |
philpem@52 | 57 | //// GENERAL CONTROL REGISTER |
philpem@18 | 58 | /// GENCON.ROMLMAP -- false ORs the address with 0x800000, forcing the |
philpem@18 | 59 | /// 68010 to access ROM instead of RAM when booting. TRM page 2-36. |
philpem@24 | 60 | bool romlmap; |
philpem@44 | 61 | /// GENCON.PIE -- Parity Error Check Enable |
philpem@44 | 62 | bool pie; |
philpem@101 | 63 | /// GENCON.EE -- Error Enable |
philpem@101 | 64 | bool ee; |
philpem@52 | 65 | |
philpem@52 | 66 | /// DMA Address Register |
philpem@52 | 67 | uint32_t dma_address; |
philpem@52 | 68 | |
philpem@53 | 69 | /// DMA count |
philpem@53 | 70 | uint32_t dma_count; |
philpem@53 | 71 | |
philpem@53 | 72 | /// DMA direction |
philpem@53 | 73 | bool idmarw; |
philpem@53 | 74 | /// DMA enable |
philpem@53 | 75 | bool dmaen; |
philpem@53 | 76 | bool dmaenb; |
philpem@53 | 77 | |
philpem@112 | 78 | /// DMA device selection flags |
philpem@112 | 79 | bool fd_selected; |
philpem@112 | 80 | bool hd_selected; |
philpem@52 | 81 | /// Floppy disc controller context |
philpem@52 | 82 | WD2797_CTX fdc_ctx; |
philpem@95 | 83 | /// Current disc image file |
philpem@95 | 84 | FILE *fdc_disc; |
philpem@80 | 85 | |
philpem@112 | 86 | /// Hard disc controller context |
philpem@112 | 87 | WD2010_CTX hdc_ctx; |
philpem@112 | 88 | FILE *hdc_disc0; |
philpem@112 | 89 | FILE *hdc_disc1; |
philpem@112 | 90 | |
philpem@80 | 91 | /// Keyboard controller context |
philpem@80 | 92 | KEYBOARD_STATE kbd; |
philpem@18 | 93 | } S_state; |
philpem@18 | 94 | |
philpem@18 | 95 | // Global emulator state. Yes, I know global variables are evil, please don't |
philpem@18 | 96 | // email me and lecture me about it. -philpem |
philpem@18 | 97 | #ifndef _STATE_C |
philpem@18 | 98 | extern S_state state; |
philpem@18 | 99 | #else |
philpem@18 | 100 | S_state state; |
philpem@18 | 101 | #endif |
philpem@18 | 102 | |
philpem@18 | 103 | /** |
philpem@18 | 104 | * @brief Initialise system state |
philpem@18 | 105 | * |
philpem@62 | 106 | * @param base_ram_size Base RAM size in bytes -- must be a multiple of 512KiB, min 512KiB, max 2MiB. |
philpem@62 | 107 | * @param exp_ram_size Expansion RAM size in bytes -- must be a multiple of 512KiB, min 0, max 2MiB. |
philpem@18 | 108 | * |
philpem@18 | 109 | * Initialises the emulator's internal state. |
philpem@18 | 110 | */ |
philpem@62 | 111 | int state_init(size_t base_ram_size, size_t exp_ram_size); |
philpem@18 | 112 | |
philpem@18 | 113 | /** |
philpem@18 | 114 | * @brief Deinitialise system state |
philpem@18 | 115 | * |
philpem@18 | 116 | * Deinitialises the saved state, and frees all memory. Call this function |
philpem@18 | 117 | * before exiting your program to avoid memory leaks. |
philpem@18 | 118 | */ |
philpem@18 | 119 | void state_done(); |
philpem@18 | 120 | |
philpem@18 | 121 | #endif |