This commit is contained in:
Toni Wilen 2015-08-12 20:21:24 +03:00
parent 1da24b785f
commit a5f17c7727
17 changed files with 3311 additions and 123 deletions

2493
65c02core.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,8 @@
* *
*/ */
#define CDTVCR_4510_EMULATION 0
#define CDTVCR_DEBUG 0 #define CDTVCR_DEBUG 0
#include "sysconfig.h" #include "sysconfig.h"
@ -1018,3 +1020,485 @@ void cdtvcr_free(void)
thread_alive = 0; thread_alive = 0;
close_unit (); close_unit ();
} }
#if CDTVCR_4510_EMULATION
// VICE 65C02 emulator, waiting for future full CDTV-CR 4510 emulation.
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int CLOCK;
static void cpu65c02_reset(void)
{
}
#define CLOCK_MAX (~((CLOCK)0))
#define TRAP_OPCODE 0x02
#define STATIC_ASSERT(_x)
#define NUM_MEMSPACES e_invalid_space
enum mon_int {
MI_NONE = 0,
MI_BREAK = 1 << 0,
MI_WATCH = 1 << 1,
MI_STEP = 1 << 2
};
enum t_memspace {
e_default_space = 0,
e_comp_space,
e_disk8_space,
e_disk9_space,
e_disk10_space,
e_disk11_space,
e_invalid_space
};
typedef enum t_memspace MEMSPACE;
static unsigned monitor_mask[NUM_MEMSPACES];
static void monitor_check_icount_interrupt(void)
{
}
static void monitor_check_icount(WORD a)
{
}
static int monitor_force_import(int mem)
{
return 0;
}
static int monitor_check_breakpoints(int mem, WORD addr)
{
return 0;
}
static void monitor_check_watchpoints(unsigned int lastpc, unsigned int pc)
{
}
static void monitor_startup(int mem)
{
}
#define INTERRUPT_DELAY 2
#define INTRRUPT_MAX_DMA_PER_OPCODE (7+10000)
enum cpu_int {
IK_NONE = 0,
IK_NMI = 1 << 0,
IK_IRQ = 1 << 1,
IK_RESET = 1 << 2,
IK_TRAP = 1 << 3,
IK_MONITOR = 1 << 4,
IK_DMA = 1 << 5,
IK_IRQPEND = 1 << 6
};
struct interrupt_cpu_status_s {
/* Number of interrupt lines. */
unsigned int num_ints;
/* Define, for each interrupt source, whether it has a pending interrupt
(IK_IRQ, IK_NMI, IK_RESET and IK_TRAP) or not (IK_NONE). */
unsigned int *pending_int;
/* Name for each interrupt source */
char **int_name;
/* Number of active IRQ lines. */
int nirq;
/* Tick when the IRQ was triggered. */
CLOCK irq_clk;
/* Number of active NMI lines. */
int nnmi;
/* Tick when the NMI was triggered. */
CLOCK nmi_clk;
/* If an opcode is intercepted by a DMA, save the number of cycles
left at the start of this particular DMA (needed by *_set_irq() to
calculate irq_clk). */
unsigned int num_dma_per_opcode;
unsigned int num_cycles_left[INTRRUPT_MAX_DMA_PER_OPCODE];
CLOCK dma_start_clk[INTRRUPT_MAX_DMA_PER_OPCODE];
/* counters for delay between interrupt request and handler */
unsigned int irq_delay_cycles;
unsigned int nmi_delay_cycles;
/* If 1, do a RESET. */
int reset;
/* If 1, call the trapping function. */
int trap;
/* Debugging function. */
void(*trap_func)(WORD, void *data);
/* Data to pass to the debugging function when called. */
void *trap_data;
/* Pointer to the last executed opcode information. */
unsigned int *last_opcode_info_ptr;
/* Number of cycles we have stolen to the processor last time. */
int num_last_stolen_cycles;
/* Clock tick at which these cycles have been stolen. */
CLOCK last_stolen_cycles_clk;
/* Clock tick where just ACK'd IRQs may still trigger an interrupt.
Set to CLOCK_MAX when irrelevant. */
CLOCK irq_pending_clk;
unsigned int global_pending_int;
void(*nmi_trap_func)(void);
void(*reset_trap_func)(void);
};
typedef struct interrupt_cpu_status_s interrupt_cpu_status_t;
/* Masks to extract information. */
#define OPINFO_DELAYS_INTERRUPT_MSK (1 << 8)
#define OPINFO_DISABLES_IRQ_MSK (1 << 9)
#define OPINFO_ENABLES_IRQ_MSK (1 << 10)
/* Return nonzero if `opinfo' causes a 1-cycle interrupt delay. */
#define OPINFO_DELAYS_INTERRUPT(opinfo) \
((opinfo) & OPINFO_DELAYS_INTERRUPT_MSK)
/* Return nonzero if `opinfo' has changed the I flag from 0 to 1, so that an
IRQ that happened 2 or more cycles before the end of the opcode should be
allowed. */
#define OPINFO_DISABLES_IRQ(opinfo) \
((opinfo) & OPINFO_DISABLES_IRQ_MSK)
/* Return nonzero if `opinfo' has changed the I flag from 1 to 0, so that an
IRQ that happened 2 or more cycles before the end of the opcode should not
be allowed. */
#define OPINFO_ENABLES_IRQ(opinfo) \
((opinfo) & OPINFO_ENABLES_IRQ_MSK)
/* Set the information for `opinfo'. `number' is the opcode number,
`delays_interrupt' must be non-zero if it causes a 1-cycle interrupt
delay, `disables_interrupts' must be non-zero if it disabled IRQs. */
#define OPINFO_SET(opinfo, \
number, delays_interrupt, disables_irq, enables_irq) \
((opinfo) = ((number) \
| ((delays_interrupt) ? OPINFO_DELAYS_INTERRUPT_MSK : 0) \
| ((disables_irq) ? OPINFO_DISABLES_IRQ_MSK : 0) \
| ((enables_irq) ? OPINFO_ENABLES_IRQ_MSK : 0)))
/* Set whether the opcode causes the 1-cycle interrupt delay according to
`delay'. */
#define OPINFO_SET_DELAYS_INTERRUPT(opinfo, delay) \
do { \
if ((delay)) \
(opinfo) |= OPINFO_DELAYS_INTERRUPT_MSK; \
} while (0)
/* Set whether the opcode disables previously enabled IRQs according to
`disable'. */
#define OPINFO_SET_DISABLES_IRQ(opinfo, disable) \
do { \
if ((disable)) \
(opinfo) |= OPINFO_DISABLES_IRQ_MSK; \
} while (0)
/* Set whether the opcode enables previously disabled IRQs according to
`enable'. */
#define OPINFO_SET_ENABLES_IRQ(opinfo, enable) \
do { \
if ((enable)) \
(opinfo) |= OPINFO_ENABLES_IRQ_MSK; \
} while (0)
typedef struct mos6510_regs_s {
unsigned int pc; /* `unsigned int' required by the drive code. */
BYTE a;
BYTE x;
BYTE y;
BYTE sp;
BYTE p;
BYTE n;
BYTE z;
} mos6510_regs_t;
typedef struct R65C02_regs_s
{
unsigned int pc;
BYTE a;
BYTE x;
BYTE y;
BYTE sp;
BYTE p;
BYTE n;
BYTE z;
} R65C02_regs_t;
#define DRIVE_RAM_SIZE 32768
typedef BYTE drive_read_func_t(struct drive_context_s *, WORD);
typedef void drive_store_func_t(struct drive_context_s *, WORD,
BYTE);
typedef struct drivecpud_context_s {
/* Drive RAM */
BYTE drive_ram[DRIVE_RAM_SIZE];
/* functions */
drive_read_func_t *read_func[0x101];
drive_store_func_t *store_func[0x101];
// drive_read_func_t *read_func_watch[0x101];
// drive_store_func_t *store_func_watch[0x101];
// drive_read_func_t *read_func_nowatch[0x101];
// drive_store_func_t *store_func_nowatch[0x101];
int sync_factor;
} drivecpud_context_t;
typedef struct drive_context_s {
int mynumber; /* init to [0123] */
CLOCK *clk_ptr; /* shortcut to drive_clk[mynumber] */
struct drivecpu_context_s *cpu;
struct drivecpud_context_s *cpud;
struct drivefunc_context_s *func;
} drive_context_t;
static int drive_trap_handler(drive_context_t *d)
{
return -1;
}
typedef struct drivecpu_context_s
{
int traceflg;
/* This is non-zero each time a Read-Modify-Write instructions that accesses
memory is executed. We can emulate the RMW bug of the 6502 this way. */
int rmw_flag; /* init to 0 */
/* Interrupt/alarm status. */
struct interrupt_cpu_status_s *int_status;
struct alarm_context_s *alarm_context;
/* Clk guard. */
struct clk_guard_s *clk_guard;
struct monitor_interface_s *monitor_interface;
/* Value of clk for the last time mydrive_cpu_execute() was called. */
CLOCK last_clk;
/* Number of cycles in excess we executed last time mydrive_cpu_execute()
was called. */
CLOCK last_exc_cycles;
CLOCK stop_clk;
CLOCK cycle_accum;
BYTE *d_bank_base;
unsigned int d_bank_start;
unsigned int d_bank_limit;
/* Information about the last executed opcode. */
unsigned int last_opcode_info;
/* Address of the last executed opcode. This is used by watchpoints. */
unsigned int last_opcode_addr;
/* Public copy of the registers. */
mos6510_regs_t cpu_regs;
// R65C02_regs_t cpu_R65C02_regs;
BYTE *pageone; /* init to NULL */
int monspace; /* init to e_disk[89]_space */
char *snap_module_name;
char *identification_string;
} drivecpu_context_t;
#define LOAD(a) (drv->cpud->read_func[(a) >> 8](drv, (WORD)(a)))
#define LOAD_ZERO(a) (drv->cpud->read_func[0](drv, (WORD)(a)))
#define LOAD_ADDR(a) (LOAD(a) | (LOAD((a) + 1) << 8))
#define LOAD_ZERO_ADDR(a) (LOAD_ZERO(a) | (LOAD_ZERO((a) + 1) << 8))
#define STORE(a, b) (drv->cpud->store_func[(a) >> 8](drv, (WORD)(a), \
(BYTE)(b)))
#define STORE_ZERO(a, b) (drv->cpud->store_func[0](drv, (WORD)(a), \
(BYTE)(b)))
#define JUMP(addr) \
#define P_SIGN 0x80
#define P_OVERFLOW 0x40
#define P_UNUSED 0x20
#define P_BREAK 0x10
#define P_DECIMAL 0x08
#define P_INTERRUPT 0x04
#define P_ZERO 0x02
#define P_CARRY 0x01
#define CPU_WDC65C02 0
#define CPU_R65C02 1
#define CPU_65SC02 2
#define CLK (*(drv->clk_ptr))
#define RMW_FLAG (cpu->rmw_flag)
#define PAGE_ONE (cpu->pageone)
#define LAST_OPCODE_INFO (cpu->last_opcode_info)
#define LAST_OPCODE_ADDR (cpu->last_opcode_addr)
#define TRACEFLG (debug.drivecpu_traceflg[drv->mynumber])
#define CPU_INT_STATUS (cpu->int_status)
#define ALARM_CONTEXT (cpu->alarm_context)
#define ROM_TRAP_ALLOWED() 1
#define ROM_TRAP_HANDLER() drive_trap_handler(drv)
#define CALLER (cpu->monspace)
#define DMA_FUNC drive_generic_dma()
#define DMA_ON_RESET
#define cpu_reset() (cpu_reset)(drv)
#define bank_limit (cpu->d_bank_limit)
#define bank_start (cpu->d_bank_start)
#define bank_base (cpu->d_bank_base)
/* WDC_STP() and WDC_WAI() are not used on the R65C02. */
#define WDC_STP()
#define WDC_WAI()
#define GLOBAL_REGS cpu->cpu_R65C02_regs
#define DRIVE_CPU
static void drive_generic_dma(void)
{
}
static void interrupt_trigger_dma(interrupt_cpu_status_t *cs, CLOCK cpu_clk)
{
cs->global_pending_int = (enum cpu_int)
(cs->global_pending_int | IK_DMA);
}
static void interrupt_ack_dma(interrupt_cpu_status_t *cs)
{
cs->global_pending_int = (enum cpu_int)
(cs->global_pending_int & ~IK_DMA);
}
static void interrupt_do_trap(interrupt_cpu_status_t *cs, WORD address)
{
cs->global_pending_int &= ~IK_TRAP;
cs->trap_func(address, cs->trap_data);
}
static void interrupt_ack_reset(interrupt_cpu_status_t *cs)
{
cs->global_pending_int &= ~IK_RESET;
if (cs->reset_trap_func)
cs->reset_trap_func();
}
static void interrupt_ack_nmi(interrupt_cpu_status_t *cs)
{
cs->global_pending_int =
(cs->global_pending_int & ~IK_NMI);
if (cs->nmi_trap_func) {
cs->nmi_trap_func();
}
}
static void interrupt_ack_irq(interrupt_cpu_status_t *cs)
{
cs->global_pending_int =
(cs->global_pending_int & ~IK_IRQPEND);
cs->irq_pending_clk = CLOCK_MAX;
}
static int interrupt_check_nmi_delay(interrupt_cpu_status_t *cs,
CLOCK cpu_clk)
{
CLOCK nmi_clk = cs->nmi_clk + INTERRUPT_DELAY;
/* Branch instructions delay IRQs and NMI by one cycle if branch
is taken with no page boundary crossing. */
if (OPINFO_DELAYS_INTERRUPT(*cs->last_opcode_info_ptr))
nmi_clk++;
if (cpu_clk >= nmi_clk)
return 1;
return 0;
}
static int interrupt_check_irq_delay(interrupt_cpu_status_t *cs,
CLOCK cpu_clk)
{
CLOCK irq_clk = cs->irq_clk + INTERRUPT_DELAY;
/* Branch instructions delay IRQs and NMI by one cycle if branch
is taken with no page boundary crossing. */
if (OPINFO_DELAYS_INTERRUPT(*cs->last_opcode_info_ptr))
irq_clk++;
/* If an opcode changes the I flag from 1 to 0, the 6510 needs
one more opcode before it triggers the IRQ routine. */
if (cpu_clk >= irq_clk) {
if (!OPINFO_ENABLES_IRQ(*cs->last_opcode_info_ptr)) {
return 1;
} else {
cs->global_pending_int |= IK_IRQPEND;
}
}
return 0;
}
struct alarm_context_s {
CLOCK next_pending_alarm_clk;
};
typedef struct alarm_context_s alarm_context_t;
static void alarm_context_dispatch(alarm_context_t *context, CLOCK cpu_clk)
{
}
static CLOCK alarm_context_next_pending_clk(alarm_context_t *context)
{
return context->next_pending_alarm_clk;
}
static void cpu_4510(void)
{
int cpu_type = CPU_R65C02;
drivecpu_context_t *cpu = NULL;
drive_context_t *drv = NULL;
#define reg_a (cpu->cpu_regs.a)
#define reg_x (cpu->cpu_regs.x)
#define reg_y (cpu->cpu_regs.y)
#define reg_pc (cpu->cpu_regs.pc)
#define reg_sp (cpu->cpu_regs.sp)
#define reg_p (cpu->cpu_regs.p)
#define flag_z (cpu->cpu_regs.z)
#define flag_n (cpu->cpu_regs.n)
#include "65c02core.cpp"
}
static void init_65c02(struct drive_context_s *drv)
{
drivecpu_context_t *cpu = drv->cpu;
cpu->rmw_flag = 0;
cpu->d_bank_limit = 0;
cpu->d_bank_start = 0;
cpu->pageone = NULL;
}
#endif

