typedef unsigned char UINT8; typedef unsigned int UINT32; typedef void genf(void); typedef UINT32 offs_t; struct _subtable_data { UINT32 usecount; }; typedef struct _subtable_data subtable_data; struct _table_data { UINT8 *table; subtable_data subtable[64]; }; typedef struct _table_data table_data; struct _addrspace_data { table_data read; table_data write; }; typedef struct _addrspace_data addrspace_data; struct _cpu_data { addrspace_data space[3]; }; typedef struct _cpu_data cpu_data; static cpu_data cpudata[8]; static void install_mem_handler(addrspace_data * space, int iswrite, int databits, int ismatchmask, offs_t start, offs_t end, offs_t mask, offs_t mirror, genf * handler, int isfixed, const char *handler_name); static void reallocate_subtable(table_data * tabledata, UINT8 subentry); static void release_subtable(table_data * tabledata, UINT8 subentry); void *_memory_install_read_handler(int cpunum, int spacenum, offs_t start, offs_t end, offs_t mask, offs_t mirror, int handler, const char *handler_name) { addrspace_data *space = &cpudata[cpunum].space[spacenum]; install_mem_handler(space, 0, 8, 0, start, end, mask, mirror, (genf *) handler, 0, handler_name); } static void install_mem_handler(addrspace_data * space, int iswrite, int databits, int ismatchmask, offs_t start, offs_t end, offs_t mask, offs_t mirror, genf * handler, int isfixed, const char *handler_name) { offs_t lmirrorbit[18], lmirrorbits, hmirrorbit[(32 - 18)], hmirrorbits, lmirrorcount, hmirrorcount; table_data *tabledata = iswrite ? &space->write : &space->read; UINT8 idx, prev_entry = 0; int cur_index, prev_index = 0; int i; for (i = (32 - 18); hmirrorcount < (1 << hmirrorbits); hmirrorcount++) { offs_t hmirrorbase = 0; if (cur_index == ((end + hmirrorbase) >> (32 - 18))) { if (hmirrorcount != 0 && prev_entry == tabledata->table[cur_index]) { if (tabledata->table[cur_index] >= (256 - 64)) release_subtable(tabledata, tabledata-> table[cur_index]); if (tabledata->table[prev_index] >= (256 - 64)) reallocate_subtable(tabledata, tabledata-> table[prev_index]); } prev_entry = tabledata->table[cur_index]; } for (lmirrorcount = 0; lmirrorcount < (1 << lmirrorbits); lmirrorcount++) { offs_t lmirrorbase = hmirrorbase; for (i = 0; i < lmirrorbits; i++) if (lmirrorcount & (1 << i)) lmirrorbase |= lmirrorbit[i]; } } } static void reallocate_subtable(table_data * tabledata, UINT8 subentry) { UINT8 subindex = subentry - (256 - 64); if (tabledata->subtable[subindex].usecount <= 0) osd_die ("Called reallocate_subtable on a table with a usecount of 0\n"); } static void release_subtable(table_data * tabledata, UINT8 subentry) { UINT8 subindex = subentry - (256 - 64); if (tabledata->subtable[subindex].usecount <= 0) osd_die ("Called release_subtable on a table with a usecount of 0\n"); }