rombankswitcher = 0;
rombank = 0;
- rl = getromlistbyids (roms);
- if (rl) {
- struct zfile *z;
- rd = rl->rd;
- z = read_rom (&rd);
- if (z) {
- int slotsize = 65536;
- write_log (_T("A590/A2091 BOOT ROM %d.%d\n"), rd->ver, rd->rev);
- rom_size = rd->size;
- rom = xmalloc (uae_u8, slotsize);
- zfile_fread (rom, rom_size, 1, z);
- zfile_fclose (z);
- if (rl->rd->id == 56) {
- rombankswitcher = 1;
- for (int i = rom_size - 1; i >= 0; i--) {
- rom[i * 2 + 0] = rom[i];
- rom[i * 2 + 1] = 0xff;
- }
- } else {
- for (int i = 1; i < slotsize / rom_size; i++)
- memcpy (rom + i * rom_size, rom, rom_size);
+ struct zfile *z = read_rom_name (currprefs.a2091romfile);
+ if (!z) {
+ rl = getromlistbyids (roms);
+ if (rl) {
+ rd = rl->rd;
+ z = read_rom (&rd);
+ }
+ }
+ if (z) {
+ int slotsize = 65536;
+ write_log (_T("A590/A2091 BOOT ROM '%s'\n"), zfile_getname (z));
+ rom_size = rd->size;
+ rom = xmalloc (uae_u8, slotsize);
+ zfile_fread (rom, rom_size, 1, z);
+ zfile_fclose (z);
+ if (rl->rd->id == 56) {
+ rombankswitcher = 1;
+ for (int i = rom_size - 1; i >= 0; i--) {
+ rom[i * 2 + 0] = rom[i];
+ rom[i * 2 + 1] = 0xff;
}
- rom_mask = rom_size - 1;
+ } else {
+ for (int i = 1; i < slotsize / rom_size; i++)
+ memcpy (rom + i * rom_size, rom, rom_size);
}
+ rom_mask = rom_size - 1;
} else {
romwarning (roms);
}
cfgfile_write_str (f, _T("use_gui"), guimode1[p->start_gui]);
cfgfile_write_bool (f, _T("use_debugger"), p->start_debugger);
+
cfgfile_write_rom (f, &p->path_rom, p->romfile, _T("kickstart_rom_file"));
cfgfile_write_rom (f, &p->path_rom, p->romextfile, _T("kickstart_ext_rom_file"));
if (p->romextfile2addr) {
cfgfile_dwrite_str (f, _T("kickstart_rom"), p->romident);
if (p->romextident[0])
cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident);
+
+ cfgfile_write_rom (f, &p->path_rom, p->a2091romfile, _T("a2091_rom_file"));
+ cfgfile_write_rom (f, &p->path_rom, p->a4091romfile, _T("a4091_rom_file"));
+ if (p->a2091romident[0])
+ cfgfile_dwrite_str (f, _T("a2091_rom"), p->a2091romident);
+ if (p->a4091romident[0])
+ cfgfile_dwrite_str (f, _T("a4091_rom"), p->a4091romident);
+
cfgfile_write_path (f, &p->path_rom, _T("flash_file"), p->flashfile);
cfgfile_write_path (f, &p->path_rom, _T("cart_file"), p->cartfile);
cfgfile_write_path (f, &p->path_rom, _T("rtc_file"), p->rtcfile);
cfgfile_write_bool (f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite);
cfgfile_write (f, _T("chipmem_size"), _T("%d"), p->chipmem_size == 0x20000 ? -1 : (p->chipmem_size == 0x40000 ? 0 : p->chipmem_size / 0x80000));
cfgfile_dwrite (f, _T("megachipmem_size"), _T("%d"), p->z3chipmem_size / 0x100000);
- if (p->custom_memory_sizes[0])
- cfgfile_write (f, _T("addmem1"), _T("0x%x,0x%x"), p->custom_memory_addrs[0], p->custom_memory_sizes[0]);
- if (p->custom_memory_sizes[1])
- cfgfile_write (f, _T("addmem2"), _T("0x%x,0x%x"), p->custom_memory_addrs[1], p->custom_memory_sizes[1]);
+ // do not save aros rom special space
+ if (!(p->custom_memory_sizes[0] == 512 * 1024 && p->custom_memory_sizes[1] == 512 * 1024 && p->custom_memory_addrs[0] == 0xa80000 && p->custom_memory_addrs[1] == 0xb00000)) {
+ if (p->custom_memory_sizes[0])
+ cfgfile_write (f, _T("addmem1"), _T("0x%x,0x%x"), p->custom_memory_addrs[0], p->custom_memory_sizes[0]);
+ if (p->custom_memory_sizes[1])
+ cfgfile_write (f, _T("addmem2"), _T("0x%x,0x%x"), p->custom_memory_addrs[1], p->custom_memory_sizes[1]);
+ }
if (p->m68k_speed > 0) {
cfgfile_write (f, _T("finegrain_cpu_speed"), _T("%d"), p->m68k_speed);
if (cfgfile_path (option, value, _T("kickstart_rom_file"), p->romfile, sizeof p->romfile / sizeof (TCHAR), &p->path_rom)
|| cfgfile_path (option, value, _T("kickstart_ext_rom_file"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR), &p->path_rom)
|| cfgfile_path (option, value, _T("kickstart_ext_rom_file2"), p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR), &p->path_rom)
+ || cfgfile_path (option, value, _T("a2091_rom_file"), p->a2091romfile, sizeof p->a2091romfile / sizeof (TCHAR), &p->path_rom)
+ || cfgfile_path (option, value, _T("a4091_rom_file"), p->a4091romfile, sizeof p->a4091romfile / sizeof (TCHAR), &p->path_rom)
|| cfgfile_rom (option, value, _T("kickstart_rom_file_id"), p->romfile, sizeof p->romfile / sizeof (TCHAR))
|| cfgfile_rom (option, value, _T("kickstart_ext_rom_file_id"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR))
+ || cfgfile_rom (option, value, _T("a2091_rom_file_id"), p->a2091romfile, sizeof p->a2091romfile / sizeof (TCHAR))
+ || cfgfile_rom (option, value, _T("a4091_rom_file_id"), p->a4091romfile, sizeof p->a4091romfile / sizeof (TCHAR))
|| cfgfile_path (option, value, _T("amax_rom_file"), p->amaxromfile, sizeof p->amaxromfile / sizeof (TCHAR))
|| cfgfile_path (option, value, _T("flash_file"), p->flashfile, sizeof p->flashfile / sizeof (TCHAR), &p->path_rom)
|| cfgfile_path (option, value, _T("cart_file"), p->cartfile, sizeof p->cartfile / sizeof (TCHAR), &p->path_rom)
decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident, ROMTYPE_ALL_EXT);
return 1;
}
+ if (cfgfile_string (option, value, _T("a2091_rom"), p->a2091romident, sizeof p->a2091romident / sizeof (TCHAR))) {
+ decode_rom_ident (p->a2091romident, sizeof p->a2091romident / sizeof (TCHAR), p->a2091romident, ROMTYPE_A2091BOOT);
+ return 1;
+ }
+ if (cfgfile_string (option, value, _T("a4091_rom"), p->a4091romident, sizeof p->a4091romident / sizeof (TCHAR))) {
+ decode_rom_ident (p->a4091romident, sizeof p->a4091romident / sizeof (TCHAR), p->a4091romident, ROMTYPE_A4091BOOT);
+ return 1;
+ }
if (cfgfile_string (option, value, _T("cart"), p->cartident, sizeof p->cartident / sizeof (TCHAR))) {
decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART);
return 1;
subst (p->path_rom.path[0], p->romfile, sizeof p->romfile / sizeof (TCHAR));
subst (p->path_rom.path[0], p->romextfile, sizeof p->romextfile / sizeof (TCHAR));
subst (p->path_rom.path[0], p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR));
+ subst (p->path_rom.path[0], p->a2091romfile, sizeof p->a2091romfile / sizeof (TCHAR));
+ subst (p->path_rom.path[0], p->a4091romfile, sizeof p->a4091romfile / sizeof (TCHAR));
return 1;
}
_tcscpy (p->romfile, _T(""));
_tcscpy (p->romextfile, _T(""));
+ _tcscpy (p->a2091romfile, _T(""));
+ _tcscpy (p->a4091romfile, _T(""));
_tcscpy (p->flashfile, _T(""));
_tcscpy (p->cartfile, _T(""));
_tcscpy (p->rtcfile, _T(""));
void mmu_dump_tables(void)
{
write_log(_T("URP: %08x SRP: %08x MMUSR: %x TC: %x\n"), regs.urp, regs.srp, regs.mmusr, regs.tcr);
- mmu_dump_ttr(L"DTT0", regs.dtt0);
- mmu_dump_ttr(L"DTT1", regs.dtt1);
- mmu_dump_ttr(L"ITT0", regs.itt0);
- mmu_dump_ttr(L"ITT1", regs.itt1);
+ mmu_dump_ttr(_T("DTT0"), regs.dtt0);
+ mmu_dump_ttr(_T("DTT1"), regs.dtt1);
+ mmu_dump_ttr(_T("ITT0"), regs.itt0);
+ mmu_dump_ttr(_T("ITT1"), regs.itt1);
mmu_dump_atc();
#if MMUDEBUG
// mmu_dump_table("SRP", regs.srp);
return (super ? 4 : 0) | (data ? 1 : 2);
}
-static void mmu_bus_error(uaecptr addr, int fc, bool write, int size, bool rmw, uae_u32 status)
+void mmu_bus_error(uaecptr addr, int fc, bool write, int size, bool rmw, uae_u32 status)
{
if (currprefs.mmu_model == 68040) {
uae_u16 ssw = 0;
#define ATC030_PHYS_CI 0x04000000
#define ATC030_PHYS_BE 0x08000000
-static void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) {
+void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) {
regs.mmu_fault_addr = addr;
regs.mmu_ssw = (fc & 1) ? MMU030_SSW_DF | (MMU030_SSW_DF << 1) : (MMU030_SSW_FB | MMU030_SSW_RB);
regs.mmu_ssw |= read ? MMU030_SSW_RW : 0;
#define CUSTOM_DEBUG 0
#define SPRITE_DEBUG 0
-#define SPRITE_DEBUG_MINY 246
+#define SPRITE_DEBUG_MINY 0
#define SPRITE_DEBUG_MAXY 0x300
#define SPR0_HPOS 0x15
#define MAX_SPRITES 8
static int sprite_vblank_endline = VBLANK_SPRITE_PAL;
-static unsigned int sprctl[MAX_SPRITES], sprpos[MAX_SPRITES];
+static uae_u16 sprctl[MAX_SPRITES], sprpos[MAX_SPRITES];
#ifdef AGA
static uae_u16 sprdata[MAX_SPRITES][4], sprdatb[MAX_SPRITES][4];
#else
static struct decision thisline_decision;
static int fetch_cycle, fetch_modulo_cycle;
-
+static bool aga_plf_passed_stop2;
enum plfstate
{
plf_idle,
return equ_vblank_endline + (equ_vblank_toggle ? (lof_current ? 1 : 0) : 0);
}
+#define HARD_DDF_LIMITS_DISABLED ((beamcon0 & 0x80) || (bplcon0 & 0x40))
+/* The HRM says 0xD8, but that can't work... */
+#define HARD_DDF_STOP (HARD_DDF_LIMITS_DISABLED ? 0xff : 0xd6)
+#define HARD_DDF_START_REAL 0x18
+/* Programmed rates or superhires (!) disable normal DMA limits */
+#define HARD_DDF_START (HARD_DDF_LIMITS_DISABLED ? 0x04 : 0x18)
+
/* Called to determine the state of the horizontal display window state
* machine at the current position. It might have changed since we last
* checked. */
thisline_decision.diwfirstword = diwfirstword < 0 ? PIXEL_XPOS(0) : diwfirstword;
hdiwstate = DIW_waiting_stop;
}
- if (lhdiw >= diw_hstop && last_hdiw < diw_hstop && hdiwstate == DIW_waiting_stop) {
+ if (((hpos >= maxhpos && HARD_DDF_LIMITS_DISABLED) || (lhdiw >= diw_hstop && last_hdiw < diw_hstop)) && hdiwstate == DIW_waiting_stop) {
if (thisline_decision.diwlastword < 0)
thisline_decision.diwlastword = diwlastword < 0 ? 0 : diwlastword;
hdiwstate = DIW_waiting_start;
return real_bitplane_number[fetchmode][res][planes];
}
-#define HARD_DDF_LIMITS_DISABLED ((beamcon0 & 0x80) || (bplcon0 & 0x40))
-/* The HRM says 0xD8, but that can't work... */
-#define HARD_DDF_STOP (HARD_DDF_LIMITS_DISABLED ? 0xff : 0xd6)
-#define HARD_DDF_START_REAL 0x18
-/* Programmed rates or superhires (!) disable normal DMA limits */
-#define HARD_DDF_START (HARD_DDF_LIMITS_DISABLED ? 0x04 : 0x18)
-
static void reset_dbplh (int hpos, int num)
{
if (dbplpth_on[num] && hpos >= dbplpth_on[num]) {
static void set_delay_lastcycle (void)
{
- delay_lastcycle[0] = ((maxhpos + 1) * 2 + 0) << bplcon0_res;
- delay_lastcycle[1] = delay_lastcycle[0];
- if (islinetoggle ())
- delay_lastcycle[1]++;
+ if (HARD_DDF_LIMITS_DISABLED) {
+ delay_lastcycle[0] = (256 * 2) << bplcon0_res;
+ delay_lastcycle[1] = (256 * 2) << bplcon0_res;
+ } else {
+ delay_lastcycle[0] = ((maxhpos + 1) * 2 + 0) << bplcon0_res;
+ delay_lastcycle[1] = delay_lastcycle[0];
+ if (islinetoggle ())
+ delay_lastcycle[1]++;
+ }
}
static int bpldmasetuphpos, bpldmasetuphpos_diff;
if (plfr_state < plf_end)
finish_last_fetch (maxhpos, fetchmode, true);
plfr_state = plfr_finished;
+
+ // workaround for too long fetches that don't pass plf_passed_stop2 before end of scanline
+ if (aga_plf_passed_stop2 && plf_state >= plf_passed_stop)
+ plf_state = plf_end;
+
// This is really the end of scanline, we can finally flush all remaining data.
thisline_decision.plfright += flush_plane_data (fetchmode);
thisline_decision.plflinelen = out_offs;
case 5: fetch (2, fm, pos); break;
case 6: fetch (4, fm, pos); break;
case 7: fetch (0, fm, pos); break;
+#ifdef AGA
+ default:
+ // if AGA: consider plf_passed_stop2 already
+ // active when last plane has been written,
+ // even if there is still idle cycles left
+ if (plf_state == plf_passed_stop)
+ aga_plf_passed_stop2 = true;
+ break;
+#endif
}
break;
case 4:
case 1: fetch (1, fm, pos); break;
case 2: fetch (2, fm, pos); break;
case 3: fetch (0, fm, pos); break;
+#ifdef AGA
+ default:
+ if (plf_state == plf_passed_stop)
+ aga_plf_passed_stop2 = true;
+ break;
+#endif
}
break;
case 2:
switch (cycle_start) {
case 0: fetch (1, fm, pos); break;
case 1: fetch (0, fm, pos); break;
+#ifdef AGA
+ default:
+ if (plf_state == plf_passed_stop)
+ aga_plf_passed_stop2 = true;
+ break;
+#endif
}
break;
}
}
if (dma) {
- if (plf_state == plf_active && (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) || hpos >= 0x18)) {
+ if (plf_state == plf_active && (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) || hpos >= 0x18 || HARD_DDF_LIMITS_DISABLED)) {
start_bpl_dma (hpos, bplstart);
last_decide_line_hpos = hpos;
#ifndef CUSTOM_SIMPLE
memset (todisplay_aga, 0, sizeof todisplay_aga);
memset (todisplay2_aga, 0, sizeof todisplay2_aga);
}
+ aga_plf_passed_stop2 = false;
#endif
if (bitplane_line_crossing) {
beginning_of_plane_block (bitplane_line_crossing, fetchmode);
}
bitplane_line_crossing = 0;
+ } else {
+ reset_bpl_vars ();
}
last_decide_line_hpos = -1;
}
STATIC_INLINE uae_u16 sprite_fetch2 (struct sprite *s, int hpos, int cycle, int mode)
{
- uae_u16 data = last_custom_value1 = chipmem_wget_indirect (s->pt);
+ uae_u16 data = chipmem_wget_indirect (s->pt);
s->pt += 2;
return data;
}
autoscale_bordercolors = 0;
for (i = 0; i < MAX_SPRITES; i++)
spr[i].ptxhpos = MAXHPOS;
+ plf_state = plf_end;
}
void init_hardware_for_drawing_frame (void)
static unsigned int cycles;
/*
-Robocop 3
+RoboCop 3
- set firebutton as output
- read JOY1DAT
- pulse firebutton (high->low)
- read JOY1DAT
- JOY1DAT bit 8 must toggle
-Leaderboard
+Leader Board
- JOY1DAT, both up and down active (0x0101)
B.A.T. II
- delay
- CTS must be zero
-Italy'90 Soccer
+Italy '90 Soccer
- 220k resistor between pins 5 (+5v) and 7 (POTX)
- POT1DAT POTX must be between 0x32 and 0x60
v = 0;
}
return v;
-}
\ No newline at end of file
+}
{
uae_u16 mid = (currprefs.cs_a2091 || currprefs.uae_hide) ? commodore : uae_id;
uae_u8 pid = (currprefs.cs_a2091 || currprefs.uae_hide) ? commodore_a2091_ram : (currprefs.maprom ? 1 : 81);
+ uae_u8 type = add_memory | zorroII | (currprefs.cs_a2091 ? chainedconfig : 0);
expamem_init_clear ();
if (fastmem_bank.allocated == 0x100000)
- expamem_write (0x00, Z2_MEM_1MB + add_memory + zorroII);
+ type |= Z2_MEM_1MB;
else if (fastmem_bank.allocated == 0x200000)
- expamem_write (0x00, Z2_MEM_2MB + add_memory + zorroII);
+ type |= Z2_MEM_2MB;
else if (fastmem_bank.allocated == 0x400000)
- expamem_write (0x00, Z2_MEM_4MB + add_memory + zorroII);
+ type |= Z2_MEM_4MB;
else if (fastmem_bank.allocated == 0x800000)
- expamem_write (0x00, Z2_MEM_8MB + add_memory + zorroII);
+ type |= Z2_MEM_8MB;
+
+ expamem_write (0x00, type);
expamem_write (0x08, care_addr);
}
if (need_uae_boot_rom () == 0)
do_mount = 0;
+
if (fastmem_bank.baseaddr != NULL && currprefs.chipmem_size <= 2 * 1024 * 1024) {
if (currprefs.fastmem_autoconfig) {
fastmem_bank.name = _T("Fast memory");
map_banks (&fastmem_bank, 0x00200000 >> 16, fastmem_bank.allocated >> 16, 0);
}
}
+ // immediately after Z2Fast so that they can be emulated as A590/A2091 with fast ram.
+#ifdef A2091
+ if (currprefs.cs_a2091) {
+ card_name[cardno] = _T("A2091");
+ card_init[cardno] = expamem_init_a2091;
+ card_map[cardno++] = NULL;
+ }
+#endif
#ifdef CDTV
if (currprefs.cs_cdtvcd) {
}
}
#endif
-#ifdef A2091
- if (currprefs.cs_a2091) {
- card_name[cardno] = _T("A2091");
- card_init[cardno] = expamem_init_a2091;
- card_map[cardno++] = NULL;
- }
-#endif
#ifdef A2065
if (currprefs.a2065name[0]) {
card_name[cardno] = _T("A2065");
}
/* return value = old position. -1 = error. */
-static uae_u64 fs_lseek64 (struct fs_filehandle *fsf, uae_s64 offset, int whence)
+static uae_s64 fs_lseek64 (struct fs_filehandle *fsf, uae_s64 offset, int whence)
{
if (fsf->fstype == FS_ARCHIVE)
return zfile_lseek_archive (fsf->zf, offset, whence);
return isofs_lseek (fsf->isof, offset, whence);
return -1;
}
-static uae_u32 fs_lseek (struct fs_filehandle *fsf, uae_s32 offset, int whence)
+static uae_s32 fs_lseek (struct fs_filehandle *fsf, uae_s32 offset, int whence)
{
- return (uae_u32)fs_lseek64 (fsf, offset, whence);
+ uae_s64 v = fs_lseek64 (fsf, offset, whence);
+ if (v < 0 || v > 0x7fffffff)
+ return -1;
+ return (uae_s32)v;
}
-static uae_u64 fs_fsize64 (struct fs_filehandle *fsf)
+static uae_s64 fs_fsize64 (struct fs_filehandle *fsf)
{
if (fsf->fstype == FS_ARCHIVE)
return zfile_fsize_archive (fsf->zf);
actual = fs_read (k->fd, buf, size);
- if (actual < 0) {
+ if ((uae_s32)actual == -1) {
PUT_PCK_RES1 (packet, 0);
PUT_PCK_RES2 (packet, dos_errno ());
} else {
PUT_PCK_RES1 (packet, actual);
if (actual != size)
PUT_PCK_RES2 (packet, dos_errno ());
- if (actual >= 0)
+ if ((uae_s32)actual != -1)
k->file_pos += actual;
k->notifyactive = 1;
#include "custom.h"
#include "events.h"
#include "newcpu.h"
-#include "ersatz.h"
#include "md-fpp.h"
#include "savestate.h"
#include "cpu_prefetch.h"
break;
case 2:
{
+ uae_u32 wrd1, wrd2, wrd3;
if (fault_if_4060 (opcode, extra, ad, oldpc, FPU_EXP_UNIMP_DATATYPE))
return -1;
- uae_u32 wrd1, wrd2, wrd3;
wrd1 = (doext ? exts[0] : x_cp_get_long (ad));
ad += 4;
wrd2 = (doext ? exts[1] : x_cp_get_long (ad));
break;
case 3:
{
+ uae_u32 wrd1, wrd2, wrd3;
if (fault_if_4060 (opcode, extra, ad, oldpc, FPU_EXP_UNIMP_DATATYPE))
return -1;
- uae_u32 wrd1, wrd2, wrd3;
wrd1 = (doext ? exts[0] : x_cp_get_long (ad));
ad += 4;
wrd2 = (doext ? exts[1] : x_cp_get_long (ad));
break;
case 2:
{
+ uae_u32 wrd1, wrd2, wrd3;
if (fault_if_4060 (opcode, extra, ad, oldpc, FPU_EXP_UNIMP_DATATYPE))
return -1;
- uae_u32 wrd1, wrd2, wrd3;
from_exten (value, &wrd1, &wrd2, &wrd3);
x_cp_put_long (ad, wrd1);
ad += 4;
break;
case 3:
{
+ uae_u32 wrd1, wrd2, wrd3;
if (fault_if_4060 (opcode, extra, ad, oldpc, FPU_EXP_UNIMP_DATATYPE))
return -1;
- uae_u32 wrd1, wrd2, wrd3;
from_pack (value, &wrd1, &wrd2, &wrd3);
x_cp_put_long (ad, wrd1);
ad += 4;
DE0000 to DEFFFF 64 KB Motherboard resources
*/
+/* A4000T NCR */
#define NCR_OFFSET 0x40
#define NCR_LONG_OFFSET 0x80
#define NCR_MASK 0x3f
dummy_lgeti, dummy_wgeti, ABFLAG_IO
};
-static bool isa4000t (uaecptr addr)
+static bool isa4000t (uaecptr *paddr)
{
if (currprefs.cs_mbdmac != 2)
return false;
+ uaecptr addr = *paddr;
if ((addr & 0xffff) >= (GAYLE_BASE_4000 & 0xffff))
return false;
+ addr &= 0xff;
+ *paddr = addr;
return true;
}
#ifdef JIT
special_mem |= S_READ;
#endif
- if (isa4000t (addr)) {
- addr &= 0xff;
+#ifdef NCR
+ if (currprefs.cs_mbdmac == 2 && (addr & 0xffff) == 0x3000)
+ return 0xffffffff; // NCR DIP BANK
+ if (isa4000t (&addr)) {
if (addr >= NCR_LONG_OFFSET) {
addr &= NCR_MASK;
- v = (ncr_io_bget (addr + 3) << 24) | (ncr_io_bget (addr + 2) << 16) |
- (ncr_io_bget (addr + 1) << 8) | (ncr_io_bget (addr + 0));
+ v = (ncr_io_bget (addr + 3) << 0) | (ncr_io_bget (addr + 2) << 8) |
+ (ncr_io_bget (addr + 1) << 16) | (ncr_io_bget (addr + 0) << 24);
} else if (addr >= NCR_OFFSET) {
addr &= NCR_MASK;
- v = (ncr_io_bget (addr + 0) << 24) | (ncr_io_bget (addr + 1) << 16) |
- (ncr_io_bget (addr + 2) << 8) | (ncr_io_bget (addr + 3));
+ v = (ncr_io_bget (addr + 3) << 0) | (ncr_io_bget (addr + 2) << 8) |
+ (ncr_io_bget (addr + 1) << 16) | (ncr_io_bget (addr + 0) << 24);
}
return v;
}
+#endif
ide_reg = get_gayle_ide_reg (addr, &ide);
if (ide_reg == IDE_DATA) {
v = ide_get_data (ide) << 16;
special_mem |= S_READ;
#endif
#ifdef NCR
- if (isa4000t (addr)) {
- addr &= 0xff;
+ if (currprefs.cs_mbdmac == 2 && (addr & (0xffff - 1)) == 0x3000)
+ return 0xffff; // NCR DIP BANK
+ if (isa4000t (&addr)) {
if (addr >= NCR_OFFSET) {
addr &= NCR_MASK;
v = (ncr_io_bget (addr) << 8) | ncr_io_bget (addr + 1);
special_mem |= S_READ;
#endif
#ifdef NCR
- if (isa4000t (addr)) {
- addr &= 0xff;
+ if (currprefs.cs_mbdmac == 2 && (addr & (0xffff - 3)) == 0x3000)
+ return 0xff; // NCR DIP BANK
+ if (isa4000t (&addr)) {
if (addr >= NCR_OFFSET) {
addr &= NCR_MASK;
return ncr_io_bget (addr);
#ifdef JIT
special_mem |= S_WRITE;
#endif
- if (isa4000t (addr)) {
- addr &= 0xff;
+ if (isa4000t (&addr)) {
if (addr >= NCR_LONG_OFFSET) {
addr &= NCR_MASK;
ncr_io_bput (addr + 3, value >> 0);
ncr_io_bput (addr + 0, value >> 24);
} else if (addr >= NCR_OFFSET) {
addr &= NCR_MASK;
- ncr_io_bput (addr + 0, value >> 24);
- ncr_io_bput (addr + 1, value >> 16);
- ncr_io_bput (addr + 2, value >> 8);
ncr_io_bput (addr + 3, value >> 0);
+ ncr_io_bput (addr + 2, value >> 8);
+ ncr_io_bput (addr + 1, value >> 16);
+ ncr_io_bput (addr + 0, value >> 24);
}
return;
}
special_mem |= S_WRITE;
#endif
#ifdef NCR
- if (isa4000t (addr)) {
- addr &= 0xff;
+ if (isa4000t (&addr)) {
if (addr >= NCR_OFFSET) {
addr &= NCR_MASK;
ncr_io_bput (addr, value >> 8);
special_mem |= S_WRITE;
#endif
#ifdef NCR
- if (isa4000t (addr)) {
- addr &= 0xff;
+ if (isa4000t (&addr)) {
if (addr >= NCR_OFFSET) {
addr &= NCR_MASK;
ncr_io_bput (addr, value);
printf ("\ts = (uae_s32)src + 2;\n");
if (using_exception_3) {
printf ("\tif (src & 1) {\n");
- printf ("\t\texception3 (opcode, m68k_getpc () + s, 0, 1, m68k_getpc () + s);\n");
+ printf ("\t\texception3b (opcode, m68k_getpc () + s, 0, 1, m68k_getpc () + s);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
need_endlabel = 1;
int unit = mangleunit (m68k_dreg (regs, 0));
struct hardfileprivdata *hfpd = &hardfpd[unit];
int err = IOERR_OPENFAIL;
- int size = get_word (ioreq + 0x12);
-
- /* boot device port size == 0!? KS 1.x size = 12??? */
- if (size >= IOSTDREQ_SIZE || size == 0 || kickstart_version == 0xffff || kickstart_version < 39) {
- /* Check unit number */
- if (unit >= 0) {
- struct hardfiledata *hfd = get_hardfile_data (unit);
- if (hfd && (hfd->handle_valid || hfd->drive_empty) && start_thread (context, unit)) {
- put_word (hfpd->base + 32, get_word (hfpd->base + 32) + 1);
- put_long (ioreq + 24, unit); /* io_Unit */
- put_byte (ioreq + 31, 0); /* io_Error */
- put_byte (ioreq + 8, 7); /* ln_type = NT_REPLYMSG */
- hf_log (_T("hardfile_open, unit %d (%d), OK\n"), unit, m68k_dreg (regs, 0));
- return 0;
- }
+
+ /* boot device port size == 0!? KS 1.x size = 12???
+ * Ignore message size, too many programs do not set it correct
+ * int size = get_word (ioreq + 0x12);
+ */
+ /* Check unit number */
+ if (unit >= 0) {
+ struct hardfiledata *hfd = get_hardfile_data (unit);
+ if (hfd && (hfd->handle_valid || hfd->drive_empty) && start_thread (context, unit)) {
+ put_word (hfpd->base + 32, get_word (hfpd->base + 32) + 1);
+ put_long (ioreq + 24, unit); /* io_Unit */
+ put_byte (ioreq + 31, 0); /* io_Error */
+ put_byte (ioreq + 8, 7); /* ln_type = NT_REPLYMSG */
+ hf_log (_T("hardfile_open, unit %d (%d), OK\n"), unit, m68k_dreg (regs, 0));
+ return 0;
}
- if (unit < 1000 || is_hardfile (unit) == FILESYS_VIRTUAL || is_hardfile (unit) == FILESYS_CD)
- err = 50; /* HFERR_NoBoard */
- } else {
- err = IOERR_BADLENGTH;
}
+ if (unit < 1000 || is_hardfile (unit) == FILESYS_VIRTUAL || is_hardfile (unit) == FILESYS_CD)
+ err = 50; /* HFERR_NoBoard */
hf_log (_T("hardfile_open, unit %d (%d), ERR=%d\n"), unit, m68k_dreg (regs, 0), err);
put_long (ioreq + 20, (uae_u32)err);
put_byte (ioreq + 31, (uae_u8)err);
#define FC_INST (regs.s ? 6 : 2)
extern uaecptr REGPARAM3 mmu_translate(uaecptr addr, bool super, bool data, bool write) REGPARAM;
+extern void mmu_bus_error(uaecptr addr, int fc, bool write, int size, bool rmw, uae_u32 status);
extern uae_u32 REGPARAM3 sfc_get_long(uaecptr addr) REGPARAM;
extern uae_u16 REGPARAM3 sfc_get_word(uaecptr addr) REGPARAM;
STATIC_INLINE void get_move16_mmu (uaecptr addr, uae_u32 *v)
{
- return uae_mmu_get_move16 (addr, v);
+ uae_mmu_get_move16 (addr, v);
}
STATIC_INLINE void put_move16_mmu (uaecptr addr, uae_u32 *v)
{
- return uae_mmu_put_move16 (addr, v);
+ uae_mmu_put_move16 (addr, v);
}
// locked rmw 060
extern struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS];
uae_u32 REGPARAM3 get_disp_ea_020_mmu030 (uae_u32 base, int idx) REGPARAM;
+void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc);
void mmu_op30_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra);
void mmu_op30_ptest (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra);
{
uae_u32 fc = regs.dfc;
#if MMUDEBUG > 2
- write_log(_T("dfc030_put_long: FC = %i\n"),fc);
+ write_log(_T("dfc030_put_long: %08X = %08X FC = %i\n"), addr, val, fc);
#endif
if (unlikely(is_unaligned(addr, 4)))
mmu030_put_long_unaligned(addr, val, fc, 0);
{
uae_u32 fc = regs.dfc;
#if MMUDEBUG > 2
- write_log(_T("dfc030_put_word: FC = %i\n"),fc);
+ write_log(_T("dfc030_put_word: %08X = %04X FC = %i\n"), addr, val, fc);
#endif
if (unlikely(is_unaligned(addr, 2)))
mmu030_put_word_unaligned(addr, val, fc, 0);
{
uae_u32 fc = regs.dfc;
#if MMUDEBUG > 2
- write_log(_T("dfc030_put_byte: FC = %i\n"),fc);
+ write_log(_T("dfc030_put_byte: %08X = %02X FC = %i\n"), addr, val, fc);
#endif
mmu030_put_byte(addr, val, fc);
}
// take care of 2 kinds of alignement, bus size and page
#if 1
-static inline bool is_unaligned(uaecptr addr, int size)
+static ALWAYS_INLINE bool is_unaligned(uaecptr addr, int size)
{
return unlikely((addr & (size - 1)) && (addr ^ (addr + size - 1)) & regs.mmu_page_size);
}
#else
-static inline bool is_unaligned(uaecptr addr, int size)
+static ALWAYS_INLINE bool is_unaligned(uaecptr addr, int size)
{
return (addr & (size - 1));
}
regs.instruction_pc = regs.pc = newpc;
}
+extern void m68k_setpc_normal (uaecptr newpc);
+
STATIC_INLINE uaecptr m68k_getpc (void)
{
return (uaecptr)(regs.pc + ((uae_u8*)regs.pc_p - (uae_u8*)regs.pc_oldp));
extern void sm68k_disasm (TCHAR*, TCHAR*, uaecptr addr, uaecptr *nextpc);
extern int get_cpu_model (void);
+extern void set_cpu_caches (bool flush);
extern void REGPARAM3 MakeSR (void) REGPARAM;
extern void REGPARAM3 MakeFromSR (void) REGPARAM;
extern void REGPARAM3 Exception (int) REGPARAM;
-extern void REGPARAM3 Exception (int, uaecptr) REGPARAM;
+extern void REGPARAM3 ExceptionL (int, uaecptr) REGPARAM;
extern void NMI (void);
extern void NMI_delayed (void);
extern void prepare_interrupt (uae_u32);
extern void exception3 (uae_u32 opcode, uaecptr addr);
extern void exception3i (uae_u32 opcode, uaecptr addr);
-extern void exception3 (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc);
-extern void exception2 (uaecptr addr);
+extern void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc);
+extern void exception2 (uaecptr addr, bool read, int size, uae_u32 fc);
+extern void exception2_fake (uaecptr addr);
extern void cpureset (void);
extern void cpu_halt (int id);
uae_u32 romextfile2addr;
TCHAR romextfile2[MAX_DPATH];
TCHAR romextident[256];
+ TCHAR a2091romfile[MAX_DPATH];
+ TCHAR a2091romident[256];
+ TCHAR a4091romfile[MAX_DPATH];
+ TCHAR a4091romident[256];
TCHAR flashfile[MAX_DPATH];
TCHAR rtcfile[MAX_DPATH];
TCHAR cartfile[MAX_DPATH];
+#ifndef READCPU_H
+#define READCPU_H
+
ENUMDECL {
Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r,
absw, absl, PC16, PC8r, imm, imm0, imm1, imm2, immi, am_unknown, am_illg
i_CINVL, i_CINVP, i_CINVA, i_CPUSHL, i_CPUSHP, i_CPUSHA, i_MOVE16,
i_MMUOP030, i_PFLUSHN, i_PFLUSH, i_PFLUSHAN, i_PFLUSHA,
i_PLPAR, i_PLPAW, i_PTESTR, i_PTESTW,
- i_LPSTOP
+ i_LPSTOP,
+ MAX_OPCODE_FAMILY
} ENUMNAME (instrmnem);
struct mnemolookup {
extern int get_no_mismatches (void);
extern int nr_cpuop_funcs;
+#endif /* READCPU_H */
\ No newline at end of file
#endif
#ifdef A2091
a2091_free ();
+ a3000scsi_free ();
#endif
#ifdef NCR
ncr_free ();
#endif
}
+static bool singlebit (uae_u32 v)
+{
+ while (v && !(v & 1))
+ v >>= 1;
+ return (v & ~1) == 0;
+}
+
static void allocate_memory (void)
{
bogomem_aliasing = false;
mapped_free (custmem1_bank.baseaddr);
custmem1_bank.baseaddr = NULL;
custmem1_bank.allocated = currprefs.custom_memory_sizes[0];
- custmem1_bank.mask = -1;
+ // custmem1 and 2 can have non-power of 2 size so only set correct mask if size is power of 2.
+ custmem1_bank.mask = singlebit (custmem1_bank.allocated) ? custmem1_bank.allocated - 1 : -1;
custmem1_bank.start = currprefs.custom_memory_addrs[0];
if (custmem1_bank.allocated) {
custmem1_bank.baseaddr = mapped_malloc (custmem1_bank.allocated, _T("custmem1"));
mapped_free (custmem2_bank.baseaddr);
custmem2_bank.baseaddr = NULL;
custmem2_bank.allocated = currprefs.custom_memory_sizes[1];
- custmem2_bank.mask = -1;
+ custmem2_bank.mask = singlebit (custmem2_bank.allocated) ? custmem2_bank.allocated - 1 : -1;
custmem2_bank.start = currprefs.custom_memory_addrs[1];
if (custmem2_bank.allocated) {
custmem2_bank.baseaddr = mapped_malloc (custmem2_bank.allocated, _T("custmem2"));
}
fill_ce_banks ();
if (!isrestore () && valid_address (regs.pc, 4))
- m68k_setpc (m68k_getpc ());
+ m68k_setpc_normal (m68k_getpc ());
}
uae_s32 getz2size (struct uae_prefs *p)
#include "scsi.h"
#include "filesys.h"
#include "zfile.h"
+#include "blkdev.h"
#include "qemuvga\qemuuaeglue.h"
#include "qemuvga\queue.h"
#include "qemuvga\scsi\scsi.h"
static int configured;
static uae_u8 acmemory[100];
-struct ncrscsi {
- TCHAR *name;
- int be, le;
-};
-
static DeviceState devobject;
static SCSIDevice *scsid[8];
+static SCSIBus scsibus;
void pci_set_irq(PCIDevice *pci_dev, int level)
{
if (!level)
return;
INTREQ (0x8000 | 0x0008);
- write_log (_T("NCR IRQ\n"));
}
void scsi_req_continue(SCSIRequest *req)
{
+ struct scsi_data *sd = (struct scsi_data*)req->dev->handle;
+ if (sd->data_len) {
+ lsi_transfer_data (req, sd->data_len);
+ } else {
+ if (sd->direction > 0)
+ scsi_emulate_cmd(sd);
+ lsi_command_complete (req, sd->status, 0);
+ }
}
SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, uint8_t *buf, int len, void *hba_private)
{
SCSIRequest *req = xcalloc(SCSIRequest, 1);
- req->dev = d;
struct scsi_data *sd = (struct scsi_data*)d->handle;
+
+ req->dev = d;
+ req->hba_private = hba_private;
+ req->bus = &scsibus;
+ req->bus->qbus.parent = &devobject;
memcpy (sd->cmd, buf, len);
sd->cmd_len = len;
int32_t scsi_req_enqueue(SCSIRequest *req)
{
struct scsi_data *sd = (struct scsi_data*)req->dev->handle;
+
+ sd->data_len = 0;
scsi_start_transfer (sd);
scsi_emulate_analyze (sd);
- scsi_emulate_cmd(sd);
+ //write_log (_T("%02x.%02x.%02x.%02x.%02x.%02x\n"), sd->cmd[0], sd->cmd[1], sd->cmd[2], sd->cmd[3], sd->cmd[4], sd->cmd[5]);
+
+ if (sd->direction < 0)
+ scsi_emulate_cmd(sd);
+ if (sd->direction == 0)
+ return 1;
return -sd->direction;
}
void scsi_req_unref(SCSIRequest *req)
{
+ xfree (req);
}
uint8_t *scsi_req_get_buf(SCSIRequest *req)
{
- return NULL;
+ struct scsi_data *sd = (struct scsi_data*)req->dev->handle;
+ sd->data_len = 0;
+ return sd->buffer;
}
SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun)
{
- if (lun != 0)
+ if (lun != 0 || target < 0 || target >= 8)
return NULL;
return scsid[target];
}
void scsi_req_cancel(SCSIRequest *req)
{
+ write_log (_T("scsi_req_cancel\n"));
}
}
}
-void ncr_free (void)
-{
-}
-
-void ncr_reset (void)
-{
- configured = 0;
- board_mask = 0xffff;
- if (currprefs.cs_mbdmac == 2) {
- configured = -1;
- }
- if (devobject.lsistate)
- lsi_scsi_reset (&devobject);
-}
-
void ncr_init (void)
{
lsi_scsi_init (&devobject);
void ncr_autoconfig_init (void)
{
- struct zfile *z;
int roms[3];
- struct romlist *rl;
int i;
configured = 0;
roms[1] = 57;
roms[2] = -1;
- rl = getromlistbyids(roms);
- if (rl) {
- struct romdata *rd = rl->rd;
- z = read_rom (&rd);
- if (z) {
- write_log (_T("A4091 BOOT ROM %d.%d\n"), rd->ver, rd->rev);
- rom = xmalloc (uae_u8, ROM_SIZE * 4);
- for (i = 0; i < ROM_SIZE; i++) {
- uae_u8 b;
- zfile_fread (&b, 1, 1, z);
- rom[i * 4 + 0] = b;
- rom[i * 4 + 2] = b << 4;
- }
- zfile_fclose(z);
+ struct zfile *z = read_rom_name (currprefs.a4091romfile);
+ if (!z) {
+ struct romlist *rl = getromlistbyids(roms);
+ if (rl) {
+ struct romdata *rd = rl->rd;
+ z = read_rom (&rd);
+ }
+ }
+ if (z) {
+ write_log (_T("A4091 BOOT ROM '%s'\n"), zfile_getname (z));
+ rom = xmalloc (uae_u8, ROM_SIZE * 4);
+ for (i = 0; i < ROM_SIZE; i++) {
+ uae_u8 b;
+ zfile_fread (&b, 1, 1, z);
+ rom[i * 4 + 0] = b;
+ rom[i * 4 + 2] = b << 4;
}
+ zfile_fclose(z);
} else {
romwarning (roms);
}
map_banks (&ncr_bank, 0xe80000 >> 16, 65536 >> 16, 0);
}
+static void freescsi (struct scsi_data *sd)
+{
+ if (!sd)
+ return;
+ hdf_hd_close (sd->hfd);
+ scsi_free (sd);
+}
+
static void freescsi (SCSIDevice *scsi)
{
- xfree (scsi);
+ if (scsi) {
+ freescsi ((struct scsi_data*)scsi->handle);
+ xfree (scsi);
+ }
+}
+
+void ncr_free (void)
+{
+ for (int ch = 0; ch < 8; ch++) {
+ freescsi (scsid[ch]);
+ scsid[ch] = NULL;
+ }
+}
+
+void ncr_reset (void)
+{
+ configured = 0;
+ board_mask = 0xffff;
+ if (currprefs.cs_mbdmac == 2) {
+ configured = -1;
+ }
+ if (devobject.lsistate)
+ lsi_scsi_reset (&devobject);
}
static int add_scsi_hd (int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
}
+static int add_scsi_cd (int ch, int unitnum)
+{
+ void *handle;
+ device_func_init (0);
+ freescsi (scsid[ch]);
+ scsid[ch] = NULL;
+ handle = scsi_alloc_cd (ch, unitnum, false);
+ if (!handle)
+ return 0;
+ scsid[ch] = xcalloc (SCSIDevice, 1);
+ scsid[ch]->handle = handle;
+ return scsid[ch] ? 1 : 0;
+}
+
+static int add_scsi_tape (int ch, const TCHAR *tape_directory, bool readonly)
+{
+ void *handle;
+ freescsi (scsid[ch]);
+ scsid[ch] = NULL;
+ handle = scsi_alloc_tape (ch, tape_directory, readonly);
+ if (!handle)
+ return 0;
+ scsid[ch] = xcalloc (SCSIDevice, 1);
+ scsid[ch]->handle = handle;
+ return scsid[ch] ? 1 : 0;
+}
+
int a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci)
{
-// if (ci->type == UAEDEV_CD)
-// return add_scsi_cd (ch, ci->device_emu_unit);
-// else if (ci->type == UAEDEV_TAPE)
-// return add_scsi_tape (ch, ci->rootdir, ci->readonly);
-// else
+ if (ci->type == UAEDEV_CD)
+ return add_scsi_cd (ch, ci->device_emu_unit);
+ else if (ci->type == UAEDEV_TAPE)
+ return add_scsi_tape (ch, ci->rootdir, ci->readonly);
+ else
return add_scsi_hd (ch, NULL, ci, 1);
}
int a4091_add_scsi_unit (int ch, struct uaedev_config_info *ci)
{
-// if (ci->type == UAEDEV_CD)
-// return add_scsi_cd (ch, ci->device_emu_unit);
-// else if (ci->type == UAEDEV_TAPE)
-// return add_scsi_tape (ch, ci->rootdir, ci->readonly);
-// else
+ if (ci->type == UAEDEV_CD)
+ return add_scsi_cd (ch, ci->device_emu_unit);
+ else if (ci->type == UAEDEV_TAPE)
+ return add_scsi_tape (ch, ci->rootdir, ci->readonly);
+ else
return add_scsi_hd (ch, NULL, ci, 1);
}
* (c) 1995 Bernd Schmidt
*/
-#define MOVEC_DEBUG 0
#define MMUOP_DEBUG 2
#define DEBUG_CD32CDTVIO 0
#define EXCEPTION3_DEBUGGER 0
}
+void m68k_setpc_normal (uaecptr pc)
+{
+ if (currprefs.mmu_model)
+ m68k_setpc_mmu (pc);
+ else
+ m68k_setpc (pc);
+}
+
bool can_cpu_tracer (void)
{
return (currprefs.cpu_model == 68000 || currprefs.cpu_model == 68020) && currprefs.cpu_cycle_exact;
return is_cpu_tracer ();
}
-static void set_cpu_caches (bool flush)
+void set_cpu_caches (bool flush)
{
int i;
return currprefs.cpu_model;
}
-/*
-* extract bitfield data from memory and return it in the MSBs
-* bdata caches the unmodified data for put_bitfield()
-*/
-uae_u32 REGPARAM2 get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width)
-{
- uae_u32 tmp, res, mask;
-
- offset &= 7;
- mask = 0xffffffffu << (32 - width);
- switch ((offset + width + 7) >> 3) {
- case 1:
- tmp = get_byte (src);
- res = tmp << (24 + offset);
- bdata[0] = tmp & ~(mask >> (24 + offset));
- break;
- case 2:
- tmp = get_word (src);
- res = tmp << (16 + offset);
- bdata[0] = tmp & ~(mask >> (16 + offset));
- break;
- case 3:
- tmp = get_word (src);
- res = tmp << (16 + offset);
- bdata[0] = tmp & ~(mask >> (16 + offset));
- tmp = get_byte (src + 2);
- res |= tmp << (8 + offset);
- bdata[1] = tmp & ~(mask >> (8 + offset));
- break;
- case 4:
- tmp = get_long (src);
- res = tmp << offset;
- bdata[0] = tmp & ~(mask >> offset);
- break;
- case 5:
- tmp = get_long (src);
- res = tmp << offset;
- bdata[0] = tmp & ~(mask >> offset);
- tmp = get_byte (src + 4);
- res |= tmp >> (8 - offset);
- bdata[1] = tmp & ~(mask << (8 - offset));
- break;
- default:
- /* Panic? */
- write_log (_T("get_bitfield() can't happen %d\n"), (offset + width + 7) >> 3);
- res = 0;
- break;
- }
- return res;
-}
-/*
-* write bitfield data (in the LSBs) back to memory, upper bits
-* must be cleared already.
-*/
-void REGPARAM2 put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width)
-{
- offset = (offset & 7) + width;
- switch ((offset + 7) >> 3) {
- case 1:
- put_byte (dst, bdata[0] | (val << (8 - offset)));
- break;
- case 2:
- put_word (dst, bdata[0] | (val << (16 - offset)));
- break;
- case 3:
- put_word (dst, bdata[0] | (val >> (offset - 16)));
- put_byte (dst + 2, bdata[1] | (val << (24 - offset)));
- break;
- case 4:
- put_long (dst, bdata[0] | (val << (32 - offset)));
- break;
- case 5:
- put_long (dst, bdata[0] | (val >> (offset - 32)));
- put_byte (dst + 4, bdata[1] | (val << (40 - offset)));
- break;
- default:
- write_log (_T("put_bitfield() can't happen %d\n"), (offset + 7) >> 3);
- break;
- }
-}
-
-uae_u32 REGPARAM2 x_get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width)
-{
- uae_u32 tmp1, tmp2, res, mask;
-
- offset &= 7;
- mask = 0xffffffffu << (32 - width);
- switch ((offset + width + 7) >> 3) {
- case 1:
- tmp1 = x_cp_get_byte (src);
- res = tmp1 << (24 + offset);
- bdata[0] = tmp1 & ~(mask >> (24 + offset));
- break;
- case 2:
- tmp1 = x_cp_get_word (src);
- res = tmp1 << (16 + offset);
- bdata[0] = tmp1 & ~(mask >> (16 + offset));
- break;
- case 3:
- tmp1 = x_cp_get_word (src);
- tmp2 = x_cp_get_byte (src + 2);
- res = tmp1 << (16 + offset);
- bdata[0] = tmp1 & ~(mask >> (16 + offset));
- res |= tmp2 << (8 + offset);
- bdata[1] = tmp2 & ~(mask >> (8 + offset));
- break;
- case 4:
- tmp1 = x_cp_get_long (src);
- res = tmp1 << offset;
- bdata[0] = tmp1 & ~(mask >> offset);
- break;
- case 5:
- tmp1 = x_cp_get_long (src);
- tmp2 = x_cp_get_byte (src + 4);
- res = tmp1 << offset;
- bdata[0] = tmp1 & ~(mask >> offset);
- res |= tmp2 >> (8 - offset);
- bdata[1] = tmp2 & ~(mask << (8 - offset));
- break;
- default:
- /* Panic? */
- write_log (_T("x_get_bitfield() can't happen %d\n"), (offset + width + 7) >> 3);
- res = 0;
- break;
- }
- return res;
-}
-
-void REGPARAM2 x_put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width)
-{
- offset = (offset & 7) + width;
- switch ((offset + 7) >> 3) {
- case 1:
- x_cp_put_byte (dst, bdata[0] | (val << (8 - offset)));
- break;
- case 2:
- x_cp_put_word (dst, bdata[0] | (val << (16 - offset)));
- break;
- case 3:
- x_cp_put_word (dst, bdata[0] | (val >> (offset - 16)));
- x_cp_put_byte (dst + 2, bdata[1] | (val << (24 - offset)));
- break;
- case 4:
- x_cp_put_long (dst, bdata[0] | (val << (32 - offset)));
- break;
- case 5:
- x_cp_put_long (dst, bdata[0] | (val >> (offset - 32)));
- x_cp_put_byte (dst + 4, bdata[1] | (val << (40 - offset)));
- break;
- default:
- write_log (_T("x_put_bitfield() can't happen %d\n"), (offset + 7) >> 3);
- break;
- }
-}
-
-uae_u32 REGPARAM2 get_disp_ea_020 (uae_u32 base, int idx)
-{
- uae_u16 dp = next_iword ();
- int reg = (dp >> 12) & 15;
- uae_s32 regd = regs.regs[reg];
- if ((dp & 0x800) == 0)
- regd = (uae_s32)(uae_s16)regd;
- regd <<= (dp >> 9) & 3;
- if (dp & 0x100) {
- uae_s32 outer = 0;
- if (dp & 0x80) base = 0;
- if (dp & 0x40) regd = 0;
-
- if ((dp & 0x30) == 0x20)
- base += (uae_s32)(uae_s16) next_iword ();
- if ((dp & 0x30) == 0x30)
- base += next_ilong ();
-
- if ((dp & 0x3) == 0x2)
- outer = (uae_s32)(uae_s16) next_iword ();
- if ((dp & 0x3) == 0x3)
- outer = next_ilong ();
-
- if ((dp & 0x4) == 0)
- base += regd;
- if (dp & 0x3)
- base = get_long (base);
- if (dp & 0x4)
- base += regd;
-
- return base + outer;
- } else {
- return base + (uae_s32)((uae_s8)dp) + regd;
- }
-}
-
-uae_u32 REGPARAM2 x_get_disp_ea_020 (uae_u32 base, int idx)
-{
- uae_u16 dp = x_next_iword ();
- int reg = (dp >> 12) & 15;
- int cycles = 0;
- uae_u32 v;
-
- uae_s32 regd = regs.regs[reg];
- if ((dp & 0x800) == 0)
- regd = (uae_s32)(uae_s16)regd;
- regd <<= (dp >> 9) & 3;
- if (dp & 0x100) {
- uae_s32 outer = 0;
- if (dp & 0x80)
- base = 0;
- if (dp & 0x40)
- regd = 0;
-
- if ((dp & 0x30) == 0x20) {
- base += (uae_s32)(uae_s16) x_next_iword ();
- cycles++;
- }
- if ((dp & 0x30) == 0x30) {
- base += x_next_ilong ();
- cycles++;
- }
-
- if ((dp & 0x3) == 0x2) {
- outer = (uae_s32)(uae_s16) x_next_iword ();
- cycles++;
- }
- if ((dp & 0x3) == 0x3) {
- outer = x_next_ilong ();
- cycles++;
- }
-
- if ((dp & 0x4) == 0) {
- base += regd;
- cycles++;
- }
- if (dp & 0x3) {
- base = x_get_long (base);
- cycles++;
- }
- if (dp & 0x4) {
- base += regd;
- cycles++;
- }
- v = base + outer;
- } else {
- v = base + (uae_s32)((uae_s8)dp) + regd;
- }
- if (cycles && currprefs.cpu_cycle_exact)
- x_do_cycles (cycles * cpucycleunit);
- return v;
-}
-
-uae_u32 REGPARAM2 x_get_disp_ea_ce030 (uae_u32 base, int idx)
-{
- uae_u16 dp = next_iword_030ce ();
- int reg = (dp >> 12) & 15;
- uae_u32 v;
-
- uae_s32 regd = regs.regs[reg];
- if ((dp & 0x800) == 0)
- regd = (uae_s32)(uae_s16)regd;
- regd <<= (dp >> 9) & 3;
- if (dp & 0x100) {
- uae_s32 outer = 0;
- if (dp & 0x80)
- base = 0;
- if (dp & 0x40)
- regd = 0;
-
- if ((dp & 0x30) == 0x20) {
- base += (uae_s32)(uae_s16) next_iword_030ce ();
- }
- if ((dp & 0x30) == 0x30) {
- base += next_ilong_030ce ();
- }
-
- if ((dp & 0x3) == 0x2) {
- outer = (uae_s32)(uae_s16) next_iword_030ce ();
- }
- if ((dp & 0x3) == 0x3) {
- outer = next_ilong_030ce ();
- }
-
- if ((dp & 0x4) == 0) {
- base += regd;
- }
- if (dp & 0x3) {
- base = x_get_long (base);
- }
- if (dp & 0x4) {
- base += regd;
- }
- v = base + outer;
- } else {
- v = base + (uae_s32)((uae_s8)dp) + regd;
- }
- return v;
-}
-
-uae_u32 REGPARAM2 x_get_disp_ea_ce020 (uae_u32 base, int idx)
-{
- uae_u16 dp = next_iword_020ce ();
- int reg = (dp >> 12) & 15;
- uae_u32 v;
-
- uae_s32 regd = regs.regs[reg];
- if ((dp & 0x800) == 0)
- regd = (uae_s32)(uae_s16)regd;
- regd <<= (dp >> 9) & 3;
- if (dp & 0x100) {
- uae_s32 outer = 0;
- if (dp & 0x80)
- base = 0;
- if (dp & 0x40)
- regd = 0;
-
- if ((dp & 0x30) == 0x20) {
- base += (uae_s32)(uae_s16) next_iword_020ce ();
- }
- if ((dp & 0x30) == 0x30) {
- base += next_ilong_020ce ();
- }
-
- if ((dp & 0x3) == 0x2) {
- outer = (uae_s32)(uae_s16) next_iword_020ce ();
- }
- if ((dp & 0x3) == 0x3) {
- outer = next_ilong_020ce ();
- }
-
- if ((dp & 0x4) == 0) {
- base += regd;
- }
- if (dp & 0x3) {
- base = x_get_long (base);
- }
- if (dp & 0x4) {
- base += regd;
- }
- v = base + outer;
- } else {
- v = base + (uae_s32)((uae_s8)dp) + regd;
- }
- return v;
-}
STATIC_INLINE int in_rom (uaecptr pc)
{
exception3 (regs.ir, newpc);
return;
}
- m68k_setpc (newpc);
-#ifdef JIT
- set_special (SPCFLAG_END_COMPILE);
-#endif
+ m68k_setpc_mmu (newpc);
fill_prefetch ();
exception_trace (nr);
}
exception3 (regs.ir, newpc);
return;
}
- m68k_setpc (newpc);
-#ifdef JIT
- set_special (SPCFLAG_END_COMPILE);
-#endif
+ m68k_setpc_mmu (newpc);
fill_prefetch ();
exception_trace (nr);
}
{
ExceptionX (nr, -1);
}
-void REGPARAM2 Exception (int nr, uaecptr address)
+void REGPARAM2 ExceptionL (int nr, uaecptr address)
{
ExceptionX (nr, address);
}
do_interrupt (7);
}
-#ifndef CPUEMU_68000_ONLY
-
-int movec_illg (int regno)
-{
- int regno2 = regno & 0x7ff;
-
- if (currprefs.cpu_model == 68060) {
- if (regno <= 8)
- return 0;
- if (regno == 0x800 || regno == 0x801 ||
- regno == 0x806 || regno == 0x807 || regno == 0x808)
- return 0;
- return 1;
- } else if (currprefs.cpu_model == 68010) {
- if (regno2 < 2)
- return 0;
- return 1;
- } else if (currprefs.cpu_model == 68020) {
- if (regno == 3)
- return 1; /* 68040/060 only */
- /* 4 is >=68040, but 0x804 is in 68020 */
- if (regno2 < 4 || regno == 0x804)
- return 0;
- return 1;
- } else if (currprefs.cpu_model == 68030) {
- if (regno2 <= 2)
- return 0;
- if (regno == 0x803 || regno == 0x804)
- return 0;
- return 1;
- } else if (currprefs.cpu_model == 68040) {
- if (regno == 0x802)
- return 1; /* 68020/030 only */
- if (regno2 < 8) return 0;
- return 1;
- }
- return 1;
-}
-
-int m68k_move2c (int regno, uae_u32 *regp)
-{
-#if MOVEC_DEBUG > 0
- write_log (_T("move2c %04X <- %08X PC=%x\n"), regno, *regp, M68K_GETPC);
-#endif
- if (movec_illg (regno)) {
- op_illg (0x4E7B);
- return 0;
- } else {
- switch (regno) {
- case 0: regs.sfc = *regp & 7; break;
- case 1: regs.dfc = *regp & 7; break;
- case 2:
- {
- uae_u32 cacr_mask = 0;
- if (currprefs.cpu_model == 68020)
- cacr_mask = 0x0000000f;
- else if (currprefs.cpu_model == 68030)
- cacr_mask = 0x00003f1f;
- else if (currprefs.cpu_model == 68040)
- cacr_mask = 0x80008000;
- else if (currprefs.cpu_model == 68060)
- cacr_mask = 0xf8e0e000;
- regs.cacr = *regp & cacr_mask;
- set_cpu_caches (false);
- }
- break;
- /* 68040/060 only */
- case 3:
- regs.tcr = *regp & (currprefs.cpu_model == 68060 ? 0xfffe : 0xc000);
- if (currprefs.mmu_model)
- mmu_set_tc (regs.tcr);
- break;
-
- /* no differences between 68040 and 68060 */
- case 4: regs.itt0 = *regp & 0xffffe364; mmu_tt_modified (); break;
- case 5: regs.itt1 = *regp & 0xffffe364; mmu_tt_modified (); break;
- case 6: regs.dtt0 = *regp & 0xffffe364; mmu_tt_modified (); break;
- case 7: regs.dtt1 = *regp & 0xffffe364; mmu_tt_modified (); break;
- /* 68060 only */
- case 8: regs.buscr = *regp & 0xf0000000; break;
-
- case 0x800: regs.usp = *regp; break;
- case 0x801: regs.vbr = *regp; break;
- case 0x802: regs.caar = *regp; break;
- case 0x803: regs.msp = *regp; if (regs.m == 1) m68k_areg (regs, 7) = regs.msp; break;
- case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg (regs, 7) = regs.isp; break;
- /* 68040 only */
- case 0x805: regs.mmusr = *regp; break;
- /* 68040/060 */
- case 0x806: regs.urp = *regp & 0xfffffe00; break;
- case 0x807: regs.srp = *regp & 0xfffffe00; break;
- /* 68060 only */
- case 0x808:
- {
- uae_u32 opcr = regs.pcr;
- regs.pcr &= ~(0x40 | 2 | 1);
- regs.pcr |= (*regp) & (0x40 | 2 | 1);
- if (currprefs.fpu_model <= 0)
- regs.pcr |= 2;
- if (((opcr ^ regs.pcr) & 2) == 2) {
- write_log (_T("68060 FPU state: %s\n"), regs.pcr & 2 ? _T("disabled") : _T("enabled"));
- /* flush possible already translated FPU instructions */
- flush_icache (0, 3);
- }
- }
- break;
- default:
- op_illg (0x4E7B);
- return 0;
- }
- }
- return 1;
-}
-
-int m68k_movec2 (int regno, uae_u32 *regp)
-{
-#if MOVEC_DEBUG > 0
- write_log (_T("movec2 %04X PC=%x\n"), regno, M68K_GETPC);
-#endif
- if (movec_illg (regno)) {
- op_illg (0x4E7A);
- return 0;
- } else {
- switch (regno) {
- case 0: *regp = regs.sfc; break;
- case 1: *regp = regs.dfc; break;
- case 2:
- {
- uae_u32 v = regs.cacr;
- uae_u32 cacr_mask = 0;
- if (currprefs.cpu_model == 68020)
- cacr_mask = 0x00000003;
- else if (currprefs.cpu_model == 68030)
- cacr_mask = 0x00003313;
- else if (currprefs.cpu_model == 68040)
- cacr_mask = 0x80008000;
- else if (currprefs.cpu_model == 68060)
- cacr_mask = 0xf880e000;
- *regp = v & cacr_mask;
- }
- break;
- case 3: *regp = regs.tcr; break;
- case 4: *regp = regs.itt0; break;
- case 5: *regp = regs.itt1; break;
- case 6: *regp = regs.dtt0; break;
- case 7: *regp = regs.dtt1; break;
- case 8: *regp = regs.buscr; break;
-
- case 0x800: *regp = regs.usp; break;
- case 0x801: *regp = regs.vbr; break;
- case 0x802: *regp = regs.caar; break;
- case 0x803: *regp = regs.m == 1 ? m68k_areg (regs, 7) : regs.msp; break;
- case 0x804: *regp = regs.m == 0 ? m68k_areg (regs, 7) : regs.isp; break;
- case 0x805: *regp = regs.mmusr; break;
- case 0x806: *regp = regs.urp; break;
- case 0x807: *regp = regs.srp; break;
- case 0x808: *regp = regs.pcr; break;
-
- default:
- op_illg (0x4E7A);
- return 0;
- }
- }
-#if MOVEC_DEBUG > 0
- write_log (_T("-> %08X\n"), *regp);
-#endif
- return 1;
-}
-
-STATIC_INLINE int div_unsigned (uae_u32 src_hi, uae_u32 src_lo, uae_u32 div, uae_u32 *quot, uae_u32 *rem)
-{
- uae_u32 q = 0, cbit = 0;
- int i;
-
- if (div <= src_hi) {
- return 1;
- }
- for (i = 0 ; i < 32 ; i++) {
- cbit = src_hi & 0x80000000ul;
- src_hi <<= 1;
- if (src_lo & 0x80000000ul) src_hi++;
- src_lo <<= 1;
- q = q << 1;
- if (cbit || div <= src_hi) {
- q |= 1;
- src_hi -= div;
- }
- }
- *quot = q;
- *rem = src_hi;
- return 0;
-}
-
-bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
-{
- if ((extra & 0x400) && currprefs.int_no_unimplemented && currprefs.cpu_model == 68060) {
- op_unimpl (opcode);
- return false;
- }
- if (src == 0) {
- Exception (5);
- return false;
- }
-#if defined (uae_s64)
- if (extra & 0x800) {
- /* signed variant */
- uae_s64 a = (uae_s64)(uae_s32)m68k_dreg (regs, (extra >> 12) & 7);
- uae_s64 quot, rem;
-
- if (extra & 0x400) {
- a &= 0xffffffffu;
- a |= (uae_s64)m68k_dreg (regs, extra & 7) << 32;
- }
-
- if (a == 0x8000000000000000 && src == -1) {
- SET_VFLG (1);
- SET_NFLG (1);
- SET_CFLG (0);
- } else {
- rem = a % (uae_s64)(uae_s32)src;
- quot = a / (uae_s64)(uae_s32)src;
- if ((quot & UVAL64 (0xffffffff80000000)) != 0
- && (quot & UVAL64 (0xffffffff80000000)) != UVAL64 (0xffffffff80000000))
- {
- SET_VFLG (1);
- SET_NFLG (1);
- SET_CFLG (0);
- } else {
- if (((uae_s32)rem < 0) != ((uae_s64)a < 0)) rem = -rem;
- SET_VFLG (0);
- SET_CFLG (0);
- SET_ZFLG (((uae_s32)quot) == 0);
- SET_NFLG (((uae_s32)quot) < 0);
- m68k_dreg (regs, extra & 7) = (uae_u32)rem;
- m68k_dreg (regs, (extra >> 12) & 7) = (uae_u32)quot;
- }
- }
- } else {
- /* unsigned */
- uae_u64 a = (uae_u64)(uae_u32)m68k_dreg (regs, (extra >> 12) & 7);
- uae_u64 quot, rem;
-
- if (extra & 0x400) {
- a &= 0xffffffffu;
- a |= (uae_u64)m68k_dreg (regs, extra & 7) << 32;
- }
- rem = a % (uae_u64)src;
- quot = a / (uae_u64)src;
- if (quot > 0xffffffffu) {
- SET_VFLG (1);
- SET_NFLG (1);
- SET_CFLG (0);
- } else {
- SET_VFLG (0);
- SET_CFLG (0);
- SET_ZFLG (((uae_s32)quot) == 0);
- SET_NFLG (((uae_s32)quot) < 0);
- m68k_dreg (regs, extra & 7) = (uae_u32)rem;
- m68k_dreg (regs, (extra >> 12) & 7) = (uae_u32)quot;
- }
- }
-#else
- if (extra & 0x800) {
- /* signed variant */
- uae_s32 lo = (uae_s32)m68k_dreg (regs, (extra >> 12) & 7);
- uae_s32 hi = lo < 0 ? -1 : 0;
- uae_s32 save_high;
- uae_u32 quot, rem;
- uae_u32 sign;
-
- if (extra & 0x400) {
- hi = (uae_s32)m68k_dreg (regs, extra & 7);
- }
- save_high = hi;
- sign = (hi ^ src);
- if (hi < 0) {
- hi = ~hi;
- lo = -lo;
- if (lo == 0) hi++;
- }
- if ((uae_s32)src < 0) src = -src;
- if (div_unsigned (hi, lo, src, ", &rem) ||
- (sign & 0x80000000) ? quot > 0x80000000 : quot > 0x7fffffff) {
- SET_VFLG (1);
- SET_NFLG (1);
- SET_CFLG (0);
- } else {
- if (sign & 0x80000000) quot = -quot;
- if (((uae_s32)rem < 0) != (save_high < 0)) rem = -rem;
- SET_VFLG (0);
- SET_CFLG (0);
- SET_ZFLG (((uae_s32)quot) == 0);
- SET_NFLG (((uae_s32)quot) < 0);
- m68k_dreg (regs, extra & 7) = rem;
- m68k_dreg (regs, (extra >> 12) & 7) = quot;
- }
- } else {
- /* unsigned */
- uae_u32 lo = (uae_u32)m68k_dreg (regs, (extra >> 12) & 7);
- uae_u32 hi = 0;
- uae_u32 quot, rem;
-
- if (extra & 0x400) {
- hi = (uae_u32)m68k_dreg (regs, extra & 7);
- }
- if (div_unsigned (hi, lo, src, ", &rem)) {
- SET_VFLG (1);
- SET_NFLG (1);
- SET_CFLG (0);
- } else {
- SET_VFLG (0);
- SET_CFLG (0);
- SET_ZFLG (((uae_s32)quot) == 0);
- SET_NFLG (((uae_s32)quot) < 0);
- m68k_dreg (regs, extra & 7) = rem;
- m68k_dreg (regs, (extra >> 12) & 7) = quot;
- }
- }
-#endif
- return true;
-}
-
-STATIC_INLINE void mul_unsigned (uae_u32 src1, uae_u32 src2, uae_u32 *dst_hi, uae_u32 *dst_lo)
-{
- uae_u32 r0 = (src1 & 0xffff) * (src2 & 0xffff);
- uae_u32 r1 = ((src1 >> 16) & 0xffff) * (src2 & 0xffff);
- uae_u32 r2 = (src1 & 0xffff) * ((src2 >> 16) & 0xffff);
- uae_u32 r3 = ((src1 >> 16) & 0xffff) * ((src2 >> 16) & 0xffff);
- uae_u32 lo;
-
- lo = r0 + ((r1 << 16) & 0xffff0000ul);
- if (lo < r0) r3++;
- r0 = lo;
- lo = r0 + ((r2 << 16) & 0xffff0000ul);
- if (lo < r0) r3++;
- r3 += ((r1 >> 16) & 0xffff) + ((r2 >> 16) & 0xffff);
- *dst_lo = lo;
- *dst_hi = r3;
-}
-
-bool m68k_mull (uae_u32 opcode, uae_u32 src, uae_u16 extra)
-{
- if ((extra & 0x400) && currprefs.int_no_unimplemented && currprefs.cpu_model == 68060) {
- op_unimpl (opcode);
- return false;
- }
-#if defined (uae_s64)
- if (extra & 0x800) {
- /* signed variant */
- uae_s64 a = (uae_s64)(uae_s32)m68k_dreg (regs, (extra >> 12) & 7);
-
- a *= (uae_s64)(uae_s32)src;
- SET_VFLG (0);
- SET_CFLG (0);
- SET_ZFLG (a == 0);
- SET_NFLG (a < 0);
- if (extra & 0x400)
- m68k_dreg (regs, extra & 7) = (uae_u32)(a >> 32);
- else if ((a & UVAL64 (0xffffffff80000000)) != 0
- && (a & UVAL64 (0xffffffff80000000)) != UVAL64 (0xffffffff80000000))
- {
- SET_VFLG (1);
- }
- m68k_dreg (regs, (extra >> 12) & 7) = (uae_u32)a;
- } else {
- /* unsigned */
- uae_u64 a = (uae_u64)(uae_u32)m68k_dreg (regs, (extra >> 12) & 7);
-
- a *= (uae_u64)src;
- SET_VFLG (0);
- SET_CFLG (0);
- SET_ZFLG (a == 0);
- SET_NFLG (((uae_s64)a) < 0);
- if (extra & 0x400)
- m68k_dreg (regs, extra & 7) = (uae_u32)(a >> 32);
- else if ((a & UVAL64 (0xffffffff00000000)) != 0) {
- SET_VFLG (1);
- }
- m68k_dreg (regs, (extra >> 12) & 7) = (uae_u32)a;
- }
-#else
- if (extra & 0x800) {
- /* signed variant */
- uae_s32 src1, src2;
- uae_u32 dst_lo, dst_hi;
- uae_u32 sign;
-
- src1 = (uae_s32)src;
- src2 = (uae_s32)m68k_dreg (regs, (extra >> 12) & 7);
- sign = (src1 ^ src2);
- if (src1 < 0) src1 = -src1;
- if (src2 < 0) src2 = -src2;
- mul_unsigned ((uae_u32)src1, (uae_u32)src2, &dst_hi, &dst_lo);
- if (sign & 0x80000000) {
- dst_hi = ~dst_hi;
- dst_lo = -dst_lo;
- if (dst_lo == 0) dst_hi++;
- }
- SET_VFLG (0);
- SET_CFLG (0);
- SET_ZFLG (dst_hi == 0 && dst_lo == 0);
- SET_NFLG (((uae_s32)dst_hi) < 0);
- if (extra & 0x400)
- m68k_dreg (regs, extra & 7) = dst_hi;
- else if ((dst_hi != 0 || (dst_lo & 0x80000000) != 0)
- && ((dst_hi & 0xffffffff) != 0xffffffff
- || (dst_lo & 0x80000000) != 0x80000000))
- {
- SET_VFLG (1);
- }
- m68k_dreg (regs, (extra >> 12) & 7) = dst_lo;
- } else {
- /* unsigned */
- uae_u32 dst_lo, dst_hi;
-
- mul_unsigned (src, (uae_u32)m68k_dreg (regs, (extra >> 12) & 7), &dst_hi, &dst_lo);
-
- SET_VFLG (0);
- SET_CFLG (0);
- SET_ZFLG (dst_hi == 0 && dst_lo == 0);
- SET_NFLG (((uae_s32)dst_hi) < 0);
- if (extra & 0x400)
- m68k_dreg (regs, extra & 7) = dst_hi;
- else if (dst_hi != 0) {
- SET_VFLG (1);
- }
- m68k_dreg (regs, (extra >> 12) & 7) = dst_lo;
- }
-#endif
- return true;
-}
-
-#endif
static void m68k_reset (bool hardreset)
{
regs.ipl = regs.ipl_pin = 0;
#ifdef SAVESTATE
if (isrestore ()) {
- m68k_setpc (regs.pc);
+ m68k_setpc_normal (regs.pc);
SET_XFLG ((regs.sr >> 4) & 1);
SET_NFLG ((regs.sr >> 3) & 1);
SET_ZFLG ((regs.sr >> 2) & 1);
}
#endif
m68k_areg (regs, 7) = get_long (0);
- m68k_setpc (get_long (4));
+ m68k_setpc_normal (get_long (4));
regs.s = 1;
regs.m = 0;
regs.stopped = 0;
write_log (_T("68060 unimplemented opcode %04X, PC=%08x\n"), opcode, regs.instruction_pc);
warned++;
}
- Exception (61, regs.instruction_pc);
+ ExceptionL (61, regs.instruction_pc);
}
uae_u32 REGPARAM2 op_illg (uae_u32 opcode)
#if MMUOP_DEBUG > 0
write_log (_T("Unknown MMU OP %04X\n"), opcode);
#endif
- m68k_setpc (m68k_getpc () - 2);
+ m68k_setpc_normal (m68k_getpc () - 2);
op_illg (opcode);
}
/* should also include TRAP, CHK, SR modification FPcc */
/* probably never used so why bother */
/* We can afford this to be inefficient... */
- m68k_setpc (m68k_getpc ());
+ m68k_setpc_normal (m68k_getpc ());
fill_prefetch ();
opcode = x_get_word (regs.pc);
if (opcode == 0x4e73 /* RTE */
{
uae_u16 opcode;
uaecptr pc;
- flag_struct f;
+ struct flag_struct f;
retry:
TRY (prb) {
}
} CATCH (prb) {
- m68k_setpc (regs.instruction_pc);
+ m68k_setpc_mmu (regs.instruction_pc);
regflags.cznv = f.cznv;
regflags.x = f.x;
/* restore state if instruction restart */
regflags.cznv = f.cznv;
regflags.x = f.x;
- m68k_setpc (regs.instruction_pc);
+ m68k_setpc_mmu (regs.instruction_pc);
}
if (mmufixup[0].reg >= 0) {
{
uae_u16 opcode;
uaecptr pc;
- flag_struct f;
+ struct flag_struct f;
mmu030_opcode_stageb = -1;
retry:
regflags.cznv = f.cznv;
regflags.x = f.x;
- m68k_setpc (regs.instruction_pc);
+ m68k_setpc_mmu (regs.instruction_pc);
if (mmufixup[0].reg >= 0) {
m68k_areg (regs, mmufixup[0].reg) = mmufixup[0].value;
static int prevopcode;
r->instruction_pc = m68k_getpc ();
- if (regs.irc == 0xffff)
- gui_message (_T("OPCODE %04X HAS FAULTY PREFETCH!"), prevopcode);
+ if (regs.irc == 0xfffb) {
+ gui_message (_T("OPCODE %04X HAS FAULTY PREFETCH! PC=%08X"), prevopcode, r->instruction_pc);
+ }
//write_log (_T("%x %04x\n"), r->instruction_pc, regs.irc);
opcode = regs.irc;
prevopcode = opcode;
- regs.irc = 0xffff;
+ regs.irc = 0xfffb;
//write_log (_T("%08x %04x\n"), r->instruction_pc, opcode);
#endif
if (currprefs.produce_sound == 0)
eventtab[ev_audio].active = 0;
- m68k_setpc (regs.pc);
+ m68k_setpc_normal (regs.pc);
check_prefs_changed_audio ();
if (!restored || hsync_counter == 0)
-1, NULL
};
-void val_move2c2 (int regno, uae_u32 val)
-{
- switch (regno) {
- case 0: regs.sfc = val; break;
- case 1: regs.dfc = val; break;
- case 2: regs.cacr = val; break;
- case 3: regs.tcr = val; break;
- case 4: regs.itt0 = val; break;
- case 5: regs.itt1 = val; break;
- case 6: regs.dtt0 = val; break;
- case 7: regs.dtt1 = val; break;
- case 8: regs.buscr = val; break;
- case 0x800: regs.usp = val; break;
- case 0x801: regs.vbr = val; break;
- case 0x802: regs.caar = val; break;
- case 0x803: regs.msp = val; break;
- case 0x804: regs.isp = val; break;
- case 0x805: regs.mmusr = val; break;
- case 0x806: regs.urp = val; break;
- case 0x807: regs.srp = val; break;
- case 0x808: regs.pcr = val; break;
- }
-}
-
-uae_u32 val_move2c (int regno)
-{
- switch (regno) {
- case 0: return regs.sfc;
- case 1: return regs.dfc;
- case 2: return regs.cacr;
- case 3: return regs.tcr;
- case 4: return regs.itt0;
- case 5: return regs.itt1;
- case 6: return regs.dtt0;
- case 7: return regs.dtt1;
- case 8: return regs.buscr;
- case 0x800: return regs.usp;
- case 0x801: return regs.vbr;
- case 0x802: return regs.caar;
- case 0x803: return regs.msp;
- case 0x804: return regs.isp;
- case 0x805: return regs.mmusr;
- case 0x806: return regs.urp;
- case 0x807: return regs.srp;
- case 0x808: return regs.pcr;
- default: return 0;
- }
-}
-
void m68k_dumpstate (uaecptr pc, uaecptr *nextpc)
{
int i, j;
void restore_cpu_finish (void)
{
init_m68k ();
- m68k_setpc (regs.pc);
+ m68k_setpc_normal (regs.pc);
doint ();
fill_prefetch_quick ();
set_cycles (start_cycles);
#endif /* SAVESTATE */
-static void exception3f (uae_u32 opcode, uaecptr addr, int writeaccess, int instructionaccess, uae_u32 pc)
+static void exception3f (uae_u32 opcode, uaecptr addr, int writeaccess, int instructionaccess, uaecptr pc)
{
if (currprefs.cpu_model >= 68040)
addr &= ~1;
{
exception3f (opcode, addr, 0, 1, 0xffffffff);
}
-void exception3 (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
+void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
{
exception3f (opcode, addr, w, i, pc);
}
-void exception2 (uaecptr addr)
+void exception2 (uaecptr addr, bool read, int size, uae_u32 fc)
+{
+ if (currprefs.mmu_model) {
+ if (currprefs.mmu_model == 68030) {
+ uae_u32 flags = size == 1 ? MMU030_SSW_SIZE_B : (size == 2 ? MMU030_SSW_SIZE_W : MMU030_SSW_SIZE_L);
+ mmu030_page_fault (addr, read, flags, fc);
+ } else {
+ mmu_bus_error (addr, fc, read == false, size, false, 0);
+ }
+ } else {
+ // simple version
+ exception2_handle (addr, addr);
+ }
+}
+
+void exception2_fake (uaecptr addr)
{
write_log (_T("delayed exception2!\n"));
regs.panic_pc = m68k_getpc ();
regs.panic_addr = addr;
regs.panic = 6;
set_special (SPCFLAG_BRK);
- m68k_setpc (0xf80000);
+ m68k_setpc_normal (0xf80000);
#ifdef JIT
set_special (SPCFLAG_END_COMPILE);
#endif
fill_prefetch ();
}
-
void cpureset (void)
{
/* RESET hasn't increased PC yet, 1 word offset */
if (addr < 0x80000)
addr += 0xf80000;
write_log (_T("reset/jmp (ax) combination emulated -> %x\n"), addr);
- m68k_setpc (addr - 2);
+ m68k_setpc_normal (addr - 2);
return;
}
}
// (which is probably what program wanted anyway)
write_log (_T("CPU Reset PC=%x (%s), invalid memory -> %x.\n"), pc, ab->name, ksboot + 2);
custom_reset (false, false);
- m68k_setpc (ksboot);
+ m68k_setpc_normal (ksboot);
}
unset_special (SPCFLAG_STOP);
}
-/*
-* Compute exact number of CPU cycles taken
-* by DIVU and DIVS on a 68000 processor.
-*
-* Copyright (c) 2005 by Jorge Cwik, pasti@fxatari.com
-*
-* This is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this software; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*
-*/
-
-
-/*
-
-The routines below take dividend and divisor as parameters.
-They return 0 if division by zero, or exact number of cycles otherwise.
-
-The number of cycles returned assumes a register operand.
-Effective address time must be added if memory operand.
-
-For 68000 only (not 68010, 68012, 68020, etc).
-Probably valid for 68008 after adding the extra prefetch cycle.
-
-
-Best and worst cases for register operand:
-(Note the difference with the documented range.)
-
-
-DIVU:
-
-Overflow (always): 10 cycles.
-Worst case: 136 cycles.
-Best case: 76 cycles.
-
-
-DIVS:
-
-Absolute overflow: 16-18 cycles.
-Signed overflow is not detected prematurely.
-
-Worst case: 156 cycles.
-Best case without signed overflow: 122 cycles.
-Best case with signed overflow: 120 cycles
-
-
-*/
-
-int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor)
-{
- int mcycles;
- uae_u32 hdivisor;
- int i;
-
- if (divisor == 0)
- return 0;
-
- // Overflow
- if ((dividend >> 16) >= divisor)
- return (mcycles = 5) * 2;
-
- mcycles = 38;
- hdivisor = divisor << 16;
-
- for (i = 0; i < 15; i++) {
- uae_u32 temp;
- temp = dividend;
-
- dividend <<= 1;
-
- // If carry from shift
- if ((uae_s32)temp < 0)
- dividend -= hdivisor;
- else {
- mcycles += 2;
- if (dividend >= hdivisor) {
- dividend -= hdivisor;
- mcycles--;
- }
- }
- }
- return mcycles * 2;
-}
-
-int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor)
-{
- int mcycles;
- uae_u32 aquot;
- int i;
-
- if (divisor == 0)
- return 0;
-
- mcycles = 6;
-
- if (dividend < 0)
- mcycles++;
-
- // Check for absolute overflow
- if (((uae_u32)abs (dividend) >> 16) >= (uae_u16)abs (divisor))
- return (mcycles + 2) * 2;
-
- // Absolute quotient
- aquot = (uae_u32) abs (dividend) / (uae_u16)abs (divisor);
-
- mcycles += 55;
-
- if (divisor >= 0) {
- if (dividend >= 0)
- mcycles--;
- else
- mcycles++;
- }
-
- // Count 15 msbits in absolute of quotient
-
- for (i = 0; i < 15; i++) {
- if ((uae_s16)aquot >= 0)
- mcycles++;
- aquot <<= 1;
- }
-
- return mcycles * 2;
-}
-
-/* 68000 Z=1. NVC=0
- * 68020 and 68030: Signed: Z=1 NVC=0. Unsigned: V=1, N<dst, Z=!N, C=0.
- * 68040/68060 C=0.
- */
-void divbyzero_special (bool issigned, uae_s32 dst)
-{
- if (currprefs.cpu_model == 68020 || currprefs.cpu_model == 68030) {
- CLEAR_CZNV ();
- if (issigned == false) {
- if (dst < 0)
- SET_NFLG (1);
- SET_ZFLG (!GET_NFLG ());
- SET_VFLG (1);
- } else {
- SET_ZFLG (1);
- }
- } else if (currprefs.cpu_model >= 68040) {
- SET_CFLG (0);
- } else {
- // 68000/010
- CLEAR_CZNV ();
- }
-}
-
#if 0
STATIC_INLINE void fill_cache040 (uae_u32 addr)
{
continue;
}
- write_log (_T("%p %04x/%04x (%d/%d)\n"), h, rdi->hid.dwVendorId, rdi->hid.dwProductId, rdi->hid.usUsage, rdi->hid.usUsagePage);
+ write_log (_T("%p %d %04x/%04x (%d/%d)\n"), h, type, rdi->hid.dwVendorId, rdi->hid.dwProductId, rdi->hid.usUsage, rdi->hid.usUsagePage);
if (type == RIM_TYPEMOUSE) {
if (rdpdevice (buf1))
}
prodname[0] = 0;
- HANDLE hhid = CreateFile (buf1, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ HANDLE hhid = CreateFile (buf1, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hhid != INVALID_HANDLE_VALUE) {
if (!HidD_GetProductString (hhid, prodname, sizeof prodname)) {
prodname[0] = 0;
while (_tcslen (prodname) > 0 && prodname[_tcslen (prodname) - 1] == ' ')
prodname[_tcslen (prodname) - 1] = 0;
}
+ } else {
+ write_log (_T("HID CreateFile failed %d\n"), GetLastError ());
}
rnum_raw++;
did->rawinput = h;
did->connection = DIDC_RAW;
- write_log (_T("%p %s: "), h, type == RIM_TYPEHID ? _T("hid") : (type == RIM_TYPEMOUSE ? _T("mouse") : _T("keyboard")));
+ write_log (_T("%p %p %s: "), h, hhid, type == RIM_TYPEHID ? _T("hid") : (type == RIM_TYPEMOUSE ? _T("mouse") : _T("keyboard")));
did->sortname = my_strdup (buf1);
write_log (_T("'%s'\n"), buf1);
did->configname = my_strdup (buf1);
#define IDC_HDF_ADDFSRES 1384
#define IDC_ROMFILE 1390
#define IDC_KEYFILE 1391
+#define IDC_A2091ROMFILE 1391
#define IDC_KICKCHOOSER 1392
#define IDC_KEYCHOOSER 1393
+#define IDC_A2091ROMCHOOSER 1393
#define IDC_ROMFILE2 1394
#define IDC_ROMCHOOSER2 1395
#define IDC_FLASHCHOOSER 1396
#define IDC_CARTCHOOSER 1399
#define IDC_SAVE 1400
#define IDC_LOAD 1401
-#define IDC_FLASHCHOOSER2 1401
#define IDC_RTCCHOOSER 1401
+#define IDC_A4091ROMCHOOSER 1402
#define IDC_DELETE 1403
#define IDC_CONFIGLIST 1404
#define IDC_EDITNAME 1405
#define IDC_EXIT 1410
#define IDC_EDITPATH 1410
#define IDC_RTCFILE 1411
+#define IDC_A4091ROMFILE 1412
#define IDC_HDF_RDB 1500
#define IDC_HFSIZE 1501
#define IDC_HF_SIZE 1501
// Microsoft Visual C++ generated resource script.
//
-#include "winres.h"
#include "resource.h"
+#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
// English resources
// Dialog
//
-IDD_KICKSTART DIALOGEX 0, 0, 396, 217
+IDD_KICKSTART DIALOGEX 0, 0, 396, 243
STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
EXSTYLE WS_EX_CONTEXTHELP
FONT 8, "MS Sans Serif", 0, 0, 0x1
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,87,77,104,12
CONTROL "ShapeShifter support [] Patches the system ROM for ShapeShifter compatibility.",IDC_KICKSHIFTER,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,195,77,106,13
- GROUPBOX "Miscellaneous",IDC_STATIC,1,98,394,116
+ GROUPBOX "Miscellaneous",IDC_STATIC,1,98,394,143
LTEXT "Cartridge ROM file:",IDC_FLASHTEXT2,12,112,265,10
COMBOBOX IDC_CARTFILE,12,125,361,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "...",IDC_CARTCHOOSER,376,124,10,15
LTEXT "Real Time Clock file",IDC_STATIC,12,174,313,15,SS_CENTERIMAGE
EDITTEXT IDC_RTCFILE,12,191,361,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_RTCCHOOSER,376,189,10,15
+ COMBOBOX IDC_A2091ROMFILE,12,222,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "...",IDC_A2091ROMCHOOSER,187,221,10,15
+ LTEXT "A590/A2091 SCSI ROM file:",IDC_STATIC,12,207,170,15,SS_CENTERIMAGE
+ LTEXT "A4091 SCSI ROM file:",IDC_STATIC,203,207,170,15,SS_CENTERIMAGE
+ COMBOBOX IDC_A4091ROMFILE,202,222,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "...",IDC_A4091ROMCHOOSER,376,221,10,15
END
IDD_DISPLAY DIALOGEX 0, 0, 396, 298
CONTROL "Vertical Sync",IDC_CS_CIAA_TOD1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,41,68,86,10
CONTROL "Power Supply 50Hz",IDC_CS_CIAA_TOD2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,133,68,109,10
CONTROL "Power Supply 60Hz",IDC_CS_CIAA_TOD3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,249,68,116,10
- GROUPBOX "Chipset Features",IDC_STATIC,1,88,393,158
+ GROUPBOX "Chipset Features",IDC_STATIC,0,88,393,110
CONTROL "CIA ROM Overlay",IDC_CS_CIAOVERLAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,102,104,11
CONTROL "CD32 CD",IDC_CS_CD32CD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,116,104,11
CONTROL "CDTV CD",IDC_CS_CDTVCD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,130,105,11
CONTROL "A600/A1200 IDE",IDC_CS_IDE1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,143,104,11
CONTROL "ROM Mirror (E0)",IDC_CS_KSMIRROR_E0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,157,104,11
CONTROL "KB Reset Warning",IDC_CS_RESETWARNING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,171,104,11
- LTEXT "A4091/A4000T SCSI not yet implemented.",IDC_STATIC,17,202,247,8,SS_CENTERIMAGE
CONTROL "A590/A2091 SCSI",IDC_CS_A2091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,216,104,11
CONTROL "A4091 SCSI",IDC_CS_A4091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,229,104,11
CONTROL "A1000 Boot RAM/ROM",IDC_CS_A1000RAM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,102,121,11
EDITTEXT IDC_CS_AGNUSREV,311,260,45,13,ES_AUTOHSCROLL
EDITTEXT IDC_CS_DENISEREV,311,275,45,13,ES_AUTOHSCROLL
CONTROL "CIA TOD bug",IDC_CS_CIATODBUG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,184,104,11
+ GROUPBOX "SCSI Hardware",IDC_STATIC,0,201,393,45
END
IDD_AVIOUTPUT DIALOGEX 0, 0, 396, 260
BEGIN
IDD_KICKSTART, DIALOG
BEGIN
+ BOTTOMMARGIN, 217
END
IDD_DISPLAY, DIALOG
prevpc = (uae_u8*)ppc;
}
m68k_setpc ((uaecptr)p);
- exception2 (opc);
+ exception2_fake (opc);
lRet = EXCEPTION_CONTINUE_EXECUTION;
}
}
#define LANG_DLL 1
#if WINUAEPUBLICBETA
-#define WINUAEBETA _T("6")
+#define WINUAEBETA _T("7")
#else
#define WINUAEBETA _T("")
#endif
-#define WINUAEDATE MAKEBD(2014, 2, 2)
+#define WINUAEDATE MAKEBD(2014, 2, 9)
#define WINUAEEXTRA _T("")
//#define WINUAEEXTRA _T("AmiKit Preview")
//#define WINUAEEXTRA _T("Amiga Forever Edition")
11, 31, 15, -1, -1, // A1200
59, 71, 61, -1, -1, // A3000
16, 46, 31, 13, 12, -1, -1, // A4000
+ 17, -1, -1, // A4000T
18, -1, 19, -1, -1, // CD32
20, 21, 22, -1, 6, 32, -1, -1, // CDTV
- 49, 50, 51, -1, 5, 4, -1, -1, // ARCADIA
+ 49, 50, 75, 51, 76, 77, -1, 5, 4, -1, -1, // ARCADIA
46, 16, 17, 31, 13, 12, -1, -1, // highend, any 3.x A4000
- 53, 54, 55, -1, -1, // A590/A2091
- //56, 57, -1, -1, // A4091
+ 53, 54, 55, 56, -1, -1, // A590/A2091
+ 57, 58, -1, -1, // A4091
0, 0, 0
};
WIN32GUI_LoadUIString (IDS_ROM_UNAVAILABLE, unavail, sizeof (avail) / sizeof (TCHAR));
_tcscat (avail, _T("\n"));
_tcscat (unavail, _T("\n"));
- p1 = _T("A500 Boot ROM 1.2\0A500 Boot ROM 1.3\0A500+\0A600\0A1000\0A1200\0A3000\0A4000\0\nCD32\0CDTV\0Arcadia Multi Select\0High end WinUAE\0\nA590/A2091 SCSI Boot ROM\0\0");
+ p1 = _T("A500 Boot ROM 1.2\0A500 Boot ROM 1.3\0A500+\0A600\0A1000\0A1200\0A3000\0A4000\0A4000T\0\nCD32\0CDTV\0Arcadia Multi Select\0High end WinUAE\0\nA590/A2091 SCSI Boot ROM\0A4091 SCSI Boot ROM\0\0");
p = xmalloc (TCHAR, 100000);
if (!p)
_tcscpy (workprefs.cartfile, full_path);
fullpath (workprefs.cartfile, MAX_DPATH);
break;
+ case IDC_A2091ROMFILE:
+ _tcscpy (workprefs.a2091romfile, full_path);
+ fullpath (workprefs.a2091romfile, MAX_DPATH);
+ break;
+ case IDC_A4091ROMFILE:
+ _tcscpy (workprefs.a4091romfile, full_path);
+ fullpath (workprefs.a4091romfile, MAX_DPATH);
+ break;
case IDC_STATEREC_PLAY:
case IDC_STATEREC_RECORD:
case IDC_STATEREC_SAVE:
getromfile (hDlg, IDC_ROMFILE, workprefs.romfile, sizeof (workprefs.romfile) / sizeof (TCHAR));
getromfile (hDlg, IDC_ROMFILE2, workprefs.romextfile, sizeof (workprefs.romextfile) / sizeof (TCHAR));
getromfile (hDlg, IDC_CARTFILE, workprefs.cartfile, sizeof (workprefs.cartfile) / sizeof (TCHAR));
+ getromfile (hDlg, IDC_A2091ROMFILE, workprefs.a2091romfile, sizeof (workprefs.a2091romfile) / sizeof (TCHAR));
+ getromfile (hDlg, IDC_A4091ROMFILE, workprefs.a4091romfile, sizeof (workprefs.a4091romfile) / sizeof (TCHAR));
}
static void values_to_kickstartdlg (HWND hDlg)
ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV | ROMTYPE_ARCADIABIOS);
addromfiles (fkey, hDlg, IDC_CARTFILE, workprefs.cartfile,
ROMTYPE_AR | ROMTYPE_SUPERIV | ROMTYPE_NORDIC | ROMTYPE_XPOWER | ROMTYPE_ARCADIAGAME | ROMTYPE_HRTMON | ROMTYPE_CD32CART);
+ addromfiles (fkey, hDlg, IDC_A2091ROMFILE, workprefs.a2091romfile,
+ ROMTYPE_A2091BOOT);
+ addromfiles (fkey, hDlg, IDC_A4091ROMFILE, workprefs.a4091romfile,
+ ROMTYPE_A4091BOOT);
regclosetree (fkey);
SetDlgItemText(hDlg, IDC_FLASHFILE, workprefs.flashfile);
ew (hDlg, IDC_CARTCHOOSER), FALSE);
ew (hDlg, IDC_FLASHCHOOSER), FALSE);
#endif
+ ew (hDlg, IDC_A4091ROMCHOOSER, workprefs.cs_a4091);
+ ew (hDlg, IDC_A4091ROMFILE, workprefs.cs_a4091);
+ ew (hDlg, IDC_A2091ROMCHOOSER, workprefs.cs_a2091);
+ ew (hDlg, IDC_A2091ROMFILE, workprefs.cs_a2091);
if (!regexiststree (NULL , _T("DetectedROMs")))
scan_roms (NULL, rp_isactive () ? 0 : 1);
}
DiskSelection(hDlg, IDC_CARTFILE, 6, &workprefs, path);
values_to_kickstartdlg (hDlg);
break;
+ case IDC_A2091ROMCHOOSER:
+ DiskSelection(hDlg, IDC_A2091ROMFILE, 6, &workprefs, path);
+ values_to_kickstartdlg (hDlg);
+ break;
+ case IDC_A4091ROMCHOOSER:
+ DiskSelection(hDlg, IDC_A4091ROMFILE, 6, &workprefs, path);
+ values_to_kickstartdlg (hDlg);
+ break;
}
}
{
case WM_INITDIALOG:
{
- int ids[] = { IDC_ROMFILE, IDC_ROMFILE2, IDC_CARTFILE, -1 };
+ int ids[] = { IDC_ROMFILE, IDC_ROMFILE2, IDC_CARTFILE, IDC_A2091ROMFILE, IDC_A4091ROMFILE, -1 };
pages[KICKSTART_ID] = hDlg;
currentpage = KICKSTART_ID;
init_kickstart (hDlg);
case IDC_ROMFILE:
case IDC_ROMFILE2:
case IDC_CARTFILE:
+ case IDC_A2091ROMFILE:
+ case IDC_A4091ROMFILE:
values_from_kickstartdlg (hDlg);
break;
}
SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_RESETCONTENT, 0, 0L);
SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)szNone.c_str());
- SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Robocop 3"));
- SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Leaderboard"));
+ SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("RoboCop 3"));
+ SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Leader Board"));
SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("B.A.T. II"));
- SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Italy'90 Soccer"));
- SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Dames Grand Maitre"));
+ SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Italy '90 Soccer"));
+ SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Dames Grand-Maître"));
SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Rugby Coach"));
SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Cricket Captain"));
SendDlgItemMessage (hDlg, IDC_DONGLELIST, CB_ADDSTRING, 0, (LPARAM)_T("Leviathan"));
-1,
IDD_INPUT, IDC_INPUTDEVICE, IDC_INPUTLIST, IDC_INPUTAMIGA,
-1,
- IDD_KICKSTART, IDC_ROMFILE, IDC_ROMFILE2, IDC_CARTFILE, IDC_FLASHFILE, IDC_RTCFILE,
+ IDD_KICKSTART, IDC_ROMFILE, IDC_ROMFILE2, IDC_CARTFILE, IDC_FLASHFILE, IDC_RTCFILE, IDC_A2091ROMFILE, IDC_A4091ROMFILE,
-1,
IDD_LOADSAVE, IDC_CONFIGTREE, IDC_EDITNAME, IDC_EDITDESCRIPTION, IDC_CONFIGLINK, IDC_EDITPATH,
-1,
<ClCompile Include="..\..\cpuemu_22.cpp" />
<ClCompile Include="..\..\cpuemu_32.cpp" />
<ClCompile Include="..\..\cpuemu_33.cpp" />
+ <ClCompile Include="..\..\cpuemu_common.cpp" />
<ClCompile Include="..\..\cpummu30.cpp" />
<ClCompile Include="..\..\ethernet.cpp" />
<ClCompile Include="..\..\events.cpp" />
<ClCompile Include="..\..\qemuvga\lsi53c895a.cpp">
<Filter>qemu</Filter>
</ClCompile>
+ <ClCompile Include="..\..\cpuemu_common.cpp">
+ <Filter>common</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\resources\35floppy.ico">
- restore only single input target to default.
+Beta 7:
+
+- A4091 and A4000T NCR53C710 SCSI emulation works now! Now all built-in devices in all supported setups
+ are emulated. I guess last interesting big missing Commodore designed part is CD32 MPEG module.
+- Added A4000T and A4091 to ROM scanner results window.
+- Added A590/A2091 and A4091 boot ROM selection to GUI, if empty, uses old automatic selection.
+- A590/A2091 + Fast RAM: Fast RAM is always first, A590/A2091 second, then other boards (if enabled),
+ now matches real A590/A2091 with fast ram installed.
+- HID RawInput had wrong access mode in device open call, failed if other users of same device
+ used different access modes.
+- 68EC020 "opcode x has faulty prefetch" triggered too easily when program did stupid things.
+ (It is only a debug feature, it will be gone someday)
+- AGA high fetch mode screens with ddfstop near the end of right border were completely blank.
+- DDFSTRT limit should go away if programmed mode or superhires (broke in some previous beta).
+- Reset horizontal display window if it is still active at the end of scanline (even if it is
+ larger than last hpos value) if programmed mode or superhires. Perhaps this is wrong, perhaps not,
+ not bothered to test yet.. (Background "leak" in right edge in some wide programmed mode screens)
+- Accept uaehf.device open call even if ioreq->io.Message.mn_Length is invalid or too small.
+- Renamed some protection dongle names in GUI.
+
Beta 6:
- Display emulation last horizontal position (plfright) was not correctly updated, caused all kinds of
* as well-behaved operating systems will not try to use them.
*/
-/* Hacked to partially support LSI53C710 for UAE by Toni Wilen */
+/* Hacked to support LSI53C710 for UAE by Toni Wilen */
#include <assert.h>
#include "scsi/scsi.h"
//#include "sysemu/dma.h"
-#define DEBUG_LSI
-#define DEBUG_LSI_REG
+//#define DEBUG_LSI
+//#define DEBUG_LSI_REG
#ifdef DEBUG_LSI
#define DPRINTF(fmt, ...) \
#define LSI_SCNTL0_AAP 0x02
#define LSI_SCNTL0_EPG 0x08
#define LSI_SCNTL0_EPC 0x08
-#define LSI_SCNTL0_WATN 0x10
+#define LSI_SCNTL0_WATN 0x10,
#define LSI_SCNTL0_START 0x20
#define LSI_SCNTL1_RCV 0x01
#define LSI_SCNTL2_CHM 0x40
#define LSI_SCNTL2_SDU 0x80
-#define LSI_ISTAT0_DIP 0x01
-#define LSI_ISTAT0_SIP 0x02
+#define LSI_ISTAT_DIP 0x01
+#define LSI_ISTAT_SIP 0x02
//#define LSI_ISTAT0_INTF 0x04
-#define LSI_ISTAT0_CON 0x08
+#define LSI_ISTAT_CON 0x08
//#define LSI_ISTAT0_SEM 0x10
-#define LSI_ISTAT0_SIGP 0x20
-#define LSI_ISTAT0_SRST 0x40
-#define LSI_ISTAT0_ABRT 0x80
-
-#define LSI_ISTAT1_SI 0x01
-#define LSI_ISTAT1_SRUN 0x02
-#define LSI_ISTAT1_FLSH 0x04
+#define LSI_ISTAT_SIGP 0x20
+#define LSI_ISTAT_RST 0x40
+#define LSI_ISTAT_ABRT 0x80
#define LSI_SSTAT1_WOA 0x04
#define LSI_DCNTL_CLSE 0x80
#define LSI_DMODE_MAN 0x01
-#define LSI_DMODE_BOF 0x02
-#define LSI_DMODE_ERMP 0x04
-#define LSI_DMODE_ERL 0x08
-#define LSI_DMODE_DIOM 0x10
-#define LSI_DMODE_SIOM 0x20
+#define LSI_DMODE_UO 0x02
+#define LSI_DMODE_FAM 0x04
+#define LSI_DMODE_PD 0x08
#define LSI_CTEST2_DACK 0x01
#define LSI_CTEST2_DREQ 0x02
/* Enable Response to Reselection */
#define LSI_SCID_RRE 0x60
-#define LSI_CCNTL1_40BIT (LSI_CCNTL1_EN64TIBMV|LSI_CCNTL1_64TIMOD)
-
#define PHASE_DO 0
#define PHASE_DI 1
#define PHASE_CMD 2
//PCIDevice parent_obj;
/*< public >*/
- MemoryRegion mmio_io;
- MemoryRegion ram_io;
- MemoryRegion io_io;
+ //MemoryRegion mmio_io;
+ //MemoryRegion ram_io;
+ //MemoryRegion io_io;
int carry; /* ??? Should this be an a visible register somewhere? */
int status;
uint32_t temp;
uint32_t dnad;
uint32_t dbc;
- uint8_t istat0;
- uint8_t istat1;
+ uint8_t istat;
uint8_t dcmd;
uint8_t dstat;
uint8_t dien;
// uint8_t sist0;
// uint8_t sist1;
uint8_t sien0;
-// uint8_t sien1;
- uint8_t mbox0;
- uint8_t mbox1;
- uint8_t dfifo;
uint8_t ctest2;
uint8_t ctest3;
uint8_t ctest4;
uint8_t ctest5;
- uint8_t ccntl0;
- uint8_t ccntl1;
uint32_t dsp;
uint32_t dsps;
uint8_t dmode;
uint8_t dcntl;
uint8_t scntl0;
uint8_t scntl1;
- uint8_t scntl2;
- uint8_t scntl3;
uint8_t sstat0;
uint8_t sstat1;
uint8_t scid;
uint8_t sxfer;
uint8_t socl;
uint8_t sdid;
- uint8_t ssid;
uint8_t sfbr;
- uint8_t stest1;
- uint8_t stest2;
- uint8_t stest3;
uint8_t sidl;
- uint8_t stime0;
- uint8_t respid0;
- uint8_t respid1;
- uint32_t mmrs;
- uint32_t mmws;
- uint32_t sfs;
- uint32_t drs;
- uint32_t sbms;
- uint32_t dbms;
- uint32_t dnad64;
- uint32_t pmjad1;
- uint32_t pmjad2;
- uint32_t rbc;
- uint32_t ua;
- uint32_t ia;
uint32_t sbc;
- uint32_t csbc;
- uint32_t scratch[18]; /* SCRATCHA-SCRATCHR */
+ uint32_t scratch;
uint8_t sbr;
- /* Script ram is stored as 32-bit words in host byteorder. */
- uint32_t script_ram[2048];
-
uint8_t ctest0;
uint8_t ctest1;
uint8_t ctest6;
uint8_t ctest7;
+ uint8_t ctest8;
+ uint8_t lcrc;
uint8_t sstat2;
+ uint8_t dwt;
+ uint8_t script_active;
} LSIState;
-#define TYPE_LSI53C810 "lsi53c810"
-#define TYPE_LSI53C895A "lsi53c895a"
+//#define TYPE_LSI53C810 "lsi53c810"
+//#define TYPE_LSI53C895A "lsi53c895a"
#define LSI53C895A(obj) (LSIState*)obj->lsistate
//((LSIState*)(OBJECT_CHECK(LSIState, (obj), TYPE_LSI53C895A)))
static inline int lsi_irq_on_rsl(LSIState *s)
{
- return 0;// return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
+ return 0; //return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
}
static void lsi_soft_reset(LSIState *s)
{
DPRINTF("Reset\n");
s->carry = 0;
+ memset (s, 0, sizeof LSIState);
s->msg_action = 0;
s->msg_len = 0;
s->dnad = 0;
s->dbc = 0;
s->temp = 0;
- memset(s->scratch, 0, sizeof(s->scratch));
- s->istat0 = 0;
- s->istat1 = 0;
+ s->scratch = 0;
+ s->istat = 0;
s->dcmd = 0x40;
s->dstat = LSI_DSTAT_DFE;
s->dien = 0;
// s->sist1 = 0;
s->sien0 = 0;
// s->sien1 = 0;
- s->mbox0 = 0;
- s->mbox1 = 0;
- s->dfifo = 0;
s->ctest2 = LSI_CTEST2_DACK;
s->ctest3 = 0;
s->ctest4 = 0;
s->ctest5 = 0;
- s->ccntl0 = 0;
- s->ccntl1 = 0;
s->dsp = 0;
s->dsps = 0;
s->dmode = 0;
s->dcntl = 0;
s->scntl0 = 0xc0;
s->scntl1 = 0;
- s->scntl2 = 0;
- s->scntl3 = 0;
s->sstat0 = 0;
s->sstat1 = 0;
s->sstat2 = 0;
- s->scid = 7;
+ s->scid = 0x80;
s->sxfer = 0;
s->socl = 0;
s->sdid = 0;
- s->ssid = 0;
- s->stest1 = 0;
- s->stest2 = 0;
- s->stest3 = 0;
s->sidl = 0;
- s->stime0 = 0;
- s->respid0 = 0x80;
- s->respid1 = 0;
- s->mmrs = 0;
- s->mmws = 0;
- s->sfs = 0;
- s->drs = 0;
- s->sbms = 0;
- s->dbms = 0;
- s->dnad64 = 0;
- s->pmjad1 = 0;
- s->pmjad2 = 0;
- s->rbc = 0;
- s->ua = 0;
- s->ia = 0;
s->sbc = 0;
- s->csbc = 0;
s->sbr = 0;
assert(QTAILQ_EMPTY(&s->queue));
assert(!s->current);
}
+#if 0
static int lsi_dma_40bit(LSIState *s)
{
if ((s->ccntl1 & LSI_CCNTL1_40BIT) == LSI_CCNTL1_40BIT)
return 1;
return 0;
}
+#endif
static uint8_t lsi_reg_readb(LSIState *s, int offset);
static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
static void lsi_stop_script(LSIState *s)
{
- s->istat1 &= ~LSI_ISTAT1_SRUN;
+ s->script_active = 0;
}
static void lsi_update_irq(LSIState *s)
if (s->dstat) {
if (s->dstat & s->dien)
level = 1;
- s->istat0 |= LSI_ISTAT0_DIP;
+ s->istat |= LSI_ISTAT_DIP;
} else {
- s->istat0 &= ~LSI_ISTAT0_DIP;
+ s->istat &= ~LSI_ISTAT_DIP;
}
if (s->sstat0) {
if ((s->sstat0 & s->sien0))
level = 1;
- s->istat0 |= LSI_ISTAT0_SIP;
+ s->istat |= LSI_ISTAT_SIP;
} else {
- s->istat0 &= ~LSI_ISTAT0_SIP;
+ s->istat &= ~LSI_ISTAT_SIP;
}
-// if (s->istat0 & LSI_ISTAT0_INTF)
-// level = 1;
if (level != last_level) {
DPRINTF("Update IRQ level %d dstat %02x sist %02x%02x\n",
static inline void lsi_set_phase(LSIState *s, int phase)
{
s->sstat2 = (s->sstat2 & ~PHASE_MASK) | phase;
+ s->ctest0 &= ~1;
+ if (phase == PHASE_DI)
+ s->ctest0 |= 1;
}
static void lsi_bad_phase(LSIState *s, int out, int new_phase)
{
/* Trigger a phase mismatch. */
- if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
- if ((s->ccntl0 & LSI_CCNTL0_PMJCTL)) {
- s->dsp = out ? s->pmjad1 : s->pmjad2;
- } else {
- s->dsp = (s->scntl2 & LSI_SCNTL2_WSR ? s->pmjad2 : s->pmjad1);
- }
- DPRINTF("Data phase mismatch jump to %08x\n", s->dsp);
- } else {
- DPRINTF("Phase mismatch interrupt\n");
- lsi_script_scsi_interrupt(s, LSI_SSTAT0_SGE);
- lsi_stop_script(s);
- }
+ DPRINTF("Phase mismatch interrupt\n");
+ lsi_script_scsi_interrupt(s, LSI_SSTAT0_MA);
+ lsi_stop_script(s);
lsi_set_phase(s, new_phase);
}
count = s->current->dma_len;
addr = s->dnad;
- /* both 40 and Table Indirect 64-bit DMAs store upper bits in dnad64 */
+#if 0
+ /* both 40 and Table Indirect 64-bit DMAs store upper bits in dnad64 */
if (lsi_dma_40bit(s) || lsi_dma_ti64bit(s))
addr |= ((uint64_t)s->dnad64 << 32);
else if (s->dbms)
addr |= ((uint64_t)s->dbms << 32);
else if (s->sbms)
addr |= ((uint64_t)s->sbms << 32);
+#endif
DPRINTF("DMA addr=0x" DMA_ADDR_FMT " len=%d\n", addr, count);
- s->csbc += count;
s->dnad += count;
s->dbc -= count;
if (s->current->dma_buf == NULL) {
s->current = p;
id = (p->tag >> 8) & 0xf;
- s->ssid = id | 0x80;
/* LSI53C700 Family Compatibility, see LSI53C895A 4-73 */
if (!(s->dcntl & LSI_DCNTL_COM)) {
s->sfbr = 1 << (id & 0x7);
}
+ s->lcrc = 0;
DPRINTF("Reselected target %d\n", id);
s->scntl1 |= LSI_SCNTL1_CON;
lsi_set_phase(s, PHASE_MI);
for service from the device driver. */
if (s->waiting == 1 ||
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
- !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
+ !(s->istat & (LSI_ISTAT_SIP | LSI_ISTAT_DIP)))) {
/* Reselect device. */
lsi_reselect(s, p);
return 0;
out = (s->sstat2 & PHASE_MASK) == PHASE_DO;
DPRINTF("Command complete status=%d\n", (int)status);
+ s->lcrc = 0;
s->status = status;
s->command_complete = 2;
if (s->waiting && s->dbc != 0) {
num++;
id >>= 1;
}
+ if (num > 7)
+ num = -1;
return num;
}
s->command_complete = 0;
id = (s->select_tag >> 8) & 0xf;
+ s->lcrc = 1 << (id & 0x7);
dev = scsi_device_find(&s->bus, 0, idbitstonum(id), s->current_lun);
if (!dev) {
lsi_bad_selection(s, id);
{
PCIDevice *pci_dev = PCI_DEVICE(s);
uint32_t insn;
- uint32_t addr, addr_high;
+ uint32_t addr;
int opcode;
int insn_processed = 0;
- s->istat1 |= LSI_ISTAT1_SRUN;
+ s->script_active = 1;
again:
insn_processed++;
insn = read_dword(s, s->dsp);
goto again;
}
addr = read_dword(s, s->dsp + 4);
- addr_high = 0;
DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr);
s->dsps = addr;
s->dcmd = insn >> 24;
break;
}
s->dbc = insn & 0xffffff;
- s->rbc = s->dbc;
- /* ??? Set ESA. */
- s->ia = s->dsp - 8;
if (insn & (1 << 29)) {
/* Indirect addressing. */
addr = read_dword(s, addr);
pci_dma_read(pci_dev, s->dsa + offset, buf, 8);
/* byte count is stored in bits 0:23 only */
s->dbc = cpu_to_le32(buf[0]) & 0xffffff;
- s->rbc = s->dbc;
addr = cpu_to_le32(buf[1]);
- /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of
+#if 0
+ /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of
* table, bits [31:24] */
if (lsi_dma_40bit(s))
addr_high = cpu_to_le32(buf[0]) >> 24;
s->dbms = read_dword(s, s->dsp);
s->dsp += 4;
s->ia = s->dsp - 12;
+#endif
}
if ((s->sstat2 & PHASE_MASK) != ((insn >> 24) & 7)) {
DPRINTF("Wrong phase got %d expected %d\n",
break;
}
s->dnad = addr;
- s->dnad64 = addr_high;
switch (s->sstat2 & 0x7) {
case PHASE_DO:
s->waiting = 2;
BADF("Unimplemented phase %d\n", s->sstat2 & PHASE_MASK);
exit(1);
}
- s->dfifo = s->dbc & 0xff;
s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
s->sbc = s->dbc;
- s->rbc -= s->dbc;
- s->ua = addr + s->dbc;
break;
case 1: /* IO or Read/Write instruction. */
} else {
id = insn;
}
- id = (id >> 16) & 0xf;
+ id = (id >> 16) & 0xff;
if (insn & (1 << 26)) {
addr = s->dsp + sextract32(addr, 0, 24);
}
+ id &= ~s->scid;
s->dnad = addr;
switch (opcode) {
case 0: /* Select */
break;
}
DPRINTF("Selected target %d%s\n",
- id, insn & (1 << 3) ? " ATN" : "");
+ id, insn & (1 << 24) ? " ATN" : "");
/* ??? Linux drivers compain when this is set. Maybe
it only applies in low-level mode (unimplemented).
lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
s->select_tag = id << 8;
s->scntl1 |= LSI_SCNTL1_CON;
- if (insn & (1 << 3)) {
+ if (insn & (1 << 24)) {
s->socl |= LSI_SOCL_ATN;
}
lsi_set_phase(s, PHASE_MO);
case 3: /* Interrupt */
DPRINTF("Interrupt 0x%08x\n", s->dsps);
if ((insn & (1 << 20)) != 0) {
- //s->istat0 |= LSI_ISTAT0_INTF;
lsi_update_irq(s);
} else {
lsi_script_dma_interrupt(s, LSI_DSTAT_SIR);
fprintf(stderr, "inf. loop with UDC masked\n");
lsi_script_scsi_interrupt(s, LSI_SSTAT0_UDC);
lsi_disconnect(s);
- } else if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {
+ } else if (s->script_active && !s->waiting) {
if (s->dcntl & LSI_DCNTL_SSM) {
lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
} else {
case 0x05: /* SXFER */
return s->sxfer;
- case 0xc: /* DSTAT */
+ case 0xb: /* SBCL */
+ /* ??? This is not correct. However it's (hopefully) only
+ used for diagnostics, so should be ok. */
+ return 0;
+ case 0xc: /* DSTAT */
tmp = s->dstat | LSI_DSTAT_DFE;
s->dstat = 0;
// if ((s->istat0 & LSI_ISTAT0_INTF) == 0)
return s->sstat1;
case 0x0f: /* SSTAT2 */
return s->sstat2;
+ CASE_GET_REG32(dsa, 0x10)
case 0x14: /* CTEST0 */
return s->ctest0;
+ case 0x15: /* CTEST1 */
+ return 0xf0; // FMT and FFL are always empty
case 0x16: /* CTEST2 */
tmp = s->ctest2 | LSI_CTEST2_DACK;
- if (s->istat0 & LSI_ISTAT0_SIGP) {
- s->istat0 &= ~LSI_ISTAT0_SIGP;
+ if (s->istat & LSI_ISTAT_SIGP) {
+ s->istat &= ~LSI_ISTAT_SIGP;
tmp |= LSI_CTEST2_SIGP;
}
return tmp;
+ case 0x17: /* CTEST3 */
+ return s->ctest3;
+ case 0x18: /* CTEST4 */
+ return s->ctest4;
+ case 0x19: /* CTEST5 */
+ return s->ctest5;
+ case 0x1a: /* CTEST6 */
+ return s->ctest6;
case 0x1b: /* CTEST7 */
return s->ctest7;
+ CASE_GET_REG32(temp, 0x1c)
+ case 0x20: /* DFIFO */
+ return 0;
case 0x21: /* ISTAT */
- return s->istat0;
-
+ return s->istat;
+ case 0x22: /* CTEST8 */
+ return (s->ctest8 | (2 << 4)) & ~0x08; // clear CLF
+ case 0x23: /* LCRC */
+ return s->lcrc;
+ CASE_GET_REG24(dbc, 0x24)
+ case 0x27: /* DCMD */
+ return s->dcmd;
+ CASE_GET_REG32(dnad, 0x28)
+ CASE_GET_REG32(dsp, 0x2c)
CASE_GET_REG32(dsps, 0x30)
-
+ CASE_GET_REG32(scratch, 0x34)
case 0x38: /* DMODE */
return s->dmode;
+ case 0x3a: /* DWT */
+ return s->dwt;
case 0x3b: /* DCNTL */
return s->dcntl;
}
#undef CASE_GET_REG24
#undef CASE_GET_REG32
- write_log ("unknown register\n");
+ write_log ("read unknown register %02X\n", offset);
return 0;
}
static uint8_t lsi_reg_readb(LSIState *s, int offset)
return;
CASE_SET_REG32(dsa, 0x10)
case 0x14: /* CTEST0 */
- s->ctest0 = val;
+ s->ctest0 = (val & 0xfe) | (s->ctest0 & 1);
+ break;
+ case 0x18: /* CTEST4 */
+ s->ctest4 = val;
+ break;
+ case 0x19: /* CTEST5 */
+ s->ctest5 = val;
+ break;
+ case 0x1a: /* CTEST6 */
+ s->ctest6 = val;
break;
case 0x1b: /* CTEST7 */
s->ctest7 = val;
break;
+ CASE_SET_REG32(temp, 0x1c)
case 0x21: /* ISTAT */
- s->istat0 = (s->istat0 & 0x0f) | (val & 0xf0);
- if (val & LSI_ISTAT0_ABRT) {
+ s->istat = (s->istat & 0x0f) | (val & 0xf0);
+ if (val & LSI_ISTAT_ABRT) {
lsi_script_dma_interrupt(s, LSI_DSTAT_ABRT);
}
-// if (val & LSI_ISTAT0_INTF) {
-// s->istat0 &= ~LSI_ISTAT0_INTF;
-// lsi_update_irq(s);
-// }
- if (s->waiting == 1 && (val & LSI_ISTAT0_SIGP)) {
+ if (s->waiting == 1 && (val & LSI_ISTAT_SIGP)) {
DPRINTF("Woken by SIGP\n");
s->waiting = 0;
s->dsp = s->dnad;
lsi_execute_script(s);
}
-// if (val & LSI_ISTAT0_SRST) {
-// qdev_reset_all(DEVICE(s));
-// }
+ if (val & LSI_ISTAT_RST) {
+ ;//qdev_reset_all(DEVICE(s));
+ }
break;
+ case 0x22: /* CTEST8 */
+ s->ctest8 = val;
+ break;
+ case 0x23: /* LCRC */
+ s->lcrc = 0;
+ break;
+ CASE_SET_REG24(dbc, 0x24)
+ CASE_SET_REG32(dnad, 0x28)
case 0x2c: /* DSP[0:7] */
s->dsp &= 0xffffff00;
s->dsp |= val;
case 0x2f: /* DSP[24:31] */
s->dsp &= 0x00ffffff;
s->dsp |= val << 24;
- if ((s->dmode & LSI_DMODE_MAN) == 0
- && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
+ if ((s->dmode & LSI_DMODE_MAN) == 0) {
+ s->waiting = 0;
lsi_execute_script(s);
+ }
break;
-
+ CASE_SET_REG32(scratch, 0x34)
case 0x38: /* DMODE */
#if 0
if (val & (LSI_DMODE_SIOM | LSI_DMODE_DIOM)) {
s->dien = val;
lsi_update_irq(s);
break;
+ case 0x3a: /* DWT */
+ s->dwt = val;
+ break;
case 0x3b: /* DCNTL */
s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);
- if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
+ if ((val & LSI_DCNTL_STD) && (s->dmode & LSI_DMODE_MAN) == 0)
lsi_execute_script(s);
break;
default:
- write_log ("unknown register\n");
+ write_log ("write unknown register %02X\n", offset);
break;
}
#undef CASE_SET_REG24
1,
},
};
-#endif
static void lsi_ram_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
return val & mask;
}
-#if 0
static const MemoryRegionOps lsi_ram_ops = {
lsi_ram_read,
lsi_ram_write,
{ _T("Freezer: HRTMon v2.33 (built-in)"), 0, 0, 0, 0, _T("HRTMON\0"), 0, 63, 0, 0, ROMTYPE_HRTMON, 0, 1, NULL,
0xffffffff, 0, 0, 0, 0, 0, _T("HRTMon") },
- { _T("A590/A2091 SCSI boot ROM"), 6, 0, 6, 0, _T("A590\0A2091\0"), 16384, 53, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL,
+ { _T("A590/A2091 ROM 6.0"), 6, 0, 6, 0, _T("A590\0A2091\0"), 16384, 53, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL,
0x8396cf4e, 0x5E03BC61,0x8C862ABE,0x7BF79723,0xB4EEF4D2,0x1859A0F2 },
ALTROMPN(53, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390389-03"), 0xb0b8cf24,0xfcf40175,0x05f4d441,0x814b45d5,0x59c19eab,0x43816b30)
ALTROMPN(53, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390388-03"), 0x2e77bbff,0x8a098845,0x068f32cf,0xa4d34a27,0x8cd290f6,0x1d35a52c)
- { _T("A590/A2091 SCSI boot ROM"), 6, 6, 6, 6, _T("A590\0A2091\0"), 16384, 54, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL,
+ { _T("A590/A2091 ROM 6.6"), 6, 6, 6, 6, _T("A590\0A2091\0"), 16384, 54, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL,
0x33e00a7a, 0x739BB828,0xE874F064,0x9360F59D,0x26B5ED3F,0xBC99BB66 },
ALTROMPN(54, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390722-02"), 0xe536bbb2,0xfd7f8a6d,0xa18c1b02,0xd07eb990,0xc2467a24,0x183ede12)
ALTROMPN(54, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-02"), 0xc0871d25,0xe155f18a,0xbb90cf82,0x0589c15e,0x70559d3b,0x6b391af8)
- { _T("A590/A2091 SCSI boot ROM"), 7, 0, 7, 0, _T("A590\0A2091\0"), 16384, 55, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL,
+ { _T("A590/A2091 ROM 7.0"), 7, 0, 7, 0, _T("A590\0A2091\0"), 16384, 55, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL,
0x714a97a2, 0xE50F01BA,0xF2899892,0x85547863,0x72A82C33,0x3C91276E },
ALTROMPN(55, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390722-03"), 0xa9ccffed,0x149f5bd5,0x2e2d2990,0x4e3de483,0xb9ad7724,0x48e9278e)
ALTROMPN(55, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-03"), 0x2942747a,0xdbd7648e,0x79c75333,0x7ff3e4f4,0x91de224b,0xf05e6bb6)
- { _T("A590/A2091 SCSI Guru boot ROM"), 6, 14, 6, 14, _T("A590\0A2091\0"), 32768, 56, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL,
+ { _T("A590/A2091 Guru ROM 6.14"), 6, 14, 6, 14, _T("A590\0A2091\0"), 32768, 56, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL,
0x04e52f93, 0x6DA21B6F,0x5E8F8837,0xD64507CD,0x8A4D5CDC,0xAC4F426B },
- { _T("A4091 SCSI boot ROM"), 40, 9, 40, 9, _T("A4091\0"), 32768, 57, 0, 0, ROMTYPE_A4091BOOT, 0, 0, NULL,
+ { _T("A4091 ROM 40.9"), 40, 9, 40, 9, _T("A4091\0"), 32768, 57, 0, 0, ROMTYPE_A4091BOOT, 0, 0, NULL,
0x00000000, 0, 0, 0, 0, 0 },
- { _T("A4091 SCSI boot ROM"), 40, 13, 40, 13, _T("A4091\0"), 32768, 58, 0, 0, ROMTYPE_A4091BOOT, 0, 0, _T("391592-02"),
+ { _T("A4091 ROM 40.13"), 40, 13, 40, 13, _T("A4091\0"), 32768, 58, 0, 0, ROMTYPE_A4091BOOT, 0, 0, _T("391592-02"),
0x54cb9e85, 0x3CE66919,0xF6FD6797,0x4923A12D,0x91B730F1,0xFFB4A7BA },
{ _T("Arcadia OnePlay 2.11"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 49, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 },