/*
- FUJITSU FMR-50 Emulator 'eFMR-50'
- FUJITSU FMR-60 Emulator 'eFMR-60'
+ FUJITSU FM Towns Emulator 'eFMTowns'
- Author : Takeda.Toshiya
- Date : 2008.04.29 -
+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
+ Date : 2017.01.01 -
- [ memory and crtc ]
+ [ memory]
*/
-#include "memory.h"
+#include "./memory.h"
#include "../i386.h"
-
-#define SET_BANK(s, e, w, r) { \
- int sb = (s) >> 11, eb = (e) >> 11; \
- for(int i = sb; i <= eb; i++) { \
- if((w) == wdmy) { \
- wbank[i] = wdmy; \
- } else { \
- wbank[i] = (w) + 0x800 * (i - sb); \
- } \
- if((r) == rdmy) { \
- rbank[i] = rdmy; \
- } else { \
- rbank[i] = (r) + 0x800 * (i - sb); \
- } \
- } \
-}
-
-void MEMORY::initialize()
+void TOWNS_MEMORY::initialize()
{
bankf8_ram = false;
fio->Fread(dict_rom, sizeof(dict_rom), 1);
fio->Fclose();
}
-
- memset(extram_adrs, 0x00, sizeof(extram_adrs));
+ // ToDo: Will move to config.
extram_pages = TOWNS_EXTRAM_PAGES;
extram_base = (uint8_t *)malloc(extram_pages * 0x100000);
- if(extram_base == NULL) {
- extram_pages = 0;
- } else {
- for(uint32_t ui = 0; ui < extram_pages; ui++) {
- uint8_t *p;
- p = &(extram_base[ui << 20]);
- extram_adrs[ui] = p;
- }
- }
- // Address Cx000000
- memset(write_bank_adrs_cx, 0x00, sizeof(write_bank_adrs_cx));
- memset(read_bank_adrs_cx, 0x00, sizeof(read_bank_adrs_cx));
- memset(device_bank_adrs_cx, 0x00, sizeof(device_bank_adrs_cx));
-
- for(uint32_t ui = 0x0000; ui < 0x4000; ui++) {
- if(ui < 0x2000) {
- // ROM CARD?
- } else if(ui < 0x2080) {
- read_bank_adrs_cx[ui] = &(msdos_rom[(ui - 0x2000) << 12]);
- } else if(ui < 0x2100) {
- read_bank_adrs_cx[ui] = &(dict_rom[(ui - 0x2080) << 12]);
- } else if(ui < 0x2140) {
- read_bank_adrs_cx[ui] = &(font_rom[(ui - 0x2100) << 12]);
- } else if(ui < 0x2142) {
- devicetype_adrs_cx[ui] = TOWNS_MEMORY_TYPE_DICTLEARN;
- } eise if(ui < 0x2200) {
- // Reserved.
- } else if(ui < 0x2201) {
- devicetype_adrs_cx[ui] = TOWNS_MEMORY_TYPE_WAVERAM;
- } else {
- // Reserved.
- }
- }
-
+
+ initialize_tables();
}
-void MEMORY::reset()
+void TOWNS_MEMORY::reset()
{
// reset memory
protect = rst = 0;
- mainmem = rplane = wplane = 0;
-#ifndef _FMR60
- pagesel = ankcg = 0;
-#endif
- update_bank();
-
- // reset crtc
- blink = 0;
- apalsel = 0;
- outctrl = 0xf;
-#ifndef _FMR60
- dispctrl = 0x47;
- mix = 8;
- accaddr = dispaddr = 0;
- kj_l = kj_h = kj_ofs = kj_row = 0;
-
- // reset logical operation
- cmdreg = maskreg = compbit = bankdis = 0;
- memset(compreg, sizeof(compreg), 0xff);
-#endif
+ // ToDo
dma_addr_reg = dma_wrap_reg = 0;
dma_addr_mask = 0x00ffffff;
d_cpu->set_address_mask(0xffffffff);
}
-void MEMORY::write_page0_8(uint32_t addr, uint32_t data, int *wait)
+void TOWNS_MEMORY::write_page0_8(uint32_t addr, uint32_t data, int *wait)
{
addr = addr & 0x000fffff;
if(wait != NULL) *wait = mem_wait_val;
if(d_vram != NULL) {
d_vram->write_plane_data8(addr & 0x7fff, data);
if(wait != NULL) *wait = vram_wait_val;
+ }
} else if(addr < 0xd0000) {
// MMIO, VRAM and ram.
if(0xcff80 <= addr && addr < 0xcffe0) {
}
}
-void MEMORY::write_data8(uint32_t addr, uint32_t data)
+void TOWNS_MEMORY::initialize_tables(void)
+{
+ memset(extram_adrs, 0x00, sizeof(extram_adrs));
+ if(extram_base == NULL) {
+ extram_pages = 0;
+ } else {
+ for(uint32_t ui = 0; ui < extram_pages; ui++) {
+ uint8_t *p;
+ p = &(extram_base[ui << 20]);
+ extram_adrs[ui] = p;
+ }
+ }
+ // Address Cx000000
+ memset(write_bank_adrs_cx, 0x00, sizeof(write_bank_adrs_cx));
+ memset(read_bank_adrs_cx, 0x00, sizeof(read_bank_adrs_cx));
+ memset(device_bank_adrs_cx, 0x00, sizeof(device_bank_adrs_cx));
+
+ for(uint32_t ui = 0x0000; ui < 0x4000; ui++) {
+ if(ui < 0x2000) {
+ // ROM CARD?
+ } else if(ui < 0x2080) {
+ read_bank_adrs_cx[ui] = &(msdos_rom[(ui - 0x2000) << 12]);
+ } else if(ui < 0x2100) {
+ read_bank_adrs_cx[ui] = &(dict_rom[(ui - 0x2080) << 12]);
+ } else if(ui < 0x2140) {
+ read_bank_adrs_cx[ui] = &(font_rom[(ui - 0x2100) << 12]);
+ } else if(ui < 0x2142) {
+ devicetype_adrs_cx[ui] = TOWNS_MEMORY_TYPE_DICTLEARN;
+ } eise if(ui < 0x2200) {
+ // Reserved.
+ } else if(ui < 0x2201) {
+ devicetype_adrs_cx[ui] = TOWNS_MEMORY_TYPE_WAVERAM;
+ } else {
+ // Reserved.
+ }
+ }
+}
+void TOWNS_MEMORY::write_data8(uint32_t addr, uint32_t data)
{
int wait = 0;
write_data8w(addr, data, &wait);
}
-void MEMORY::write_data16(uint32_t addr, uint32_t data)
+void TOWNS_MEMORY::write_data16(uint32_t addr, uint32_t data)
{
int wait = 0;
write_data16w(addr, data, &wait);
}
-void MEMORY::write_data32(uint32_t addr, uint32_t data)
+void TOWNS_MEMORY::write_data32(uint32_t addr, uint32_t data)
{
int wait = 0;
write_data32w(addr, data, &wait);
}
-void MEMORY::write_data8w(uint32_t addr, uint32_t data, int *wait)
+void TOWNS_MEMORY::write_data8w(uint32_t addr, uint32_t data, int *wait)
{
uint32_t addr_head = (addr & 0xf0000000) >> 28;
uint32_t addr_mid;
}
}
-void MEMORY::write_data16w(uint32_t addr, uint32_t data, int *wait)
+void TOWNS_MEMORY::write_data16w(uint32_t addr, uint32_t data, int *wait)
{
uint32_t addr_head = (addr & 0xf0000000) >> 28;
uint32_t addr_low;
}
}
-void MEMORY::write_data32w(uint32_t addr, uint32_t data, int *wait)
+void TOWNS_MEMORY::write_data32w(uint32_t addr, uint32_t data, int *wait)
{
uint32_t addr_head = (addr & 0xf0000000) >> 28;
uint32_t addr_low;
}
}
-uint32_t MEMORY::read_page0_8(uint32_t addr, int *wait)
+uint32_t TOWNS_MEMORY::read_page0_8(uint32_t addr, int *wait)
{
addr = addr & 0x000fffff;
}
-uint32_t MEMORY::read_data8(uint32_t addr)
+uint32_t TOWNS_MEMORY::read_data8(uint32_t addr)
{
int wait;
return read_data8w(addr, &wait);
}
-uint32_t MEMORY::read_data16(uint32_t addr)
+uint32_t TOWNS_MEMORY::read_data16(uint32_t addr)
{
int wait;
return read_data16w(addr, &wait);
}
-uint32_t MEMORY::read_data32(uint32_t addr)
+uint32_t TOWNS_MEMORY::read_data32(uint32_t addr)
{
int wait;
return read_data32w(addr, &wait);
}
-uint32_t MEMORY::read_data8w(uint32_t addr, int *wait)
+uint32_t TOWNS_MEMORY::read_data8w(uint32_t addr, int *wait)
{
uint32_t addr_head = (addr & 0xf0000000) >> 28;
uint32_t addr_mid;
return 0xff;
}
-uint32_t MEMORY::read_data16w(uint32_t addr, int *wait)
+uint32_t TOWNS_MEMORY::read_data16w(uint32_t addr, int *wait)
{
uint32_t addr_head = (addr & 0xf0000000) >> 28;
uint32_t addr_mid;
return 0xffff;
}
-uint32_t MEMORY::read_data32w(uint32_t addr, int *wait)
+uint32_t TOWNS_MEMORY::read_data32w(uint32_t addr, int *wait)
{
uint32_t addr_head = (addr & 0xf0000000) >> 28;
uint32_t addr_mid;
return 0xffffffff;
}
-void MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
+void TOWNS_MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
{
int wait;
write_data8w(addr & dma_addr_mask, data, &wait);
}
-uint32_t MEMORY::read_dma_data8(uint32_t addr)
+uint32_t TOWNS_MEMORY::read_dma_data8(uint32_t addr)
{
int wait;
return read_data8w(addr & dma_addr_mask, &wait);
}
-void MEMORY::write_dma_data16(uint32_t addr, uint32_t data)
+void TOWNS_MEMORY::write_dma_data16(uint32_t addr, uint32_t data)
{
int wait;
write_data16w(addr & dma_addr_mask, data, &wait);
}
-uint32_t MEMORY::read_dma_data16(uint32_t addr)
+uint32_t TOWNS_MEMORY::read_dma_data16(uint32_t addr)
{
int wait;
return read_data16w(addr & dma_addr_mask, &wait);
}
-void MEMORY::write_io8(uint32_t addr, uint32_t data)
+void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
{
switch(addr & 0xffff) {
case 0x20:
}
}
-uint32_t MEMORY::read_io8(uint32_t addr)
+uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
{
uint32_t val = 0xff;
return 0xff;
}
-void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
+void TOWNS_MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
{
if(id == SIG_MEMORY_DISP) {
disp = ((data & mask) != 0);
}
}
-void MEMORY::event_frame()
-{
- blink++;
-}
-
-void MEMORY::update_bank()
-{
- if(!mainmem) {
-#ifdef _FMR60
- int ofs = rplane * 0x20000;
- SET_BANK(0xc0000, 0xdffff, vram + ofs, vram + ofs);
- SET_BANK(0xe0000, 0xeffff, wdmy, rdmy);
-#else
- if(dispctrl & 0x40) {
- // 400 line
- int ofs = (rplane | ((pagesel >> 2) & 4)) * 0x8000;
- SET_BANK(0xc0000, 0xc7fff, vram + ofs, vram + ofs);
- } else {
- // 200 line
- int ofs = (rplane | ((pagesel >> 1) & 0xc)) * 0x4000;
- SET_BANK(0xc0000, 0xc3fff, vram + ofs, vram + ofs);
- SET_BANK(0xc4000, 0xc7fff, vram + ofs, vram + ofs);
- }
- SET_BANK(0xc8000, 0xc8fff, cvram, cvram);
- SET_BANK(0xc9000, 0xc9fff, wdmy, rdmy);
- if(ankcg & 1) {
- SET_BANK(0xca000, 0xca7ff, wdmy, ank8);
- SET_BANK(0xca800, 0xcafff, wdmy, rdmy);
- SET_BANK(0xcb000, 0xcbfff, wdmy, ank16);
- } else {
- SET_BANK(0xca000, 0xcafff, kvram, kvram);
- SET_BANK(0xcb000, 0xcbfff, wdmy, rdmy);
- }
- SET_BANK(0xcc000, 0xeffff, wdmy, rdmy);
-#endif
- } else {
- SET_BANK(0xc0000, 0xeffff, ram + 0xc0000, ram + 0xc0000);
- }
- if(!(protect & 0x20)) {
-#ifdef _FMR60
- SET_BANK(0xf8000, 0xf9fff, cvram, cvram);
- SET_BANK(0xfa000, 0xfbfff, avram, avram);
-#else
- SET_BANK(0xf8000, 0xfbfff, wdmy, rdmy);
-#endif
- SET_BANK(0xfc000, 0xfffff, wdmy, ipl);
- } else {
- SET_BANK(0xf8000, 0xfffff, ram + 0xf8000, ram + 0xf8000);
- }
-}
-
-void MEMORY::update_dma_addr_mask()
+void TOWNS_MEMORY::update_dma_addr_mask()
{
switch(dma_addr_reg & 3) {
case 0:
}
}
-#ifndef _FMR60
-void MEMORY::point(int x, int y, int col)
-{
- if(x < 640 && y < 400) {
- int ofs = ((lofs & 0x3fff) + (x >> 3) + y * 80) & 0x7fff;
- uint8_t bit = 0x80 >> (x & 7);
- for(int pl = 0; pl < 4; pl++) {
- uint8_t pbit = 1 << pl;
- if(!(bankdis & pbit)) {
- if(col & pbit) {
- vram[0x8000 * pl + ofs] |= bit;
- } else {
- vram[0x8000 * pl + ofs] &= ~bit;
- }
- }
- }
- }
-}
+#define STATE_VERSION 1
-void MEMORY::line()
+void TOWNS_MEMORY::save_state(FILEIO* state_fio)
{
- int nx = lsx, ny = lsy;
- int dx = abs(lex - lsx) * 2;
- int dy = abs(ley - lsy) * 2;
- int sx = (lex < lsx) ? -1 : 1;
- int sy = (ley < lsy) ? -1 : 1;
- int c = 0;
-
- point(lsx, lsy, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
- if(dx > dy) {
- int frac = dy - dx / 2;
- while(nx != lex) {
- if(frac >= 0) {
- ny += sy;
- frac -= dx;
- }
- nx += sx;
- frac += dy;
- point(nx, ny, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
- }
- } else {
- int frac = dx - dy / 2;
- while(ny != ley) {
- if(frac >= 0) {
- nx += sx;
- frac -= dy;
- }
- ny += sy;
- frac += dx;
- point(nx, ny, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
- }
- }
-// point(lex, ley, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
-}
-#endif
+ state_fio->FputUint32(STATE_VERSION);
+ state_fio->FputInt32(this_device_id);
-void MEMORY::draw_screen()
-{
- // render screen
- memset(screen_txt, 0, sizeof(screen_txt));
- memset(screen_cg, 0, sizeof(screen_cg));
- if(outctrl & 1) {
-#ifdef _FMR60
- draw_text();
-#else
- if(mix & 8) {
- draw_text80();
- } else {
- draw_text40();
- }
-#endif
- }
- if(outctrl & 4) {
- draw_cg();
- }
-
- for(int y = 0; y < SCREEN_HEIGHT; y++) {
- scrntype_t* dest = emu->get_screen_buffer(y);
- uint8_t* txt = screen_txt[y];
- uint8_t* cg = screen_cg[y];
-
- for(int x = 0; x < SCREEN_WIDTH; x++) {
- dest[x] = txt[x] ? palette_txt[txt[x] & 15] : palette_cg[cg[x]];
- }
- }
- emu->screen_skip_line(false);
-}
+ state_fio->FputBool(bank8_ram);
+ state_fio->FputBool(bankd0_dict);
+ state_fio->FputUint8(dict_bank);
+ state_fio->FputUint32_LE(extram_pages);
-#ifdef _FMR60
-void MEMORY::draw_text()
-{
- int src = ((chreg[12] << 9) | (chreg[13] << 1)) & 0x1fff;
- int caddr = ((chreg[8] & 0xc0) == 0xc0) ? -1 : (((chreg[14] << 9) | (chreg[15] << 1)) & 0x1fff);
- int ymax = (chreg[6] > 0) ? chreg[6] : 25;
- int yofs = 750 / ymax;
-
- for(int y = 0; y < 25; y++) {
- for(int x = 0; x < 80; x++) {
- bool cursor = ((src >> 1) == caddr);
- int cx = x;
- uint8_t codel = cvram[src];
- uint8_t attrl = avram[src];
- src = (src + 1) & 0x1ffff;
- uint8_t codeh = cvram[src];
- uint8_t attrh = avram[src];
- src = (src + 1) & 0x1ffff;
- uint8_t col = (attrl & 15) | 16;
- bool blnk = (attrh & 0x40) || ((blink & 32) && (attrh & 0x10));
- bool rev = ((attrh & 8) != 0);
- uint8_t xor_mask = (rev != blnk) ? 0xff : 0;
-
- if(codeh & 0x80) {
- // kanji
- int ofs = (codel | ((codeh & 0x7f) << 8)) * 72;
- for(int l = 3; l < 27 && l < yofs; l++) {
- uint8_t pat0 = kanji24[ofs++] ^ xor_mask;
- uint8_t pat1 = kanji24[ofs++] ^ xor_mask;
- uint8_t pat2 = kanji24[ofs++] ^ xor_mask;
- int yy = y * yofs + l;
- if(yy >= 750) {
- break;
- }
- uint8_t* d = &screen_txt[yy][x * 14];
-
- d[ 2] = (pat0 & 0x80) ? col : 0;
- d[ 3] = (pat0 & 0x40) ? col : 0;
- d[ 4] = (pat0 & 0x20) ? col : 0;
- d[ 5] = (pat0 & 0x10) ? col : 0;
- d[ 6] = (pat0 & 0x08) ? col : 0;
- d[ 7] = (pat0 & 0x04) ? col : 0;
- d[ 8] = (pat0 & 0x02) ? col : 0;
- d[ 9] = (pat0 & 0x01) ? col : 0;
- d[10] = (pat1 & 0x80) ? col : 0;
- d[11] = (pat1 & 0x40) ? col : 0;
- d[12] = (pat1 & 0x20) ? col : 0;
- d[13] = (pat1 & 0x10) ? col : 0;
- d[14] = (pat1 & 0x08) ? col : 0;
- d[15] = (pat1 & 0x04) ? col : 0;
- d[16] = (pat1 & 0x02) ? col : 0;
- d[17] = (pat1 & 0x01) ? col : 0;
- d[18] = (pat2 & 0x80) ? col : 0;
- d[19] = (pat2 & 0x40) ? col : 0;
- d[20] = (pat2 & 0x20) ? col : 0;
- d[21] = (pat2 & 0x10) ? col : 0;
- d[22] = (pat2 & 0x08) ? col : 0;
- d[23] = (pat2 & 0x04) ? col : 0;
- d[24] = (pat2 & 0x02) ? col : 0;
- d[25] = (pat2 & 0x01) ? col : 0;
- }
- src = (src + 2) & 0x1fff;
- x++;
- } else if(codeh) {
- } else {
- // ank
- int ofs = codel * 48;
- for(int l = 3; l < 27 && l < yofs; l++) {
- uint8_t pat0 = ank24[ofs++] ^ xor_mask;
- uint8_t pat1 = ank24[ofs++] ^ xor_mask;
- int yy = y * yofs + l;
- if(yy >= 750) {
- break;
- }
- uint8_t* d = &screen_txt[yy][x * 14];
-
- d[ 0] = (pat0 & 0x80) ? col : 0;
- d[ 1] = (pat0 & 0x40) ? col : 0;
- d[ 2] = (pat0 & 0x20) ? col : 0;
- d[ 3] = (pat0 & 0x10) ? col : 0;
- d[ 4] = (pat0 & 0x08) ? col : 0;
- d[ 5] = (pat0 & 0x04) ? col : 0;
- d[ 6] = (pat0 & 0x02) ? col : 0;
- d[ 7] = (pat0 & 0x01) ? col : 0;
- d[ 8] = (pat1 & 0x80) ? col : 0;
- d[ 9] = (pat1 & 0x40) ? col : 0;
- d[10] = (pat1 & 0x20) ? col : 0;
- d[11] = (pat1 & 0x10) ? col : 0;
- d[12] = (pat1 & 0x08) ? col : 0;
- d[13] = (pat1 & 0x04) ? col : 0;
- }
- }
-/*
- if(cursor) {
- int bp = chreg[10] & 0x60;
- if(bp == 0 || (bp == 0x40 && (blink & 8)) || (bp == 0x60 && (blink & 0x10))) {
- int st = chreg[10] & 15;
- int ed = chreg[11] & 15;
- for(int i = st; i < ed && i < yofs; i++) {
- memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
- }
- }
- }
-*/
- }
- }
-}
-#else
-void MEMORY::draw_text40()
-{
- int src = ((chreg[12] << 9) | (chreg[13] << 1)) & 0xfff;
- int caddr = ((chreg[8] & 0xc0) == 0xc0) ? -1 : (((chreg[14] << 9) | (chreg[15] << 1) | (mix & 0x20 ? 1 : 0)) & 0x7ff);
- int ymax = (chreg[6] > 0) ? chreg[6] : 25;
- int yofs = 400 / ymax;
+ state_fio->FputInt8((int8_t)vram_wait_val);
+ state_fio->FputInt8((int8_t)mem_wait_val);
+ state_fio->FputInt8((int8_t)extio_wait_val);
- for(int y = 0; y < ymax; y++) {
- for(int x = 0; x < 40; x++) {
- bool cursor = ((src >> 1) == caddr);
- int cx = x;
- uint8_t code = cvram[src];
- uint8_t h = kvram[src] & 0x7f;
- src = (src + 1) & 0xfff;
- uint8_t attr = cvram[src];
- uint8_t l = kvram[src] & 0x7f;
- src = (src + 1) & 0xfff;
- uint8_t col = ((attr & 0x20) >> 2) | (attr & 7) | 16;
- bool blnk = (blink & 32) && (attr & 0x10);
- bool rev = ((attr & 8) != 0);
- uint8_t xor_mask = (rev != blnk) ? 0xff : 0;
-
- if(attr & 0x40) {
- // kanji
- int ofs;
- if(h < 0x30) {
- ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10);
- } else if(h < 0x70) {
- ofs = (((l - 0x00) & 0x1f) << 5) + (((l - 0x20) & 0x60) << 9) + (((h - 0x00) & 0x0f) << 10) + (((h - 0x30) & 0x70) * 0xc00) + 0x08000;
- } else {
- ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10) | 0x38000;
- }
-
- for(int l = 0; l < 16 && l < yofs; l++) {
- uint8_t pat0 = kanji16[ofs + (l << 1) + 0] ^ xor_mask;
- uint8_t pat1 = kanji16[ofs + (l << 1) + 1] ^ xor_mask;
- int yy = y * yofs + l;
- if(yy >= 400) {
- break;
- }
- uint8_t* d = &screen_txt[yy][x << 4];
-
- d[ 0] = d[ 1] = (pat0 & 0x80) ? col : 0;
- d[ 2] = d[ 3] = (pat0 & 0x40) ? col : 0;
- d[ 4] = d[ 5] = (pat0 & 0x20) ? col : 0;
- d[ 6] = d[ 7] = (pat0 & 0x10) ? col : 0;
- d[ 8] = d[ 9] = (pat0 & 0x08) ? col : 0;
- d[10] = d[11] = (pat0 & 0x04) ? col : 0;
- d[12] = d[13] = (pat0 & 0x02) ? col : 0;
- d[14] = d[15] = (pat0 & 0x01) ? col : 0;
- d[16] = d[17] = (pat1 & 0x80) ? col : 0;
- d[18] = d[19] = (pat1 & 0x40) ? col : 0;
- d[20] = d[21] = (pat1 & 0x20) ? col : 0;
- d[22] = d[23] = (pat1 & 0x10) ? col : 0;
- d[24] = d[25] = (pat1 & 0x08) ? col : 0;
- d[26] = d[27] = (pat1 & 0x04) ? col : 0;
- d[28] = d[29] = (pat1 & 0x02) ? col : 0;
- d[30] = d[31] = (pat1 & 0x01) ? col : 0;
- }
- src = (src + 2) & 0xfff;
- x++;
- } else {
- for(int l = 0; l < 16 && l < yofs; l++) {
- uint8_t pat = ank16[(code << 4) + l] ^ xor_mask;
- int yy = y * yofs + l;
- if(yy >= 400) {
- break;
- }
- uint8_t* d = &screen_txt[yy][x << 4];
-
- d[ 0] = d[ 1] = (pat & 0x80) ? col : 0;
- d[ 2] = d[ 3] = (pat & 0x40) ? col : 0;
- d[ 4] = d[ 5] = (pat & 0x20) ? col : 0;
- d[ 6] = d[ 7] = (pat & 0x10) ? col : 0;
- d[ 8] = d[ 9] = (pat & 0x08) ? col : 0;
- d[10] = d[11] = (pat & 0x04) ? col : 0;
- d[12] = d[13] = (pat & 0x02) ? col : 0;
- d[14] = d[15] = (pat & 0x01) ? col : 0;
- }
- }
- if(cursor) {
- int bp = chreg[10] & 0x60;
- if(bp == 0 || (bp == 0x40 && (blink & 8)) || (bp == 0x60 && (blink & 0x10))) {
- int st = chreg[10] & 15;
- int ed = chreg[11] & 15;
- for(int i = st; i < ed && i < yofs; i++) {
- memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
- }
- }
- }
- }
- }
-}
-
-void MEMORY::draw_text80()
-{
- int src = ((chreg[12] << 9) | (chreg[13] << 1)) & 0xfff;
- int caddr = ((chreg[8] & 0xc0) == 0xc0) ? -1 : (((chreg[14] << 9) | (chreg[15] << 1) | (mix & 0x20 ? 1 : 0)) & 0x7ff);
- int ymax = (chreg[6] > 0) ? chreg[6] : 25;
- int yofs = 400 / ymax;
+ // Save rom?
+ state_fio->Fwrite(page0, sizeof(page0));
+ state_fio->Fwrite(ram_0d0, sizeof(ram_0d0));
+ state_fio->Fwrite(ram_0f0, sizeof(ram_0f0));
+ state_fio->Fwrite(ram_0f8, sizeof(ram_0f8));
- for(int y = 0; y < 25; y++) {
- for(int x = 0; x < 80; x++) {
- bool cursor = ((src >> 1) == caddr);
- int cx = x;
- uint8_t code = cvram[src];
- uint8_t h = kvram[src] & 0x7f;
- src = (src + 1) & 0xfff;
- uint8_t attr = cvram[src];
- uint8_t l = kvram[src] & 0x7f;
- src = (src + 1) & 0xfff;
- uint8_t col = ((attr & 0x20) >> 2) | (attr & 7) | 16;
- bool blnk = (blink & 32) && (attr & 0x10);
- bool rev = ((attr & 8) != 0);
- uint8_t xor_mask = (rev != blnk) ? 0xff : 0;
-
- if(attr & 0x40) {
- // kanji
- int ofs;
- if(h < 0x30) {
- ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10);
- } else if(h < 0x70) {
- ofs = (((l - 0x00) & 0x1f) << 5) + (((l - 0x20) & 0x60) << 9) + (((h - 0x00) & 0x0f) << 10) + (((h - 0x30) & 0x70) * 0xc00) + 0x08000;
- } else {
- ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10) | 0x38000;
- }
-
- for(int l = 0; l < 16 && l < yofs; l++) {
- uint8_t pat0 = kanji16[ofs + (l << 1) + 0] ^ xor_mask;
- uint8_t pat1 = kanji16[ofs + (l << 1) + 1] ^ xor_mask;
- int yy = y * yofs + l;
- if(yy >= 400) {
- break;
- }
- uint8_t* d = &screen_txt[yy][x << 3];
-
- d[ 0] = (pat0 & 0x80) ? col : 0;
- d[ 1] = (pat0 & 0x40) ? col : 0;
- d[ 2] = (pat0 & 0x20) ? col : 0;
- d[ 3] = (pat0 & 0x10) ? col : 0;
- d[ 4] = (pat0 & 0x08) ? col : 0;
- d[ 5] = (pat0 & 0x04) ? col : 0;
- d[ 6] = (pat0 & 0x02) ? col : 0;
- d[ 7] = (pat0 & 0x01) ? col : 0;
- d[ 8] = (pat1 & 0x80) ? col : 0;
- d[ 9] = (pat1 & 0x40) ? col : 0;
- d[10] = (pat1 & 0x20) ? col : 0;
- d[11] = (pat1 & 0x10) ? col : 0;
- d[12] = (pat1 & 0x08) ? col : 0;
- d[13] = (pat1 & 0x04) ? col : 0;
- d[14] = (pat1 & 0x02) ? col : 0;
- d[15] = (pat1 & 0x01) ? col : 0;
- }
- src = (src + 2) & 0xfff;
- x++;
- } else {
- for(int l = 0; l < 16 && l < yofs; l++) {
- uint8_t pat = ank16[(code << 4) + l] ^ xor_mask;
- int yy = y * yofs + l;
- if(yy >= 400) {
- break;
- }
- uint8_t* d = &screen_txt[yy][x << 3];
-
- d[0] = (pat & 0x80) ? col : 0;
- d[1] = (pat & 0x40) ? col : 0;
- d[2] = (pat & 0x20) ? col : 0;
- d[3] = (pat & 0x10) ? col : 0;
- d[4] = (pat & 0x08) ? col : 0;
- d[5] = (pat & 0x04) ? col : 0;
- d[6] = (pat & 0x02) ? col : 0;
- d[7] = (pat & 0x01) ? col : 0;
- }
- }
- if(cursor) {
- int bp = chreg[10] & 0x60;
- if(bp == 0 || (bp == 0x40 && (blink & 8)) || (bp == 0x60 && (blink & 0x10))) {
- int st = chreg[10] & 15;
- int ed = chreg[11] & 15;
- for(int i = st; i < ed && i < yofs; i++) {
- memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
- }
- }
- }
- }
- }
-}
-#endif
-
-void MEMORY::draw_cg()
-{
-#ifdef _FMR60
- uint8_t* p0 = &vram[0x00000];
- uint8_t* p1 = &vram[0x20000];
- uint8_t* p2 = &vram[0x40000];
- uint8_t* p3 = &vram[0x60000];
- int ptr = 0;
+ // ROM?
+ state_fio->Fwrite(msdos_rom, sizeof(msdos_rom));
+ state_fio->Fwrite(dict_rom, sizeof(dict_rom));
+ state_fio->Fwrite(font_rom, sizeof(font_rom));
+ //state_fio->Fwrite(font_20_rom, sizeof(font_20_rom));
+ state_fio->Fwrite(system_rom, sizeof(system_rom));
- for(int y = 0; y < 750; y++) {
- for(int x = 0; x < 1120; x += 8) {
- uint8_t r = p0[ptr];
- uint8_t g = p1[ptr];
- uint8_t b = p2[ptr];
- uint8_t i = p3[ptr++];
- ptr &= 0x1ffff;
- uint8_t* d = &screen_cg[y][x];
-
- d[0] = ((r & 0x80) >> 7) | ((g & 0x80) >> 6) | ((b & 0x80) >> 5) | ((i & 0x80) >> 4);
- d[1] = ((r & 0x40) >> 6) | ((g & 0x40) >> 5) | ((b & 0x40) >> 4) | ((i & 0x40) >> 3);
- d[2] = ((r & 0x20) >> 5) | ((g & 0x20) >> 4) | ((b & 0x20) >> 3) | ((i & 0x20) >> 2);
- d[3] = ((r & 0x10) >> 4) | ((g & 0x10) >> 3) | ((b & 0x10) >> 2) | ((i & 0x10) >> 1);
- d[4] = ((r & 0x08) >> 3) | ((g & 0x08) >> 2) | ((b & 0x08) >> 1) | ((i & 0x08) >> 0);
- d[5] = ((r & 0x04) >> 2) | ((g & 0x04) >> 1) | ((b & 0x04) >> 0) | ((i & 0x04) << 1);
- d[6] = ((r & 0x02) >> 1) | ((g & 0x02) >> 0) | ((b & 0x02) << 1) | ((i & 0x02) << 2);
- d[7] = ((r & 0x01) >> 0) | ((g & 0x01) << 1) | ((b & 0x01) << 2) | ((i & 0x01) << 3);
- }
- }
-#else
- if(dispctrl & 0x40) {
- // 400line
- int pofs = ((dispctrl >> 3) & 1) * 0x20000;
- uint8_t* p0 = (dispctrl & 0x01) ? &vram[pofs | 0x00000] : dummy;
- uint8_t* p1 = (dispctrl & 0x02) ? &vram[pofs | 0x08000] : dummy;
- uint8_t* p2 = (dispctrl & 0x04) ? &vram[pofs | 0x10000] : dummy;
- uint8_t* p3 = (dispctrl & 0x20) ? &vram[pofs | 0x18000] : dummy; // ???
- int ptr = dispaddr & 0x7ffe;
-
- for(int y = 0; y < 400; y++) {
- for(int x = 0; x < 640; x += 8) {
- uint8_t r = p0[ptr];
- uint8_t g = p1[ptr];
- uint8_t b = p2[ptr];
- uint8_t i = p3[ptr++];
- ptr &= 0x7fff;
- uint8_t* d = &screen_cg[y][x];
-
- d[0] = ((r & 0x80) >> 7) | ((g & 0x80) >> 6) | ((b & 0x80) >> 5) | ((i & 0x80) >> 4);
- d[1] = ((r & 0x40) >> 6) | ((g & 0x40) >> 5) | ((b & 0x40) >> 4) | ((i & 0x40) >> 3);
- d[2] = ((r & 0x20) >> 5) | ((g & 0x20) >> 4) | ((b & 0x20) >> 3) | ((i & 0x20) >> 2);
- d[3] = ((r & 0x10) >> 4) | ((g & 0x10) >> 3) | ((b & 0x10) >> 2) | ((i & 0x10) >> 1);
- d[4] = ((r & 0x08) >> 3) | ((g & 0x08) >> 2) | ((b & 0x08) >> 1) | ((i & 0x08) >> 0);
- d[5] = ((r & 0x04) >> 2) | ((g & 0x04) >> 1) | ((b & 0x04) >> 0) | ((i & 0x04) << 1);
- d[6] = ((r & 0x02) >> 1) | ((g & 0x02) >> 0) | ((b & 0x02) << 1) | ((i & 0x02) << 2);
- d[7] = ((r & 0x01) >> 0) | ((g & 0x01) << 1) | ((b & 0x01) << 2) | ((i & 0x01) << 3);
- }
- }
- } else {
- // 200line
- int pofs = ((dispctrl >> 3) & 3) * 0x10000;
- uint8_t* p0 = (dispctrl & 0x01) ? &vram[pofs | 0x0000] : dummy;
- uint8_t* p1 = (dispctrl & 0x02) ? &vram[pofs | 0x4000] : dummy;
- uint8_t* p2 = (dispctrl & 0x04) ? &vram[pofs | 0x8000] : dummy;
- uint8_t* p3 = (dispctrl & 0x20) ? &vram[pofs | 0xc000] : dummy; // ???
- int ptr = dispaddr & 0x3ffe;
-
- for(int y = 0; y < 400; y += 2) {
- for(int x = 0; x < 640; x += 8) {
- uint8_t r = p0[ptr];
- uint8_t g = p1[ptr];
- uint8_t b = p2[ptr];
- uint8_t i = p3[ptr++];
- ptr &= 0x3fff;
- uint8_t* d = &screen_cg[y][x];
-
- d[0] = ((r & 0x80) >> 7) | ((g & 0x80) >> 6) | ((b & 0x80) >> 5) | ((i & 0x80) >> 4);
- d[1] = ((r & 0x40) >> 6) | ((g & 0x40) >> 5) | ((b & 0x40) >> 4) | ((i & 0x40) >> 3);
- d[2] = ((r & 0x20) >> 5) | ((g & 0x20) >> 4) | ((b & 0x20) >> 3) | ((i & 0x20) >> 2);
- d[3] = ((r & 0x10) >> 4) | ((g & 0x10) >> 3) | ((b & 0x10) >> 2) | ((i & 0x10) >> 1);
- d[4] = ((r & 0x08) >> 3) | ((g & 0x08) >> 2) | ((b & 0x08) >> 1) | ((i & 0x08) >> 0);
- d[5] = ((r & 0x04) >> 2) | ((g & 0x04) >> 1) | ((b & 0x04) >> 0) | ((i & 0x04) << 1);
- d[6] = ((r & 0x02) >> 1) | ((g & 0x02) >> 0) | ((b & 0x02) << 1) | ((i & 0x02) << 2);
- d[7] = ((r & 0x01) >> 0) | ((g & 0x01) << 1) | ((b & 0x01) << 2) | ((i & 0x01) << 3);
- }
- memcpy(screen_cg[y + 1], screen_cg[y], 640);
- }
- }
-#endif
-}
-
-#define STATE_VERSION 1
-
-void MEMORY::save_state(FILEIO* state_fio)
-{
- state_fio->FputUint32(STATE_VERSION);
- state_fio->FputInt32(this_device_id);
+ state_fio->Fwrite(extram_base, extram_pages * 0x100000);
- state_fio->Fwrite(ram, sizeof(ram), 1);
- state_fio->Fwrite(vram, sizeof(vram), 1);
- state_fio->Fwrite(cvram, sizeof(cvram), 1);
-#ifdef _FMR60
- state_fio->Fwrite(avram, sizeof(avram), 1);
-#else
- state_fio->Fwrite(kvram, sizeof(kvram), 1);
-#endif
- state_fio->FputUint8(machine_id);
+// ToDo
state_fio->FputUint8(protect);
state_fio->FputUint8(rst);
- state_fio->FputUint8(mainmem);
- state_fio->FputUint8(rplane);
- state_fio->FputUint8(wplane);
- state_fio->FputUint8(dma_addr_reg);
- state_fio->FputUint8(dma_wrap_reg);
- state_fio->FputUint32(dma_addr_mask);
- state_fio->FputBool(disp);
- state_fio->FputBool(vsync);
- state_fio->FputInt32(blink);
- state_fio->Fwrite(apal, sizeof(apal), 1);
- state_fio->FputUint8(apalsel);
- state_fio->Fwrite(dpal, sizeof(dpal), 1);
- state_fio->FputUint8(outctrl);
-#ifndef _FMR60
- state_fio->FputUint8(pagesel);
- state_fio->FputUint8(ankcg);
- state_fio->FputUint8(dispctrl);
- state_fio->FputUint8(mix);
- state_fio->FputUint16(accaddr);
- state_fio->FputUint16(dispaddr);
- state_fio->FputInt32(kj_h);
- state_fio->FputInt32(kj_l);
- state_fio->FputInt32(kj_ofs);
- state_fio->FputInt32(kj_row);
- state_fio->FputUint8(cmdreg);
- state_fio->FputUint8(imgcol);
- state_fio->FputUint8(maskreg);
- state_fio->Fwrite(compreg, sizeof(compreg), 1);
- state_fio->FputUint8(compbit);
- state_fio->FputUint8(bankdis);
- state_fio->Fwrite(tilereg, sizeof(tilereg), 1);
- state_fio->FputUint16(lofs);
- state_fio->FputUint16(lsty);
- state_fio->FputUint16(lsx);
- state_fio->FputUint16(lsy);
- state_fio->FputUint16(lex);
- state_fio->FputUint16(ley);
-#endif
- state_fio->Fwrite(palette_cg, sizeof(palette_cg), 1);
}
-bool MEMORY::load_state(FILEIO* state_fio)
+bool TOWNS_MEMORY::load_state(FILEIO* state_fio)
{
if(state_fio->FgetUint32() != STATE_VERSION) {
return false;
if(state_fio->FgetInt32() != this_device_id) {
return false;
}
- state_fio->Fread(ram, sizeof(ram), 1);
- state_fio->Fread(vram, sizeof(vram), 1);
- state_fio->Fread(cvram, sizeof(cvram), 1);
-#ifdef _FMR60
- state_fio->Fread(avram, sizeof(avram), 1);
-#else
- state_fio->Fread(kvram, sizeof(kvram), 1);
-#endif
- machine_id = state_fio->FgetUint8();
+
+ bank8_tam = state_fio->FgetBool();
+ bank0_dict = state_fio->FgetBool();
+ dict_bank = state_fio->FgetUint8();
+ extram_pages = state_fio->FgetUint32_LE();
+
+ vram_wait_val = (int)state_fio->FgetInt8();
+ mem_wait_val = (int)state_fio->FgetInt8();
+ extio_wait_val = (int)state_fio->FgetInt8();
+
+ // Save rom?
+ state_fio->Fread(page0, sizeof(page0));
+ state_fio->Fread(ram_0d0, sizeof(ram_0d0));
+ state_fio->Fread(ram_0f0, sizeof(ram_0f0));
+ state_fio->Fread(ram_0f8, sizeof(ram_0f8));
+
+ // ROM?
+ state_fio->Fread(msdos_rom, sizeof(msdos_rom));
+ state_fio->Fread(dict_rom, sizeof(dict_rom));
+ state_fio->Fread(font_rom, sizeof(font_rom));
+ //state_fio->Fwrite(font_20_rom, sizeof(font_20_rom));
+ state_fio->Fread(system_rom, sizeof(system_rom));
+
+ uint8_t *pp;
+ pp = malloc(extram_pages * 0x100000);
+ if(pp == NULL) {
+ return false;
+ } else {
+ state_fio->Fread(pp, extram_pages * 0x100000);
+ }
+ //ToDo
protect = state_fio->FgetUint8();
rst = state_fio->FgetUint8();
- mainmem = state_fio->FgetUint8();
- rplane = state_fio->FgetUint8();
- wplane = state_fio->FgetUint8();
- dma_addr_reg = state_fio->FgetUint8();
- dma_wrap_reg = state_fio->FgetUint8();
- dma_addr_mask = state_fio->FgetUint32();
- disp = state_fio->FgetBool();
- vsync = state_fio->FgetBool();
- blink = state_fio->FgetInt32();
- state_fio->Fread(apal, sizeof(apal), 1);
- apalsel = state_fio->FgetUint8();
- state_fio->Fread(dpal, sizeof(dpal), 1);
- outctrl = state_fio->FgetUint8();
-#ifndef _FMR60
- pagesel = state_fio->FgetUint8();
- ankcg = state_fio->FgetUint8();
- dispctrl = state_fio->FgetUint8();
- mix = state_fio->FgetUint8();
- accaddr = state_fio->FgetUint16();
- dispaddr = state_fio->FgetUint16();
- kj_h = state_fio->FgetInt32();
- kj_l = state_fio->FgetInt32();
- kj_ofs = state_fio->FgetInt32();
- kj_row = state_fio->FgetInt32();
- cmdreg = state_fio->FgetUint8();
- imgcol = state_fio->FgetUint8();
- maskreg = state_fio->FgetUint8();
- state_fio->Fread(compreg, sizeof(compreg), 1);
- compbit = state_fio->FgetUint8();
- bankdis = state_fio->FgetUint8();
- state_fio->Fread(tilereg, sizeof(tilereg), 1);
- lofs = state_fio->FgetUint16();
- lsty = state_fio->FgetUint16();
- lsx = state_fio->FgetUint16();
- lsy = state_fio->FgetUint16();
- lex = state_fio->FgetUint16();
- ley = state_fio->FgetUint16();
-#endif
- state_fio->Fread(palette_cg, sizeof(palette_cg), 1);
+
// post process
- update_bank();
+ //update_bank();
+ extram_base = pp;
+ initialize_tables();
+
return true;
}