View File

@ -868,7 +868,7 @@ static void led_vsync (void)
led_cycles_off = 0; led_cycles_off = 0;
if (led_old_brightness != gui_data.powerled_brightness) { if (led_old_brightness != gui_data.powerled_brightness) {
gui_data.powerled = gui_data.powerled_brightness > 127; gui_data.powerled = gui_data.powerled_brightness > 127;
gui_led (LED_POWER, gui_data.powerled); gui_led (LED_POWER, gui_data.powerled, gui_data.powerled_brightness);
led_filter_audio (); led_filter_audio ();
} }
led_old_brightness = gui_data.powerled_brightness; led_old_brightness = gui_data.powerled_brightness;

View File

@ -711,7 +711,7 @@ static void reset_drive (int num)
drv->dskready_up_time = 0; drv->dskready_up_time = 0;
drv->buffered_cyl = -1; drv->buffered_cyl = -1;
drv->buffered_side = -1; drv->buffered_side = -1;
gui_led (num + LED_DF0, 0); gui_led (num + LED_DF0, 0, -1);
drive_settype_id (drv); drive_settype_id (drv);
_tcscpy (currprefs.floppyslots[num].df, changed_prefs.floppyslots[num].df); _tcscpy (currprefs.floppyslots[num].df, changed_prefs.floppyslots[num].df);
drv->newname[0] = 0; drv->newname[0] = 0;
@ -742,7 +742,7 @@ static void update_drive_gui (int num, bool force)
else else
gui_data.drive_side = side; gui_data.drive_side = side;
gui_data.drive_writing[num] = writ; gui_data.drive_writing[num] = writ;
gui_led (num + LED_DF0, (gui_data.drive_motor[num] ? 1 : 0) | (gui_data.drive_writing[num] ? 2 : 0)); gui_led (num + LED_DF0, (gui_data.drive_motor[num] ? 1 : 0) | (gui_data.drive_writing[num] ? 2 : 0), -1);
} }
static void drive_fill_bigbuf (drive * drv,int); static void drive_fill_bigbuf (drive * drv,int);

View File

@ -431,7 +431,7 @@ void gfxboard_vsync_handler (void)
monswitch_delay = 0; monswitch_delay = 0;
} }
if (monswitch_current && picasso_on) { if (!monswitch_delay && monswitch_current && picasso_on && picasso_requested_on) {
picasso_getwritewatch (vram_start_offset); picasso_getwritewatch (vram_start_offset);
if (fullrefresh) if (fullrefresh)
vga.vga.graphic_mode = -1; vga.vga.graphic_mode = -1;
@ -2308,6 +2308,7 @@ addrbank *gfxboard_init_memory (int devnum)
if (ISP4()) { if (ISP4()) {
int roms[] = { 91, -1 }; int roms[] = { 91, -1 };
struct romlist *rl = getromlistbyids(roms, NULL);
TCHAR path[MAX_DPATH]; TCHAR path[MAX_DPATH];
fetch_rompath (path, sizeof path / sizeof (TCHAR)); fetch_rompath (path, sizeof path / sizeof (TCHAR));
@ -2316,6 +2317,9 @@ addrbank *gfxboard_init_memory (int devnum)
if (!p4rom && currprefs.picassoivromfile[0]) if (!p4rom && currprefs.picassoivromfile[0])
p4rom = read_rom_name(currprefs.picassoivromfile); p4rom = read_rom_name(currprefs.picassoivromfile);
if (!p4rom && rl)
p4rom = read_rom(rl->rd);
if (!p4rom) { if (!p4rom) {
_tcscat (path, _T("picasso_iv_flash.rom")); _tcscat (path, _T("picasso_iv_flash.rom"));
p4rom = read_rom_name (path); p4rom = read_rom_name (path);

View File

@ -9,7 +9,7 @@
extern int gui_init (void); extern int gui_init (void);
extern int gui_update (void); extern int gui_update (void);
extern void gui_exit (void); extern void gui_exit (void);
extern void gui_led (int, int); extern void gui_led (int, int, int);
extern void gui_handle_events (void); extern void gui_handle_events (void);
extern void gui_filename (int, const TCHAR *); extern void gui_filename (int, const TCHAR *);
extern void gui_fps (int fps, int idle, int color); extern void gui_fps (int fps, int idle, int color);

View File

@ -1979,14 +1979,14 @@ static void allocate_memory (void)
} }
} }
if (mem25bit_bank.allocated != currprefs.mem25bit_size) { if (mem25bit_bank.allocated != currprefs.mem25bit_size) {
mapped_free (&mem25bit_bank); mapped_free(&mem25bit_bank);
mem25bit_bank.allocated = currprefs.mem25bit_size; mem25bit_bank.allocated = currprefs.mem25bit_size;
mem25bit_bank.mask = mem25bit_bank.allocated - 1; mem25bit_bank.mask = mem25bit_bank.allocated - 1;
mem25bit_bank.start = 0x01000000; mem25bit_bank.start = 0x01000000;
if (mem25bit_bank.allocated) { if (mem25bit_bank.allocated) {
if (!mapped_malloc (&mem25bit_bank)) { if (!mapped_malloc(&mem25bit_bank)) {
write_log (_T("Out of memory for 25 bit memory.\n")); write_log(_T("Out of memory for 25 bit memory.\n"));
mem25bit_bank.allocated = 0; mem25bit_bank.allocated = 0;
} }
} }
@ -2069,7 +2069,7 @@ static void allocate_memory (void)
if (bogomem_bank.allocated > 0) if (bogomem_bank.allocated > 0)
restore_ram (bogo_filepos, bogomem_bank.baseaddr); restore_ram (bogo_filepos, bogomem_bank.baseaddr);
if (mem25bit_bank.allocated > 0) if (mem25bit_bank.allocated > 0)
restore_ram (mem25bit_filepos, mem25bit_bank.baseaddr); restore_ram(mem25bit_filepos, mem25bit_bank.baseaddr);
if (a3000lmem_bank.allocated > 0) if (a3000lmem_bank.allocated > 0)
restore_ram (a3000lmem_filepos, a3000lmem_bank.baseaddr); restore_ram (a3000lmem_filepos, a3000lmem_bank.baseaddr);
if (a3000hmem_bank.allocated > 0) if (a3000hmem_bank.allocated > 0)
@ -2096,14 +2096,14 @@ static void fill_ce_banks (void)
memset (ce_banktype, CE_MEMBANK_FAST32, sizeof ce_banktype); memset (ce_banktype, CE_MEMBANK_FAST32, sizeof ce_banktype);
} }
// data cachable regions (2 = burst supported) // data cachable regions (2 = burst supported)
memset (ce_cachable, 0, sizeof ce_cachable); memset(ce_cachable, 0, sizeof ce_cachable);
memset (ce_cachable + (0x00200000 >> 16), 1 | 2, currprefs.fastmem_size >> 16); memset(ce_cachable + (0x00200000 >> 16), 1 | 2, currprefs.fastmem_size >> 16);
memset (ce_cachable + (0x00c00000 >> 16), 1, currprefs.bogomem_size >> 16); memset(ce_cachable + (0x00c00000 >> 16), 1, currprefs.bogomem_size >> 16);
memset (ce_cachable + (z3fastmem_bank.start >> 16), 1 | 2, currprefs.z3fastmem_size >> 16); memset(ce_cachable + (z3fastmem_bank.start >> 16), 1 | 2, currprefs.z3fastmem_size >> 16);
memset (ce_cachable + (z3fastmem2_bank.start >> 16), 1 | 2, currprefs.z3fastmem2_size >> 16); memset(ce_cachable + (z3fastmem2_bank.start >> 16), 1 | 2, currprefs.z3fastmem2_size >> 16);
memset (ce_cachable + (a3000hmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_high_size >> 16); memset(ce_cachable + (a3000hmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_high_size >> 16);
memset (ce_cachable + (a3000lmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_low_size >> 16); memset(ce_cachable + (a3000lmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_low_size >> 16);
memset (ce_cachable + (mem25bit_bank.start >> 16), 1 | 2, currprefs.mem25bit_size >> 16); memset(ce_cachable + (mem25bit_bank.start >> 16), 1 | 2, currprefs.mem25bit_size >> 16);
if (&get_mem_bank (0) == &chipmem_bank) { if (&get_mem_bank (0) == &chipmem_bank) {
for (i = 0; i < (0x200000 >> 16); i++) { for (i = 0; i < (0x200000 >> 16); i++) {
@ -2242,15 +2242,15 @@ void memory_clear (void)
if (savestate_state == STATE_RESTORE) if (savestate_state == STATE_RESTORE)
return; return;
if (chipmem_bank.baseaddr) if (chipmem_bank.baseaddr)
memset (chipmem_bank.baseaddr, 0, chipmem_bank.allocated); memset(chipmem_bank.baseaddr, 0, chipmem_bank.allocated);
if (bogomem_bank.baseaddr) if (bogomem_bank.baseaddr)
memset (bogomem_bank.baseaddr, 0, bogomem_bank.allocated); memset(bogomem_bank.baseaddr, 0, bogomem_bank.allocated);
if (mem25bit_bank.baseaddr) if (mem25bit_bank.baseaddr)
memset (mem25bit_bank.baseaddr, 0, mem25bit_bank.allocated); memset(mem25bit_bank.baseaddr, 0, mem25bit_bank.allocated);
if (a3000lmem_bank.baseaddr) if (a3000lmem_bank.baseaddr)
memset (a3000lmem_bank.baseaddr, 0, a3000lmem_bank.allocated); memset(a3000lmem_bank.baseaddr, 0, a3000lmem_bank.allocated);
if (a3000hmem_bank.baseaddr) if (a3000hmem_bank.baseaddr)
memset (a3000hmem_bank.baseaddr, 0, a3000hmem_bank.allocated); memset(a3000hmem_bank.baseaddr, 0, a3000hmem_bank.allocated);
expansion_clear (); expansion_clear ();
cpuboard_clear(); cpuboard_clear();
} }
@ -2449,11 +2449,11 @@ void memory_reset (void)
#endif #endif
if (mem25bit_bank.baseaddr) if (mem25bit_bank.baseaddr)
map_banks (&mem25bit_bank, mem25bit_bank.start >> 16, mem25bit_bank.allocated >> 16, 0); map_banks(&mem25bit_bank, mem25bit_bank.start >> 16, mem25bit_bank.allocated >> 16, 0);
if (a3000lmem_bank.baseaddr) if (a3000lmem_bank.baseaddr)
map_banks (&a3000lmem_bank, a3000lmem_bank.start >> 16, a3000lmem_bank.allocated >> 16, 0); map_banks(&a3000lmem_bank, a3000lmem_bank.start >> 16, a3000lmem_bank.allocated >> 16, 0);
if (a3000hmem_bank.baseaddr) if (a3000hmem_bank.baseaddr)
map_banks (&a3000hmem_bank, a3000hmem_bank.start >> 16, a3000hmem_bank.allocated >> 16, 0); map_banks(&a3000hmem_bank, a3000hmem_bank.start >> 16, a3000hmem_bank.allocated >> 16, 0);
#ifdef CDTV #ifdef CDTV
if (cardmem_bank.baseaddr) if (cardmem_bank.baseaddr)
map_banks (&cardmem_bank, cardmem_bank.start >> 16, cardmem_bank.allocated >> 16, 0); map_banks (&cardmem_bank, cardmem_bank.start >> 16, cardmem_bank.allocated >> 16, 0);
@ -2610,13 +2610,13 @@ void memory_init (void)
void memory_cleanup (void) void memory_cleanup (void)
{ {
mapped_free (&mem25bit_bank); mapped_free(&mem25bit_bank);
mapped_free (&a3000lmem_bank); mapped_free(&a3000lmem_bank);
mapped_free (&a3000hmem_bank); mapped_free(&a3000hmem_bank);
mapped_free (&bogomem_bank); mapped_free(&bogomem_bank);
mapped_free (&kickmem_bank); mapped_free(&kickmem_bank);
xfree (a1000_bootrom); xfree(a1000_bootrom);
mapped_free (&chipmem_bank); mapped_free(&chipmem_bank);
#ifdef CDTV #ifdef CDTV
if (cardmem_bank.baseaddr) { if (cardmem_bank.baseaddr) {
cdtv_savecardmem (cardmem_bank.baseaddr, cardmem_bank.allocated); cdtv_savecardmem (cardmem_bank.baseaddr, cardmem_bank.allocated);

View File

@ -1420,7 +1420,7 @@ void rp_fixup_options (struct uae_prefs *p)
rp_turbo_cpu (currprefs.turbo_emulation); rp_turbo_cpu (currprefs.turbo_emulation);
rp_turbo_floppy (currprefs.floppy_speed == 0); rp_turbo_floppy (currprefs.floppy_speed == 0);
for (i = 0; i <= 4; i++) for (i = 0; i <= 4; i++)
rp_update_leds (i, 0, 0); rp_update_leds (i, 0, -1, 0);
set_config_changed (); set_config_changed ();
} }
@ -1543,7 +1543,7 @@ void rp_floppy_track (int floppy, int track)
RPPostMessagex (RP_IPC_TO_HOST_DEVICESEEK, MAKEWORD (RP_DEVICECATEGORY_FLOPPY, floppy), track, &guestinfo); RPPostMessagex (RP_IPC_TO_HOST_DEVICESEEK, MAKEWORD (RP_DEVICECATEGORY_FLOPPY, floppy), track, &guestinfo);
} }
void rp_update_leds (int led, int onoff, int write) void rp_update_leds (int led, int onoff, int brightness, int write)
{ {
static int oldled[5]; static int oldled[5];
int ledstate; int ledstate;
@ -1554,10 +1554,12 @@ void rp_update_leds (int led, int onoff, int write)
return; return;
if (onoff < 0) if (onoff < 0)
return; return;
if (brightness < 0)
brightness = onoff ? 250 : 0;
switch (led) switch (led)
{ {
case LED_POWER: case LED_POWER:
ledstate = onoff >= 250 ? 100 : onoff * 5 / 26 + 49; ledstate = brightness >= 250 ? 100 : brightness * 5 / 26 + 49;
if (ledstate == oldled[led]) if (ledstate == oldled[led])
return; return;
oldled[led] = ledstate; oldled[led] = ledstate;

View File

@ -33,7 +33,7 @@ extern void rp_cd_image_change (int num, const TCHAR *name);
extern void rp_update_gameport (int port, int mask, int onoff); extern void rp_update_gameport (int port, int mask, int onoff);
extern void rp_update_volume (struct uae_prefs*); extern void rp_update_volume (struct uae_prefs*);
extern void rp_update_leds (int, int, int); extern void rp_update_leds (int, int, int, int);
extern void rp_floppy_track (int floppy, int track); extern void rp_floppy_track (int floppy, int track);
extern void rp_hd_activity (int, int, int); extern void rp_hd_activity (int, int, int);
extern void rp_cd_activity (int, int); extern void rp_cd_activity (int, int);

View File

@ -2305,7 +2305,7 @@ bool handle_events (void)
was_paused = pause_emulation; was_paused = pause_emulation;
manual_painting_needed++; manual_painting_needed++;
gui_fps (0, 0, 0); gui_fps (0, 0, 0);
gui_led (LED_SND, 0); gui_led (LED_SND, 0, -1);
} }
MsgWaitForMultipleObjects (0, NULL, FALSE, 100, QS_ALLINPUT); MsgWaitForMultipleObjects (0, NULL, FALSE, 100, QS_ALLINPUT);
while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) { while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {

View File

@ -20,12 +20,12 @@
#define LANG_DLL_FULL_VERSION_MATCH 1 #define LANG_DLL_FULL_VERSION_MATCH 1
#if WINUAEPUBLICBETA #if WINUAEPUBLICBETA
#define WINUAEBETA _T("6") #define WINUAEBETA _T("7")
#else #else
#define WINUAEBETA _T("") #define WINUAEBETA _T("")
#endif #endif
#define WINUAEDATE MAKEBD(2015, 8, 1) #define WINUAEDATE MAKEBD(2015, 8, 12)
//#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("AmiKit Preview")
//#define WINUAEEXTRA _T("Amiga Forever Edition") //#define WINUAEEXTRA _T("Amiga Forever Edition")

View File

@ -1744,13 +1744,13 @@ static int open_windows (bool mousecapture)
if (upd > 1) { if (upd > 1) {
for (i = 0; i < NUM_LEDS; i++) for (i = 0; i < NUM_LEDS; i++)
gui_flicker_led (i, -1, -1); gui_flicker_led (i, -1, -1);
gui_led (LED_POWER, gui_data.powerled); gui_led (LED_POWER, gui_data.powerled, gui_data.powerled_brightness);
gui_fps (0, 0, 0); gui_fps (0, 0, 0);
if (gui_data.md >= 0) if (gui_data.md >= 0)
gui_led (LED_MD, 0); gui_led (LED_MD, 0, -1);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (currprefs.floppyslots[i].dfxtype >= 0) if (currprefs.floppyslots[i].dfxtype >= 0)
gui_led (LED_DF0 + i, 0); gui_led (LED_DF0 + i, 0, -1);
} }
} }
if (upd > 0) { if (upd > 0) {

View File

@ -1707,6 +1707,7 @@ static void show_rom_list (void)
110, -1, -1, // GVP G-Force 030 110, -1, -1, // GVP G-Force 030
114, -1, -1, // A3001 114, -1, -1, // A3001
126, -1, -1, // Golem 030 126, -1, -1, // Golem 030
144, -1, -1, // E-Matrix 530
89, -1, -1, // 1230-IV 89, -1, -1, // 1230-IV
89, -1, 94, -1, -1, // 1230-IV SCSI 89, -1, 94, -1, -1, // 1230-IV SCSI
90, -1, -1, // 1260 90, -1, -1, // 1260
@ -1759,6 +1760,7 @@ static void show_rom_list (void)
_T("GVP G-FORCE 030\0") _T("GVP G-FORCE 030\0")
_T("GVP A3001 Series I\0") _T("GVP A3001 Series I\0")
_T("Kupke Golem 030\0") _T("Kupke Golem 030\0")
_T("M-Tec E-Matrix 530\0")
_T("Blizzard 1230-IV\0Blizzard 1260\0") _T("Blizzard 1230-IV\0Blizzard 1260\0")
_T("Blizzard 1230-IV/SCSI\0Blizzard 1260/SCSI\0") _T("Blizzard 1230-IV/SCSI\0Blizzard 1260/SCSI\0")
_T("Blizzard 2060\0Warp Engine\0TekMagic 2040/2060\0") _T("Blizzard 2060\0Warp Engine\0TekMagic 2040/2060\0")
@ -7738,8 +7740,9 @@ static void setcpuboardmemsize(HWND hDlg)
if (cpuboard_memorytype(&workprefs) == BOARD_MEMORY_25BITMEM) { if (cpuboard_memorytype(&workprefs) == BOARD_MEMORY_25BITMEM) {
workprefs.mem25bit_size = workprefs.cpuboardmem1_size; workprefs.mem25bit_size = workprefs.cpuboardmem1_size;
} }
if (workprefs.cpuboard_type == 0) if (workprefs.cpuboard_type == 0) {
workprefs.mem25bit_size = 0; workprefs.mem25bit_size = 0;
}
if (cpuboard_memorytype(&workprefs) == BOARD_MEMORY_HIGHMEM) if (cpuboard_memorytype(&workprefs) == BOARD_MEMORY_HIGHMEM)
workprefs.mbresmem_high_size = workprefs.cpuboardmem1_size; workprefs.mbresmem_high_size = workprefs.cpuboardmem1_size;
@ -8827,6 +8830,8 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
case IDC_A2065: case IDC_A2065:
if (ischecked(hDlg, IDC_A2065)) { if (ischecked(hDlg, IDC_A2065)) {
_tcscpy(workprefs.a2065name, _T("none")); _tcscpy(workprefs.a2065name, _T("none"));
workprefs.ne2000pciname[0] = 0;
setchecked(hDlg, IDC_NE2000, false);
expansion_net(hDlg); expansion_net(hDlg);
enable_for_expansion2dlg(hDlg); enable_for_expansion2dlg(hDlg);
} else { } else {
@ -8839,6 +8844,8 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
case IDC_NE2000: case IDC_NE2000:
if (ischecked(hDlg, IDC_NE2000)) { if (ischecked(hDlg, IDC_NE2000)) {
_tcscpy(workprefs.ne2000pciname, _T("none")); _tcscpy(workprefs.ne2000pciname, _T("none"));
workprefs.a2065name[0] = 0;
setchecked(hDlg, IDC_A2065, false);
expansion_net(hDlg); expansion_net(hDlg);
enable_for_expansion2dlg(hDlg); enable_for_expansion2dlg(hDlg);
} else { } else {
@ -8859,15 +8866,33 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
if (!workprefs.sound_toccata) if (!workprefs.sound_toccata)
workprefs.sound_toccata_mixer = false; workprefs.sound_toccata_mixer = false;
enable_for_expansion2dlg(hDlg); enable_for_expansion2dlg(hDlg);
if (workprefs.sound_toccata && (workprefs.sound_fm801 || workprefs.sound_es1370)) {
workprefs.sound_fm801 = 0;
workprefs.sound_es1370 = 0;
}
break; break;
case IDC_CS_TOCCATAMIXER: case IDC_CS_TOCCATAMIXER:
workprefs.sound_toccata_mixer = ischecked(hDlg, IDC_CS_TOCCATAMIXER) ? 1 : 0; workprefs.sound_toccata_mixer = ischecked(hDlg, IDC_CS_TOCCATAMIXER) ? 1 : 0;
break; break;
case IDC_CS_ES1370: case IDC_CS_ES1370:
workprefs.sound_es1370 = ischecked(hDlg, IDC_CS_ES1370) ? 1 : 0; workprefs.sound_es1370 = ischecked(hDlg, IDC_CS_ES1370) ? 1 : 0;
if (workprefs.sound_es1370 && (workprefs.sound_fm801 || workprefs.sound_toccata)) {
workprefs.sound_fm801 = 0;
workprefs.sound_toccata = 0;
workprefs.sound_toccata_mixer = false;
values_to_expansion2dlg(hDlg);
enable_for_expansion2dlg(hDlg);
}
break; break;
case IDC_CS_FM801: case IDC_CS_FM801:
workprefs.sound_fm801 = ischecked(hDlg, IDC_CS_FM801) ? 1 : 0; workprefs.sound_fm801 = ischecked(hDlg, IDC_CS_FM801) ? 1 : 0;
if (workprefs.sound_fm801 && (workprefs.sound_es1370 || workprefs.sound_toccata)) {
workprefs.sound_es1370 = 0;
workprefs.sound_toccata = 0;
workprefs.sound_toccata_mixer = false;
values_to_expansion2dlg(hDlg);
enable_for_expansion2dlg(hDlg);
}
break; break;
case IDC_SCSIROMSELECTED: case IDC_SCSIROMSELECTED:
values_from_expansion2dlg(hDlg); values_from_expansion2dlg(hDlg);
@ -8968,10 +8993,16 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
v--; v--;
s = ndd[v]->name; s = ndd[v]->name;
} }
if (ischecked(hDlg, IDC_A2065)) if (ischecked(hDlg, IDC_A2065)) {
_tcscpy(workprefs.a2065name, s); _tcscpy(workprefs.a2065name, s);
if (ischecked(hDlg, IDC_NE2000)) workprefs.ne2000pciname[0] = 0;
setchecked(hDlg, IDC_NE2000, false);
}
if (ischecked(hDlg, IDC_NE2000)) {
_tcscpy(workprefs.ne2000pciname, s); _tcscpy(workprefs.ne2000pciname, s);
workprefs.a2065name[0] = 0;
setchecked(hDlg, IDC_A2065, false);
}
} }
break; break;
} }
@ -18903,16 +18934,16 @@ static void gui_flicker_led2 (int led, int unitnum, int status)
old = *p; old = *p;
if (status < 0) { if (status < 0) {
if (old < 0) { if (old < 0) {
gui_led (led, -1); gui_led (led, -1, -1);
} else { } else {
gui_led (led, 0); gui_led (led, 0, -1);
} }
return; return;
} }
if (status == 0 && old < 0) { if (status == 0 && old < 0) {
*p = 0; *p = 0;
resetcounter[led] = 0; resetcounter[led] = 0;
gui_led (led, 0); gui_led (led, 0, -1);
return; return;
} }
if (status == 0) { if (status == 0) {
@ -18931,7 +18962,7 @@ static void gui_flicker_led2 (int led, int unitnum, int status)
*p = status; *p = status;
resetcounter[led] = 6; resetcounter[led] = 6;
if (old != *p) if (old != *p)
gui_led (led, *p); gui_led (led, *p, -1);
} }
void gui_flicker_led (int led, int unitnum, int status) void gui_flicker_led (int led, int unitnum, int status)
@ -18951,13 +18982,13 @@ void gui_fps (int fps, int idle, int color)
gui_data.fps = fps; gui_data.fps = fps;
gui_data.idle = idle; gui_data.idle = idle;
gui_data.fps_color = color; gui_data.fps_color = color;
gui_led (LED_FPS, 0); gui_led (LED_FPS, 0, -1);
gui_led (LED_CPU, 0); gui_led (LED_CPU, 0, -1);
gui_led (LED_SND, (gui_data.sndbuf_status > 1 || gui_data.sndbuf_status < 0) ? 0 : 1); gui_led (LED_SND, (gui_data.sndbuf_status > 1 || gui_data.sndbuf_status < 0) ? 0 : 1, -1);
} }
#define LED_STRING_WIDTH 40 #define LED_STRING_WIDTH 40
void gui_led (int led, int on) void gui_led (int led, int on, int brightness)
{ {
WORD type; WORD type;
static TCHAR drive_text[NUM_LEDS * LED_STRING_WIDTH]; static TCHAR drive_text[NUM_LEDS * LED_STRING_WIDTH];
@ -18976,7 +19007,7 @@ void gui_led (int led, int on)
rp_floppy_track (led - LED_DF0, gui_data.drive_track[led - LED_DF0]); rp_floppy_track (led - LED_DF0, gui_data.drive_track[led - LED_DF0]);
writing = gui_data.drive_writing[led - LED_DF0]; writing = gui_data.drive_writing[led - LED_DF0];
} }
rp_update_leds (led, on, writing); rp_update_leds (led, on, brightness, writing);
#endif #endif
if (!hStatusWnd) if (!hStatusWnd)
return; return;

View File

@ -1,4 +1,36 @@
Beta 7:
- 68030 prefetch/ce mode now also uses improved prefetch pipeline emulation.
- b4 prefetch RTS (and others) special case does not exist, my original test must have been broken.
- GUI won't anymore allow multiple sound or network cards enabled at the same. (It has never been
supported configuration)
- Cirrus Logic out of bounds VRAM access check improved.
- Picasso IV ROM loader update didn't support all old ROM paths (b6)
- SCSI Unit Attention (bus reset/media change) status handling should be now exactly as described in
SCSI spec. (Roctec Rochard v2 boot ROM*)
- A1060 Diagnostics and 8087 jumper was inverted.
- Continuing WD SCSI transfer with another Select and Transfer when previous SaT had already transferred
all buffered data: new SaT restarted from beginning. (A590/A2091 omniscsi.device + cdfs)
- Config file loaded with non-existing *_rom_file_id: rom key file ("rom" with ID=0) was selected.
- M-Tec E-Matrix 530 accelerator board added (Thanks to Jozsef Vamosi)
Rochard RH800C with v2 boot ROM:
- Supports both SCSI and IDE. v1 is IDE only.
- Has crazy "Is drive ready?" polling routine, driver executes 300 (!) TEST UNIT READY commands in
CPU loop per LUN (timer.device exists for a reason..), with single SCSI drive, driver executes total
6*300=1800 TUR commands during drive detection! (I recommend not to enable scsi logging..)
- ROM not yet added.
M-Tec E-Matrix 530:
- ROM image is software dumped (chip is not socketed), ROM layout (single chip contains two logical
autoconfig boot ROMs) may not match real ROM dump.
- 53C94 based SCSI. Fake DMA, 2*long word wide data port. Whole transfer loop runs in level 2
interrupt routine..
- Boot ROM requires KS2.0+ only because it calls CacheControl() without checking ROM version.
Beta 6:
- Bridgeboard floppy drive motor and click sound supported. - Bridgeboard floppy drive motor and click sound supported.
- x86 CPU status string was visible even when bridgeboard was not active. - x86 CPU status string was visible even when bridgeboard was not active.
- Added software readable A4091 DIP switches and Warp Engine SCSI jumpers to GUI. Note that default - Added software readable A4091 DIP switches and Warp Engine SCSI jumpers to GUI. Note that default

View File

@ -513,6 +513,10 @@ void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val)
break; break;
case CMD_RESET: case CMD_RESET:
esp_soft_reset(s); esp_soft_reset(s);
// E-Matrix 530 detects existence of SCSI chip by
// writing CMD_RESET and then immediately checking
// if it reads back.
s->rregs[saddr] = CMD_RESET;
break; break;
case CMD_BUSRESET: case CMD_BUSRESET:
s->rregs[ESP_RINTR] = INTR_RST; s->rregs[ESP_RINTR] = INTR_RST;

View File

@ -102,6 +102,20 @@ STATIC_INLINE uae_u8 FIRGB(struct vidbuffer *src, uae_u8 *dataline)
return v; return v;
} }
STATIC_INLINE uae_u8 DCTV_FIRBG(struct vidbuffer *src, uae_u8 *dataline)
{
uae_u8 v = 0;
if (FI(src, dataline))
v |= 0x40;
if (FR(src, dataline))
v |= 0x10;
if (FB(src, dataline))
v |= 0x04;
if (FG(src, dataline))
v |= 0x01;
return v;
}
STATIC_INLINE void PRGB(struct vidbuffer *dst, uae_u8 *dataline, uae_u8 r, uae_u8 g, uae_u8 b) STATIC_INLINE void PRGB(struct vidbuffer *dst, uae_u8 *dataline, uae_u8 r, uae_u8 g, uae_u8 b)
{ {
if (dst->pixbytes == 4) { if (dst->pixbytes == 4) {
@ -171,73 +185,6 @@ static void clearmonitor(struct vidbuffer *dst)
} }
} }
static bool dctv(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines)
{
int y, x, vdbl, hdbl;
int ystart, yend, isntsc;
int xadd;
isntsc = (beamcon0 & 0x20) ? 0 : 1;
if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
isntsc = currprefs.ntscmode ? 1 : 0;
vdbl = gfxvidinfo.ychange;
hdbl = gfxvidinfo.xchange;
xadd = ((1 << 1) / hdbl) * src->pixbytes;
ystart = isntsc ? VBLANK_ENDLINE_NTSC : VBLANK_ENDLINE_PAL;
yend = isntsc ? MAXVPOS_NTSC : MAXVPOS_PAL;
oddlines = 1;
uae_u8 r, g, b;
for (y = ystart; y < yend; y += 2) {
int yoff = (((y * 2 + oddlines) - src->yoffset) / vdbl);
if (yoff < 0)
continue;
if (yoff >= src->inheight)
continue;
uae_u8 *line = src->bufmem + yoff * src->rowbytes;
uae_u8 *dstline = dst->bufmem + (((y * 2 + oddlines) - dst->yoffset) / vdbl) * dst->rowbytes;
if (y < 60) {
write_log(_T("%d:\n"), y);
for (x = 22; x < 300; x += 1) {
uae_u8 *s = line + ((x << 1) / hdbl) * src->pixbytes;
write_log(_T("%01x"), FIRGB(src, s));
}
write_log(_T("*\n"));
for (x = 21; x < 300; x += 1) {
uae_u8 *s = line + ((x << 1) / hdbl) * src->pixbytes;
write_log(_T("%01x"), FIRGB(src, s));
}
write_log(_T("\n"));
}
for (x = 1; x < src->inwidth; x += 4) {
uae_u8 *s = line + ((x << 1) / hdbl) * src->pixbytes;
uae_u8 *d = dstline + ((x << 1) / hdbl) * dst->pixbytes;
uae_u8 *s2 = s + src->rowbytes;
uae_u8 *d2 = d + dst->rowbytes;
uae_u8 newval = FIRGB(src, s);
r = newval << 4;
g = newval << 4;
b = newval << 4;
for (int xx = 0; xx < 4; xx++) {
PRGB(dst, d + dst->pixbytes * xx, r, g, b);
PRGB(dst, d + dst->rowbytes + dst->pixbytes * xx, r, g, b);
}
}
}
dst->nativepositioning = true;
return true;
}
static void blank_generic(struct vidbuffer *src, struct vidbuffer *dst, int oddlines) static void blank_generic(struct vidbuffer *src, struct vidbuffer *dst, int oddlines)
{ {
int y, vdbl; int y, vdbl;
@ -263,6 +210,197 @@ static void blank_generic(struct vidbuffer *src, struct vidbuffer *dst, int oddl
} }
} }
static uae_s8 dctv_chroma[1600];
static uae_u8 dctv_luma[1600];
static const uae_u16 dctv_tables[] = {
0xF9AF, 0xF9C9, 0xF9E2, 0xF9FC, 0xFA15, 0xFA2F, 0xFA48, 0xFA62,
0xFA7B, 0xFA95, 0xFAAE, 0xFAC8, 0xFAE1, 0xFAFB, 0xFB14, 0xFB2E,
0xFB47, 0xFB61, 0xFB7A, 0xFB94, 0xFBAD, 0xFBC7, 0xFBE0, 0xFBFA,
0xFC13, 0xFC2D, 0xFC46, 0xFC60, 0xFC79, 0xFC93, 0xFCAC, 0xFCC6,
0xFCDF, 0xFCF9, 0xFD12, 0xFD2C, 0xFD45, 0xFD5F, 0xFD78, 0xFD92,
0xFDAB, 0xFDC5, 0xFDDE, 0xFDF8, 0xFE11, 0xFE2B, 0xFE44, 0xFE5E,
0xFE77, 0xFE91, 0xFEAA, 0xFEC4, 0xFEDD, 0xFEF7, 0xFF10, 0xFF2A,
0xFF43, 0xFF5D, 0xFF76, 0xFF90, 0xFFA9, 0xFFC3, 0xFFDC, 0xFFF6,
0x000F, 0x0029, 0x0042, 0x005C, 0x0075, 0x008F, 0x00A8, 0x00C2,
0x00DB, 0x00F5, 0x010E, 0x0128, 0x0141, 0x015B, 0x0174, 0x018E,
0x01A7, 0x01C1, 0x01DA, 0x01F4, 0x020D, 0x0227, 0x0240, 0x025A,
0x0273, 0x028D, 0x02A6, 0x02C0, 0x02D9, 0x02F3, 0x030C, 0x0326,
0x033F, 0x0359, 0x0372, 0x038C, 0x03A5, 0x03BF, 0x03D8, 0x03F2,
0x040B, 0x0425, 0x043E, 0x0458, 0x0471, 0x048B, 0x04A4, 0x04BE,
0x04D7, 0x04F1, 0x050A, 0x0524, 0x053D, 0x0557, 0x0570, 0x058A,
0x05A3, 0x05BD, 0x05D6, 0x05F0, 0x0609, 0x0623, 0x063C, 0x0656,
0x066F, 0x0689, 0x06A2, 0x06BC, 0x06D5, 0x06EF, 0x0708, 0x0722,
0x073B, 0x0755, 0x076E, 0x0788, 0x07A1, 0x07BB, 0x07D4, 0x07EE,
0x0807, 0x0821, 0x083A, 0x0854, 0x086D, 0x0887, 0x08A0, 0x08BA,
0x08D3, 0x08ED, 0x0906, 0x0920, 0x0939, 0x0953, 0x096C, 0x0986,
0x099F, 0x09B9, 0x09D2, 0x09EC, 0x0A05, 0x0A1F, 0x0A38, 0x0A52,
0x0A6B, 0x0A85, 0x0A9E, 0x0AB8, 0x0AD1, 0x0AEB, 0x0B04, 0x0B1E,
0x0B37, 0x0B51, 0x0B6A, 0x0B84, 0x0B9D, 0x0BB7, 0x0BD0, 0x0BEA,
0x0C03, 0x0C1D, 0x0C36, 0x0C50, 0x0C69, 0x0C83, 0x0C9C, 0x0CB6,
0x0CCF, 0x0CE9, 0x0D02, 0x0D1C, 0x0D35, 0x0D4F, 0x0D68, 0x0D82,
0x0D9B, 0x0DB5, 0x0DCE, 0x0DE8, 0x0E01, 0x0E1B, 0x0E34, 0x0E4E,
0x0E67, 0x0E81, 0x0E9A, 0x0EB4, 0x0ECD, 0x0EE7, 0x0F00, 0x0F1A,
0x0F33, 0x0F4D, 0x0F66, 0x0F80, 0x0F99, 0x0FB3, 0x0FCC, 0x0FE6,
0x0FFF, 0x1019, 0x1032, 0x104C, 0x1065, 0x107F, 0x1098, 0x10B2,
0x10CB, 0x10E5, 0x10FE, 0x1118, 0x1131, 0x114B, 0x1164, 0x117E,
0x1197, 0x11B1, 0x11CA, 0x11E4, 0x11FD, 0x1217, 0x1230, 0x124A,
0x1263, 0x127D, 0x1296, 0x12B0, 0x12C9, 0x12E3, 0x12FC, 0x1316
};
STATIC_INLINE int minmax(int v, int min, int max)
{
if (v < min)
v = min;
if (v > max)
v = max;
return v;
}
static bool dctv(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines)
{
int y, x, vdbl, hdbl;
int ystart, yend, isntsc;
int xadd;
isntsc = (beamcon0 & 0x20) ? 0 : 1;
if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
isntsc = currprefs.ntscmode ? 1 : 0;
vdbl = gfxvidinfo.ychange;
hdbl = gfxvidinfo.xchange;
xadd = ((1 << 1) / hdbl) * src->pixbytes;
ystart = isntsc ? VBLANK_ENDLINE_NTSC : VBLANK_ENDLINE_PAL;
yend = isntsc ? MAXVPOS_NTSC : MAXVPOS_PAL;
oddlines = 1;
memset(dctv_luma, 0x40, sizeof dctv_luma);
int signature_detected = -1;
int signature_x = -1;
int linenr = 0;
uae_u8 r, g, b;
for (y = ystart; y < yend; y++) {
int yoff = (((y * 2 + oddlines) - src->yoffset) / vdbl);
if (yoff < 0)
continue;
if (yoff >= src->inheight)
continue;
uae_u8 *line = src->bufmem + yoff * src->rowbytes;
uae_u8 *dstline = dst->bufmem + (((y * 2 + oddlines) - dst->yoffset) / vdbl) * dst->rowbytes;
#if 0
if (y < 60) {
write_log(_T("%d:\n"), y);
for (x = 22; x < 300; x += 1) {
uae_u8 *s = line + ((x << 1) / hdbl) * src->pixbytes;
write_log(_T("%01x"), FIRGB(src, s));
}
write_log(_T("*\n"));
for (x = 21; x < 300; x += 1) {
uae_u8 *s = line + ((x << 1) / hdbl) * src->pixbytes;
write_log(_T("%01x"), FIRGB(src, s));
}
write_log(_T("\n"));
}
#endif
int signature_cnt = -1;
bool signature_line = false;
int firstnz = -1;
bool sign = false;
int oddeven = 0;
uae_u8 prev = 0;
uae_u8 vals[3] = { 0x40, 0x40, 0x40 };
int chrsum = 0;
uae_s8 *chrbuf = dctv_chroma + 10;
uae_u8 *lumabuf = dctv_luma + 10;
int zigzagoffset = 0;
int prevtval = 0;
for (x = 0; x < src->inwidth; x++) {
uae_u8 *s = line + ((x << 1) / hdbl) * src->pixbytes;
uae_u8 *d = dstline + ((x << 1) / hdbl) * dst->pixbytes + zigzagoffset;
uae_u8 *s2 = s + src->rowbytes;
uae_u8 *d2 = d + dst->rowbytes;
uae_u8 newval = DCTV_FIRBG(src, s);
uae_u8 val = prev | newval;
if (firstnz < 0 && newval) {
firstnz = 0;
if (newval == 0x14) {
zigzagoffset = -1 * dst->pixbytes;
oddeven = -2;
} else {
zigzagoffset = 0;
oddeven = -2;
}
}
if (oddeven > 0) {
if (!val)
val = 64;
int tval = minmax(val, 64, 224);
if (tval != val)
tval = prevtval;
prevtval = tval;
uae_s16 luma = (uae_s16)dctv_tables[tval];
tval = minmax(luma / 16, 0, 255);
uae_u8 v1 = (uae_u8)tval;
r = b = g = v1;
if (val < 64) {
r = 0x80 + val * 2;
b = g = 0;
} else if (val > 224) {
r = b = 0;
g = 0x80 + (val - 224) * 2;
}
sign = !sign;
PRGB(dst, d - dst->pixbytes, r, g, b);
PRGB(dst, d, r, g, b);
if (doublelines) {
PRGB(dst, d2 - dst->pixbytes, r, g, b);
PRGB(dst, d2, r, g, b);
}
}
if (oddeven >= 0)
oddeven = oddeven ? 0 : 1;
else
oddeven++;
prev = newval << 1;
}
}
dst->nativepositioning = true;
return true;
}
static bool do_dctv(struct vidbuffer *src, struct vidbuffer *dst)
{
bool v;
if (interlace_seen) {
if (currprefs.gfx_iscanlines) {
v = dctv(src, dst, false, lof_store ? 0 : 1);
if (v && currprefs.gfx_iscanlines > 1)
blank_generic(src, dst, lof_store ? 1 : 0);
} else {
v = dctv(src, dst, false, 0);
v |= dctv(src, dst, false, 1);
}
} else {
v = dctv(src, dst, true, 0);
}
return v;
}
static uae_u8 *sm_frame_buffer; static uae_u8 *sm_frame_buffer;
#define SM_VRAM_WIDTH 1024 #define SM_VRAM_WIDTH 1024
#define SM_VRAM_HEIGHT 800 #define SM_VRAM_HEIGHT 800
@ -1782,7 +1920,7 @@ static bool emulate_specialmonitors2(struct vidbuffer *src, struct vidbuffer *ds
} else if (currprefs.monitoremu == MONITOREMU_GRAFFITI) { } else if (currprefs.monitoremu == MONITOREMU_GRAFFITI) {
return graffiti(src, dst); return graffiti(src, dst);
} else if (currprefs.monitoremu == MONITOREMU_DCTV) { } else if (currprefs.monitoremu == MONITOREMU_DCTV) {
return dctv(src, dst, false, 0); return do_dctv(src, dst);
} else if (currprefs.monitoremu == MONITOREMU_HAM_E || currprefs.monitoremu == MONITOREMU_HAM_E_PLUS) { } else if (currprefs.monitoremu == MONITOREMU_HAM_E || currprefs.monitoremu == MONITOREMU_HAM_E_PLUS) {
return do_hame(src, dst); return do_hame(src, dst);
} else if (currprefs.monitoremu == MONITOREMU_VIDEODAC18) { } else if (currprefs.monitoremu == MONITOREMU_VIDEODAC18) {

View File

@ -2970,7 +2970,7 @@ addrbank *x86_bridge_init(struct romconfig *rc, int type)
load_vga_bios(); load_vga_bios();
} }
xb->pc_jumpers = (xb->settings & 0xff) ^ ((0x80 | 0x40) | (0x20 | 0x10)); xb->pc_jumpers = (xb->settings & 0xff) ^ ((0x80 | 0x40) | (0x20 | 0x10 | 0x01 | 0x02));
int ramsize = (xb->settings >> 2) & 3; int ramsize = (xb->settings >> 2) & 3;
switch(ramsize) { switch(ramsize) {