From: Toni Wilen Date: Sun, 7 Jul 2013 15:24:56 +0000 (+0300) Subject: 2700b1 X-Git-Tag: 2700~17 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=251b2f77af88c0f9777db9b3ac4c045437fc8c61;p=francis%2Fwinuae.git 2700b1 --- diff --git a/a2065.cpp b/a2065.cpp index 3d735f84..0d270693 100644 --- a/a2065.cpp +++ b/a2065.cpp @@ -15,13 +15,14 @@ #include "custom.h" #include "newcpu.h" #include "a2065.h" -#include "win32_uaenet.h" +#include "ethernet.h" #include "crc32.h" #include "savestate.h" #include "autoconf.h" #define DUMPPACKET 0 +#define MEM_MIN 0x8100 int log_a2065 = 0; static int log_transmit = 1; static int log_receive = 1; @@ -51,7 +52,7 @@ static uae_u64 am_ladrf; static uae_u32 am_rdr, am_rdr_rlen, am_rdr_rdra; static uae_u32 am_tdr, am_tdr_tlen, am_tdr_tdra; static int tdr_offset, rdr_offset; -static int byteswap, prom, fakeprom; +static int dbyteswap, prom, fakeprom; static uae_u8 fakemac[6], realmac[6]; static uae_u8 broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -110,6 +111,20 @@ static uae_u8 broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; #define RX_STP 0x0200 #define RX_ENP 0x0100 +static uae_u16 gword2 (uae_u8 *p) +{ + return (p[0] << 8) | p[1]; +} +static uae_u16 gword (uae_u8 *p) +{ + return (p[0] << 8) | p[1]; +} +static void pword (uae_u8 *p, uae_u16 v) +{ + p[0] = v >> 8; + p[1] = v; +} + static void ew (int addr, uae_u32 value) { addr &= 0xffff; @@ -127,9 +142,10 @@ void a2065_reset (void) am_initialized = 0; csr[0] = CSR0_STOP; csr[1] = csr[2] = csr[3] = 0; + dbyteswap = 0; rap = 0; - uaenet_close (sysdata); + ethernet_close (td, sysdata); xfree (sysdata); sysdata = NULL; td = NULL; @@ -357,10 +373,10 @@ static void gotfunc (struct s2devstruct *dev, const uae_u8 *databuf, int len) for (;;) { rdr_offset %= am_rdr_rlen; p = boardram + ((am_rdr_rdra + rdr_offset * 8) & RAM_MASK); - rmd0 = (p[1] << 8) | (p[0] << 0); - rmd1 = (p[3] << 8) | (p[2] << 0); - rmd2 = (p[5] << 8) | (p[4] << 0); - rmd3 = (p[7] << 8) | (p[6] << 0); + rmd0 = gword (p + 0); + rmd1 = gword (p + 2); + rmd2 = gword (p + 4); + rmd3 = gword (p + 6); addr = rmd0 | ((rmd1 & 0xff) << 16); addr &= RAM_MASK; @@ -372,8 +388,7 @@ static void gotfunc (struct s2devstruct *dev, const uae_u8 *databuf, int len) } else { csr[0] |= CSR0_MISS; } - p[3] = rmd1 >> 8; - p[2] = rmd1 >> 0; + pword (p + 2, rmd1); rethink_a2065 (); return; } @@ -388,16 +403,14 @@ static void gotfunc (struct s2devstruct *dev, const uae_u8 *databuf, int len) size = 65536 - rmd2; for (i = 0; i < size && insize < len; i++, insize++) - boardram[((addr + i) ^ byteswap) & RAM_MASK] = data[insize]; + boardram[((addr + i) ^ 0) & RAM_MASK] = data[insize]; if (insize >= len) { rmd1 |= RX_ENP; rmd3 = len; } - p[3] = rmd1 >> 8; - p[2] = rmd1 >> 0; - p[7] = rmd3 >> 8; - p[6] = rmd3 >> 0; + pword (p + 2, rmd1); + pword (p + 6, rmd3); if (insize >= len) break; @@ -439,7 +452,7 @@ static void do_transmit (void) tdr_offset %= am_tdr_tlen; bufaddr = am_tdr_tdra + tdr_offset * 8; p = boardram + (bufaddr & RAM_MASK); - tmd1 = (p[3] << 8) | (p[2] << 0); + tmd1 = gword (p + 2); if (!(tmd1 & TX_OWN) || !(tmd1 & TX_STP)) { tdr_offset++; return; @@ -452,10 +465,10 @@ static void do_transmit (void) for (;;) { tdr_offset %= am_tdr_tlen; p = boardram + ((am_tdr_tdra + tdr_offset * 8) & RAM_MASK); - tmd0 = (p[1] << 8) | (p[0] << 0); - tmd1 = (p[3] << 8) | (p[2] << 0); - tmd2 = (p[5] << 8) | (p[4] << 0); - tmd3 = (p[7] << 8) | (p[6] << 0); + tmd0 = gword (p + 0); + tmd1 = gword (p + 2); + tmd2 = gword (p + 4); + tmd3 = gword (p + 6); addr = tmd0 | ((tmd1 & 0xff) << 16); addr &= RAM_MASK; @@ -471,13 +484,11 @@ static void do_transmit (void) if (size > MAX_PACKET_SIZE) size = MAX_PACKET_SIZE; for (i = 0; i < size; i++) - transmitbuffer[outsize++] = boardram[((addr + i) ^ byteswap) & RAM_MASK]; + transmitbuffer[outsize++] = boardram[((addr + i) ^ 0) & RAM_MASK]; tdr_offset++; } - p[3] = tmd1 >> 8; - p[2] = tmd1 >> 0; - p[7] = tmd3 >> 8; - p[6] = tmd3 >> 0; + pword (p + 2, tmd1); + pword (p + 6, tmd3); if ((tmd1 & TX_ENP) || err) break; } @@ -487,10 +498,8 @@ static void do_transmit (void) csr[0] &= ~CSR0_TXON; write_log (_T("A2065: TRANSMIT UNDERFLOW %d\n"), outsize); err = 1; - p[3] = tmd1 >> 8; - p[2] = tmd1 >> 0; - p[7] = tmd3 >> 8; - p[6] = tmd3 >> 0; + pword (p + 2, tmd1); + pword (p + 6, tmd3); } if (!err) { @@ -512,7 +521,7 @@ static void do_transmit (void) (d[12] << 8) | d[13], outsize); } } - uaenet_trigger (sysdata); + ethernet_trigger (sysdata); } csr[0] |= CSR0_TINT; rethink_a2065 (); @@ -561,10 +570,10 @@ static void chip_init (void) write_log (_T(".%02X"), p[i]); write_log (_T("\n")); - am_mode = (p[0] << 8) | (p[1] << 0); - am_ladrf = ((uae_u64)p[15] << 56) | ((uae_u64)p[14] << 48) | ((uae_u64)p[13] << 40) | ((uae_u64)p[12] << 32) | (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | (p[8] << 0); - am_rdr = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | (p[16] << 0); - am_tdr = (p[23] << 24) | (p[22] << 16) | (p[21] << 8) | (p[20] << 0); + am_mode = gword2 (p + 0); + am_ladrf = (((uae_u64)gword2 (p + 14)) << 48) | (((uae_u64)gword2 (p + 12)) << 32) | (((uae_u64)gword2 (p + 10)) << 16) | gword2 (p + 8); + am_rdr = (gword2 (p + 18) << 16) | gword2 (p + 16); + am_tdr = (gword2 (p + 22) << 16) | gword2 (p + 20); am_rdr_rlen = 1 << ((am_rdr >> 29) & 7); am_tdr_tlen = 1 << ((am_tdr >> 29) & 7); @@ -574,27 +583,26 @@ static void chip_init (void) prom = (am_mode & MODE_PROM) ? 1 : 0; fakeprom = a2065_promiscuous ? 1 : 0; - fakemac[0] = p[2]; - fakemac[1] = p[3]; - fakemac[2] = p[4]; - fakemac[3] = p[5]; - fakemac[4] = p[6]; - fakemac[5] = p[7]; + fakemac[0] = p[3]; + fakemac[1] = p[2]; + fakemac[2] = p[5]; + fakemac[3] = p[4]; + fakemac[4] = p[7]; + fakemac[5] = p[6]; write_log (_T("A2065: %04X %06X %d %d %d %d %06X %06X %02X:%02X:%02X:%02X:%02X:%02X\n"), am_mode, iaddr, prom, fakeprom, am_rdr_rlen, am_tdr_tlen, am_rdr_rdra, am_tdr_tdra, fakemac[0], fakemac[1], fakemac[2], fakemac[3], fakemac[4], fakemac[5]); - am_rdr_rdra &= RAM_MASK; am_tdr_tdra &= RAM_MASK; tdr_offset = rdr_offset = 0; - uaenet_close (sysdata); + ethernet_close (td, sysdata); if (td != NULL) { if (!sysdata) - sysdata = xcalloc (uae_u8, uaenet_getdatalenght()); - if (!uaenet_open (sysdata, td, NULL, gotfunc, getfunc, prom || fakeprom)) { + sysdata = xcalloc (uae_u8, ethernet_getdatalenght (td)); + if (!ethernet_open (td, sysdata, NULL, gotfunc, getfunc, prom || fakeprom)) { write_log (_T("A2065: failed to initialize winpcap driver\n")); } } @@ -650,6 +658,7 @@ static void chip_wput (uaecptr addr, uae_u16 v) if (log_a2065) write_log (_T("A2065: STOP. %04X -> %04X -> %04X\n"), oreg, v, csr[0]); csr[3] = 0; + dbyteswap = 0; } else if ((csr[0] & CSR0_STRT) && !(oreg & CSR0_STRT) && (oreg & (CSR0_STOP | CSR0_INIT))) { @@ -674,6 +683,7 @@ static void chip_wput (uaecptr addr, uae_u16 v) csr[0] |= CSR0_IDON; csr[0] &= ~(CSR0_RXON | CSR0_TXON | CSR0_STOP); am_initialized = 1; + csr[3] = 0; if (log_a2065) write_log (_T("A2065: INIT. %04X -> %04X -> %04X\n"), oreg, v, csr[0]); } @@ -703,7 +713,12 @@ static void chip_wput (uaecptr addr, uae_u16 v) csr[3] = v; csr[3] &= 7; } - byteswap = (csr[3] & CSR3_BSWP) ? 1 : 0; + dbyteswap = 0; + /* + * Some drivers set this but only work if no byteswapping + * is done. Weird.. + * dbyteswap = (csr[3] & CSR3_BSWP) ? 1 : 0; + */ break; } @@ -715,23 +730,17 @@ static uae_u32 a2065_bget2 (uaecptr addr) { uae_u32 v = 0; - if (addr < 0x40) { - v = config[addr]; - } else if (addr >= RAM_OFFSET) { - v = boardram[(addr & RAM_MASK) ^ 1]; + if (addr >= RAM_OFFSET) { + v = boardram[(addr & RAM_MASK)]; } - if (log_a2065 > 2) - write_log (_T("A2065_BGET: %08X -> %02X PC=%08X\n"), addr, v & 0xff, M68K_GETPC); return v; } static void a2065_bput2 (uaecptr addr, uae_u32 v) { if (addr >= RAM_OFFSET) { - boardram[(addr & RAM_MASK) ^ 1] = v; + boardram[(addr & RAM_MASK)] = v; } - if (log_a2065 > 2) - write_log (_T("A2065_BPUT: %08X <- %02X PC=%08X\n"), addr, v & 0xff, M68K_GETPC); } static uae_u32 REGPARAM2 a2065_wget (uaecptr addr) @@ -744,9 +753,16 @@ static uae_u32 REGPARAM2 a2065_wget (uaecptr addr) if (addr == CHIP_OFFSET || addr == CHIP_OFFSET + 2) { v = chip_wget (addr); } else { - v = a2065_bget2 (addr) << 8; +#if 1 + v = a2065_bget2 (addr + 0) << 8; v |= a2065_bget2 (addr + 1); +#else + v = a2065_bget2 (addr + 1) << 8; + v |= a2065_bget2 (addr + 0); +#endif } + if (log_a2065 > 3 && addr < MEM_MIN) + write_log (_T("A2065_WGET: %08X -> %04X PC=%08X\n"), addr, v & 0xffff, M68K_GETPC); return v; } @@ -769,9 +785,15 @@ static uae_u32 REGPARAM2 a2065_bget (uaecptr addr) special_mem |= S_READ; #endif addr &= 65535; - v = a2065_bget2 (addr); - if (!configured) - return v; + if (addr < 0x40) { + v = config[addr]; + } else { + if (!configured) + return 0; + v = a2065_bget2 (addr ^ 0); + } + if (log_a2065 > 3 && addr < MEM_MIN) + write_log (_T("A2065_BGET: %08X -> %02X PC=%08X\n"), addr, v & 0xff, M68K_GETPC); return v; } @@ -784,9 +806,16 @@ static void REGPARAM2 a2065_wput (uaecptr addr, uae_u32 w) if (addr == CHIP_OFFSET || addr == CHIP_OFFSET + 2) { chip_wput (addr, w); } else { +#if 1 a2065_bput2 (addr, w >> 8); a2065_bput2 (addr + 1, w); +#else + a2065_bput2 (addr + 1, w >> 8); + a2065_bput2 (addr + 0, w); +#endif } + if (log_a2065 > 3 && addr < MEM_MIN) + write_log (_T("A2065_WPUT: %08X <- %04X PC=%08X\n"), addr, w & 0xffff, M68K_GETPC); } static void REGPARAM2 a2065_lput (uaecptr addr, uae_u32 l) @@ -823,7 +852,9 @@ static void REGPARAM2 a2065_bput (uaecptr addr, uae_u32 b) } if (!configured) return; - a2065_bput2 (addr, b); + if (log_a2065 > 3 && addr < MEM_MIN) + write_log (_T("A2065_BPUT: %08X <- %02X PC=%08X\n"), addr, b & 0xff, M68K_GETPC); + a2065_bput2 (addr ^ 0, b); } static uae_u32 REGPARAM2 a2065_wgeti (uaecptr addr) @@ -864,7 +895,7 @@ static void a2065_config (void) ew (0x14, 0x02); td = NULL; - if ((td = uaenet_enumerate (NULL, currprefs.a2065name))) { + if (ethernet_enumerate (&td, currprefs.a2065name)) { memcpy (realmac, td->mac, sizeof realmac); write_log (_T("A2065: '%s' %02X:%02X:%02X:%02X:%02X:%02X\n"), td->name, td->mac[0], td->mac[1], td->mac[2], td->mac[3], td->mac[4], td->mac[5]); diff --git a/a2091.cpp b/a2091.cpp index fb6c24d7..319e028c 100644 --- a/a2091.cpp +++ b/a2091.cpp @@ -554,6 +554,10 @@ static void wd_cmd_sel_xfer (bool atn) if (!scsi) { set_status (CSR_TIMEOUT, 0); wdregs[WD_COMMAND_PHASE] = 0x00; +#if WD33C93_DEBUG > 0 + write_log (_T("* %s select and transfer%s, ID=%d: No device\n"), + WD33C93, atn ? _T(" with atn") : _T(""), wdregs[WD_DESTINATION_ID] & 0x7); +#endif return; } if (!wd_selected) { @@ -569,6 +573,7 @@ static void wd_cmd_sel_xfer (bool atn) scsi->buffer[0] = 0; scsi->status = 0; memcpy (scsi->cmd, &wdregs[3], 16); + scsi->data_len = tmp_tc; scsi_emulate_analyze (scsi); settc (scsi->cmd_len); wd_dataoffset = 0; @@ -582,6 +587,7 @@ static void wd_cmd_sel_xfer (bool atn) wd_dataoffset++; } // 0x30 = command phase has started + scsi->data_len = tmp_tc; scsi_emulate_analyze (scsi); wdregs[WD_COMMAND_PHASE] = 0x30 + gettc (); settc (0); @@ -606,7 +612,7 @@ static void wd_cmd_sel_xfer (bool atn) // target replied or start/continue data phase (if data available) if (wdregs[WD_COMMAND_PHASE] == 0x44) { - if (scsi->direction < 0) { + if (scsi->direction <= 0) { scsi_emulate_cmd (scsi); } scsi_start_transfer (scsi); @@ -1674,6 +1680,13 @@ int add_scsi_cd (int ch, int unitnum) return scsis[ch] ? 1 : 0; } +int add_scsi_tape (int ch, const TCHAR *tape_directory, bool readonly) +{ + freescsi (scsis[ch]); + scsis[ch] = scsi_alloc_tape (ch, tape_directory, readonly); + return scsis[ch] ? 1 : 0; +} + static void freenativescsi (void) { int i; @@ -1733,8 +1746,10 @@ static void addnativescsi (void) int a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci) { init_scsi (); - if (ci->cd_emu_unit >= 0) - return add_scsi_cd (ch, ci->cd_emu_unit); + 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, 2); } @@ -1761,8 +1776,10 @@ void a3000scsi_free (void) int a2091_add_scsi_unit (int ch, struct uaedev_config_info *ci) { init_scsi (); - if (ci->cd_emu_unit >= 0) - return add_scsi_cd (ch, ci->cd_emu_unit); + 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); } @@ -1895,72 +1912,102 @@ uae_u8 *restore_scsi_dmac (uae_u8 *src) return src; } -uae_u8 *save_scsi_hd (int num, int *len, uae_u8 *dstptr) +uae_u8 *save_scsi_device (int num, int *len, uae_u8 *dstptr) { uae_u8 *dstbak, *dst; struct scsi_data *s; - if (!scsis[num]) - return NULL; s = scsis[num]; - if (s->hfd == NULL) + if (!s) return NULL; if (dstptr) dstbak = dst = dstptr; else dstbak = dst = xmalloc (uae_u8, 1000); save_u32 (num); - save_u32 (0); // flags - save_u64 (s->hfd->size); - save_string (s->hfd->hfd.ci.rootdir); - save_u32 (s->hfd->hfd.ci.blocksize); - save_u32 (s->hfd->hfd.ci.readonly); - save_u32 (s->hfd->cyls); - save_u32 (s->hfd->heads); - save_u32 (s->hfd->secspertrack); - save_u64 (s->hfd->hfd.virtual_size); - save_u32 (s->hfd->hfd.ci.sectors); - save_u32 (s->hfd->hfd.ci.surfaces); - save_u32 (s->hfd->hfd.ci.reserved); - save_u32 (s->hfd->hfd.ci.bootpri); - save_u32 (s->hfd->ansi_version); + save_u32 (s->device_type); // flags + switch (s->device_type) + { + case UAEDEV_HDF: + case 0: + save_u64 (s->hfd->size); + save_string (s->hfd->hfd.ci.rootdir); + save_u32 (s->hfd->hfd.ci.blocksize); + save_u32 (s->hfd->hfd.ci.readonly); + save_u32 (s->hfd->cyls); + save_u32 (s->hfd->heads); + save_u32 (s->hfd->secspertrack); + save_u64 (s->hfd->hfd.virtual_size); + save_u32 (s->hfd->hfd.ci.sectors); + save_u32 (s->hfd->hfd.ci.surfaces); + save_u32 (s->hfd->hfd.ci.reserved); + save_u32 (s->hfd->hfd.ci.bootpri); + save_u32 (s->hfd->ansi_version); + break; + case UAEDEV_CD: + save_u32 (s->cd_emu_unit); + break; + case UAEDEV_TAPE: + save_u32 (s->cd_emu_unit); + save_u32 (s->tape->blocksize); + save_u32 (s->tape->wp); + save_string (s->tape->tape_dir); + break; + } *len = dst - dstbak; return dstbak; } -uae_u8 *restore_scsi_hd (uae_u8 *src) +uae_u8 *restore_scsi_device (uae_u8 *src) { - int num; + int num, num2; struct hd_hardfiledata *hfd; struct scsi_data *s; uae_u64 size; + uae_u32 flags; int blocksize, readonly; TCHAR *path; num = restore_u32 (); - hfd = xcalloc (struct hd_hardfiledata, 1); - s = scsis[num] = scsi_alloc_hd (num, hfd); - restore_u32 (); - size = restore_u64 (); - path = restore_string (); - _tcscpy (s->hfd->hfd.ci.rootdir, path); - blocksize = restore_u32 (); - readonly = restore_u32 (); - s->hfd->cyls = restore_u32 (); - s->hfd->heads = restore_u32 (); - s->hfd->secspertrack = restore_u32 (); - s->hfd->hfd.virtual_size = restore_u64 (); - s->hfd->hfd.ci.sectors = restore_u32 (); - s->hfd->hfd.ci.surfaces = restore_u32 (); - s->hfd->hfd.ci.reserved = restore_u32 (); - s->hfd->hfd.ci.bootpri = restore_u32 (); - s->hfd->ansi_version = restore_u32 (); - - if (size) { - add_scsi_hd (num, hfd, NULL, s->hfd->ansi_version); + flags = restore_u32 (); + switch (flags & 15) + { + case UAEDEV_HDF: + case 0: + hfd = xcalloc (struct hd_hardfiledata, 1); + s = scsis[num] = scsi_alloc_hd (num, hfd); + size = restore_u64 (); + path = restore_string (); + _tcscpy (s->hfd->hfd.ci.rootdir, path); + blocksize = restore_u32 (); + readonly = restore_u32 (); + s->hfd->cyls = restore_u32 (); + s->hfd->heads = restore_u32 (); + s->hfd->secspertrack = restore_u32 (); + s->hfd->hfd.virtual_size = restore_u64 (); + s->hfd->hfd.ci.sectors = restore_u32 (); + s->hfd->hfd.ci.surfaces = restore_u32 (); + s->hfd->hfd.ci.reserved = restore_u32 (); + s->hfd->hfd.ci.bootpri = restore_u32 (); + s->hfd->ansi_version = restore_u32 (); + s->hfd->hfd.ci.blocksize = blocksize; + if (size) + add_scsi_hd (num, hfd, NULL, s->hfd->ansi_version); + xfree (path); + break; + case UAEDEV_CD: + num2 = restore_u32 (); + add_scsi_cd (num, num2); + break; + case UAEDEV_TAPE: + num2 = restore_u32 (); + blocksize = restore_u32 (); + readonly = restore_u32 (); + path = restore_string (); + add_scsi_tape (num, path, readonly != 0); + xfree (path); + break; } - xfree (path); return src; - } diff --git a/audio.cpp b/audio.cpp index 2ee141e3..8fbdc589 100644 --- a/audio.cpp +++ b/audio.cpp @@ -1678,7 +1678,7 @@ void set_audio (void) schedule_audio (); events_schedule (); } - config_changed = 1; + set_config_changed (); } void update_audio (void) diff --git a/blitter.cpp b/blitter.cpp index 12bf642b..b4adf5ec 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -994,7 +994,7 @@ static void do_startcycles (int hpos) while (vhpos < hpos) { int v = canblit (vhpos); vhpos++; - if (v >= 0) { + if (v > 0) { blit_startcycles--; if (blit_startcycles == 0) { if (blit_faulty) diff --git a/blkdev.cpp b/blkdev.cpp index 2a12ad9b..79236da1 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -44,6 +44,7 @@ struct blkdevstate bool cdimagefileinuse; int wasopen; bool mediawaschanged; + struct scsi_data_tape *tape; }; struct blkdevstate state[MAX_TOTAL_SCSI_DEVICES]; @@ -428,6 +429,19 @@ int sys_command_isopen (int unitnum) return st->isopen; } +int sys_command_open_tape (int unitnum, const TCHAR *tape_directory, bool readonly) +{ + struct blkdevstate *st = &state[unitnum]; + if (st->isopen == 0) { + struct scsi_data_tape *tape = tape_alloc (unitnum, tape_directory, readonly); + if (!tape) + return 0; + st->tape = tape; + } + st->isopen++; + return 1; +} + int sys_command_open (int unitnum) { struct blkdevstate *st = &state[unitnum]; @@ -458,6 +472,10 @@ void sys_command_close (int unitnum) st->isopen--; return; } + if (st->tape) { + tape_free (st->tape); + st->tape = NULL; + } #ifdef RETROPLATFORM rp_cd_device_enable (unitnum, false); #endif @@ -642,7 +660,7 @@ static void check_changes (int unitnum) gotsem = false; } - config_changed = 1; + set_config_changed (); } @@ -1227,8 +1245,6 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, dlen = *data_len; *reply_len = *sense_len = 0; - memset (r, 0, 256); - memset (s, 0, 256); sys_command_info (unitnum, &di, 1); @@ -1667,8 +1683,8 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, scsi_len = maxlen2; } } - break; - case 0x42: // READ SUB-CHANNEL + break; + case 0x42: // READ SUB-CHANNEL { int msf = cmdbuf[1] & 2; int subq = cmdbuf[2] & 0x40; @@ -1708,181 +1724,181 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, scsi_data[3] = 0; } } - break; - case 0x1b: // START/STOP - sys_command_cd_stop (unitnum); - scsiemudrv (unitnum, cmdbuf); - scsi_len = 0; - break; - case 0x4e: // STOP PLAY/SCAN - if (nodisk (&di)) - goto nodisk; - sys_command_cd_stop (unitnum); - scsi_len = 0; - break; - case 0xba: // SCAN - { - if (nodisk (&di)) - goto nodisk; - struct cd_toc_head ttoc; - if (!sys_command_cd_toc (unitnum, &ttoc)) - goto readerr; - struct cd_toc_head *toc = &ttoc; - int scan = (cmdbuf[1] & 0x10) ? -1 : 1; - int start = rl (cmdbuf + 1) & 0x00ffffff; - int end = scan > 0 ? toc->lastaddress : toc->toc[toc->first_track_offset].paddress; - int type = cmdbuf[9] >> 6; - if (type == 1) - start = lsn2msf (start); - if (type == 3) + break; + case 0x1b: // START/STOP + sys_command_cd_stop (unitnum); + scsiemudrv (unitnum, cmdbuf); + scsi_len = 0; + break; + case 0x4e: // STOP PLAY/SCAN + if (nodisk (&di)) + goto nodisk; + sys_command_cd_stop (unitnum); + scsi_len = 0; + break; + case 0xba: // SCAN + { + if (nodisk (&di)) + goto nodisk; + struct cd_toc_head ttoc; + if (!sys_command_cd_toc (unitnum, &ttoc)) + goto readerr; + struct cd_toc_head *toc = &ttoc; + int scan = (cmdbuf[1] & 0x10) ? -1 : 1; + int start = rl (cmdbuf + 1) & 0x00ffffff; + int end = scan > 0 ? toc->lastaddress : toc->toc[toc->first_track_offset].paddress; + int type = cmdbuf[9] >> 6; + if (type == 1) + start = lsn2msf (start); + if (type == 3) + goto errreq; + if (type == 2) { + if (toc->first_track_offset + start >= toc->last_track_offset) goto errreq; - if (type == 2) { - if (toc->first_track_offset + start >= toc->last_track_offset) - goto errreq; - start = toc->toc[toc->first_track_offset + start].paddress; - } - sys_command_cd_pause (unitnum, 0); - sys_command_cd_play (unitnum, start, end, scan); - scsi_len = 0; + start = toc->toc[toc->first_track_offset + start].paddress; } - break; - case 0x48: // PLAY AUDIO TRACK/INDEX - { - if (nodisk (&di)) - goto nodisk; - int strack = cmdbuf[4]; - int etrack = cmdbuf[7]; - struct cd_toc_head ttoc; - if (!sys_command_cd_toc (unitnum, &ttoc)) - goto readerr; - struct cd_toc_head *toc = &ttoc; - if (strack < toc->first_track || strack > toc->last_track || - etrack < toc->first_track || etrack > toc->last_track || - strack > etrack) - goto errreq; - int start = toc->toc[toc->first_track_offset + strack - 1].paddress; - int end = etrack == toc->last_track ? toc->lastaddress : toc->toc[toc->first_track_offset + etrack - 1 + 1].paddress; + sys_command_cd_pause (unitnum, 0); + sys_command_cd_play (unitnum, start, end, scan); + scsi_len = 0; + } + break; + case 0x48: // PLAY AUDIO TRACK/INDEX + { + if (nodisk (&di)) + goto nodisk; + int strack = cmdbuf[4]; + int etrack = cmdbuf[7]; + struct cd_toc_head ttoc; + if (!sys_command_cd_toc (unitnum, &ttoc)) + goto readerr; + struct cd_toc_head *toc = &ttoc; + if (strack < toc->first_track || strack > toc->last_track || + etrack < toc->first_track || etrack > toc->last_track || + strack > etrack) + goto errreq; + int start = toc->toc[toc->first_track_offset + strack - 1].paddress; + int end = etrack == toc->last_track ? toc->lastaddress : toc->toc[toc->first_track_offset + etrack - 1 + 1].paddress; + sys_command_cd_pause (unitnum, 0); + if (!sys_command_cd_play (unitnum, start, end, 0)) + goto notdatatrack; + scsi_len = 0; + } + break; + case 0x49: // PLAY AUDIO TRACK RELATIVE (10) + case 0xa9: // PLAY AUDIO TRACK RELATIVE (12) + { + if (nodisk (&di)) + goto nodisk; + int len = cmd == 0xa9 ? rl (cmdbuf + 6) : rw (cmdbuf + 7); + int track = cmd == 0xa9 ? cmdbuf[10] : cmdbuf[6]; + if (track < di.toc.first_track || track > di.toc.last_track) + goto errreq; + int start = di.toc.toc[di.toc.first_track_offset + track - 1].paddress; + int rel = rl (cmdbuf + 2); + start += rel; + int end = start + len; + if (end > di.toc.lastaddress) + end = di.toc.lastaddress; + if (len > 0) { sys_command_cd_pause (unitnum, 0); - if (!sys_command_cd_play (unitnum, start, end, 0)) + if (!sys_command_cd_play (unitnum, start, start + len, 0)) goto notdatatrack; - scsi_len = 0; } - break; - case 0x49: // PLAY AUDIO TRACK RELATIVE (10) - case 0xa9: // PLAY AUDIO TRACK RELATIVE (12) - { - if (nodisk (&di)) - goto nodisk; - int len = cmd == 0xa9 ? rl (cmdbuf + 6) : rw (cmdbuf + 7); - int track = cmd == 0xa9 ? cmdbuf[10] : cmdbuf[6]; - if (track < di.toc.first_track || track > di.toc.last_track) - goto errreq; - int start = di.toc.toc[di.toc.first_track_offset + track - 1].paddress; - int rel = rl (cmdbuf + 2); - start += rel; - int end = start + len; - if (end > di.toc.lastaddress) - end = di.toc.lastaddress; - if (len > 0) { - sys_command_cd_pause (unitnum, 0); - if (!sys_command_cd_play (unitnum, start, start + len, 0)) - goto notdatatrack; - } - scsi_len = 0; + scsi_len = 0; + } + break; + case 0x47: // PLAY AUDIO MSF + { + if (nodisk (&di)) + goto nodisk; + int start = rl (cmdbuf + 2) & 0x00ffffff; + if (start == 0x00ffffff) { + uae_u8 buf[SUBQ_SIZE] = { 0 }; + sys_command_cd_qcode (unitnum, buf); + start = fromlongbcd (buf + 4 + 7); } - break; - case 0x47: // PLAY AUDIO MSF - { - if (nodisk (&di)) - goto nodisk; - int start = rl (cmdbuf + 2) & 0x00ffffff; - if (start == 0x00ffffff) { + int end = msf2lsn (rl (cmdbuf + 5) & 0x00ffffff); + if (end > di.toc.lastaddress) + end = di.toc.lastaddress; + start = msf2lsn (start); + if (start > end) + goto errreq; + if (start < end) + sys_command_cd_pause (unitnum, 0); + if (!sys_command_cd_play (unitnum, start, end, 0)) + goto notdatatrack; + scsi_len = 0; + } + break; + case 0x45: // PLAY AUDIO (10) + case 0xa5: // PLAY AUDIO (12) + { + if (nodisk (&di)) + goto nodisk; + int start = rl (cmdbuf + 2); + int len; + if (cmd == 0xa5) + len = rl (cmdbuf + 6); + else + len = rw (cmdbuf + 7); + if (len > 0) { + if (start == -1) { uae_u8 buf[SUBQ_SIZE] = { 0 }; sys_command_cd_qcode (unitnum, buf); - start = fromlongbcd (buf + 4 + 7); + start = msf2lsn (fromlongbcd (buf + 4 + 7)); } - int end = msf2lsn (rl (cmdbuf + 5) & 0x00ffffff); + int end = start + len; if (end > di.toc.lastaddress) end = di.toc.lastaddress; - start = msf2lsn (start); - if (start > end) - goto errreq; - if (start < end) - sys_command_cd_pause (unitnum, 0); - if (!sys_command_cd_play (unitnum, start, end, 0)) - goto notdatatrack; - scsi_len = 0; - } - break; - case 0x45: // PLAY AUDIO (10) - case 0xa5: // PLAY AUDIO (12) - { - if (nodisk (&di)) - goto nodisk; - int start = rl (cmdbuf + 2); - int len; - if (cmd == 0xa5) - len = rl (cmdbuf + 6); - else - len = rw (cmdbuf + 7); - if (len > 0) { - if (start == -1) { - uae_u8 buf[SUBQ_SIZE] = { 0 }; - sys_command_cd_qcode (unitnum, buf); - start = msf2lsn (fromlongbcd (buf + 4 + 7)); - } - int end = start + len; - if (end > di.toc.lastaddress) - end = di.toc.lastaddress; - sys_command_cd_pause (unitnum, 0); - if (!sys_command_cd_play (unitnum, start, end, 0)) - goto notdatatrack; - } - scsi_len = 0; + sys_command_cd_pause (unitnum, 0); + if (!sys_command_cd_play (unitnum, start, end, 0)) + goto notdatatrack; } - break; - case 0xbc: // PLAY CD - { - if (nodisk (&di)) - goto nodisk; - int start = -1; - int end = -1; - if (cmdbuf[1] & 2) { - start = msf2lsn (rl (cmdbuf + 2) & 0x00ffffff); - end = msf2lsn (rl (cmdbuf + 5) & 0x00ffffff); - } else { - start = rl (cmdbuf + 2); - end = start + rl (cmdbuf + 6); - } - if (end > di.toc.lastaddress) - end = di.toc.lastaddress; - if (start > end) - goto errreq; - if (start < end) { - sys_command_cd_pause (unitnum, 0); - if (!sys_command_cd_play (unitnum, start, end, 0)) - goto notdatatrack; - } + scsi_len = 0; + } + break; + case 0xbc: // PLAY CD + { + if (nodisk (&di)) + goto nodisk; + int start = -1; + int end = -1; + if (cmdbuf[1] & 2) { + start = msf2lsn (rl (cmdbuf + 2) & 0x00ffffff); + end = msf2lsn (rl (cmdbuf + 5) & 0x00ffffff); + } else { + start = rl (cmdbuf + 2); + end = start + rl (cmdbuf + 6); } - break; - case 0x4b: // PAUSE/RESUME - { - if (nodisk (&di)) - goto nodisk; - uae_u8 buf[SUBQ_SIZE] = { 0 }; - int resume = cmdbuf[8] & 1; - sys_command_cd_qcode (unitnum, buf); - if (buf[1] != AUDIO_STATUS_IN_PROGRESS && buf[1] != AUDIO_STATUS_PAUSED) - goto errreq; - sys_command_cd_pause (unitnum, resume ? 0 : 1); - scsi_len = 0; + if (end > di.toc.lastaddress) + end = di.toc.lastaddress; + if (start > end) + goto errreq; + if (start < end) { + sys_command_cd_pause (unitnum, 0); + if (!sys_command_cd_play (unitnum, start, end, 0)) + goto notdatatrack; } - break; - case 0x35: /* SYNCRONIZE CACHE (10) */ - scsi_len = 0; - break; + } + break; + case 0x4b: // PAUSE/RESUME + { + if (nodisk (&di)) + goto nodisk; + uae_u8 buf[SUBQ_SIZE] = { 0 }; + int resume = cmdbuf[8] & 1; + sys_command_cd_qcode (unitnum, buf); + if (buf[1] != AUDIO_STATUS_IN_PROGRESS && buf[1] != AUDIO_STATUS_PAUSED) + goto errreq; + sys_command_cd_pause (unitnum, resume ? 0 : 1); + scsi_len = 0; + } + break; + case 0x35: /* SYNCRONIZE CACHE (10) */ + scsi_len = 0; + break; - default: + default: err: write_log (_T("CDEMU: unsupported scsi command 0x%02X\n"), cmdbuf[0]); readprot: @@ -1891,35 +1907,35 @@ readprot: s[2] = 5; s[12] = 0x20; /* INVALID COMMAND */ ls = 0x12; - break; + break; nodisk: status = 2; /* CHECK CONDITION */ s[0] = 0x70; s[2] = 2; /* NOT READY */ s[12] = 0x3A; /* MEDIUM NOT PRESENT */ ls = 0x12; - break; + break; readerr: status = 2; /* CHECK CONDITION */ s[0] = 0x70; s[2] = 2; /* NOT READY */ s[12] = 0x11; /* UNRECOVERED READ ERROR */ ls = 0x12; - break; + break; notdatatrack: status = 2; s[0] = 0x70; s[2] = 5; s[12] = 0x64; /* ILLEGAL MODE FOR THIS TRACK */ ls = 0x12; - break; + break; outofbounds: status = 2; /* CHECK CONDITION */ s[0] = 0x70; s[2] = 5; /* ILLEGAL REQUEST */ s[12] = 0x21; /* LOGICAL BLOCK OUT OF RANGE */ ls = 0x12; - break; + break; toolarge: write_log (_T("CDEMU: too large scsi data tranfer %d > %d\n"), len, dlen); status = 2; /* CHECK CONDITION */ @@ -1927,7 +1943,7 @@ toolarge: s[2] = 2; /* NOT READY */ s[12] = 0x11; /* UNRECOVERED READ ERROR */ ls = 0x12; - break; + break; errreq: lr = -1; status = 2; /* CHECK CONDITION */ @@ -1935,7 +1951,7 @@ errreq: s[2] = 5; /* ILLEGAL REQUEST */ s[12] = 0x24; /* ILLEGAL FIELD IN CDB */ ls = 0x12; - break; + break; } end: *data_len = scsi_len; @@ -1953,13 +1969,13 @@ end: return status; } -static int execscsicmd_direct (int unitnum, struct amigascsi *as) +static int execscsicmd_direct (int unitnum, int type, struct amigascsi *as) { int io_error = 0; uae_u8 *scsi_datap, *scsi_datap_org; uae_u32 scsi_cmd_len_orig = as->cmd_len; uae_u8 cmd[16] = { 0 }; - uae_u8 replydata[256]; + uae_u8 replydata[256] = { 0 }; int datalen = as->len; int senselen = as->sense_len; int replylen = 0; @@ -1972,7 +1988,18 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as) /* never report media change state if uaescsi.device */ state[unitnum].mediawaschanged = false; - as->status = scsi_cd_emulate (unitnum, cmd, as->cmd_len, scsi_datap, &datalen, replydata, &replylen, as->sensedata, &senselen, false); + switch (type) + { + case INQ_ROMD: + as->status = scsi_cd_emulate (unitnum, cmd, as->cmd_len, scsi_datap, &datalen, replydata, &replylen, as->sensedata, &senselen, false); + break; + case INQ_SEQD: + as->status = scsi_tape_emulate (state[unitnum].tape, cmd, as->cmd_len, scsi_datap, &datalen, replydata, &replylen, as->sensedata, &senselen); + break; + default: + as->status = 2; + break; + } as->cmdactual = as->status != 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */ if (as->status) { @@ -2001,11 +2028,11 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as) return io_error; } -int sys_command_scsi_direct_native (int unitnum, struct amigascsi *as) +int sys_command_scsi_direct_native (int unitnum, int type, struct amigascsi *as) { struct blkdevstate *st = &state[unitnum]; - if (st->scsiemu) { - return execscsicmd_direct (unitnum, as); + if (st->scsiemu || type >= 0) { + return execscsicmd_direct (unitnum, type, as); } else { if (!st->device_func->exec_direct) return -1; @@ -2016,7 +2043,7 @@ int sys_command_scsi_direct_native (int unitnum, struct amigascsi *as) return ret; } -int sys_command_scsi_direct (int unitnum, uaecptr acmd) +int sys_command_scsi_direct (int unitnum, int type, uaecptr acmd) { int ret, i; struct amigascsi as = { 0 }; @@ -2042,7 +2069,7 @@ int sys_command_scsi_direct (int unitnum, uaecptr acmd) as.flags = get_byte (acmd + 20); as.sense_len = get_word (acmd + 26); - ret = sys_command_scsi_direct_native (unitnum, &as); + ret = sys_command_scsi_direct_native (unitnum, type, &as); put_long (acmd + 8, as.actual); put_word (acmd + 18, as.cmdactual); diff --git a/cfgfile.cpp b/cfgfile.cpp index e86385f3..545160a5 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -33,6 +33,8 @@ #include "statusline.h" #include "debug.h" #include "calc.h" +#include "gfxboard.h" +#include "luascript.h" static int config_newfilesystem; static struct strlist *temp_lines; @@ -187,7 +189,14 @@ static const TCHAR *dongles[] = static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), 0 }; static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), 0 }; static const TCHAR *specialmonitors[] = { _T("none"), _T("autodetect"), _T("a2024"), _T("graffiti"), 0 }; -static const TCHAR *rtgtype[] = { _T("ZorroII"), _T("ZorroIII"), 0 }; +static const TCHAR *rtgtype[] = { + _T("ZorroII"), _T("ZorroIII"), + _T("PicassoII"), _T("PicassoII+"), + _T("Piccolo"), _T("PiccoloSD64_Z2"), _T("PiccoloSD64_Z3"), + _T("PiccoloSD64_Z2"), _T("PiccoloSD64_Z3"), + _T("Spectrum28/24_Z2"), _T("Spectrum28/24_Z3"), + _T("PicassoIV_Z2"), _T("PicassoIV_Z3"), + 0 }; static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 }; static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 }; static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 }; @@ -538,7 +547,7 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) uci->volname, str); zfile_fputs (f, tmp2); #endif - } else if (ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD) { + } else if (ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD || ci->type == UAEDEV_TAPE) { _stprintf (tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"), ci->readonly ? _T("ro") : _T("rw"), ci->devname ? ci->devname : _T(""), str, @@ -563,7 +572,9 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) } _stprintf (tmp2, _T("uaehf%d"), i); if (ci->type == UAEDEV_CD) { - cfgfile_write (f, tmp2, _T("cd%d,%s"), ci->cd_emu_unit, tmp); + cfgfile_write (f, tmp2, _T("cd%d,%s"), ci->device_emu_unit, tmp); + } else if (ci->type == UAEDEV_TAPE) { + cfgfile_write (f, tmp2, _T("tape%d,%s"), ci->device_emu_unit, tmp); } else { cfgfile_write (f, tmp2, _T("%s,%s"), ci->type == UAEDEV_HDF ? _T("hdf") : _T("dir"), tmp); } @@ -748,6 +759,12 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) } } + for (i = 0; i < MAX_LUA_STATES; i++) { + if (p->luafiles[i][0]) { + cfgfile_write_str (f, _T("lua"), p->luafiles[i]); + } + } + if (p->statefile[0]) cfgfile_write_str (f, _T("statefile"), p->statefile); if (p->quitstatefile[0]) @@ -1492,6 +1509,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) } return 0; } + for (i = 0; i < MAX_SPARE_DRIVES; i++) { _stprintf (tmpbuf, _T("diskimage%d"), i); if (cfgfile_path (option, value, tmpbuf, p->dfxlist[i], sizeof p->dfxlist[i] / sizeof (TCHAR), &p->path_floppy)) { @@ -1575,6 +1593,16 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) } } + if (!_tcsicmp (option, _T("lua"))) { + for (i = 0; i < MAX_LUA_STATES; i++) { + if (!p->luafiles[i][0]) { + _tcscpy (p->luafiles[i], value); + break; + } + } + return 1; + } + if (cfgfile_strval (option, value, _T("gfx_autoresolution_min_vertical"), &p->gfx_autoresolution_minv, vertmode, 0)) { p->gfx_autoresolution_minv--; return 1; @@ -2399,7 +2427,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s struct uaedev_config_data *uci; int i; - if (index < 0 && ci->devname && _tcslen (ci->devname) > 0) { + if (index < 0 && (ci->type == UAEDEV_DIR || ci->type == UAEDEV_HDF) && ci->devname && _tcslen (ci->devname) > 0) { for (i = 0; i < p->mountitems; i++) { if (p->mountconfig[i].ci.devname && !_tcscmp (p->mountconfig[i].ci.devname, ci->devname)) return 0; @@ -2409,6 +2437,10 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s if (ci->controller > HD_CONTROLLER_SCSI6 || ci->controller < HD_CONTROLLER_IDE0) return NULL; } + if (ci->type == UAEDEV_TAPE) { + if (ci->controller != HD_CONTROLLER_UAE && (ci->controller > HD_CONTROLLER_SCSI6 || ci->controller < HD_CONTROLLER_IDE0)) + return NULL; + } if (index < 0) { if (ci->controller != HD_CONTROLLER_UAE) { int ctrl = ci->controller; @@ -2428,12 +2460,13 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s } if (ci->type == UAEDEV_CD) { for (i = 0; i < p->mountitems; i++) { - if (p->mountconfig[i].ci.type == UAEDEV_CD) + if (p->mountconfig[i].ci.type == ci->type) return 0; } } uci = getuci (p); uci->configoffset = -1; + uci->unitnum = -1; } else { uci = &p->mountconfig[index]; } @@ -2443,7 +2476,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s memcpy (&uci->ci, ci, sizeof (struct uaedev_config_info)); validatedevicename (uci->ci.devname); validatevolumename (uci->ci.volname); - if (!uci->ci.devname[0] && ci->type != UAEDEV_CD) { + if (!uci->ci.devname[0] && ci->type != UAEDEV_CD && ci->type != UAEDEV_TAPE) { TCHAR base[32]; TCHAR base2[32]; int num = 0; @@ -2692,7 +2725,7 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA _tcscpy (uci.devname, devname); if (! getintval (&tmpp, &uci.bootpri, 0)) goto empty_fs; - } else if (type == 1 || (type == 2 && uaehfentry)) { + } else if (type == 1 || ((type == 2 || type == 3) && uaehfentry)) { tmpp = _tcschr (value, ':'); if (tmpp == 0) goto invalid_fs; @@ -2732,10 +2765,14 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA } } if (type == 2) { - uci.cd_emu_unit = unit; + uci.device_emu_unit = unit; uci.blocksize = 2048; uci.readonly = true; uci.type = UAEDEV_CD; + } else if (type == 3) { + uci.device_emu_unit = unit; + uci.blocksize = 512; + uci.type = UAEDEV_TAPE; } else { uci.type = UAEDEV_HDF; } @@ -2787,6 +2824,13 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA if (unit >= 0 && unit <= MAX_TOTAL_SCSI_DEVICES) { type = 2; } + } else if (_tcsnicmp (value, _T("tape"), 4) == 0 && (value[4] == 0 || value[5] == 0)) { + unit = 0; + if (value[4] > 0) + unit = value[4] - '0'; + if (unit >= 0 && unit <= MAX_TOTAL_SCSI_DEVICES) { + type = 3; + } } else if (_tcsicmp (value, _T("dir")) != 0) { type = 0; return 1; /* ignore for now */ @@ -4232,6 +4276,76 @@ static bool cfgfile_parse_uaelib_option (struct uae_prefs *p, TCHAR *option, TCH return false; } +int cfgfile_searchconfig(const TCHAR *in, int index, TCHAR *out, int outsize) +{ + TCHAR tmp[CONFIG_BLEN]; + int j = 0; + int inlen = _tcslen (in); + int joker = 0; + uae_u32 err = 0; + bool configsearchfound = false; + + if (in[inlen - 1] == '*') { + joker = 1; + inlen--; + } + *out = 0; + + if (!configstore) + createconfigstore(&currprefs); + if (!configstore) + return 20; + + if (index < 0) + zfile_fseek(configstore, 0, SEEK_SET); + + for (;;) { + uae_u8 b = 0; + + if (zfile_fread (&b, 1, 1, configstore) != 1) { + err = 10; + if (configsearchfound) + err = 0; + goto end; + } + if (j >= sizeof (tmp) / sizeof (TCHAR) - 1) + j = sizeof (tmp) / sizeof (TCHAR) - 1; + if (b == 0) { + err = 10; + if (configsearchfound) + err = 0; + goto end; + } + if (b == '\n') { + if (!_tcsncmp (tmp, in, inlen) && ((inlen > 0 && _tcslen (tmp) > inlen && tmp[inlen] == '=') || (joker))) { + TCHAR *p; + if (joker) + p = tmp - 1; + else + p = _tcschr (tmp, '='); + if (p) { + for (int i = 0; out && i < outsize - 1; i++) { + TCHAR b = *++p; + out[i] = b; + out[i + 1] = 0; + if (!b) + break; + } + } + err = 0xffffffff; + configsearchfound = true; + goto end; + } + j = 0; + } else { + tmp[j++] = b; + tmp[j] = 0; + } + } +end: + return err; +} + uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize) { TCHAR *p; @@ -4240,9 +4354,8 @@ uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, u uae_u32 err; TCHAR zero = 0; static TCHAR *configsearch; - static int configsearchfound; - config_changed = 1; + *out = 0; err = 0; argv = 0; p = 0; @@ -4252,66 +4365,8 @@ uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, u goto end; } if (configsearch) { - TCHAR tmp[CONFIG_BLEN]; - int j = 0; - TCHAR *in = configsearch; - int inlen = _tcslen (configsearch); - int joker = 0; - - if (in[inlen - 1] == '*') { - joker = 1; - inlen--; - } - - for (;;) { - uae_u8 b = 0; - - if (zfile_fread (&b, 1, 1, configstore) != 1) { - err = 10; - if (configsearch) - err = 5; - if (configsearchfound) - err = 0; - goto end; - } - if (j >= sizeof (tmp) / sizeof (TCHAR) - 1) - j = sizeof (tmp) / sizeof (TCHAR) - 1; - if (b == 0) { - err = 10; - if (configsearch) - err = 5; - if (configsearchfound) - err = 0; - goto end; - } - if (b == '\n') { - if (configsearch && !_tcsncmp (tmp, in, inlen) && - ((inlen > 0 && _tcslen (tmp) > inlen && tmp[inlen] == '=') || (joker))) { - TCHAR *p; - if (joker) - p = tmp - 1; - else - p = _tcschr (tmp, '='); - if (p) { - for (i = 0; out && i < outsize - 1; i++) { - TCHAR b = *++p; - out[i] = b; - out[i + 1] = 0; - if (!b) - break; - } - } - err = 0xffffffff; - configsearchfound++; - goto end; - } - index--; - j = 0; - } else { - tmp[j++] = b; - tmp[j] = 0; - } - } + err = cfgfile_searchconfig(configsearch, index, out, outsize); + goto end; } err = 0xffffffff; for (i = 0; out && i < outsize - 1; i++) { @@ -4345,7 +4400,6 @@ uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, u if (argv > 0 && _tcslen (argc[0]) > 0) configsearch = my_strdup (argc[0]); err = 0xffffffff; - configsearchfound = 0; goto end; } @@ -4361,6 +4415,7 @@ uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, u } } } + set_config_changed (); set_special (SPCFLAG_BRK); i++; } @@ -4425,11 +4480,20 @@ end: return ret; } +const TCHAR *cfgfile_read_config_value (const TCHAR *option) +{ + struct strlist *sl; + for (sl = currprefs.all_lines; sl; sl = sl->next) { + if (sl->option && !strcasecmp (sl->option, option)) + return sl->value; + } + return NULL; +} + uae_u32 cfgfile_uaelib (int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen) { TCHAR tmp[CONFIG_BLEN]; int i; - struct strlist *sl; if (mode) return 0; @@ -4442,13 +4506,9 @@ uae_u32 cfgfile_uaelib (int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen) tmp[sizeof(tmp) / sizeof (TCHAR) - 1] = 0; if (tmp[0] == 0) return 0; - for (sl = currprefs.all_lines; sl; sl = sl->next) { - if (!strcasecmp (sl->option, tmp)) - break; - } - - if (sl) { - char *s = ua (sl->value); + const TCHAR *value = cfgfile_read_config_value (tmp); + if (value) { + char *s = ua (value); for (i = 0; i < maxlen; i++) { put_byte (dst + i, s[i]); if (s[i] == 0) @@ -4555,6 +4615,7 @@ void default_prefs (struct uae_prefs *p, int type) p->mountitems = 0; for (i = 0; i < MOUNT_CONFIG_SIZE; i++) { p->mountconfig[i].configoffset = -1; + p->mountconfig[i].unitnum = -1; } memset (&p->jports[0], 0, sizeof (struct jport)); @@ -4704,6 +4765,10 @@ void default_prefs (struct uae_prefs *p, int type) _tcscpy (p->floppyslots[2].df, _T("df2.adf")); _tcscpy (p->floppyslots[3].df, _T("df3.adf")); + for (int i = 0; i < MAX_LUA_STATES; i++) { + p->luafiles[i][0] = 0; + } + configure_rom (p, roms, 0); _tcscpy (p->romextfile, _T("")); _tcscpy (p->romextfile2, _T("")); @@ -4749,7 +4814,7 @@ void default_prefs (struct uae_prefs *p, int type) p->chipmem_size = 0x00080000; p->bogomem_size = 0x00080000; p->rtgmem_size = 0x00000000; - p->rtgmem_type = 1; + p->rtgmem_type = GFXBOARD_UAE_Z3; p->custom_memory_addrs[0] = 0; p->custom_memory_sizes[0] = 0; p->custom_memory_addrs[1] = 0; @@ -4901,7 +4966,7 @@ static void buildin_default_prefs (struct uae_prefs *p) p->z3fastmem2_size = 0x00000000; p->z3chipmem_size = 0x00000000; p->rtgmem_size = 0x00000000; - p->rtgmem_type = 1; + p->rtgmem_type = GFXBOARD_UAE_Z3; p->cs_rtc = 0; p->cs_a1000ram = false; @@ -5555,11 +5620,20 @@ int built_in_chipset_prefs (struct uae_prefs *p) return 1; } +void set_config_changed (void) +{ + config_changed = 1; +} + void config_check_vsync (void) { if (config_changed) { -// if (config_changed == 1) -// write_log (_T("* configuration check trigger\n")); +#ifdef WITH_LUA + if (config_changed == 1) { + createconfigstore (&currprefs); + uae_lua_run_handler ("on_uae_config_changed"); + } +#endif config_changed++; if (config_changed >= 3) config_changed = 0; diff --git a/custom.cpp b/custom.cpp index cd193995..974f3ac3 100644 --- a/custom.cpp +++ b/custom.cpp @@ -52,6 +52,7 @@ #include "gfxfilter.h" #include "a2091.h" #include "a2065.h" +#include "gfxboard.h" #include "ncr_scsi.h" #include "blkdev.h" #include "sampler.h" @@ -59,6 +60,7 @@ #ifdef RETROPLATFORM #include "rp.h" #endif +#include "luascript.h" #define CUSTOM_DEBUG 0 #define SPRITE_DEBUG 0 @@ -135,10 +137,14 @@ int vpos; static int vpos_count, vpos_count_diff; int lof_store; // real bit in custom registers static int lof_current; // what display device thinks +static bool lof_lastline, lof_prev_lastline; static int lol; static int next_lineno, prev_lineno; static enum nln_how nextline_how; static int lof_changed = 0, lof_changing = 0, interlace_changed = 0; +static int lof_changed_previous_field; +static bool lof_lace; +static bool bplcon0_interlace_seen; static int scandoubled_line; static bool vsync_rendered, frame_rendered, frame_shown; static int vsynctimeperline; @@ -146,10 +152,12 @@ static int jitcount = 0; static int frameskiptime; static bool genlockhtoggle; static bool genlockvtoggle; +static bool graphicsbuffer_retry; -#define LOF_TOGGLES_NEEDED 4 -#define NLACE_CNT_NEEDED 50 -static int lof_togglecnt_lace, lof_togglecnt_nlace, lof_previous, nlace_cnt; + +#define LOF_TOGGLES_NEEDED 3 +//#define NLACE_CNT_NEEDED 50 +static int lof_togglecnt_lace, lof_togglecnt_nlace; //, nlace_cnt; /* Stupid genlock-detection prevention hack. * We should stop calling vsync_handler() and @@ -192,6 +200,7 @@ int minfirstline = VBLANK_ENDLINE_PAL; static int equ_vblank_endline = EQU_ENDLINE_PAL; static bool equ_vblank_toggle = true; double vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_hz_stored; +static float vblank_hz_lof, vblank_hz_shf, vblank_hz_lace; static int vblank_hz_mult, vblank_hz_state; static struct chipset_refresh *stored_chipset_refresh; int doublescan; @@ -2980,7 +2989,7 @@ void compute_vsynctime (void) } #endif if (currprefs.produce_sound > 1) - update_sound (fake_vblank_hz, (bplcon0 & 4) ? -1 : lof_store, islinetoggle ()); + update_sound (fake_vblank_hz, interlace_seen ? -1 : lof_store, islinetoggle ()); } @@ -3002,6 +3011,7 @@ int current_maxvpos (void) return maxvpos + (lof_store ? 1 : 0); } +#if 0 static void checklacecount (bool lace) { if (!interlace_changed) { @@ -3031,6 +3041,7 @@ static void checklacecount (bool lace) nlace_cnt = NLACE_CNT_NEEDED * 2; } } +#endif struct chipset_refresh *get_chipset_refresh (void) { @@ -3065,6 +3076,14 @@ void compute_framesync (void) int isntsc = (beamcon0 & 0x20) ? 0 : 1; bool found = false; + if (islace) { + vblank_hz = vblank_hz_lace; + } else if (lof_current) { + vblank_hz = vblank_hz_lof; + } else { + vblank_hz = vblank_hz_shf; + } + struct chipset_refresh *cr = get_chipset_refresh (); while (cr) { double v = -1; @@ -3123,7 +3142,7 @@ void compute_framesync (void) interlace_changed = 0; lof_togglecnt_lace = 0; lof_togglecnt_nlace = 0; - nlace_cnt = NLACE_CNT_NEEDED; + //nlace_cnt = NLACE_CNT_NEEDED; lof_changing = 0; gfxvidinfo.drawbuffer.inxoffset = -1; gfxvidinfo.drawbuffer.inyoffset = -1; @@ -3189,17 +3208,13 @@ void compute_framesync (void) if (gfxvidinfo.drawbuffer.outheight > gfxvidinfo.drawbuffer.height_allocated) gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.height_allocated; - if (target_graphics_buffer_update ()) { - reset_drawing (); - } - memset (line_decisions, 0, sizeof line_decisions); compute_vsynctime (); write_log (_T("%s mode%s%s V=%.4fHz H=%0.4fHz (%dx%d+%d) IDX=%d (%s) D=%d RTG=%d/%d\n"), isntsc ? _T("NTSC") : _T("PAL"), - islace ? _T(" lace") : _T(""), + islace ? _T(" lace") : (lof_lace ? _T(" loflace") : _T("")), doublescan > 0 ? _T(" dblscan") : _T(""), vblank_hz, (double)(currprefs.ntscmode ? CHIPSET_CLOCK_NTSC : CHIPSET_CLOCK_PAL) / (maxhpos + (islinetoggle () ? 0.5 : 0)), @@ -3209,7 +3224,7 @@ void compute_framesync (void) currprefs.gfx_apmode[picasso_on ? 1 : 0].gfx_display, picasso_on, picasso_requested_on ); - config_changed = 1; + set_config_changed (); } /* set PAL/NTSC or custom timing variables */ @@ -3242,10 +3257,12 @@ void init_hz (bool fullinit) maxvpos = MAXVPOS_PAL; maxhpos = MAXHPOS_PAL; minfirstline = VBLANK_ENDLINE_PAL; - vblank_hz = VBLANK_HZ_PAL; sprite_vblank_endline = VBLANK_SPRITE_PAL; equ_vblank_endline = EQU_ENDLINE_PAL; equ_vblank_toggle = true; + vblank_hz_shf = (double)CHIPSET_CLOCK_PAL / ((maxvpos + 0) * maxhpos); + vblank_hz_lof = (double)CHIPSET_CLOCK_PAL / ((maxvpos + 1) * maxhpos); + vblank_hz_lace = (double)CHIPSET_CLOCK_PAL / ((maxvpos + 0.5) * maxhpos); } else { maxvpos = MAXVPOS_NTSC; maxhpos = MAXHPOS_NTSC; @@ -3254,9 +3271,11 @@ void init_hz (bool fullinit) sprite_vblank_endline = VBLANK_SPRITE_NTSC; equ_vblank_endline = EQU_ENDLINE_NTSC; equ_vblank_toggle = false; + vblank_hz_shf = (double)CHIPSET_CLOCK_NTSC / ((maxvpos + 0) * maxhpos); + vblank_hz_lof = (double)CHIPSET_CLOCK_NTSC / ((maxvpos + 1) * maxhpos); + vblank_hz_lace = (double)CHIPSET_CLOCK_NTSC / ((maxvpos + 0.5) * maxhpos); } - // long/short field refresh rate adjustment - vblank_hz = vblank_hz * (maxvpos * 2 + 1) / ((maxvpos + lof_current) * 2); + vblank_hz = vblank_hz_lof; maxvpos_nom = maxvpos; if (vpos_count > 0) { @@ -3265,6 +3284,7 @@ void init_hz (bool fullinit) if (vpos_count < 10) vpos_count = 10; vblank_hz = (isntsc ? 15734 : 15625.0) / vpos_count; + vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = vblank_hz; maxvpos_nom = vpos_count - (lof_current ? 1 : 0); reset_drawing (); } @@ -3277,6 +3297,9 @@ void init_hz (bool fullinit) htotal = MAXHPOS - 1; maxhpos = htotal + 1; vblank_hz = 227.0 * 312.0 * 50.0 / (maxvpos * maxhpos); + vblank_hz_shf = vblank_hz; + vblank_hz_lof = 227.0 * 313.0 * 50.0 / (maxvpos * maxhpos);; + vblank_hz_lace = 227.0 * 312.5 * 50.0 / (maxvpos * maxhpos);; minfirstline = vsstop > vbstop ? vsstop : vbstop; if (minfirstline > maxvpos / 2) minfirstline = vsstop > vsstop ? vbstop : vsstop; @@ -4111,8 +4134,8 @@ static void BPLCON0 (int hpos, uae_u16 v) hpos_previous = hpos; } - if ((bplcon0 & 4) != (v & 4)) - checklacecount ((v & 4) != 0); + if (bplcon0 & 4) + bplcon0_interlace_seen = true; bplcon0 = v; @@ -6055,7 +6078,7 @@ static void vsync_handler_pre (void) vblank_hz_state = 1; vsync_handle_check (); - checklacecount ((bplcon0 & 4) != 0); + //checklacecount (bplcon0_interlace_seen || lof_lace); } // emulated hardware vsync @@ -6072,6 +6095,10 @@ static void vsync_handler_post (void) #endif DISK_vsync (); +#ifdef WITH_LUA + uae_lua_run_handler ("on_uae_vsync"); +#endif + if ((bplcon0 & 2) && currprefs.genlock) { genlockvtoggle = !genlockvtoggle; //lof_store = genlockvtoggle ? 1 : 0; @@ -6079,6 +6106,22 @@ static void vsync_handler_post (void) if (bplcon0 & 4) { lof_store = lof_store ? 0 : 1; } + if (lof_prev_lastline != lof_lastline) { + if (lof_togglecnt_lace < LOF_TOGGLES_NEEDED) + lof_togglecnt_lace++; + if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED) + lof_togglecnt_nlace = 0; + } else { + lof_togglecnt_nlace = LOF_TOGGLES_NEEDED; + lof_togglecnt_lace = 0; +#if 0 + if (lof_togglecnt_nlace < LOF_TOGGLES_NEEDED) + lof_togglecnt_nlace++; + if (lof_togglecnt_nlace >= LOF_TOGGLES_NEEDED) + lof_togglecnt_lace = 0; +#endif + } + lof_prev_lastline = lof_lastline; lof_current = lof_store; if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED) { interlace_changed = notice_interlace_seen (true); @@ -6094,9 +6137,23 @@ static void vsync_handler_post (void) if (lof_changing) { // still same? Trigger change now. if ((!lof_store && lof_changing < 0) || (lof_store && lof_changing > 0)) { + lof_changed_previous_field++; lof_changed = 1; + // lof toggling? decide as interlace. + if (lof_changed_previous_field >= LOF_TOGGLES_NEEDED) { + lof_changed_previous_field = LOF_TOGGLES_NEEDED; + if (lof_lace == false) + lof_lace = true; + else + lof_changed = 0; + } + if (bplcon0 & 4) + lof_changed = 0; } lof_changing = 0; + } else { + lof_changed_previous_field = 0; + lof_lace = false; } if (debug_copper) @@ -6110,14 +6167,22 @@ static void vsync_handler_post (void) vtotal = vpos_count; } #endif +#ifdef GFXBOARD + if (!picasso_on) + gfxboard_vsync_handler (); +#endif - if ((beamcon0 & (0x20 | 0x80)) != (new_beamcon0 & (0x20 | 0x80)) || (vpos_count > 0 && abs (vpos_count - vpos_count_diff) > 1) || lof_changed) { + if ((beamcon0 & (0x20 | 0x80)) != (new_beamcon0 & (0x20 | 0x80)) || (vpos_count > 0 && abs (vpos_count - vpos_count_diff) > 1)) { init_hz (); - } else if (interlace_changed || changed_chipset_refresh ()) { + } else if (interlace_changed || changed_chipset_refresh () || lof_changed) { compute_framesync (); } + if (target_graphics_buffer_update ()) { + reset_drawing (); + } lof_changed = 0; + bplcon0_interlace_seen = false; COPJMP (1, 1); @@ -6472,27 +6537,6 @@ static void hsync_handler_post (bool onvsync) CIA_vsync_posthandler (ciavsyncs); } - if (vpos == equ_vblank_endline + 1) { - if (lof_current != lof_store) { - // argh, line=0 field decision was wrong, someone did - // something stupid and changed LOF - // lof_current = lof_store; - // don't really know what to do here exactly without corrupt display - } - if (lof_store != lof_previous) { - if (lof_togglecnt_lace < LOF_TOGGLES_NEEDED) - lof_togglecnt_lace++; - if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED) - lof_togglecnt_nlace = 0; - } else { - if (lof_togglecnt_nlace < LOF_TOGGLES_NEEDED) - lof_togglecnt_nlace++; - if (lof_togglecnt_nlace >= LOF_TOGGLES_NEEDED) - lof_togglecnt_lace = 0; - } - lof_previous = lof_store; - } - inputdevice_hsync (); last_custom_value1 = 0xffff; // refresh slots should set this to 0xffff @@ -6524,6 +6568,10 @@ static void hsync_handler_post (bool onvsync) if (vpos == 0) send_interrupt (5, 1 * CYCLE_UNIT); } + // lastline - 1? + if (vpos + 1 == maxvpos + lof_store || vpos + 1 == maxvpos + lof_store + 1) { + lof_lastline = lof_store != 0; + } #ifdef CPUEMU_12 if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) { @@ -6665,7 +6713,8 @@ static void hsync_handler_post (bool onvsync) bsdsock_fake_int_handler (); } - plfstrt_sprite = plfstrt; + /* Default to no bitplane DMA overriding sprite DMA */ + plfstrt_sprite = 0xff; /* See if there's a chance of a copper wait ending this line. */ cop_state.hpos = 0; cop_state.last_write = 0; @@ -6863,7 +6912,8 @@ void custom_reset (bool hardreset, bool keyboardreset) beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; bltstate = BLT_done; blit_interrupt = 1; - lof_store = lof_current = 1; + lof_store = lof_current = 0; + lof_lace = false; } gayle_reset (hardreset); @@ -6877,6 +6927,9 @@ void custom_reset (bool hardreset, bool keyboardreset) #ifdef A2091 a2091_reset (); #endif +#ifdef GFXBOARD + gfxboard_reset (); +#endif #ifdef NCR ncr_reset (); #endif @@ -6908,8 +6961,7 @@ void custom_reset (bool hardreset, bool keyboardreset) vpos_lpen = -1; lof_changing = 0; lof_togglecnt_nlace = lof_togglecnt_lace = 0; - lof_previous = lof_store; - nlace_cnt = NLACE_CNT_NEEDED; + //nlace_cnt = NLACE_CNT_NEEDED; audio_reset (); if (!isrestore ()) { diff --git a/debug.cpp b/debug.cpp index 77805695..5f684131 100644 --- a/debug.cpp +++ b/debug.cpp @@ -38,6 +38,7 @@ #include "calc.h" #include "cpummu.h" #include "cpummu030.h" +#include "ar.h" int debugger_active; static uaecptr skipaddr_start, skipaddr_end; @@ -3478,6 +3479,60 @@ static void debug_sprite (TCHAR **inptr) } +int debug_write_memory_16 (uaecptr addr, uae_u16 v) +{ + addrbank *ad; + + ad = &get_mem_bank (addr); + if (ad) { + ad->wput (addr, v); + return 1; + } + return -1; +} +int debug_write_memory_8 (uaecptr addr, uae_u8 v) +{ + addrbank *ad; + + ad = &get_mem_bank (addr); + if (ad) { + ad->bput (addr, v); + return 1; + } + return -1; +} +int debug_peek_memory_16 (uaecptr addr) +{ + addrbank *ad; + + ad = &get_mem_bank (addr); + if (ad->flags & (ABFLAG_RAM | ABFLAG_ROM | ABFLAG_ROMIN | ABFLAG_SAFE)) + return ad->wget (addr); + if (ad == &custom_bank) { + addr &= 0x1fe; + return (ar_custom[addr + 0] << 8) | ar_custom[addr + 1]; + } + return -1; +} +int debug_read_memory_16 (uaecptr addr) +{ + addrbank *ad; + + ad = &get_mem_bank (addr); + if (ad) + return ad->wget (addr); + return -1; +} +int debug_read_memory_8 (uaecptr addr) +{ + addrbank *ad; + + ad = &get_mem_bank (addr); + if (ad) + return ad->bget (addr); + return -1; +} + static void disk_debug (TCHAR **inptr) { TCHAR parm[10]; diff --git a/disk.cpp b/disk.cpp index ae9c4e43..6696b044 100644 --- a/disk.cpp +++ b/disk.cpp @@ -2439,7 +2439,7 @@ int disk_setwriteprotect (struct uae_prefs *p, int num, const TCHAR *name, bool void disk_eject (int num) { - config_changed = 1; + set_config_changed (); gui_filename (num, _T("")); drive_eject (floppy + num); *currprefs.floppyslots[num].df = *changed_prefs.floppyslots[num].df = 0; @@ -2539,14 +2539,14 @@ static void disk_insert_2 (int num, const TCHAR *name, bool forced, bool forcedw void disk_insert (int num, const TCHAR *name, bool forcedwriteprotect) { - config_changed = 1; + set_config_changed (); target_addtorecent (name, 0); disk_insert_2 (num, name, 0, forcedwriteprotect); } void disk_insert (int num, const TCHAR *name) { - config_changed = 1; + set_config_changed (); target_addtorecent (name, 0); disk_insert_2 (num, name, 0, false); } diff --git a/drawing.cpp b/drawing.cpp index e10a6187..04f80ff0 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -2396,13 +2396,21 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in if (dosprites) { int i; + for (i = 0; i < dip_for_drawing->nr_sprites; i++) draw_sprites_aga (curr_sprite_entries + dip_for_drawing->first_sprite_entry + i, 1); uae_u16 oxor = bplxor; memset (pixdata.apixels, 0, sizeof pixdata); - bplxor = 0; - do_color_changes (pfield_do_fill_line, pfield_do_linetoscr_border, lineno); - bplxor = oxor; + if (dp_for_drawing->ham_seen) { + int todraw_amiga = res_shift_from_window (visible_right_border - visible_left_border); + init_ham_decoding (); + memset (ham_linebuf + ham_decode_pixel, 0, todraw_amiga * sizeof (uae_u32)); + } + if (dip_for_drawing->nr_color_changes) { + bplxor = 0; + do_color_changes (pfield_do_fill_line, pfield_do_linetoscr_border, lineno); + bplxor = oxor; + } } else { @@ -2572,13 +2580,13 @@ static void init_drawing_frame (void) write_log (_T("RES -> %d (%d) LINE -> %d (%d) (%d - %d, %d - %d)\n"), nr, nr_o, nl, nl_o, currprefs.gfx_autoresolution_minh, currprefs.gfx_autoresolution_minv, gfxvidinfo.gfx_resolution_reserved, gfxvidinfo.gfx_vresolution_reserved); - config_changed = 1; + set_config_changed (); //activate_debugger (); } if (src->width > 0 && src->height > 0) { if (memcmp (dst, src, sizeof *dst)) { *dst = *src; - config_changed = 1; + set_config_changed (); } } break; diff --git a/ethernet.cpp b/ethernet.cpp new file mode 100644 index 00000000..ac4c09aa --- /dev/null +++ b/ethernet.cpp @@ -0,0 +1,176 @@ + +#include "slirp/slirp.h" +#include "slirp/libslirp.h" + +#ifdef _WIN32 +#include "win32_uaenet.h" +#else +#include "ethernet.h" +#endif +#include "threaddep/thread.h" +#include "options.h" + +struct ethernet_data +{ + ethernet_gotfunc *gotfunc; + ethernet_getfunc *getfunc; +}; + + +static int getmode (void) +{ + if (!_tcsicmp (currprefs.a2065name, _T("none")) || currprefs.a2065name[0] == 0) + return UAENET_NONE; + if (!_tcsicmp (currprefs.a2065name, _T("slirp"))) + return UAENET_SLIRP; + return UAENET_PCAP; +} + +static struct ethernet_data *slirp_data; +uae_sem_t slirp_sem1, slirp_sem2; +static int netmode; + +static struct netdriverdata slirpd = { + UAENET_SLIRP, + _T("slirp"), _T("SLIRP User Mode NAT"), + 1500, + { 0x00,0x80,0x10,50,51,52 }, + 1 +}; + +int slirp_can_output(void) +{ + return 1; +} + +void slirp_output (const uint8 *pkt, int pkt_len) +{ + if (!slirp_data) + return; + uae_sem_wait (&slirp_sem1); + slirp_data->gotfunc (NULL, pkt, pkt_len); + uae_sem_post (&slirp_sem1); +} + +void ethernet_trigger (void *vsd) +{ + switch (netmode) + { + case UAENET_SLIRP: + { + struct ethernet_data *ed = (struct ethernet_data*)vsd; + if (slirp_data) { + uae_u8 pkt[4000]; + int len = sizeof pkt; + int v; + uae_sem_wait (&slirp_sem1); + v = slirp_data->getfunc(NULL, pkt, &len); + uae_sem_post (&slirp_sem1); + if (v) { + uae_sem_wait (&slirp_sem2); + slirp_input(pkt, len); + uae_sem_post (&slirp_sem2); + } + } + } + return; + case UAENET_PCAP: + uaenet_trigger (vsd); + return; + } +} + +int ethernet_open (struct netdriverdata *ndd, void *vsd, void *user, ethernet_gotfunc *gotfunc, ethernet_getfunc *getfunc, int promiscuous) +{ + switch (ndd->type) + { + case UAENET_SLIRP: + { + struct ethernet_data *ed = (struct ethernet_data*)vsd; + ed->gotfunc = gotfunc; + ed->getfunc = getfunc; + slirp_data = ed; + uae_sem_init (&slirp_sem1, 0, 1); + uae_sem_init (&slirp_sem2, 0, 1); + slirp_init (); + slirp_start (); + } + return 1; + case UAENET_PCAP: + return uaenet_open (vsd, ndd, user, gotfunc, getfunc, promiscuous); + } + return 0; +} + +void ethernet_close (struct netdriverdata *ndd, void *vsd) +{ + if (!ndd) + return; + switch (ndd->type) + { + case UAENET_SLIRP: + slirp_end (); + slirp_data = NULL; + return; + case UAENET_PCAP: + return uaenet_close (vsd); + } +} + +void ethernet_enumerate_free (void) +{ + uaenet_enumerate_free (); +} + +bool ethernet_enumerate (struct netdriverdata **nddp, const TCHAR *name) +{ + int j; + struct netdriverdata *nd; + if (name) { + netmode = 0; + *nddp = NULL; + if (!_tcsicmp (slirpd.name, name)) + *nddp = &slirpd; + if (*nddp == NULL) + *nddp = uaenet_enumerate (name); + if (*nddp) { + netmode = (*nddp)->type; + return true; + } + return false; + } + j = 0; + nddp[j++] = &slirpd; + nd = uaenet_enumerate (NULL); + if (nd) { + for (int i = 0; i < nd[i].active; i++) { + nddp[j++] = nd; + } + } + nddp[j] = NULL; + return true; +} + +void ethernet_close_driver (struct netdriverdata *ndd) +{ + switch (ndd->type) + { + case UAENET_SLIRP: + return; + case UAENET_PCAP: + return uaenet_close_driver (ndd); + } + netmode = 0; +} + +int ethernet_getdatalenght (struct netdriverdata *ndd) +{ + switch (ndd->type) + { + case UAENET_SLIRP: + return sizeof (struct ethernet_data); + case UAENET_PCAP: + return uaenet_getdatalenght (); + } + return 0; +} \ No newline at end of file diff --git a/expansion.cpp b/expansion.cpp index 222719dc..f5c03114 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -27,6 +27,7 @@ #include "cdtv.h" #include "a2091.h" #include "a2065.h" +#include "gfxboard.h" #include "cd32_fmv.h" #include "ncr_scsi.h" #include "debug.h" @@ -974,13 +975,13 @@ static uae_u8 *REGPARAM2 z3chipmem_xlate (uaecptr addr) addrbank z3fastmem_bank = { z3fastmem_lget, z3fastmem_wget, z3fastmem_bget, z3fastmem_lput, z3fastmem_wput, z3fastmem_bput, - z3fastmem_xlate, z3fastmem_check, NULL, _T("ZorroIII Fast RAM"), + z3fastmem_xlate, z3fastmem_check, NULL, _T("Zorro III Fast RAM"), z3fastmem_lget, z3fastmem_wget, ABFLAG_RAM }; addrbank z3fastmem2_bank = { z3fastmem2_lget, z3fastmem2_wget, z3fastmem2_bget, z3fastmem2_lput, z3fastmem2_wput, z3fastmem2_bput, - z3fastmem2_xlate, z3fastmem2_check, NULL, _T("ZorroIII Fast RAM #2"), + z3fastmem2_xlate, z3fastmem2_check, NULL, _T("Zorro III Fast RAM #2"), z3fastmem2_lget, z3fastmem2_wget, ABFLAG_RAM }; addrbank z3chipmem_bank = { @@ -1490,6 +1491,18 @@ static void expamem_init_a4091 (void) ncr_init (); #endif } +static void expamem_init_gfxboard_memory (void) +{ +#ifdef GFXBOARD + gfxboard_init_memory (); +#endif +} +static void expamem_init_gfxboard_registers (void) +{ +#ifdef GFXBOARD + gfxboard_init_registers (); +#endif +} #if 0 void p96memstart (void) { @@ -1588,13 +1601,24 @@ void expamem_reset (void) } #endif #ifdef PICASSO96 - if (!currprefs.rtgmem_type && gfxmemory != NULL) { + if (currprefs.rtgmem_type == GFXBOARD_UAE_Z2 && gfxmemory != NULL) { card_name[cardno] = _T("Z2RTG"); card_init[cardno] = expamem_init_gfxcard_z2; card_map[cardno++] = expamem_map_gfxcard; } #endif - +#ifdef GFXBOARD + if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && !gfxboard_is_z3 (currprefs.rtgmem_type)) { + card_name[cardno] = _T ("Gfxboard VRAM Zorro II"); + card_init[cardno] = expamem_init_gfxboard_memory; + card_map[cardno++] = NULL; + if (gfxboard_is_registers (currprefs.rtgmem_type)) { + card_name[cardno] = _T ("Gfxboard Registers"); + card_init[cardno] = expamem_init_gfxboard_registers; + card_map[cardno++] = NULL; + } + } +#endif /* Z3 boards last */ if (z3fastmem != NULL) { @@ -1620,14 +1644,22 @@ void expamem_reset (void) } #endif #ifdef PICASSO96 - if (currprefs.rtgmem_type && gfxmemory != NULL) { + if (currprefs.rtgmem_type == GFXBOARD_UAE_Z3 && gfxmemory != NULL) { card_name[cardno] = _T("Z3RTG"); card_init[cardno] = expamem_init_gfxcard_z3; card_map[cardno++] = expamem_map_gfxcard; } #endif - - +#ifdef GFXBOARD + if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_is_z3 (currprefs.rtgmem_type)) { + card_name[cardno] = _T ("Gfxboard VRAM Zorro III"); + card_init[cardno] = expamem_init_gfxboard_memory; + card_map[cardno++] = NULL; + card_name[cardno] = _T ("Gfxboard Registers"); + card_init[cardno] = expamem_init_gfxboard_registers; + card_map[cardno++] = NULL; + } +#endif if (cardno > 0 && cardno < MAX_EXPANSION_BOARDS) { card_name[cardno] = _T("Empty"); card_init[cardno] = expamem_init_last; diff --git a/filesys.cpp b/filesys.cpp index 835e8ebd..90b8dda6 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -54,6 +54,7 @@ #include "consolehook.h" #include "blkdev.h" #include "isofs_api.h" +#include "scsi.h" #ifdef RETROPLATFORM #include "rp.h" #endif @@ -139,7 +140,7 @@ static int cd_unit_offset, cd_unit_number; typedef struct { int unit_type; - bool open; + int open; // >0 start as filesystem, <0 = allocated but do not start TCHAR *devname; /* device name, e.g. UAE0: */ uaecptr devname_amiga; uaecptr startup; @@ -197,7 +198,7 @@ int nr_units (void) { int i, cnt = 0; for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { - if (mountinfo.ui[i].open) + if (mountinfo.ui[i].open > 0) cnt++; } return cnt; @@ -213,7 +214,7 @@ int nr_directory_units (struct uae_prefs *p) } } else { for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { - if (mountinfo.ui[i].open && mountinfo.ui[i].controller == 0) + if (mountinfo.ui[i].open > 0 && mountinfo.ui[i].controller == 0) cnt++; } } @@ -288,6 +289,12 @@ static UnitInfo *getuip (struct uae_prefs *p, int index) return NULL; return &mountinfo.ui[index]; } +static int getuindex (struct uae_prefs *p, int index) +{ + if (index < 0) + return -1; + return p->mountconfig[index].unitnum; +} int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo *mi) { @@ -335,7 +342,7 @@ int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo * ui->hf.ci.blocksize = uci->ci.blocksize; mi->size = -1; mi->ismounted = true; - if (blkdev_get_info (p, ui->hf.ci.cd_emu_unit, &di)) { + if (blkdev_get_info (p, ui->hf.ci.device_emu_unit, &di)) { mi->ismedia = di.media_inserted != 0; _tcscpy (mi->rootdir, di.label); } @@ -346,7 +353,7 @@ int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo * _stprintf (mi->rootdir, _T("CD %d"), ui->hf.ci.cd_emu_unit); #endif } - } else { + } else if (uci->ci.type != UAEDEV_TAPE) { if (!ui->controller || (ui->controller && p->cs_ide)) { mi->ismounted = 1; if (uci->ci.type == UAEDEV_HDF) @@ -355,6 +362,32 @@ int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo * mi->ismedia = true; } } + if (uci->ci.type == UAEDEV_TAPE) { + struct device_info di; + int unitnum = getuindex (p, index); + mi->size = -1; + mi->ismounted = false; + if (unitnum >= 0) { + mi->ismounted = true; + if (tape_get_info (unitnum, &di)) { + mi->ismedia = di.media_inserted != 0; + _tcscpy (mi->rootdir, di.label); + } + } else { + struct scsi_data_tape *tape; + unitnum = 0; + tape = tape_alloc (unitnum, uci->ci.rootdir, uci->ci.readonly); + if (tape) { + if (tape_get_info (unitnum, &di)) { + mi->ismedia = di.media_inserted != 0; + _tcscpy (mi->rootdir, di.label); + } + tape_free (tape); + } + } + return FILESYS_TAPE; + } + if (mi->size < 0) return -1; mi->size = ui->hf.virtsize; @@ -519,7 +552,7 @@ void uci_set_defaults (struct uaedev_config_info *uci, bool rdb) uci->stacksize = 4000; uci->priority = -129; uci->sectorsperblock = 1; - uci->cd_emu_unit = -1; + uci->device_emu_unit = -1; } static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci) @@ -532,8 +565,6 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci) memcpy (&c, ci, sizeof (struct uaedev_config_info)); - if (ci->controller) - return -1; if (nr < 0) { for (nr = 0; nr < MAX_FILESYSTEM_UNITS; nr++) { if (!mountinfo.ui[nr].open) @@ -545,6 +576,16 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci) } } + if (ci->controller || ci->type == UAEDEV_TAPE) { + ui = &mountinfo.ui[nr]; + memset (ui, 0, sizeof (UnitInfo)); + memcpy (&ui->hf.ci, &c, sizeof (struct uaedev_config_info)); + ui->readonly = c.readonly; + ui->unit_type = -1; + ui->open = -1; + return nr; + } + my_resolvesoftlink (c.rootdir, MAX_DPATH); iscd = nr >= cd_unit_offset && nr < cd_unit_offset + cd_unit_number; @@ -702,7 +743,7 @@ int move_filesys_unitconfig (struct uae_prefs *p, int nr, int to) void filesys_addexternals (void); -static void allocuci (struct uae_prefs *p, int nr, int idx) +static void allocuci (struct uae_prefs *p, int nr, int idx, int unitnum) { struct uaedev_config_data *uci = &p->mountconfig[nr]; if (idx >= 0) { @@ -710,10 +751,16 @@ static void allocuci (struct uae_prefs *p, int nr, int idx) uci->configoffset = idx; ui = &mountinfo.ui[idx]; ui->configureddrive = 1; + uci->unitnum = unitnum; } else { uci->configoffset = -1; + uci->unitnum = -1; } } +static void allocuci (struct uae_prefs *p, int nr, int idx) +{ + allocuci (p, nr, idx, -1); +} static void initialize_mountinfo (void) { @@ -724,7 +771,7 @@ static void initialize_mountinfo (void) for (nr = 0; nr < currprefs.mountitems; nr++) { struct uaedev_config_data *uci = &currprefs.mountconfig[nr]; - if (uci->ci.controller == HD_CONTROLLER_UAE) { + if (uci->ci.controller == HD_CONTROLLER_UAE && (uci->ci.type == UAEDEV_DIR || uci->ci.type == UAEDEV_HDF)) { struct uaedev_config_info ci; memcpy (&ci, &uci->ci, sizeof (struct uaedev_config_info)); ci.flags = MYVOLUMEINFO_REUSABLE; @@ -755,11 +802,26 @@ static void initialize_mountinfo (void) } } + for (nr = 0; nr < currprefs.mountitems; nr++) { + struct uaedev_config_data *uci = &currprefs.mountconfig[nr]; + if (uci->ci.controller == HD_CONTROLLER_UAE) { + if (uci->ci.type == UAEDEV_TAPE) { + struct uaedev_config_info ci; + memcpy (&ci, &uci->ci, sizeof (struct uaedev_config_info)); + int unitnum = scsi_add_tape (&uci->ci); + if (unitnum >= 0) { + int idx = set_filesys_unit_1 (-1, &ci); + allocuci (&currprefs, nr, idx, unitnum); + } + } + } + } + for (nr = 0; nr < currprefs.mountitems; nr++) { struct uaedev_config_info *uci = &currprefs.mountconfig[nr].ci; - if (uci->controller == HD_CONTROLLER_UAE) + if (uci->controller == HD_CONTROLLER_UAE) { continue; - if (uci->controller <= HD_CONTROLLER_IDE3) { + } else if (uci->controller <= HD_CONTROLLER_IDE3) { gayle_add_ide_unit (uci->controller - HD_CONTROLLER_IDE0, uci); allocuci (&currprefs, nr, -1); } else if (uci->controller <= HD_CONTROLLER_SCSI6) { @@ -1414,7 +1476,7 @@ int filesys_eject (int nr) if (!mountertask || u->mount_changed) return 0; - if (!ui->open || u == NULL) + if (ui->open <= 0 || u == NULL) return 0; if (!is_virtual (nr)) return 0; @@ -1436,7 +1498,7 @@ static int heartbeat_task; // This uses filesystem process to reduce resource usage void setsystime (void) { - if (!currprefs.tod_hack) + if (!currprefs.tod_hack || !rtarea_base) return; heartbeat = get_long (rtarea_base + RTAREA_HEARTBEAT); heartbeat_task = 1; @@ -1489,7 +1551,7 @@ int filesys_insert (int nr, const TCHAR *volume, const TCHAR *rootdir, bool read u = ui->self; } - if (!ui->open || u == NULL) + if (ui->open <= 0 || u == NULL) return 0; if (u->reinsertdelay) return -1; @@ -1651,7 +1713,8 @@ int filesys_media_change (const TCHAR *rootdir, int inserted, struct uaedev_conf for (u = units; u; u = u->next) { if (is_virtual (u->unit)) { ui = &mountinfo.ui[u->unit]; - if (ui->rootdir && !memcmp (ui->rootdir, rootdir, _tcslen (rootdir)) && _tcslen (rootdir) + 3 >= _tcslen (ui->rootdir)) { + // inserted == 2: drag&drop insert, do not replace existing normal drives + if (inserted < 2 && ui->rootdir && !memcmp (ui->rootdir, rootdir, _tcslen (rootdir)) && _tcslen (rootdir) + 3 >= _tcslen (ui->rootdir)) { if (filesys_isvolume (u) && inserted) { if (uci) filesys_delayed_change (u, 50, rootdir, uci->ci.volname, uci->ci.readonly, 0); @@ -2726,7 +2789,7 @@ static uae_u32 REGPARAM2 startup_handler (TrapContext *context) for (nr = 0; nr < MAX_FILESYSTEM_UNITS; nr++) { /* Hardfile volume name? */ - if (!mountinfo.ui[nr].open) + if (mountinfo.ui[nr].open <= 0) continue; if (!is_virtual (nr)) continue; @@ -5365,7 +5428,7 @@ static void return; } amiga_to_timeval (&tv, get_long (date), get_long (date + 4), get_long (date + 8)); - write_log (_T("%llu.%u (%d,%d,%d) %s\n"), tv.tv_sec, tv.tv_usec, get_long (date), get_long (date + 4), get_long (date + 8), a->nname); + //write_log (_T("%llu.%u (%d,%d,%d) %s\n"), tv.tv_sec, tv.tv_usec, get_long (date), get_long (date + 4), get_long (date + 8), a->nname); if (!my_utime (a->nname, &tv)) err = dos_errno (); if (err != 0) { @@ -5833,7 +5896,7 @@ static uae_u32 REGPARAM2 exter_int_helper (TrapContext *context) if (unit_no >= MAX_FILESYSTEM_UNITS) return 0; - if (uip[unit_no].open && uip[unit_no].self != 0 + if (uip[unit_no].open > 0 && uip[unit_no].self != 0 && uip[unit_no].self->cmds_acked == uip[unit_no].self->cmds_complete && uip[unit_no].self->cmds_acked != uip[unit_no].self->cmds_sent) break; @@ -6073,7 +6136,7 @@ void filesys_start_threads (void) filesys_in_interrupt = 0; for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { UnitInfo *ui = &mountinfo.ui[i]; - if (!ui->open) + if (ui->open <= 0) continue; filesys_start_thread (ui, i); } @@ -6147,7 +6210,7 @@ static void filesys_prepare_reset2 (void) uip = mountinfo.ui; #ifdef UAE_FILESYS_THREADS for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { - if (uip[i].open && uip[i].unit_pipe != 0) { + if (uip[i].open > 0 && uip[i].unit_pipe != 0) { uae_sem_init (&uip[i].reset_sync_sem, 0, 0); uip[i].reset_state = FS_GO_DOWN; /* send death message */ @@ -7940,7 +8003,7 @@ uae_u8 *save_filesys (int num, int *len) int type = is_hardfile (num); ui = &mountinfo.ui[num]; - if (!ui->open) + if (ui->open <= 0) return NULL; /* not initialized yet, do not save */ if ((type == FILESYS_VIRTUAL || type == FILESYS_CD) && ui->self == NULL) diff --git a/gayle.cpp b/gayle.cpp index 8ca0d241..1be9e28d 100644 --- a/gayle.cpp +++ b/gayle.cpp @@ -1886,21 +1886,21 @@ static struct ide_hdf *add_ide_unit (int ch, struct uaedev_config_info *ci) ide = idedrive[ch]; if (ci) memcpy (&ide->hdhfd.hfd.ci, ci, sizeof (struct uaedev_config_info)); - if (ci->cd_emu_unit >= 0) { + if (ci->type == UAEDEV_CD && ci->device_emu_unit >= 0) { device_func_init (0); - ide->scsi = scsi_alloc_cd (ch, ci->cd_emu_unit, true); + ide->scsi = scsi_alloc_cd (ch, ci->device_emu_unit, true); if (!ide->scsi) { write_log (_T("IDE: CD EMU unit %d failed to open\n"), ide->cd_unit_num); return NULL; } - ide->cd_unit_num = ci->cd_emu_unit; + ide->cd_unit_num = ci->device_emu_unit; ide->atapi = true; ide->blocksize = 512; gui_flicker_led (LED_CD, ch, -1); write_log (_T("IDE%d CD %d\n"), ch, ide->cd_unit_num); - } else { + } else if (ci->type == UAEDEV_HDF) { if (!hdf_hd_open (&ide->hdhfd)) return NULL; ide->blocksize = ide->hdhfd.hfd.ci.blocksize; diff --git a/gfxboard.cpp b/gfxboard.cpp new file mode 100644 index 00000000..cf54c2ca --- /dev/null +++ b/gfxboard.cpp @@ -0,0 +1,869 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* Cirrus Logic based graphics board emulation +* +* Copyright 2013 Toni Wilen +* +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "memory.h" +#include "debug.h" +#include "custom.h" +#include "newcpu.h" +#include "picasso96.h" +#include "statusline.h" +#include "gfxboard.h" + +#include "qemuvga/qemuuaeglue.h" +#include "qemuvga/vga.h" + +#define BOARD_REGISTERS_SIZE 0x00010000 + +#define BOARD_MANUFACTURER_PICASSO 2167 +#define BOARD_MODEL_MEMORY_PICASSOII 11 +#define BOARD_MODEL_REGISTERS_PICASSOII 12 + +#define BOARD_MODEL_MEMORY_PICASSOIV 24 +#define BOARD_MODEL_REGISTERS_PICASSOIV 23 +#define PICASSOIV_REG 0x00600000 +#define PICASSOIV_IO 0x00200000 +#define PICASSOIV_VRAM 0x01000000 + + +#define BOARD_MANUFACTURER_PICCOLO 2195 +#define BOARD_MODEL_MEMORY_PICCOLO 5 +#define BOARD_MODEL_REGISTERS_PICCOLO 6 +#define BOARD_MODEL_MEMORY_PICCOLO64 10 +#define BOARD_MODEL_REGISTERS_PICCOLO64 11 + +#define BOARD_MANUFACTURER_SPECTRUM 2193 +#define BOARD_MODEL_MEMORY_SPECTRUM 1 +#define BOARD_MODEL_REGISTERS_SPECTRUM 2 + +struct gfxboard +{ + TCHAR *name; + int manufacturer; + int model_memory; + int model_registers; + int serial; + int vrammin; + int vrammax; + int banksize; + int chiptype; + bool z3; + bool irq; + bool swap; +}; + +#define PICASSOIV 10 + +static struct gfxboard boards[] = +{ + { + _T("Picasso II"), + BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOII, BOARD_MODEL_REGISTERS_PICASSOII, + 0x00020000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, false, false, false + }, + { + _T("Picasso II+"), + BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOII, BOARD_MODEL_REGISTERS_PICASSOII, + 0x00100000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, false, true, false + }, + { + _T("Piccolo"), + BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO, + 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, false, true, true + }, + { + _T("Piccolo SD64 Zorro II"), + BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64, + 0x00000000, 0x00200000, 0x00400000, 0x00200000, CIRRUS_ID_CLGD5434, false, true, true + }, + { + _T("Piccolo SD64 Zorro III"), + BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64, + 0x00000000, 0x00200000, 0x00400000, 0x01000000, CIRRUS_ID_CLGD5434, true, true, true + }, + { + _T("Spectrum 28/24 Zorro II"), + BOARD_MANUFACTURER_SPECTRUM, BOARD_MODEL_MEMORY_SPECTRUM, BOARD_MODEL_REGISTERS_SPECTRUM, + 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, false, true, true + }, + { + _T("Spectrum 28/24 Zorro III"), + BOARD_MANUFACTURER_SPECTRUM, BOARD_MODEL_MEMORY_SPECTRUM, BOARD_MODEL_REGISTERS_SPECTRUM, + 0x00000000, 0x00100000, 0x00200000, 0x01000000, CIRRUS_ID_CLGD5428, true, true, true + }, + { + _T("Picasso IV Zorro II"), + BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOIV, BOARD_MODEL_REGISTERS_PICASSOIV, + 0x00000000, 0x00400000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5446, false, true, true + }, + { + // REG:00600000 IO:00200000 VRAM:01000000 + _T("Picasso IV Zorro III"), + BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOIV, 0, + 0x00000000, 0x00400000, 0x00400000, 0x04000000, CIRRUS_ID_CLGD5446, true, true, true + } +}; + + +static int configured_mem, configured_regs; +static struct gfxboard *board; +static uae_u32 memory_mask; + +static uae_u8 automemory[256]; +static CirrusVGAState vga; +static uae_u8 *vram; +static uae_u32 gfxboardmem_start; +static bool monswitch; +static bool oldswitch; +static int fullrefresh; +static bool modechanged; +static uae_u8 *gfxboard_surface, *vram_address, *fakesurface_surface; +static bool gfxboard_vblank; +static bool blit_cpu_to_vram; + +static const MemoryRegionOps *vgaio, *vgablitram; +static const MemoryRegion *vgaioregion, *vgavramregion; + +static void init_board (void) +{ + int vramsize = board->vrammax; + xfree (fakesurface_surface); + fakesurface_surface = xmalloc (uae_u8, 4 * 10000); + if (currprefs.rtgmem_type == PICASSOIV) + vramsize = 16 * 1024 * 1024; + vram = mapped_malloc (vramsize, board->z3 ? _T("z3_gfx") : _T("z2_gfx")); + vga.vga.vram_size_mb = currprefs.rtgmem_size >> 20; + vga_common_init(&vga.vga); + cirrus_init_common(&vga, board->chiptype, 0, NULL, NULL); + picasso_allocatewritewatch (currprefs.rtgmem_size); +} + +static void gfxboard_setmode (void) +{ + int bpp, width, height; + + bpp = vga.vga.get_bpp (&vga.vga); + vga.vga.get_resolution (&vga.vga, &width, &height); + + picasso96_state.Width = width; + picasso96_state.Height = height; + picasso96_state.BytesPerPixel = bpp / 8; + picasso96_state.RGBFormat = RGBFB_CLUT; + write_log (_T("GFXBOARD %dx%dx%d\n"), width, height, bpp); + gfx_set_picasso_modeinfo (width, height, bpp, RGBFB_NONE); + fullrefresh = 2; +} + +static bool gfxboard_checkchanged (void) +{ + int bpp, width, height; + bpp = vga.vga.get_bpp (&vga.vga); + vga.vga.get_resolution (&vga.vga, &width, &height); + + if (picasso96_state.Width != width || + picasso96_state.Height != height || + picasso96_state.BytesPerPixel != bpp / 8) + return true; + return false; +} + +static DisplaySurface gfxsurface, fakesurface; +DisplaySurface *qemu_console_surface(QemuConsole *con) +{ + if (picasso_on) + return &gfxsurface; + modechanged = true; + return &fakesurface; +} + +void qemu_console_resize(QemuConsole *con, int width, int height) +{ +} + +static uae_u8 pal64 (uae_u8 v) +{ + v = (v << 2) | ((v >> 2) & 3); + return v; +} + +DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp, + int linesize, uint8_t *data, + bool byteswap) +{ + modechanged = true; + return &fakesurface; +} + +int surface_bits_per_pixel(DisplaySurface *s) +{ + if (s == &fakesurface) + return 32; + return picasso_vidinfo.pixbytes * 8; +} +int surface_bytes_per_pixel(DisplaySurface *s) +{ + if (s == &fakesurface) + return 4; + return picasso_vidinfo.pixbytes; +} + +int surface_stride(DisplaySurface *s) +{ + if (s == &fakesurface) + return 0; + if (gfxboard_surface == NULL) + gfxboard_surface = gfx_lock_picasso (false, false); + return picasso_vidinfo.rowbytes; +} +uint8_t *surface_data(DisplaySurface *s) +{ + if (s == &fakesurface) + return fakesurface_surface; + if (gfxboard_surface == NULL) + gfxboard_surface = gfx_lock_picasso (false, false); + return gfxboard_surface; +} + +void gfxboard_refresh (void) +{ + fullrefresh = 2; +} + +void gfxboard_vsync_handler (void) +{ + if (!configured_mem || !configured_regs) + return; + + if ((modechanged || gfxboard_checkchanged ()) && monswitch) { + gfxboard_setmode (); + init_hz_p96 (); + modechanged = false; + picasso_requested_on = true; + return; + } + + if (monswitch != oldswitch) { + if (!monswitch) + picasso_requested_on = monswitch; + oldswitch = monswitch; + write_log (_T("GFXBOARD ACTIVE=%d\n"), monswitch); + } + + if (monswitch) { + picasso_getwritewatch (); + vga.vga.hw_ops->gfx_update(&vga); + } + + if (picasso_on) { + if (currprefs.leds_on_screen & STATUSLINE_RTG) { + if (gfxboard_surface == NULL) { + gfxboard_surface = gfx_lock_picasso (false, false); + } + if (gfxboard_surface) { + if (!(currprefs.leds_on_screen & STATUSLINE_TARGET)) + picasso_statusline (gfxboard_surface); + } + } + } + + if (gfxboard_surface) + gfx_unlock_picasso (true); + gfxboard_surface = NULL; + + // Vertical Sync End Register, 0x10 = Clear Vertical Interrupt. + if (board->irq && (vga.vga.cr[0x11] & 0x10)) { + gfxboard_vblank = true; + INTREQ (0x8000 | 0x0008); + } + + if (fullrefresh > 0) + fullrefresh--; +} + +double gfxboard_get_vsync (void) +{ + return vblank_hz; // FIXME +} + +void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h) +{ + picasso_invalidate (x, y, w, h); +} + +void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr, + hwaddr size, unsigned client) +{ +} +bool memory_region_get_dirty(MemoryRegion *mr, hwaddr addr, + hwaddr size, unsigned client) +{ + if (mr != vgavramregion) + return false; + if (fullrefresh) + return true; + return picasso_is_vram_dirty (addr + p96ram_start, size); +} + +static QEMUResetHandler *reset_func; +static void *reset_parm; +void qemu_register_reset(QEMUResetHandler *func, void *opaque) +{ + reset_func = func; + reset_parm = opaque; + reset_func (reset_parm); +} + +static void bput_regtest (uaecptr addr, uae_u8 v) +{ + addr += 0x3b0; + if ((addr == 0x3b5 || addr == 0x3c5) && vga.vga.cr_index == 0x11) { + if (!(vga.vga.cr[0x11] & 0x10)) + gfxboard_vblank = false; + } + if (vga.cirrus_srcptr != vga.cirrus_srcptr_end && !blit_cpu_to_vram) { + blit_cpu_to_vram = true; +#ifdef JIT + if (currprefs.cachesize && (!currprefs.comptrustbyte || !currprefs.comptrustword || !currprefs.comptrustlong)) + flush_icache (0, 3); +#endif + } +} + +static uae_u8 bget_regtest (uaecptr addr, uae_u8 v) +{ + addr += 0x3b0; + if (gfxboard_vblank) { + // Input Status 0 + if (addr == 0x3c2) { + // Disable Vertical Interrupt == 0? + // Clear Vertical Interrupt == 1 + if (!(vga.vga.cr[0x11] & 0x20) && (vga.vga.cr[0x11] & 0x10)) { + v |= 0x80; // interrupt pending + } + } + } + return v; +} + +static void checkblitend (void) +{ + if (vga.cirrus_srcptr == vga.cirrus_srcptr_end) { + blit_cpu_to_vram = false; + } +} + +void *memory_region_get_ram_ptr(MemoryRegion *mr) +{ + if (mr == vgavramregion) + return vram; + return NULL; +} + +void memory_region_init_ram(MemoryRegion *mr, + const char *name, + uint64_t size) +{ + if (!stricmp (name, "vga.vram")) { + vgavramregion = mr; + } +} + +void memory_region_init_io(MemoryRegion *mr, + const MemoryRegionOps *ops, + void *opaque, + const char *name, + uint64_t size) +{ + if (!stricmp (name, "cirrus-io")) { + vgaio = ops; + vgaioregion = mr; + } else if (!stricmp (name, "cirrus-low-memory")) { + vgablitram = ops; + } +} + +int is_surface_bgr(DisplaySurface *surface) +{ + return board->swap; +} + +static uae_u32 REGPARAM2 gfxboard_lget_mem (uaecptr addr) +{ +#if 0 +#ifdef JIT + special_mem |= S_READ; +#endif + return vgavram->read (&vga, addr, 4); +#else + uae_u8 *m; + addr -= gfxboardmem_start & memory_mask; + addr &= memory_mask; + m = vram + addr; + return do_get_mem_long ((uae_u32 *)m); +#endif +} +static uae_u32 REGPARAM2 gfxboard_wget_mem (uaecptr addr) +{ +#if 0 +#ifdef JIT + special_mem |= S_READ; +#endif + return vgavram->read (&vga, addr, 2); +#else + uae_u8 *m; + addr -= gfxboardmem_start & memory_mask; + addr &= memory_mask; + m = vram + addr; + return do_get_mem_word ((uae_u16 *)m); +#endif +} +static uae_u32 REGPARAM2 gfxboard_bget_mem (uaecptr addr) +{ +#if 0 +#ifdef JIT + special_mem |= S_READ; +#endif + return vgavram->read (&vga, addr, 1); +#else + addr -= gfxboardmem_start & memory_mask; + addr &= memory_mask; + return vram[addr]; +#endif +} +static void REGPARAM2 gfxboard_lput_mem (uaecptr addr, uae_u32 l) +{ + if (blit_cpu_to_vram) { +#ifdef JIT + special_mem |= S_WRITE; +#endif + vgablitram->write (&vga, 0, l >> 24, 1); + vgablitram->write (&vga, 0, l >> 16, 1); + vgablitram->write (&vga, 0, l >> 8, 1); + vgablitram->write (&vga, 0, l >> 0, 1); + checkblitend (); + } else { + uae_u8 *m; + addr -= gfxboardmem_start & memory_mask; + addr &= memory_mask; + m = vram + addr; + do_put_mem_long ((uae_u32 *) m, l); + } +} +static void REGPARAM2 gfxboard_wput_mem (uaecptr addr, uae_u32 w) +{ + if (blit_cpu_to_vram) { +#ifdef JIT + special_mem |= S_WRITE; +#endif + vgablitram->write (&vga, 0, w >> 8, 1); + vgablitram->write (&vga, 0, w >> 0, 1); + checkblitend (); + } else { + uae_u8 *m; + addr -= gfxboardmem_start & memory_mask; + addr &= memory_mask; + m = vram + addr; + do_put_mem_word ((uae_u16 *)m, w); + } +} +static void REGPARAM2 gfxboard_bput_mem (uaecptr addr, uae_u32 b) +{ + if (blit_cpu_to_vram) { +#ifdef JIT + special_mem |= S_WRITE; +#endif + vgablitram->write (&vga, 0, b, 1); + checkblitend (); + } else { + addr -= gfxboardmem_start & memory_mask; + addr &= memory_mask; + vram[addr] = b; + } +} + +static int REGPARAM2 gfxboard_check (uaecptr addr, uae_u32 size) +{ + addr -= gfxboardmem_start & memory_mask; + addr &= memory_mask; + return (addr + size) <= currprefs.rtgmem_size; +} +static uae_u8 *REGPARAM2 gfxboard_xlate (uaecptr addr) +{ + addr -= gfxboardmem_start & memory_mask; + addr &= memory_mask; + return vram + addr; +} + +static uae_u32 REGPARAM2 gfxboard_bget_mem_autoconfig (uaecptr addr) +{ + uae_u32 v = 0; +#ifdef JIT + special_mem |= S_READ; +#endif + addr &= 65535; + if (addr < 0x40) + v = automemory[addr]; + return v; +} + +static void REGPARAM2 gfxboard_wput_mem_autoconfig (uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + if (!board->z3) + return; + b &= 0xffff; + addr &= 65535; + if (addr == 0x44) { + put_word (regs.regs[11] + 0x20, p96ram_start >> 16); + put_word (regs.regs[11] + 0x28, p96ram_start >> 16); + gfxboard_bank_memory.bget = gfxboard_bget_mem; + gfxboard_bank_memory.bput = gfxboard_bput_mem; + gfxboard_bank_memory.wput = gfxboard_wput_mem; + if (currprefs.rtgmem_type == PICASSOIV) { + map_banks (&gfxboard_bank_memory, (p96ram_start + PICASSOIV_VRAM) >> 16, (board->banksize - PICASSOIV_VRAM) >> 16, currprefs.rtgmem_size); + map_banks (&gfxboard_bank_registers, (p96ram_start + PICASSOIV_IO) >> 16, BOARD_REGISTERS_SIZE >> 16, BOARD_REGISTERS_SIZE); + } else { + map_banks (&gfxboard_bank_memory, p96ram_start >> 16, board->banksize >> 16, currprefs.rtgmem_size); + } + write_log (_T("%s autoconfigured at 0x%04X0000\n"), gfxboard_bank_memory.name, p96ram_start >> 16); + configured_mem = p96ram_start >> 16; + gfxboardmem_start = p96ram_start; + expamem_next (); + return; + } + if (addr == 0x4c) { + write_log (_T("%s AUTOCONFIG SHUT-UP!\n"), gfxboard_bank_memory.name); + configured_mem = 0xff; + expamem_next (); + return; + } +} + + +static void REGPARAM2 gfxboard_bput_mem_autoconfig (uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + b &= 0xff; + addr &= 65535; + if (addr == 0x48) { + if (!board->z3) { + gfxboard_bank_memory.bget = gfxboard_bget_mem; + gfxboard_bank_memory.bput = gfxboard_bput_mem; + map_banks (&gfxboard_bank_memory, b, board->banksize >> 16, currprefs.rtgmem_size); + write_log (_T("%s autoconfigured at 0x00%02X0000\n"), gfxboard_bank_memory.name, b); + configured_mem = b; + gfxboardmem_start = b << 16; + expamem_next (); + } + return; + } + if (addr == 0x4c) { + write_log (_T("%s AUTOCONFIG SHUT-UP!\n"), gfxboard_bank_memory.name); + configured_mem = 0xff; + expamem_next (); + return; + } +} + +static uaecptr mungeaddr (uaecptr addr) +{ + addr &= 65535; + if (addr >= 0x2000) + return 0; + if (addr >= 0x1000) + addr++; + addr &= 0x0fff; + if (addr < 0x3b0) + return 0; + addr -= 0x3b0; + return addr; +} + +static uae_u32 REGPARAM2 gfxboard_lget_regs (uaecptr addr) +{ + uae_u32 v = 0xffffffff; +#ifdef JIT + special_mem |= S_READ; +#endif + addr = mungeaddr (addr); + if (addr) + v = vgaio->read (&vga, addr, 4); + return v; +} +static uae_u32 REGPARAM2 gfxboard_wget_regs (uaecptr addr) +{ + uae_u16 v = 0xffff; +#ifdef JIT + special_mem |= S_READ; +#endif + addr = mungeaddr (addr); + if (addr) { + uae_u8 v1, v2; + v1 = vgaio->read (&vga, addr + 0, 1); + v1 = bget_regtest (addr + 0, v1); + v2 = vgaio->read (&vga, addr + 1, 1); + v2 = bget_regtest (addr + 1, v2); + v = (v1 << 8) | v2; + } + return v; +} +static uae_u32 REGPARAM2 gfxboard_bget_regs (uaecptr addr) +{ + uae_u8 v = 0xff; +#ifdef JIT + special_mem |= S_READ; +#endif + addr &= 65535; + if (addr >= 0x8000) + return 0; + addr = mungeaddr (addr); + if (addr) { + v = vgaio->read (&vga, addr, 1); + v = bget_regtest (addr, v); + } + return v; +} + +static void REGPARAM2 gfxboard_lput_regs (uaecptr addr, uae_u32 l) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + //write_log (_T("GFX LONG PUT IO %04X = %04X\n"), addr & 65535, l); + addr = mungeaddr (addr); + if (addr) + vgaio->write (&vga, addr, l, 4); +} +static void REGPARAM2 gfxboard_wput_regs (uaecptr addr, uae_u32 w) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + //write_log (_T("GFX WORD PUT IO %04X = %04X\n"), addr & 65535, w & 0xffff); + addr = mungeaddr (addr); + if (addr) { + vgaio->write (&vga, addr + 0, (w >> 8) & 0xff, 1); + bput_regtest (addr + 0, (w >> 8) & 0xff); + vgaio->write (&vga, addr + 1, (w >> 0) & 0xff, 1); + bput_regtest (addr + 1, (w >> 0) & 0xff); + } +} +static void REGPARAM2 gfxboard_bput_regs (uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + //write_log (_T("GFX BYTE PUT IO %04X = %02X\n"), addr & 65535, b & 0xff); + addr &= 65535; + if (addr >= 0x8000) { + write_log (_T("GFX SPECIAL BYTE PUT IO %04X = %02X\n"), addr & 65535, b & 0xff); + switch (board->manufacturer) + { + case BOARD_MANUFACTURER_PICASSO: + { + int idx = addr >> 12; + if (idx == 11) + monswitch = false; + else if (idx == 10) + monswitch = true; + } + break; + case BOARD_MANUFACTURER_PICCOLO: + case BOARD_MANUFACTURER_SPECTRUM: + monswitch = (b & 0x20) != 0; + break; + } + return; + } + addr = mungeaddr (addr); + if (addr) { + vgaio->write (&vga, addr, b & 0xff, 1); + bput_regtest (addr, b); + } +} + +static uae_u32 REGPARAM2 gfxboard_bget_regs_autoconfig (uaecptr addr) +{ + uae_u32 v = 0; +#ifdef JIT + special_mem |= S_READ; +#endif + addr &= 65535; + if (addr < 0x40) + v = automemory[addr]; + return v; +} + +static void REGPARAM2 gfxboard_bput_regs_autoconfig (uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + b &= 0xff; + addr &= 65535; + if (addr == 0x48) { + gfxboard_bank_registers.bget = gfxboard_bget_regs; + gfxboard_bank_registers.bput = gfxboard_bput_regs; + map_banks (&gfxboard_bank_registers, b, BOARD_REGISTERS_SIZE >> 16, BOARD_REGISTERS_SIZE); + write_log (_T("%s autoconfigured at 0x00%02X0000\n"), gfxboard_bank_registers.name, b); + configured_regs = b; + init_board (); + expamem_next (); + return; + } + if (addr == 0x4c) { + write_log (_T("%s AUTOCONFIG SHUT-UP!\n"), gfxboard_bank_registers.name); + configured_regs = 0xff; + expamem_next (); + return; + } +} + +static void ew (int addr, uae_u32 value) +{ + addr &= 0xffff; + if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) { + automemory[addr] = (value & 0xf0); + automemory[addr + 2] = (value & 0x0f) << 4; + } else { + automemory[addr] = ~(value & 0xf0); + automemory[addr + 2] = ~((value & 0x0f) << 4); + } +} + +void gfxboard_reset (void) +{ + if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE) { + board = &boards[currprefs.rtgmem_type - GFXBOARD_HARDWARE]; + memory_mask = currprefs.rtgmem_size - 1; + } + if (vram) + mapped_free (vram); + vram = NULL; + xfree (fakesurface_surface); + fakesurface_surface = NULL; + configured_mem = 0; + configured_regs = 0; + gfxboard_bank_registers.bget = gfxboard_bget_regs_autoconfig; + gfxboard_bank_registers.bput = gfxboard_bput_regs_autoconfig; + gfxboard_bank_memory.bget = gfxboard_bget_mem_autoconfig; + gfxboard_bank_memory.bput = gfxboard_bput_mem_autoconfig; + if (board) { + if (board->z3) + gfxboard_bank_memory.wput = gfxboard_wput_mem_autoconfig; + if (reset_func) + reset_func (reset_parm); + } +} + +addrbank gfxboard_bank_memory = { + gfxboard_lget_mem, gfxboard_wget_mem, gfxboard_bget_mem, + gfxboard_lput_mem, gfxboard_wput_mem, gfxboard_bput_mem_autoconfig, + gfxboard_xlate, gfxboard_check, NULL, NULL, + gfxboard_lget_mem, gfxboard_wget_mem, ABFLAG_RAM +}; +addrbank gfxboard_bank_registers = { + gfxboard_lget_regs, gfxboard_wget_regs, gfxboard_bget_regs, + gfxboard_lput_regs, gfxboard_wput_regs, gfxboard_bput_regs_autoconfig, + default_xlate, default_check, NULL, NULL, + dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE +}; + +bool gfxboard_is_z3 (int type) +{ + if (type == GFXBOARD_UAE_Z2) + return false; + if (type == GFXBOARD_UAE_Z3) + return true; + board = &boards[type - GFXBOARD_HARDWARE]; + return board->z3; +} + +int gfxboard_get_vram_min (int type) +{ + if (type < 2) + return -1; + board = &boards[type - 2]; + return board->vrammax; //board->vrammin; +} + +int gfxboard_get_vram_max (int type) +{ + if (type < 2) + return -1; + board = &boards[type - 2]; + return board->vrammax; +} + +bool gfxboard_is_registers (int type) +{ + if (type < 2) + return false; + board = &boards[type - 2]; + return board->model_registers != 0; +} + +void gfxboard_init_memory (void) +{ + int vram = currprefs.rtgmem_size; + uae_u8 flags; + memset (automemory, 0xff, sizeof automemory); + + flags = 0x05; + vram /= 0x00100000; + while (vram > 1) { + flags++; + vram >>= 1; + } + if (board->z3) { + ew (0x00, 0x00 | 0x08 | 0x80); // 16M Z3 + ew (0x08, flags | 0x10); + } else { + ew (0x00, flags | 0x08 | 0xc0); + } + ew (0x04, board->model_memory); + ew (0x10, board->manufacturer >> 8); + ew (0x14, board->manufacturer); + + uae_u32 ser = board->serial; + ew (0x18, ser >> 24); /* ser.no. Byte 0 */ + ew (0x1c, ser >> 16); /* ser.no. Byte 1 */ + ew (0x20, ser >> 8); /* ser.no. Byte 2 */ + ew (0x24, ser >> 0); /* ser.no. Byte 3 */ + + gfxboard_bank_memory.name = board->name; + gfxboard_bank_registers.name = board->name; + map_banks (&gfxboard_bank_memory, 0xe80000 >> 16, 0x10000 >> 16, 0x10000); +} + +void gfxboard_init_registers (void) +{ + if (!board->model_registers) + return; + memset (automemory, 0xff, sizeof automemory); + ew (0x00, 0xc0 | 0x01); // 64k Z2 + ew (0x04, board->model_registers); + ew (0x10, board->manufacturer >> 8); + ew (0x14, board->manufacturer); + + uae_u32 ser = board->serial; + ew (0x18, ser >> 24); /* ser.no. Byte 0 */ + ew (0x1c, ser >> 16); /* ser.no. Byte 1 */ + ew (0x20, ser >> 8); /* ser.no. Byte 2 */ + ew (0x24, ser >> 0); /* ser.no. Byte 3 */ + + map_banks (&gfxboard_bank_registers, 0xe80000 >> 16, 0x10000 >> 16, 0x10000); +} diff --git a/hardfile.cpp b/hardfile.cpp index 60b68dc3..7e161428 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -35,7 +35,7 @@ #include "archivers/chd/chd.h" #endif -#undef DEBUGME +//#undef DEBUGME #define hf_log #define hf_log2 #define scsi_log @@ -1121,8 +1121,6 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua char *ss; *reply_len = *sense_len = 0; - memset (r, 0, 256); - memset (s, 0, 256); lun = cmdbuf[1] >> 5; if (cmdbuf[0] != 0x03 && cmdbuf[0] != 0x12 && lun) { status = 2; /* CHECK CONDITION */ diff --git a/include/a2091.h b/include/a2091.h index d00edd49..fe32c431 100644 --- a/include/a2091.h +++ b/include/a2091.h @@ -28,5 +28,6 @@ extern int a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci); extern int add_scsi_hd (int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level); extern int add_scsi_cd (int ch, int unitnum); +extern int add_scsi_tape (int ch, const TCHAR *tape_directory, bool readonly); #endif diff --git a/include/blkdev.h b/include/blkdev.h index 75361378..9e4f6a17 100644 --- a/include/blkdev.h +++ b/include/blkdev.h @@ -155,6 +155,7 @@ struct device_functions { extern int device_func_init(int flags); extern void device_func_reset(void); extern int sys_command_open (int unitnum); +extern int sys_command_open_tape (int unitnum, const TCHAR *tape_directory, bool readonly); extern void sys_command_close (int unitnum); extern int sys_command_isopen (int unitnum); extern struct device_info *sys_command_info (int unitnum, struct device_info *di, int); @@ -170,8 +171,8 @@ extern int sys_command_cd_rawread (int unitnum, uae_u8 *data, int sector, int si extern int sys_command_cd_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize, uae_u8 scsicmd9, uae_u8 subs); extern int sys_command_read (int unitnum, uae_u8 *data, int block, int size); extern int sys_command_write (int unitnum, uae_u8 *data, int block, int size); -extern int sys_command_scsi_direct_native (int unitnum, struct amigascsi *as); -extern int sys_command_scsi_direct (int unitnum, uaecptr request); +extern int sys_command_scsi_direct_native (int unitnum, int type, struct amigascsi *as); +extern int sys_command_scsi_direct (int unitnum, int type, uaecptr request); extern int sys_command_ismedia (int unitnum, int quick); extern struct device_info *sys_command_info_session (int unitnum, struct device_info *di, int, int); extern bool blkdev_get_info (struct uae_prefs *p, int unitnum, struct device_info *di); diff --git a/include/debug.h b/include/debug.h index a266288c..9c51d332 100644 --- a/include/debug.h +++ b/include/debug.h @@ -42,6 +42,12 @@ extern int debug_bankchange (int); extern void log_dma_record (void); extern void debug_parser (const TCHAR *cmd, TCHAR *out, uae_u32 outsize); extern void mmu_disasm (uaecptr pc, int lines); +extern int debug_read_memory_16 (uaecptr addr); +extern int debug_peek_memory_16 (uaecptr addr); +extern int debug_read_memory_8 (uaecptr addr); +extern int debug_peek_memory_8 (uaecptr addr); +extern int debug_write_memory_16 (uaecptr addr, uae_u16 v); +extern int debug_write_memory_8 (uaecptr addr, uae_u8 v); #define BREAKPOINT_TOTAL 20 struct breakpoint_node { diff --git a/include/ethernet.h b/include/ethernet.h new file mode 100644 index 00000000..bad2d8e3 --- /dev/null +++ b/include/ethernet.h @@ -0,0 +1,34 @@ + + +#define UAENET_NONE 0 +#define UAENET_SLIRP 1 +#define UAENET_PCAP 2 + +struct netdriverdata +{ + int type; + TCHAR *name; + TCHAR *desc; + int mtu; + uae_u8 mac[6]; + int active; +}; + + +typedef void (ethernet_gotfunc)(struct s2devstruct *dev, const uae_u8 *data, int len); +typedef int (ethernet_getfunc)(struct s2devstruct *dev, uae_u8 *d, int *len); + +extern bool ethernet_enumerate (struct netdriverdata **, const TCHAR *name); +extern void ethernet_enumerate_free (void); +extern void ethernet_close_driver (struct netdriverdata *ndd); + +extern int ethernet_getdatalenght (struct netdriverdata *ndd); +extern int ethernet_getbytespending (void*); +extern int ethernet_open (struct netdriverdata *ndd, void*, void*, ethernet_gotfunc*, ethernet_getfunc*, int); +extern void ethernet_close (struct netdriverdata *ndd, void*); +extern void ethernet_gotdata (struct s2devstruct *dev, const uae_u8 *data, int len); +extern int ethernet_getdata (struct s2devstruct *dev, uae_u8 *d, int *len); +extern void ethernet_trigger (void*); + +extern bool slirp_start (void); +extern void slirp_end (void); \ No newline at end of file diff --git a/include/filesys.h b/include/filesys.h index 36ab02b9..81efaf7b 100644 --- a/include/filesys.h +++ b/include/filesys.h @@ -104,6 +104,7 @@ struct hd_hardfiledata { #define FILESYS_HARDFILE_RDB 2 #define FILESYS_HARDDRIVE 3 #define FILESYS_CD 4 +#define FILESYS_TAPE 5 #define MAX_FILESYSTEM_UNITS 30 diff --git a/include/gfxboard.h b/include/gfxboard.h new file mode 100644 index 00000000..81d0a4e5 --- /dev/null +++ b/include/gfxboard.h @@ -0,0 +1,20 @@ + +extern addrbank gfxboard_bank_memory; +extern addrbank gfxboard_bank_memory_blit; +extern addrbank gfxboard_bank_registers; + +extern void gfxboard_init_memory (void); +extern void gfxboard_init_registers (void); +extern void gfxboard_free (void); +extern void gfxboard_reset (void); +extern void gfxboard_vsync_handler (void); +extern bool gfxboard_is_z3 (int); +extern bool gfxboard_is_registers (int); +extern int gfxboard_get_vram_min (int); +extern int gfxboard_get_vram_max (int); +extern double gfxboard_get_vsync (void); +extern void gfxboard_refresh (void); + +#define GFXBOARD_UAE_Z2 0 +#define GFXBOARD_UAE_Z3 1 +#define GFXBOARD_HARDWARE 2 diff --git a/include/luascript.h b/include/luascript.h new file mode 100644 index 00000000..5f0eb13f --- /dev/null +++ b/include/luascript.h @@ -0,0 +1,26 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* LUA Scripting Layer +* +* Copyright 2013 Frode SOlheim +*/ + +#ifndef LUASCRIPT_H_ +#define LUASCRIPT_H_ + +#ifdef WITH_LUA +#include + +void uae_lua_init(void); +void uae_lua_load(const TCHAR *filename); +void uae_lua_loadall(void); +void uae_lua_free(void); +void uae_lua_init_state(lua_State *L); +void uae_lua_run_handler(const char *name); +void uae_lua_aquire_lock(); +void uae_lua_release_lock(); + +#endif // WITH_LUA + +#endif // LUASCRIPT_H_ diff --git a/include/options.h b/include/options.h index 09b6de10..8a6e61b5 100644 --- a/include/options.h +++ b/include/options.h @@ -8,8 +8,8 @@ */ #define UAEMAJOR 2 -#define UAEMINOR 6 -#define UAESUBREV 1 +#define UAEMINOR 7 +#define UAESUBREV 0 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang; @@ -113,6 +113,7 @@ struct wh { #define UAEDEV_DIR 0 #define UAEDEV_HDF 1 #define UAEDEV_CD 2 +#define UAEDEV_TAPE 3 #define BOOTPRI_NOAUTOBOOT -128 #define BOOTPRI_NOAUTOMOUNT -129 @@ -148,14 +149,15 @@ struct uaedev_config_info { int interleave; int sectorsperblock; int forceload; - int cd_emu_unit; + int device_emu_unit; }; struct uaedev_config_data { struct uaedev_config_info ci; - int configoffset; + int configoffset; // HD config entry index + int unitnum; // scsi unit number (if tape currently) }; enum { CP_GENERIC = 1, CP_CDTV, CP_CD32, CP_A500, CP_A500P, CP_A600, CP_A1000, @@ -226,6 +228,8 @@ struct apmode int gfx_refreshrate; }; +#define MAX_LUA_STATES 16 + struct uae_prefs { struct strlist *all_lines; @@ -467,6 +471,7 @@ struct uae_prefs { bool rtg_hardwareinterrupt; bool rtg_hardwaresprite; int rtgmem_type; + bool rtg_more_compatible; uae_u32 custom_memory_addrs[MAX_CUSTOM_MEMORY_ADDRS]; uae_u32 custom_memory_sizes[MAX_CUSTOM_MEMORY_ADDRS]; @@ -488,6 +493,8 @@ struct uae_prefs { int dfxclickvolume; int dfxclickchannelmask; + TCHAR luafiles[MAX_LUA_STATES][MAX_DPATH]; + /* Target specific options */ bool win32_middle_mouse; @@ -570,6 +577,7 @@ struct uae_prefs { extern int config_changed; extern void config_check_vsync (void); +extern void set_config_changed (void); /* Contains the filename of .uaerc */ extern TCHAR optionsfile[]; @@ -623,6 +631,7 @@ extern void cfgfile_parse_lines (struct uae_prefs *p, const TCHAR *, int); extern int cfgfile_parse_option (struct uae_prefs *p, TCHAR *option, TCHAR *value, int); extern int cfgfile_get_description (const TCHAR *filename, TCHAR *description, TCHAR *hostlink, TCHAR *hardwarelink, int *type); extern void cfgfile_show_usage (void); +extern int cfgfile_searchconfig(const TCHAR *in, int index, TCHAR *out, int outsize); extern uae_u32 cfgfile_uaelib (int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen); extern uae_u32 cfgfile_uaelib_modify (uae_u32 mode, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize); extern uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize); diff --git a/include/packed.h b/include/packed.h new file mode 100644 index 00000000..0ac0fd64 --- /dev/null +++ b/include/packed.h @@ -0,0 +1,5 @@ +#ifdef _MSC_VER +#define PACKED +#pragma pack(push,1) +#endif + diff --git a/include/savestate.h b/include/savestate.h index 3c1a3e60..9d8b186e 100644 --- a/include/savestate.h +++ b/include/savestate.h @@ -138,8 +138,8 @@ extern uae_u8 *save_cdtv_dmac (int *len, uae_u8*); extern uae_u8 *restore_scsi_dmac (uae_u8 *src); extern uae_u8 *save_scsi_dmac (int *len, uae_u8*); -extern uae_u8 *save_scsi_hd (int num, int *len, uae_u8 *dstptr); -extern uae_u8 *restore_scsi_hd (uae_u8 *src); +extern uae_u8 *save_scsi_device (int num, int *len, uae_u8 *dstptr); +extern uae_u8 *restore_scsi_device (uae_u8 *src); extern uae_u8 *restore_filesys (uae_u8 *src); extern uae_u8 *save_filesys (int num, int *len); diff --git a/include/scsi.h b/include/scsi.h index f09d44ec..71cbc9a0 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -1,5 +1,22 @@ #define SCSI_DATA_BUFFER_SIZE (512 * 512) + +struct scsi_data_tape +{ + TCHAR tape_dir[MAX_DPATH]; + int file_number; + uae_s64 file_offset; + int blocksize; + bool realdir; + struct zdirectory *zd; + struct my_opendir_s *od; + struct zfile *zf; + struct zfile *index; + int beom; + bool wp; + bool nomedia; +}; + struct scsi_data { int id; @@ -19,13 +36,16 @@ struct scsi_data int offset; uae_u8 buffer[SCSI_DATA_BUFFER_SIZE]; struct hd_hardfiledata *hfd; - int nativescsiunit; + struct scsi_data_tape *tape; + int device_type; + int nativescsiunit; int cd_emu_unit; bool atapi; }; extern struct scsi_data *scsi_alloc_hd(int, struct hd_hardfiledata*); extern struct scsi_data *scsi_alloc_cd(int, int, bool); +extern struct scsi_data *scsi_alloc_tape(int id, const TCHAR *tape_directory, bool readonly); extern struct scsi_data *scsi_alloc_native(int, int); extern void scsi_free(struct scsi_data*); extern void scsi_reset(void); @@ -35,7 +55,56 @@ extern int scsi_send_data(struct scsi_data*, uae_u8); extern int scsi_receive_data(struct scsi_data*, uae_u8*); extern void scsi_emulate_cmd(struct scsi_data *sd); extern void scsi_illegal_lun(struct scsi_data *sd); +extern void scsi_clear_sense(struct scsi_data *sd); extern int scsi_hd_emulate(struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, uae_u8 *cmdbuf, int scsi_cmd_len, uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len); -extern void scsi_emulate_analyze (struct scsi_data*); \ No newline at end of file +extern int scsi_tape_emulate(struct scsi_data_tape *sd, uae_u8 *cmdbuf, int scsi_cmd_len, + uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len); +extern void scsi_emulate_analyze (struct scsi_data*); + +extern bool tape_get_info (int, struct device_info*); +extern struct scsi_data_tape *tape_alloc (int unitnum, const TCHAR *tape_directory, bool readonly); +extern void tape_free (struct scsi_data_tape*); +extern void tape_media_change (int unitnum, struct uaedev_config_info*); + +#define SCSI_NO_SENSE_DATA 0x00 +#define SCSI_NOT_READY 0x04 +#define SCSI_NOT_LOADED 0x09 +#define SCSI_INSUF_CAPACITY 0x0a +#define SCSI_HARD_DATA_ERROR 0x11 +#define SCSI_WRITE_PROTECT 0x17 +#define SCSI_CORRECTABLE_ERROR 0x18 +#define SCSI_FILE_MARK 0x1c +#define SCSI_INVALID_COMMAND 0x20 +#define SCSI_INVALID_FIELD 0x24 +#define SCSI_INVALID_LUN 0x25 +#define SCSI_UNIT_ATTENTION 0x30 +#define SCSI_END_OF_MEDIA 0x34 +#define SCSI_MEDIUM_NOT_PRESENT 0x3a + +#define SCSI_SK_NO_SENSE 0x0 +#define SCSI_SK_REC_ERR 0x1 /* recovered error */ +#define SCSI_SK_NOT_READY 0x2 +#define SCSI_SK_MED_ERR 0x3 /* medium error */ +#define SCSI_SK_HW_ERR 0x4 /* hardware error */ +#define SCSI_SK_ILLEGAL_REQ 0x5 +#define SCSI_SK_UNIT_ATT 0x6 /* unit attention */ +#define SCSI_SK_DATA_PROTECT 0x7 +#define SCSI_SK_BLANK_CHECK 0x8 +#define SCSI_SK_VENDOR_SPEC 0x9 +#define SCSI_SK_COPY_ABORTED 0xA +#define SCSI_SK_ABORTED_CMND 0xB +#define SCSI_SK_VOL_OVERFLOW 0xD +#define SCSI_SK_MISCOMPARE 0xE + +#define SCSI_STATUS_GOOD 0x00 +#define SCSI_STATUS_CHECK_CONDITION 0x02 +#define SCSI_STATUS_CONDITION_MET 0x04 +#define SCSI_STATUS_BUSY 0x08 +#define SCSI_STATUS_INTERMEDIATE 0x10 +#define SCSI_STATUS_ICM 0x14 /* intermediate condition met */ +#define SCSI_STATUS_RESERVATION_CONFLICT 0x18 +#define SCSI_STATUS_COMMAND_TERMINATED 0x22 +#define SCSI_STATUS_QUEUE_FULL 0x28 +#define SCSI_STATUS_ACA_ACTIVE 0x30 \ No newline at end of file diff --git a/include/scsidev.h b/include/scsidev.h index fdbe4bd1..aaa542f7 100644 --- a/include/scsidev.h +++ b/include/scsidev.h @@ -16,6 +16,7 @@ int scsi_do_disk_change (int unitnum, int insert, int *pollmode); int scsi_do_disk_device_change (void); uae_u32 scsi_get_cd_drive_mask (void); uae_u32 scsi_get_cd_drive_media_mask (void); +int scsi_add_tape (struct uaedev_config_info *uci); extern int log_scsi; diff --git a/include/sysdeps.h b/include/sysdeps.h index d976c54c..189959c3 100644 --- a/include/sysdeps.h +++ b/include/sysdeps.h @@ -444,8 +444,10 @@ extern void mallocemu_free (void *ptr); #if __GNUC__ - 1 > 1 || __GNUC_MINOR__ - 1 > 6 extern void write_log (const TCHAR *, ...) __attribute__ ((format (printf, 1, 2))); +extern void write_log (char *, ...) __attribute__ ((format (printf, 1, 2))); #else extern void write_log (const TCHAR *, ...); +extern void write_log (const char *, ...); #endif extern void write_dlog (const TCHAR *, ...); diff --git a/include/uae.h b/include/uae.h index 2180d22e..f02342b5 100644 --- a/include/uae.h +++ b/include/uae.h @@ -65,6 +65,7 @@ struct bstring { extern TCHAR *colormodes[]; extern void fetch_saveimagepath (TCHAR*, int, int); extern void fetch_configurationpath (TCHAR *out, int size); +extern void fetch_luapath (TCHAR *out, int size); extern void fetch_screenshotpath (TCHAR *out, int size); extern void fetch_ripperpath (TCHAR *out, int size); extern void fetch_statefilepath (TCHAR *out, int size); diff --git a/include/unpacked.h b/include/unpacked.h new file mode 100644 index 00000000..c5608d67 --- /dev/null +++ b/include/unpacked.h @@ -0,0 +1,8 @@ +#ifdef _MSC_VER +; +#pragma pack(pop) +#undef PACKED +#else +PACKED__; +#endif + diff --git a/include/zfile.h b/include/zfile.h index 57090c15..97192da4 100644 --- a/include/zfile.h +++ b/include/zfile.h @@ -122,6 +122,7 @@ extern struct zdirectory *zfile_opendir_archive (const TCHAR *path, int flags); extern void zfile_closedir_archive (struct zdirectory *); extern int zfile_readdir_archive (struct zdirectory *, TCHAR*); extern int zfile_readdir_archive (struct zdirectory *, TCHAR*, bool fullpath); +extern struct zfile *zfile_readdir_archive_open (struct zdirectory *zd, const TCHAR *mode); extern void zfile_resetdir_archive (struct zdirectory *); extern int zfile_fill_file_attrs_archive (const TCHAR *path, int *isdir, int *flags, TCHAR **comment); extern uae_s64 zfile_lseek_archive (struct zfile *d, uae_s64 offset, int whence); diff --git a/inputdevice.cpp b/inputdevice.cpp index 1c156dba..2e8cb4bc 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -2383,7 +2383,7 @@ static int handle_custom_event (const TCHAR *custom) if (custom == NULL) return 0; - config_changed = 1; + set_config_changed (); write_log (_T("%s\n"), custom); p = buf = my_strdup_trim (custom); if (p[0] != '\"') @@ -2408,7 +2408,7 @@ static int handle_custom_event (const TCHAR *custom) if (!_tcsicmp (p, _T("no_config_check"))) { config_changed = 0; } else if (!_tcsicmp (p, _T("do_config_check"))) { - config_changed = 1; + set_config_changed (); } else if (!_tcsnicmp (p, _T("dbg "), 4)) { debug_parser (p + 4, NULL, -1); } else if (!_tcsnicmp (p, _T("kbr "), 4)) { @@ -2889,7 +2889,7 @@ void inputdevice_handle_inputcode (void) changed_prefs.chipset_refreshrate = 10.0; if (changed_prefs.chipset_refreshrate > 900.0) changed_prefs.chipset_refreshrate = 900.0; - config_changed = 1; + set_config_changed (); } break; case AKS_DISKSWAPPER_NEXT: @@ -2912,7 +2912,7 @@ void inputdevice_handle_inputcode (void) case AKS_DISKSWAPPER_INSERT2: case AKS_DISKSWAPPER_INSERT3: _tcscpy (changed_prefs.floppyslots[code - AKS_DISKSWAPPER_INSERT0].df, currprefs.dfxlist[swapperslot]); - config_changed = 1; + set_config_changed (); break; break; @@ -5277,7 +5277,7 @@ void inputdevice_updateconfig (const struct uae_prefs *srcprefs, struct uae_pref { inputdevice_updateconfig_internal (srcprefs, dstprefs); - config_changed = 1; + set_config_changed (); #ifdef RETROPLATFORM rp_input_change (0); @@ -5353,7 +5353,7 @@ void inputdevice_devicechange (struct uae_prefs *prefs) #ifdef RETROPLATFORM rp_enumdevices (); #endif - config_changed = 1; + set_config_changed (); } @@ -6609,12 +6609,13 @@ void setjoystickstate (int joy, int axis, int state, int max) v1 = state; v2 = id2->states[axis][MAX_INPUT_SUB_EVENT]; - write_log (_T("new=%d old=%d state=%d max=%d\n"), v1, v2, state, max); - if (v1 < deadzone && v1 > -deadzone) v1 = 0; if (v2 < deadzone && v2 > -deadzone) v2 = 0; + + //write_log (_T("%d:%d new=%d old=%d state=%d max=%d\n"), joy, axis, v1, v2, state, max); + if (input_play && state) { if (v1 != v2) inprec_realtime (); @@ -6628,12 +6629,13 @@ void setjoystickstate (int joy, int axis, int state, int max) } for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) { uae_u64 flags = id->flags[ID_AXIS_OFFSET + axis][i]; + int state2 = v1; if (flags & ID_FLAG_INVERT) - state = -state; - if (state != id2->states[axis][i]) { - write_log(_T("-> %d %d\n"), i, state); - handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, flags & ID_FLAG_AUTOFIRE, true, false); - id2->states[axis][i] = state; + state2 = -state2; + if (state2 != id2->states[axis][i]) { + //write_log(_T("-> %d %d\n"), i, state2); + handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state2, max, flags & ID_FLAG_AUTOFIRE, true, false); + id2->states[axis][i] = state2; } } id2->states[axis][MAX_INPUT_SUB_EVENT] = v1; @@ -6752,7 +6754,7 @@ void warpmode (int mode) rp_turbo_cpu (currprefs.turbo_emulation); #endif changed_prefs.turbo_emulation = currprefs.turbo_emulation; - config_changed = 1; + set_config_changed (); setsystime (); } @@ -6762,7 +6764,7 @@ void pausemode (int mode) pause_emulation = pause_emulation ? 0 : 9; else pause_emulation = mode; - config_changed = 1; + set_config_changed (); setsystime (); } @@ -6823,7 +6825,7 @@ int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int por p->jports[portnum].id = idnum + i; if (mode >= 0) p->jports[portnum].mode = mode; - config_changed = 1; + set_config_changed (); return 1; } } @@ -6875,13 +6877,13 @@ int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int por p->jports[portnum].mode = mode; if (start < JSEM_JOYS) default_keyboard_layout[portnum] = start; - config_changed = 1; + set_config_changed (); return 1; } // joystick not found, select default if (start == JSEM_JOYS && p->jports[portnum].id < JSEM_JOYS) { p->jports[portnum].id = default_keyboard_layout[portnum]; - config_changed = 1; + set_config_changed (); return 1; } } diff --git a/luascript.cpp b/luascript.cpp new file mode 100644 index 00000000..84f2c045 --- /dev/null +++ b/luascript.cpp @@ -0,0 +1,224 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* LUA Scripting Layer +* +* Copyright 2013 Frode SOlheim +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include + +#include "options.h" +#include "savestate.h" +#include "memory.h" +#include "debug.h" +#include "identify.h" +#include "luascript.h" +#include "uae.h" +#include "zfile.h" +#include "threaddep/thread.h" + +#ifdef WITH_LUA + +static int g_num_states; +static lua_State *g_states[MAX_LUA_STATES]; + +static uae_sem_t lua_sem; + +static int l_uae_read_u8(lua_State *L) +{ + int addr = luaL_checkint(L, 1); + int value = debug_read_memory_8(addr); + lua_pushinteger(L, value); + return value >= 0 ? 1 : 0; +} + +static int l_uae_write_u8(lua_State *L) +{ + int addr = luaL_checkint(L, 1); + uint8_t value = luaL_checkint(L, 2); + debug_write_memory_8(addr, value); + return 0; +} +static int l_uae_write_u16(lua_State *L) +{ + int addr = luaL_checkint(L, 1); + uint16_t value = luaL_checkint(L, 2); + debug_write_memory_16(addr, value); + return 0; +} + +static int l_uae_read_u16(lua_State *L) +{ + int addr = luaL_checkint(L, 1); + int value = debug_read_memory_16(addr); + lua_pushinteger(L, value); + return value >= 0 ? 1 : 0; +} + +/* peek = read without any side-effects */ +static int l_uae_peek_u16(lua_State *L) +{ + int result = 0; + uint16_t value; + int addr = luaL_checkint(L, 1); + + value = debug_peek_memory_16 (addr); + if (value >= 0) { + lua_pushinteger(L, value); + result = 1; + } + return result; +} + +static int l_uae_read_config(lua_State *L) +{ + int result = 0; + const char *s = luaL_checkstring(L, 1); + TCHAR *ts = au(s); + TCHAR out[MAX_DPATH]; + if (cfgfile_searchconfig(ts, -1, out, sizeof out / sizeof(TCHAR)) == -1) { + char *c = ua(out); + lua_pushstring(L, c); + xfree(c); + result = 1; + } + xfree(ts); + return result; +} + +static int l_uae_write_config(lua_State *L) +{ + const char *s = luaL_checkstring(L, 1); + TCHAR *ts = au(s); + TCHAR out[MAX_DPATH]; + cfgfile_modify(-1, ts, _tcslen(ts), out, sizeof out / sizeof(TCHAR)); + char *c = ua(out); + lua_pushstring(L, c); + xfree(c); + return 1; +} + +static int l_uae_log(lua_State *L) +{ + const char *s = luaL_checkstring(L, 1); + write_log("%s", s); + //printf("%s", s); + return 0; +} + +void uae_lua_log_error(lua_State *L, const char *msg) +{ + write_log("%s: %s\n", msg, lua_tostring(L, -1)); + //printf("%s: %s\n", msg, lua_tostring(L, -1)); +} + +void uae_lua_aquire_lock() +{ + uae_sem_wait (&lua_sem); +} + +void uae_lua_release_lock() +{ + uae_sem_post (&lua_sem); +} + +void uae_lua_run_handler(const char *name) +{ + lua_State **L = g_states; + while(*L) { + uae_lua_aquire_lock(); + lua_getglobal(*L, name); + if (lua_isnil(*L, -1)) { + //lua_pop(*L, 1); + } + else if (lua_pcall(*L, 0, 0, 0) != 0) { + uae_lua_log_error(*L, name); + //lua_pop(*L, 1); + } + lua_settop(*L, 0); + uae_lua_release_lock(); + L++; + } +} + +void uae_lua_load(const TCHAR *filename) +{ + char *fn; + lua_State *L = luaL_newstate(); + luaL_openlibs(L); + fn = ua (filename); + int err = luaL_loadfilex(L, fn, NULL); + if (!err) { + err = lua_pcall(L, 0, LUA_MULTRET, 0); + if (!err) { + write_log (_T("'%s' loaded\n"), filename); + uae_lua_init_state (L); + } + } + if (err) + write_log (_T("'%s' initialization failed: %d\n"), err); + xfree (fn); +} + +void uae_lua_loadall(void) +{ + TCHAR tmp[MAX_DPATH]; + fetch_luapath (tmp, sizeof tmp / sizeof (TCHAR)); + _tcscat (tmp, _T("default.lua")); + if (zfile_exists (tmp)) + uae_lua_load(tmp); + for (int i = 0; i < MAX_LUA_STATES; i++) { + if (currprefs.luafiles[i][0]) { + uae_lua_load(currprefs.luafiles[i]); + } + } +} + +void uae_lua_init_state(lua_State *L) +{ + write_log(_T("uae_lua_init_state %p\n"), L); + if (g_num_states == MAX_LUA_STATES) { + write_log(_T("WARNING: too many lua states (ignored this one)\n")); + return; + } + g_states[g_num_states] = L; + g_num_states++; + + lua_register(L, "uae_log", l_uae_log); + + lua_register(L, "uae_read_u8", l_uae_read_u8); + lua_register(L, "uae_read_u16", l_uae_read_u16); + lua_register(L, "uae_peek_u16", l_uae_peek_u16); + lua_register(L, "uae_write_u8", l_uae_write_u8); + lua_register(L, "uae_write_u16", l_uae_write_u16); + + lua_register(L, "uae_read_config", l_uae_read_config); + lua_register(L, "uae_write_config", l_uae_write_config); + + for (int i = 0; custd[i].name; i++) { + char *s = ua(custd[i].name); + lua_pushinteger(L, custd[i].adr); + lua_setglobal(L, s); + xfree(s); + } +} + +void uae_lua_init(void) +{ + uae_sem_init (&lua_sem, 0, 1); +} + +void uae_lua_free(void) +{ + for (int i = 0; i < g_num_states; i++) { + lua_close(g_states[i]); + } + g_num_states = 0; + uae_sem_destroy(&lua_sem); +} + +#endif diff --git a/main.cpp b/main.cpp index a42cc5f9..cdb22e54 100644 --- a/main.cpp +++ b/main.cpp @@ -54,6 +54,8 @@ #include "sampler.h" #include "consolehook.h" #include "gayle.h" +#include "gfxboard.h" +#include "luascript.h" #ifdef RETROPLATFORM #include "rp.h" #endif @@ -271,7 +273,7 @@ void fixup_prefs (struct uae_prefs *p) err = 1; } if ((p->rtgmem_size & (p->rtgmem_size - 1)) != 0 - || (p->rtgmem_size != 0 && (p->rtgmem_size < 0x100000 || p->rtgmem_size > max_z3fastmem))) + || (p->rtgmem_size != 0 && (p->rtgmem_size < 0x100000 || (p->rtgmem_size > max_z3fastmem && p->rtgmem_type == GFXBOARD_UAE_Z3)))) { write_log (_T("Unsupported graphics card memory size %x (%x)!\n"), p->rtgmem_size, max_z3fastmem); if (p->rtgmem_size > max_z3fastmem) @@ -342,14 +344,17 @@ void fixup_prefs (struct uae_prefs *p) write_log (_T("Unsupported Motherboard RAM size\n")); } - if (p->address_space_24 && p->rtgmem_size) - p->rtgmem_type = 0; - if (!p->rtgmem_type && (p->chipmem_size > 2 * 1024 * 1024 || getz2size (p) > 8 * 1024 * 1024 || getz2size (p) < 0)) { + if (p->rtgmem_type >= GFXBOARD_HARDWARE) { + if (p->rtgmem_size < gfxboard_get_vram_min (p->rtgmem_type)) + p->rtgmem_size = gfxboard_get_vram_min (p->rtgmem_type); + } + if (p->address_space_24 && p->rtgmem_size && p->rtgmem_type == GFXBOARD_UAE_Z3) + p->rtgmem_type = GFXBOARD_UAE_Z2; + if (p->rtgmem_type == GFXBOARD_UAE_Z2 && (p->chipmem_size > 2 * 1024 * 1024 || getz2size (p) > 8 * 1024 * 1024 || getz2size (p) < 0)) { p->rtgmem_size = 0; write_log (_T("Too large Z2 RTG memory size\n")); } - #if 0 if (p->m68k_speed < -1 || p->m68k_speed > 20) { write_log (_T("Bad value for -w parameter: must be -1, 0, or within 1..20.\n")); @@ -394,12 +399,13 @@ void fixup_prefs (struct uae_prefs *p) p->z3fastmem_size = 0; err = 1; } - if (p->rtgmem_size > 0 && p->rtgmem_type && (p->cpu_model < 68020 || p->address_space_24)) { + if (p->rtgmem_size > 0 && p->rtgmem_type == GFXBOARD_UAE_Z3 && (p->cpu_model < 68020 || p->address_space_24)) { write_log (_T("RTG can't be used with a 68000/68010 or 68EC020 emulation. It\n") _T("requires a 68020 emulation. Turning off RTG.\n")); p->rtgmem_size = 0; err = 1; } + #if !defined (BSDSOCKET) if (p->socket_emu) { write_log (_T("Compile-time option of BSDSOCKET_SUPPORTED was not enabled. You can't use bsd-socket emulation.\n")); @@ -815,6 +821,9 @@ void do_start_program (void) inputdevice_updateconfig (&changed_prefs, &currprefs); if (quit_program >= 0) quit_program = UAE_RESET; +#ifdef WITH_LUA + uae_lua_loadall (); +#endif #if (defined (_WIN32) || defined (_WIN64)) && !defined (NO_WIN32_EXCEPTION_HANDLER) extern int EvalException (LPEXCEPTION_POINTERS blah, int n_except); __try @@ -873,6 +882,9 @@ void do_leave_program (void) #endif gayle_free (); device_func_reset (); +#ifdef WITH_LUA + uae_lua_free (); +#endif savestate_free (); memory_cleanup (); free_shm (); @@ -930,7 +942,7 @@ static int real_main2 (int argc, TCHAR **argv) #ifdef USE_SDL SDL_Init (SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE); #endif - config_changed = 1; + set_config_changed (); if (restart_config[0]) { default_prefs (&currprefs, 0); fixup_prefs (&currprefs); @@ -975,7 +987,7 @@ static int real_main2 (int argc, TCHAR **argv) if (! no_gui) { int err = gui_init (); currprefs = changed_prefs; - config_changed = 1; + set_config_changed (); if (err == -1) { write_log (_T("Failed to initialize the GUI\n")); return -1; @@ -994,7 +1006,9 @@ static int real_main2 (int argc, TCHAR **argv) #ifdef NATMEM_OFFSET init_shm (); #endif - +#ifdef WITH_LUA + uae_lua_init (); +#endif #ifdef PICASSO96 picasso_reset (); #endif diff --git a/memory.cpp b/memory.cpp index 62c23554..6577cd59 100644 --- a/memory.cpp +++ b/memory.cpp @@ -32,6 +32,7 @@ #include "a2091.h" #include "gayle.h" #include "debug.h" +#include "gfxboard.h" bool canbang; int candirect = -1; @@ -2401,7 +2402,7 @@ uae_s32 getz2size (struct uae_prefs *p) { ULONG start; start = p->fastmem_size; - if (p->rtgmem_size && !p->rtgmem_type) { + if (p->rtgmem_size && !gfxboard_is_z3 (p->rtgmem_type)) { while (start & (p->rtgmem_size - 1) && start < 8 * 1024 * 1024) start += 1024 * 1024; if (start + p->rtgmem_size > 8 * 1024 * 1024) @@ -2415,7 +2416,7 @@ ULONG getz2endaddr (void) { ULONG start; start = currprefs.fastmem_size; - if (currprefs.rtgmem_size && !currprefs.rtgmem_type) { + if (currprefs.rtgmem_size && !gfxboard_is_z3 (currprefs.rtgmem_type)) { if (!start) start = 0x00200000; while (start & (currprefs.rtgmem_size - 1) && start < 4 * 1024 * 1024) diff --git a/newcpu.cpp b/newcpu.cpp index e004d1de..26ae3c11 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -1229,7 +1229,7 @@ static void update_68k_cycles (void) cpucycleunit = 1; if (currprefs.cpu_cycle_exact) write_log (_T("CPU cycleunit: %d (%.3f)\n"), cpucycleunit, (float)cpucycleunit / CYCLE_UNIT); - config_changed = 1; + set_config_changed (); } static void prefs_changed_cpu (void) diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 20767275..9a8971af 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -31,6 +31,7 @@ #include "hq2x_d3d.h" #include "zfile.h" #include "uae.h" +#include "threaddep\thread.h" extern int D3DEX, d3ddebug; int forcedframelatency = -1; @@ -120,9 +121,12 @@ RECT mask2rect; static bool wasstilldrawing_broken; static bool renderdisabled; static HANDLE filenotificationhandle; +static int frames_since_init; -static bool fakemode; +static volatile bool fakemode; static uae_u8 *fakebitmap; +static uae_thread_id fakemodetid; +int fakemodewaitms = 0; static D3DXMATRIXA16 m_matProj, m_matProj2; static D3DXMATRIXA16 m_matWorld, m_matWorld2; @@ -290,6 +294,12 @@ static int isd3d (void) return 0; return 1; } +static void waitfakemode (void) +{ + while (fakemode) { + sleep_millis (10); + } +} static D3DXHANDLE postSourceTextureHandle; static D3DXHANDLE postMaskTextureHandle; @@ -879,8 +889,10 @@ static bool psEffect_LoadEffect (const TCHAR *shaderfile, int full, struct shade goto end; } ret = 1; + frames_since_init = 0; if (plugin_path && filenotificationhandle == NULL) filenotificationhandle = FindFirstChangeNotification (tmp3, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE); + end: if (Errors) Errors->Release (); @@ -2121,10 +2133,14 @@ static void D3D_free2 (void) changed_prefs.leds_on_screen = currprefs.leds_on_screen = currprefs.leds_on_screen & ~STATUSLINE_TARGET; } -void D3D_free (void) +void D3D_free (bool immediate) { - D3D_free2 (); - ddraw_fs_hack_free (); + if (!fakemodewaitms || immediate) { + waitfakemode (); + D3D_free2 (); + ddraw_fs_hack_free (); + return; + } } #define VBLANKDEBUG 0 @@ -2187,7 +2203,7 @@ static int getd3dadapter (IDirect3D9 *d3d) return D3DADAPTER_DEFAULT; } -const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) +static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int mmult) { HRESULT ret, hr; static TCHAR errmsg[100] = { 0 }; @@ -2246,7 +2262,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) d3dex = NULL; d3d = Direct3DCreate9 (D3D_SDK_VERSION); if (d3d == NULL) { - D3D_free (); + D3D_free (true); _tcscpy (errmsg, _T("Direct3D: failed to create D3D object")); return errmsg; } @@ -2381,7 +2397,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) D3DEX = 0; return D3D_init (ahwnd, w_w, w_h, depth, mmult); } - D3D_free (); + D3D_free (true); return errmsg; } @@ -2479,7 +2495,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) changed_prefs.leds_on_screen = currprefs.leds_on_screen = currprefs.leds_on_screen | STATUSLINE_TARGET; if (!restoredeviceobjects ()) { - D3D_free (); + D3D_free (true); _stprintf (errmsg, _T("%s: initialization failed."), D3DHEAD); return errmsg; } @@ -2511,6 +2527,61 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) return 0; } +struct d3d_initargs +{ + HWND hwnd; + int w; + int h; + int depth; + int mmult; +}; +static struct d3d_initargs d3dargs; + +static void *D3D_init_start (void *p) +{ + struct timeval tv1, tv2; + + gettimeofday (&tv1, NULL); + sleep_millis (1000); + write_log (_T("Threaded D3D_init() start (free)\n")); + D3D_free2 (); + sleep_millis (1000); + write_log (_T("Threaded D3D_init() start (init)\n")); + const TCHAR *t = D3D_init2 (d3dargs.hwnd, d3dargs.w, d3dargs.h, d3dargs.depth, d3dargs.mmult); + if (t) { + gui_message (_T("Threaded D3D_init() returned error '%s'\n"), t); + } + write_log (_T("Threaded D3D_init() returned\n")); + for (;;) { + uae_u64 us1, us2, diff; + gettimeofday (&tv2, NULL); + us1 = (uae_u64)tv1.tv_sec * 1000000 + tv1.tv_usec; + us2 = (uae_u64)tv2.tv_sec * 1000000 + tv2.tv_usec; + diff = us2 - us1; + if (diff >= fakemodewaitms * 1000) + break; + sleep_millis (10); + } + write_log (_T("Threaded D3D_init() finished\n")); + frames_since_init = 0; + fakemode = false; + return NULL; +} + +const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) +{ + if (!fakemodewaitms) + return D3D_init2 (ahwnd, w_w, w_h, depth, mmult); + fakemode = true; + d3dargs.hwnd = ahwnd; + d3dargs.w = w_w; + d3dargs.h = w_h; + d3dargs.depth = depth; + d3dargs.mmult = mmult; + uae_start_thread_fast (D3D_init_start, NULL, &fakemodetid); + return NULL; +} + static bool alloctextures (void) { if (!createtexture (tout_w, tout_h, window_w, window_h)) @@ -2528,6 +2599,9 @@ bool D3D_alloctexture (int w, int h) tout_w = tin_w * dmultx; tout_h = tin_h * dmultx; + if (fakemode) + return false; + changed_prefs.leds_on_screen = currprefs.leds_on_screen = currprefs.leds_on_screen | STATUSLINE_TARGET; freetextures (); @@ -2600,7 +2674,7 @@ static int D3D_needreset (void) } } #endif - } + } if (SUCCEEDED (hr)) { devicelost = 0; invalidatedeviceobjects (); @@ -3133,6 +3207,8 @@ bool D3D_renderframe (bool immediate) { static int vsync2_cnt; + frames_since_init++; + if (fakemode) return true; @@ -3142,8 +3218,10 @@ bool D3D_renderframe (bool immediate) if (filenotificationhandle != NULL) { bool notify = false; while (WaitForSingleObject (filenotificationhandle, 0) == WAIT_OBJECT_0) { - FindNextChangeNotification (filenotificationhandle); - notify = true; + if (FindNextChangeNotification (filenotificationhandle)) { + if (frames_since_init > 50) + notify = true; + } } if (notify) { devicelost = 2; @@ -3252,6 +3330,7 @@ double D3D_getrefreshrate (void) HRESULT hr; D3DDISPLAYMODE dmode; + waitfakemode (); if (!isd3d ()) return -1; hr = d3ddev->GetDisplayMode (0, &dmode); @@ -3264,6 +3343,7 @@ void D3D_guimode (bool guion) { HRESULT hr; + waitfakemode (); if (!isd3d ()) return; hr = d3ddev->SetDialogBoxMode (guion ? TRUE : FALSE); @@ -3277,6 +3357,7 @@ HDC D3D_getDC (HDC hdc) static LPDIRECT3DSURFACE9 bb; HRESULT hr; + waitfakemode (); if (!isd3d ()) return 0; if (!hdc) { diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index 7dfbd448..906fddfe 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -1,5 +1,5 @@ extern void D3D_resize (int width, int height); -extern void D3D_free (void); +extern void D3D_free (bool immediate); extern const TCHAR *D3D_init (HWND ahwnd, int w_w, int h_h, int depth, int mmult); extern bool D3D_alloctexture (int, int); extern void D3D_getpixelformat (int depth,int *rb, int *bb, int *gb, int *rs, int *bs, int *gs, int *ab, int *ar, int *a); diff --git a/od-win32/fsdb_win32.cpp b/od-win32/fsdb_win32.cpp index c0b1b52b..4d91eb84 100644 --- a/od-win32/fsdb_win32.cpp +++ b/od-win32/fsdb_win32.cpp @@ -403,12 +403,15 @@ int fsdb_fill_file_attrs (a_inode *base, a_inode *aino) } if (!aino->softlink && !aino->dir && !(mode & FILE_ATTRIBUTE_SYSTEM)) { - const TCHAR *ext = _tcsrchr (aino->nname, '.'); + TCHAR *ext = _tcsrchr (aino->nname, '.'); if (ext && !_tcsicmp (ext, _T(".lnk"))) { TCHAR tmp[MAX_DPATH]; _tcscpy (tmp, aino->nname); if (my_resolvesoftlink (tmp, sizeof tmp / sizeof (TCHAR))) { //write_log (_T("2 '%s'\n"), aino->nname); + ext = _tcsrchr (aino->aname, '.'); + if (ext && !_tcsicmp (ext, _T(".lnk"))) + *ext = 0; aino->softlink = 2; } } diff --git a/od-win32/inttypes.h b/od-win32/inttypes.h index e69de29b..aae92fb4 100644 --- a/od-win32/inttypes.h +++ b/od-win32/inttypes.h @@ -0,0 +1,10 @@ +#include + +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +typedef uint64_t u_int64_t; + +typedef u_int8_t uint8; +typedef u_int16_t uint16; +typedef u_int32_t uint32; diff --git a/od-win32/keyboard_win32.cpp b/od-win32/keyboard_win32.cpp index f701e1b0..db77ae25 100644 --- a/od-win32/keyboard_win32.cpp +++ b/od-win32/keyboard_win32.cpp @@ -499,7 +499,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate) changed_prefs.floppyslots[i].df[0] = 0; } _tcscpy (changed_prefs.floppyslots[swapperdrive].df, currprefs.dfxlist[num]); - config_changed = 1; + set_config_changed (); } special = true; } diff --git a/od-win32/mman.cpp b/od-win32/mman.cpp index 1608c54e..826fdb46 100644 --- a/od-win32/mman.cpp +++ b/od-win32/mman.cpp @@ -10,6 +10,7 @@ #include "memory.h" #include "options.h" #include "autoconf.h" +#include "gfxboard.h" #include "win32.h" #if defined(NATMEM_OFFSET) @@ -86,7 +87,7 @@ static uae_u32 lowmem (void) currprefs.z3fastmem_size /= 2; changed_prefs.z3fastmem_size = currprefs.z3fastmem_size; } - } else if (currprefs.rtgmem_type && currprefs.rtgmem_size >= 1 * 1024 * 1024) { + } else if (currprefs.rtgmem_type == GFXBOARD_UAE_Z3 && currprefs.rtgmem_size >= 1 * 1024 * 1024) { change = currprefs.rtgmem_size - currprefs.rtgmem_size / 2; currprefs.rtgmem_size /= 2; changed_prefs.rtgmem_size = currprefs.rtgmem_size; @@ -447,7 +448,7 @@ static int doinit_shm (void) rtgextra = 0; z3chipbarrier = 0; rtgbarrier = si.dwPageSize; - z3rtgmem_size = changed_prefs.rtgmem_type ? changed_prefs.rtgmem_size : 0; + z3rtgmem_size = gfxboard_is_z3 (changed_prefs.rtgmem_type) ? changed_prefs.rtgmem_size : 0; if (changed_prefs.cpu_model >= 68020) size = 0x10000000; if (changed_prefs.z3fastmem_size || changed_prefs.z3fastmem2_size || changed_prefs.z3chipmem_size) { @@ -494,9 +495,9 @@ static int doinit_shm (void) p96mem_offset = NULL; p96mem_size = z3rtgmem_size; - if (changed_prefs.rtgmem_size && changed_prefs.rtgmem_type) { + if (changed_prefs.rtgmem_size && gfxboard_is_z3 (changed_prefs.rtgmem_type)) { p96mem_offset = natmem_offset + natmemsize + rtgbarrier + z3chipbarrier; - } else if (changed_prefs.rtgmem_size && !changed_prefs.rtgmem_type) { + } else if (changed_prefs.rtgmem_size && !gfxboard_is_z3 (changed_prefs.rtgmem_type)) { p96mem_offset = natmem_offset + getz2rtgaddr (); } @@ -734,7 +735,7 @@ void *shmat (int shmid, void *shmaddr, int shmflg) } else if(!_tcscmp (shmids[shmid].name, _T("fast"))) { shmaddr=natmem_offset + 0x200000; got = TRUE; - if (!(currprefs.rtgmem_size && !currprefs.rtgmem_type)) + if (!(currprefs.rtgmem_size && gfxboard_is_z3 (currprefs.rtgmem_type))) size += BARRIER; } else if(!_tcscmp (shmids[shmid].name, _T("z2_gfx"))) { ULONG start = getz2rtgaddr (); diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 30df443e..9d9777c9 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -59,6 +59,7 @@ #include "win32gfx.h" #include "direct3d.h" #include "clipboard.h" +#include "gfxboard.h" int debug_rtg_blitter = 3; @@ -89,7 +90,6 @@ int p96hsync_counter, full_refresh; #define P96TRACING_ENABLED 1 #define P96TRACING_LEVEL 1 #endif -static bool flushpixels (void); #if P96TRACING_ENABLED #define P96TRACE(x) do { write_log x; } while(0) #else @@ -618,6 +618,8 @@ static void setupcursor (void) D3DLOCKED_RECT locked; HRESULT hr; + if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE) + return; gfx_lock (); setupcursor_needed = 1; if (cursorsurfaced3d) { @@ -707,10 +709,16 @@ void picasso_trigger_vblank (void) static bool rtg_render (void) { bool flushed = false; + bool uaegfx = currprefs.rtgmem_type < GFXBOARD_HARDWARE; + if (doskip () && p96skipmode == 0) { ; } else { - flushed = flushpixels (); + if (uaegfx) { + flushed = picasso_flushpixels (p96ram_start + natmem_offset, picasso96_state.XYOffset - gfxmem_start); + } else { + gfxboard_vsync_handler (); + } } return flushed; } @@ -730,6 +738,7 @@ static void picasso_handle_vsync2 (void) int vsync = isvsync_rtg (); int mult; bool rendered = false; + bool uaegfx = currprefs.rtgmem_type < GFXBOARD_HARDWARE; if (vsync < 0) { vsync_busywait_end (NULL); @@ -746,16 +755,20 @@ static void picasso_handle_vsync2 (void) } framecnt++; - mouseupdate (); + if (uaegfx) + mouseupdate (); if (thisisvsync) { rendered = rtg_render (); frame_drawn (); } - if (setupcursor_needed) - setupcursor (); - if (thisisvsync) - picasso_trigger_vblank (); + + if (uaegfx) { + if (setupcursor_needed) + setupcursor (); + if (thisisvsync) + picasso_trigger_vblank (); + } if (vsync < 0) { vsync_busywait_start (); @@ -769,10 +782,12 @@ static int p96hsync; void picasso_handle_vsync (void) { + bool uaegfx = currprefs.rtgmem_type < GFXBOARD_HARDWARE; + if (currprefs.rtgmem_size == 0) return; - if (!picasso_on) { + if (!picasso_on && uaegfx) { createwindowscursor (0, 0, 0, 0, 0, 1); picasso_trigger_vblank (); return; @@ -789,6 +804,8 @@ void picasso_handle_vsync (void) void picasso_handle_hsync (void) { + bool uaegfx = currprefs.rtgmem_type < GFXBOARD_HARDWARE; + if (currprefs.rtgmem_size == 0) return; @@ -809,8 +826,10 @@ void picasso_handle_hsync (void) p96hsync++; if (p96hsync >= p96syncrate) { if (!picasso_on) { - createwindowscursor (0, 0, 0, 0, 0, 1); - picasso_trigger_vblank (); + if (uaegfx) { + createwindowscursor (0, 0, 0, 0, 0, 1); + picasso_trigger_vblank (); + } } else { picasso_handle_vsync2 (); } @@ -1002,6 +1021,11 @@ void picasso_refresh (void) setupcursor (); rtg_clear (); + if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE) { + gfxboard_refresh (); + return; + } + /* Make sure that the first time we show a Picasso video mode, we don't blit any crap. * We can do this by checking if we have an Address yet. */ @@ -1998,10 +2022,50 @@ static void CopyLibResolutionStructureU2A (struct LibResolution *libres, uaecptr put_long (amigamemptr + PSSO_LibResolution_BoardInfo, libres->BoardInfo); } -static void init_alloc (TrapContext *ctx, int size) +void picasso_allocatewritewatch (int gfxmemsize) { SYSTEM_INFO si; + xfree (gwwbuf); + GetSystemInfo (&si); + gwwpagesize = si.dwPageSize; + gwwbufsize = gfxmemsize / gwwpagesize + 1; + gwwpagemask = gwwpagesize - 1; + gwwbuf = xmalloc (void*, gwwbufsize); +} + +static ULONG_PTR writewatchcount; +void picasso_getwritewatch (void) +{ + ULONG ps; + writewatchcount = gwwbufsize; + if (GetWriteWatch (WRITE_WATCH_FLAG_RESET, p96ram_start + natmem_offset, (gwwbufsize - 1) * gwwpagesize, gwwbuf, &writewatchcount, &ps)) { + write_log (_T("picasso_getwritewatch %d\n"), GetLastError ()); + writewatchcount = 0; + return; + } +} +bool picasso_is_vram_dirty (uaecptr addr, int size) +{ + uae_u8 *a = addr + natmem_offset; + int s = size; + int ms = gwwpagesize; + for (ULONG_PTR i = 0; i < writewatchcount; i++) { + uae_u8 *ma = (uae_u8*)gwwbuf[i]; + if ( + (a < ma && a + s >= ma) || + (a < ma + ms && a + s >= ma + ms) || + (a >= ma && a < ma + ms)) { + return true; + } + } + return false; +} + + + +static void init_alloc (TrapContext *ctx, int size) +{ picasso96_amem = picasso96_amemend = 0; if (uaegfx_base) { int size = get_long (uaegfx_base + CARD_RESLISTSIZE); @@ -2012,12 +2076,7 @@ static void init_alloc (TrapContext *ctx, int size) } picasso96_amemend = picasso96_amem + size; write_log (_T("P96 RESINFO: %08X-%08X (%d,%d)\n"), picasso96_amem, picasso96_amemend, size / PSSO_ModeInfo_sizeof, size); - xfree (gwwbuf); - GetSystemInfo (&si); - gwwpagesize = si.dwPageSize; - gwwbufsize = allocated_gfxmem / gwwpagesize + 1; - gwwpagemask = gwwpagesize - 1; - gwwbuf = xmalloc (void*, gwwbufsize); + picasso_allocatewritewatch (allocated_gfxmem); } static int p96depth (int depth) @@ -2647,7 +2706,7 @@ static void do_xor8 (uae_u8 *p, int w, uae_u32 v) p++; w--; } - uae_u64 vv = v | (v << 32); + uae_u64 vv = v | ((uae_u64)v << 32); while (w >= 2 * 8) { *((uae_u64*)p) ^= vv; p += 8; @@ -3408,7 +3467,7 @@ void init_hz_p96 (void) if (p96vblank >= 300) p96vblank = 300; p96syncrate = maxvpos_nom * vblank_hz / p96vblank; - write_log (_T("P96FREQ: %d*%.4f = %.4f / %.1f = %d\n"), maxvpos_nom, vblank_hz, maxvpos_nom * vblank_hz, p96vblank, p96syncrate); + write_log (_T("RTGFREQ: %d*%.4f = %.4f / %.1f = %d\n"), maxvpos_nom, vblank_hz, maxvpos_nom * vblank_hz, p96vblank, p96syncrate); } /* NOTE: Watch for those planeptrs of 0x00000000 and 0xFFFFFFFF for all zero / all one bitmaps !!!! */ @@ -3671,7 +3730,7 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Direct (TrapContext *ctx) } #include "statusline.h" -static void statusline (uae_u8 *dst) +void picasso_statusline (uae_u8 *dst) { int y, yy, slx, sly; int dst_height, dst_width, pitch; @@ -4018,11 +4077,14 @@ void freertgbuffer (uae_u8 *dst) xfree (dst); } -static bool flushpixels (void) +void picasso_invalidate (int x, int y, int w, int h) +{ + DX_Invalidate (x, y, w, h); +} + +bool picasso_flushpixels (uae_u8 *src, int off) { int i; - uae_u8 *src = p96ram_start + natmem_offset; - int off = picasso96_state.XYOffset - gfxmem_start; uae_u8 *src_start; uae_u8 *src_end; int lock = 0; @@ -4155,7 +4217,7 @@ static bool flushpixels (void) } if (dst) { if (!(currprefs.leds_on_screen & STATUSLINE_TARGET)) - statusline (dst); + picasso_statusline (dst); maxy = picasso_vidinfo.height; if (miny > picasso_vidinfo.height - TD_TOTAL_HEIGHT) miny = picasso_vidinfo.height - TD_TOTAL_HEIGHT; @@ -4165,7 +4227,7 @@ static bool flushpixels (void) if (doskip () && p96skipmode == 4) { ; } else { - DX_Invalidate (0, miny, pwidth, maxy - miny); + picasso_invalidate (0, miny, pwidth, maxy - miny); } } diff --git a/od-win32/picasso96_win.h b/od-win32/picasso96_win.h index 4659b334..a34adb15 100644 --- a/od-win32/picasso96_win.h +++ b/od-win32/picasso96_win.h @@ -557,6 +557,12 @@ extern void picasso_trigger_vblank (void); extern void picasso_reset (void); extern int picasso_setwincursor (void); extern int picasso_palette (void); +extern bool picasso_flushpixels (uae_u8 *src, int offset); +extern void picasso_allocatewritewatch (int gfxmemsize); +extern void picasso_getwritewatch (void); +extern bool picasso_is_vram_dirty (uaecptr addr, int size); +extern void picasso_statusline (uae_u8 *dst); +extern void picasso_invalidate (int x, int y, int w, int h); /* This structure describes the UAE-side framebuffer for the Picasso * screen. */ diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index 8f626301..0e7a13a5 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -2,6 +2,7 @@ // Microsoft Visual C++ generated include file. // Used by winuae.rc // +#define VS_VERSION_INFO 1 #define IDS_KICKSTART 1 #define IDS_DISK 2 #define IDS_DISPLAY 3 @@ -370,9 +371,13 @@ #define IDS_MISCLISTITEMS2 387 #define IDD_CDDRIVE 387 #define IDS_MISCLISTITEMS3 388 +#define IDD_DIALOG1 388 +#define IDD_TAPEDRIVE 388 #define IDS_WHEELMOUSE 389 #define IDS_JOYMODE_WHEELMOUSE 389 #define IDS_NUMSG_KS68030PLUS 390 +#define IDS_SELECTTAPE 391 +#define IDS_TAPE 392 #define IDS_QS_MODELS 1000 #define IDS_QS_MODEL_A500 1001 #define IDS_QS_MODEL_A500P 1002 @@ -581,6 +586,8 @@ #define IDC_NEW_FSARCH 1342 #define IDC_PORT1 1343 #define IDC_NEW_CD 1344 +#define IDC_NEW_CD2 1345 +#define IDC_NEW_TAPE 1345 #define IDC_PATH_NAME 1362 #define IDC_SELECTOR 1363 #define IDC_VOLUME_NAME 1364 @@ -1129,6 +1136,15 @@ #define IDC_INPUTMAP_DELETEALL 1823 #define IDC_INPUTMAP_EXIT 1824 #define IDC_INPUTMAPADD 1825 +#define IDC_TAPELIST 1826 +#define IDC_NEW_TAPEPATH 1827 +#define IDC_TAPEINFO 1828 +#define IDC_TAPE_PATH_NAME 1829 +#define IDC_TAPE_SELECTOR 1830 +#define IDC_NEW_TAPE_DIR 1831 +#define IDC_TAPE_SELECT_DIR 1832 +#define IDC_TAPE_SELECT_FILE 1833 +#define IDC_TAPE_RW 1834 #define ID__FLOPPYDRIVES 40004 #define ID_FLOPPYDRIVES_DF0 40005 #define ID_ST_CONFIGURATION 40010 @@ -1177,9 +1193,9 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 #define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 388 +#define _APS_NEXT_RESOURCE_VALUE 389 #define _APS_NEXT_COMMAND_VALUE 40050 -#define _APS_NEXT_CONTROL_VALUE 1826 +#define _APS_NEXT_CONTROL_VALUE 1835 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 848762af..35288fb5 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -1,16 +1,7 @@ // Microsoft Visual C++ generated resource script. // -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// #include "winres.h" -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - +#include "resource.h" ///////////////////////////////////////////////////////////////////////////// // English resources @@ -221,8 +212,8 @@ BEGIN CONTROL "",IDC_CPUIDLE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,308,85,69,21 GROUPBOX "Cycle-exact CPU Emulation Speed",IDC_STATIC,136,121,258,55 RTEXT "CPU Frequency",IDC_STATIC,139,145,67,10,SS_CENTERIMAGE - COMBOBOX IDC_CPU_FREQUENCY,215,144,46,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - EDITTEXT IDC_CPU_FREQUENCY2,268,143,70,15 + COMBOBOX IDC_CPU_FREQUENCY,215,144,89,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_CPU_FREQUENCY2,312,143,70,15 GROUPBOX "FPU",IDC_STATIC,1,181,129,99,BS_LEFT CONTROL "None",IDC_FPU0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,8,195,87,10 CONTROL "68881",IDC_FPU1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,209,87,10 @@ -325,7 +316,8 @@ BEGIN COMBOBOX IDC_CD_TYPE,282,279,71,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Eject",IDC_CD_EJECT,360,278,30,15 COMBOBOX IDC_CD_TEXT,5,297,386,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add SCSI/IDE CD Drive",IDC_NEW_CD,135,176,126,15 + PUSHBUTTON "Add SCSI/IDE CD Drive",IDC_NEW_CD,1,176,128,15 + PUSHBUTTON "Add SCSI Tape Drive",IDC_NEW_TAPE,135,176,126,15 END IDD_SOUND DIALOGEX 0, 0, 396, 288 @@ -536,7 +528,7 @@ CAPTION "Hardfile Settings" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN GROUPBOX "Settings",IDC_STATIC,2,2,392,164 - RTEXT "Path:",IDC_HARDFILE_DIR_TEXT,25,18,22,10 + RTEXT "Path:",IDC_HARDFILE_DIR_TEXT,10,18,37,10 EDITTEXT IDC_PATH_NAME,52,15,325,15,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_SELECTOR,380,14,11,15 RTEXT "FileSys:",IDC_HARDFILE_FILESYS_TEXT,13,38,34,10 @@ -1037,7 +1029,7 @@ STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN GROUPBOX "RTG Graphics Card",IDC_STATIC,1,0,393,189 - COMBOBOX IDC_RTG_Z2Z3,26,14,68,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RTG_Z2Z3,26,14,118,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP RTEXT "Memory: [] Graphics card memory. Required for RTG (Picasso96) emulation.",IDC_GFXCARDTEXT,2,35,76,10,SS_NOTIFY | SS_CENTERIMAGE CONTROL "",IDC_P96MEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,88,31,60,20 EDITTEXT IDC_P96RAM,152,34,40,12,ES_CENTER | ES_READONLY @@ -1069,11 +1061,11 @@ BEGIN GROUPBOX "Network",IDC_STATIC,181,197,213,80 CONTROL "bsdsocket.library [] bsdsocket network library emulation.",IDC_SOCKETS, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,216,187,11 - CONTROL "uaenet.device [] Sana 2 compatible network device emulation. WinPcap required.",IDC_SANA2, + CONTROL "uaenet.device [] Sana 2 compatible network device emulation.",IDC_SANA2, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,229,187,11 - CONTROL "A2065 Z2 [] A2065 Ethernet Zorro II card emulation. WinPcap required.",IDC_A2065, + CONTROL "A2065 Z2 [] A2065 Ethernet Zorro II card emulation.",IDC_A2065, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,242,187,11 - COMBOBOX IDC_NETDEVICE,202,257,156,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_NETDEVICE,202,257,178,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Always center",IDC_RTG_CENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,93,212,10 END @@ -1130,6 +1122,22 @@ BEGIN CONTROL "",IDC_CDLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,4,4,387,77 END +IDD_TAPEDRIVE DIALOGEX 0, 0, 395, 80 +STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | DS_CENTERMOUSE | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Tape Drive Settings" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "Add Tape Drive",IDOK,201,58,88,14 + PUSHBUTTON "Cancel",IDCANCEL,300,58,87,14 + RTEXT "HD Controller:",IDC_STATIC,35,61,65,10,SS_CENTERIMAGE + COMBOBOX IDC_HDF_CONTROLLER,115,59,61,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_PATH_NAME,52,15,334,15,ES_AUTOHSCROLL + RTEXT "Path:",IDC_STATIC,4,18,43,10,SS_CENTERIMAGE + PUSHBUTTON "Select Directory",IDC_TAPE_SELECT_DIR,19,36,123,15 + PUSHBUTTON "Select Archive or Plain File",IDC_TAPE_SELECT_FILE,160,36,123,15 + CONTROL "Read/write",IDC_TAPE_RW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,313,39,67,10 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -1137,8 +1145,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,6,1,0 - PRODUCTVERSION 2,6,1,0 + FILEVERSION 2,7,0,0 + PRODUCTVERSION 2,7,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1154,12 +1162,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "WinUAE" - VALUE "FileVersion", "2.6.1.0" + VALUE "FileVersion", "2.7.0.0" VALUE "InternalName", "WinUAE" VALUE "LegalCopyright", "© 1996-2013 under the GNU Public License (GPL)" VALUE "OriginalFilename", "WinUAE.exe" VALUE "ProductName", "WinUAE" - VALUE "ProductVersion", "2.6.1.0" + VALUE "ProductVersion", "2.7.0.0" END END BLOCK "VarFileInfo" @@ -1432,6 +1440,10 @@ BEGIN IDD_CDDRIVE, DIALOG BEGIN END + + IDD_TAPEDRIVE, DIALOG + BEGIN + END END #endif // APSTUDIO_INVOKED @@ -1823,6 +1835,7 @@ BEGIN IDS_MISCLISTITEMS3 "Native on-screen display\nRTG on-screen display\nCreate winuaelog.txt log\nLog illegal memory accesses\nBlank unused displays\nStart mouse uncaptured\nStart minimized\nMinimize when focus is lost\n" IDS_JOYMODE_WHEELMOUSE "Wheel Mouse" IDS_NUMSG_KS68030PLUS "The selected system ROM requires a 68030 or higher CPU." + IDS_SELECTTAPE "Select a Tape directory or archive file..." END #endif // English resources @@ -1847,14 +1860,15 @@ BEGIN "resource.h\0" END -3 TEXTINCLUDE +2 TEXTINCLUDE BEGIN - "\r\0" + "\0" END -2 TEXTINCLUDE +3 TEXTINCLUDE BEGIN - "#include ""afxres.h""\r\0" + "\r\n" + "\0" END #endif // APSTUDIO_INVOKED @@ -1870,6 +1884,7 @@ END // Generated from the TEXTINCLUDE 3 resource. // + ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index be411e29..ee382b71 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -409,7 +409,7 @@ static int cd_insert (int num, const TCHAR *name) { _tcscpy (changed_prefs.cdslots[num].name, name); changed_prefs.cdslots[num].inuse = true; - config_changed = 1; + set_config_changed (); return 1; } @@ -908,7 +908,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) updatewinfsmode (p); hwndset = 0; - config_changed = 1; + set_config_changed (); } static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM lParam, @@ -943,7 +943,7 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM warpmode ((lParam & RP_TURBO_CPU) ? 1 : 0); if (wParam & RP_TURBO_FLOPPY) changed_prefs.floppy_speed = (lParam & RP_TURBO_FLOPPY) ? 0 : 100; - config_changed = 1; + set_config_changed (); } return TRUE; case RP_IPC_TO_GUEST_PAUSE: @@ -1387,7 +1387,7 @@ void rp_fixup_options (struct uae_prefs *p) rp_turbo_floppy (currprefs.floppy_speed == 0); for (i = 0; i <= 4; i++) rp_update_leds (i, 0, 0); - config_changed = 1; + set_config_changed (); } static void rp_device_writeprotect (int dev, int num, bool writeprotected) diff --git a/od-win32/sysconfig.h b/od-win32/sysconfig.h index a2efff68..fcfa7746 100644 --- a/od-win32/sysconfig.h +++ b/od-win32/sysconfig.h @@ -70,10 +70,12 @@ #define SAVESTATE /* State file support */ #define A2091 /* A590/A2091 SCSI */ #define A2065 /* A2065 Ethernet card */ +#define GFXBOARD /* Hardware graphics board */ #define NCR /* A4000T/A4091 SCSI */ #define SANA2 /* SANA2 network driver */ #define AMAX /* A-Max ROM adapater emulation */ #define RETROPLATFORM /* Cloanto RetroPlayer support */ +#define WITH_LUA /* lua scripting */ #else @@ -119,6 +121,8 @@ #include #endif +#include + #ifdef WIN64 #undef X86_MSVC_ASSEMBLY #undef JIT diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 1a15b3b5..48cce6f7 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -86,6 +86,7 @@ #include "clipboard_win32.h" #include "blkdev.h" #include "inputrecord.h" +#include "gfxboard.h" #ifdef RETROPLATFORM #include "rp.h" #include "cloanto/RetroPlatformIPC.h" @@ -1658,6 +1659,13 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, WIN32GFX_DisplayChangeRequested (-1); return 0; + case WM_POWERBROADCAST: + if (wParam == PBT_APMRESUMEAUTOMATIC) { + setsystime (); + return TRUE; + } + return 0; + case WM_GETMINMAXINFO: { LPMINMAXINFO lpmmi; @@ -1714,7 +1722,7 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, h != changed_prefs.gfx_size_win.height + window_extra_height) { changed_prefs.gfx_size_win.width = w - window_extra_width; changed_prefs.gfx_size_win.height = h - window_extra_height; - config_changed = 1; + set_config_changed (); } } } @@ -2985,6 +2993,11 @@ void target_fixup_options (struct uae_prefs *p) } if (p->rtg_hardwaresprite && !p->gfx_api) p->rtg_hardwaresprite = false; + if (p->rtgmem_type >= GFXBOARD_HARDWARE) { + p->rtg_hardwareinterrupt = false; + p->rtg_hardwaresprite = false; + p->win32_rtgmatchdepth = false; + } } void target_default_options (struct uae_prefs *p, int type) @@ -3463,6 +3476,10 @@ void fetch_configurationpath (TCHAR *out, int size) { fetch_path (_T("ConfigurationPath"), out, size); } +void fetch_luapath (TCHAR *out, int size) +{ + fetch_path (_T("LuaPath"), out, size); +} void fetch_screenshotpath (TCHAR *out, int size) { fetch_path (_T("ScreenshotPath"), out, size); @@ -3523,12 +3540,16 @@ void fetch_path (const TCHAR *name, TCHAR *out, int size) _tcscat (out, _T("..\\shared\\adf\\")); if (!_tcscmp (name, _T("CDPath"))) _tcscat (out, _T("..\\shared\\cd\\")); + if (!_tcscmp (name, _T("TapePath"))) + _tcscat (out, _T("..\\shared\\tape\\")); if (!_tcscmp (name, _T("hdfPath"))) _tcscat (out, _T("..\\shared\\hdf\\")); if (!_tcscmp (name, _T("KickstartPath"))) _tcscat (out, _T("..\\shared\\rom\\")); if (!_tcscmp (name, _T("ConfigurationPath"))) _tcscat (out, _T("Configurations\\")); + if (!_tcscmp (name, _T("LuaPath"))) + _tcscat (out, _T("lua\\")); if (!_tcscmp (name, _T("StatefilePath"))) _tcscat (out, _T("Savestates\\")); if (!_tcscmp (name, _T("InputPath"))) @@ -3651,6 +3672,8 @@ void set_path (const TCHAR *name, TCHAR *path, pathtype mode) _tcscat (tmp, _T("Roms")); if (!_tcscmp (name, _T("ConfigurationPath"))) _tcscat (tmp, _T("Configurations")); + if (!_tcscmp (name, _T("LuaPath"))) + _tcscat (tmp, _T("lua")); if (!_tcscmp (name, _T("ScreenshotPath"))) _tcscat (tmp, _T("Screenshots")); if (!_tcscmp (name, _T("StatefilePath"))) @@ -4140,6 +4163,7 @@ static void WIN32_HandleRegistryStuff (void) initpath (_T("KickstartPath"), start_path_data); initpath (_T("hdfPath"), start_path_data); initpath (_T("ConfigurationPath"), start_path_data); + initpath (_T("LuaPath"), start_path_data); initpath (_T("ScreenshotPath"), start_path_data); initpath (_T("StatefilePath"), start_path_data); initpath (_T("SaveimagePath"), start_path_data); @@ -4743,6 +4767,8 @@ extern int inputdevice_logging; extern int vsync_modechangetimeout; extern int tablet_log; extern int log_blitter; +extern int slirp_debug; +extern int fakemodewaitms; extern DWORD_PTR cpu_affinity, cpu_paffinity; static DWORD_PTR original_affinity = -1; @@ -5049,6 +5075,10 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2) debug_vsync_forced_delay = getval (np); return 2; } + if (!_tcscmp (arg, _T("threadedd3d"))) { + fakemodewaitms = getval (np); + return 2; + } if (!_tcscmp (arg, _T("tabletlog"))) { tablet_log = getval (np); return 2; @@ -5065,6 +5095,10 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2) inputdevice_logging = getval (np); return 2; } + if (!_tcscmp (arg, _T("slirplog"))) { + slirp_debug = getval (np); + return 2; + } if (!_tcscmp (arg, _T("vsyncbusywait"))) { vsync_busy_wait_mode = getval (np); return 2; diff --git a/od-win32/win32.h b/od-win32/win32.h index b33f341f..92ab6b94 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,15 +15,15 @@ #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100) #define GETBDD(x) ((x) % 100) -#define WINUAEPUBLICBETA 0 +#define WINUAEPUBLICBETA 1 #define LANG_DLL 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("4") +#define WINUAEBETA _T("1") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2013, 6, 19) +#define WINUAEDATE MAKEBD(2013, 7, 7) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("Amiga Forever Edition") diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index 832b4ce8..fdbf9cbd 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -446,7 +446,7 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height changed_prefs.gfx_size_win.height = hh; fixup_prefs_dimensions (&changed_prefs); if (oldwinw != changed_prefs.gfx_size_win.width || oldwinh != changed_prefs.gfx_size_win.height) - config_changed = 1; + set_config_changed (); OffsetRect (zr, -(changed_prefs.gfx_size_win.width - ww + 1) / 2, -(changed_prefs.gfx_size_win.height - hh + 1) / 2); filteroffsetx = -zr->left / scale; filteroffsety = -zr->top / scale; diff --git a/od-win32/win32_uaenet.cpp b/od-win32/win32_uaenet.cpp index 53c68a2b..dbdd1d3f 100644 --- a/od-win32/win32_uaenet.cpp +++ b/od-win32/win32_uaenet.cpp @@ -6,7 +6,7 @@ * Copyright 2007 Toni Wilen */ -#include "sysconfig.h" +#include "slirp/slirp.h" #include @@ -275,18 +275,16 @@ void uaenet_close (void *vsd) write_log (_T("uaenet_win32 closed\n")); } -void uaenet_enumerate_free (struct netdriverdata *tcp) +void uaenet_enumerate_free (void) { int i; - if (!tcp) - return; for (i = 0; i < MAX_TOTAL_NET_DEVICES; i++) { - xfree (tcp[i].name); - xfree (tcp[i].desc); - tcp[i].name = NULL; - tcp[i].desc = NULL; - tcp[i].active = 0; + xfree (tds[i].name); + xfree (tds[i].desc); + tds[i].name = NULL; + tds[i].desc = NULL; + tds[i].active = 0; } } @@ -304,7 +302,7 @@ static struct netdriverdata *enumit (const TCHAR *name) return NULL; } -struct netdriverdata *uaenet_enumerate (struct netdriverdata **out, const TCHAR *name) +struct netdriverdata *uaenet_enumerate (const TCHAR *name) { static int done; char errbuf[PCAP_ERRBUF_SIZE]; @@ -319,8 +317,6 @@ struct netdriverdata *uaenet_enumerate (struct netdriverdata **out, const TCHAR TCHAR *ss; if (enumerated) { - if (out) - *out = tds; return enumit (name); } tcp = tds; @@ -404,6 +400,7 @@ struct netdriverdata *uaenet_enumerate (struct netdriverdata **out, const TCHAR write_log (_T("- MAC %02X:%02X:%02X:%02X:%02X:%02X (%d)\n"), tc->mac[0], tc->mac[1], tc->mac[2], tc->mac[3], tc->mac[4], tc->mac[5], cnt++); + tc->type = UAENET_PCAP; tc->active = 1; tc->mtu = 1522; tc->name = au (d->name); @@ -420,8 +417,6 @@ struct netdriverdata *uaenet_enumerate (struct netdriverdata **out, const TCHAR done = 1; pcap_freealldevs (alldevs); enumerated = 1; - if (out) - *out = tds; return enumit (name); } @@ -437,3 +432,63 @@ void uaenet_close_driver (struct netdriverdata *tc) } +static volatile int slirp_thread_active; +static HANDLE slirp_thread; +static uae_thread_id slirp_tid; +extern uae_sem_t slirp_sem2; + +static void *slirp_receive_func(void *arg) +{ + slirp_thread_active = 1; + while (slirp_thread_active) { + // Wait for packets to arrive + fd_set rfds, wfds, xfds; + int nfds, ret, timeout; + + // ... in the output queue + nfds = -1; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + uae_sem_wait (&slirp_sem2); + timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); + uae_sem_post (&slirp_sem2); + if (nfds < 0) { + /* Windows does not honour the timeout if there is not + descriptor to wait for */ + sleep_millis (timeout / 1000); + ret = 0; + } + else { + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = timeout; + ret = select(0, &rfds, &wfds, &xfds, &tv); + } + if (ret >= 0) { + uae_sem_wait (&slirp_sem2); + slirp_select_poll(&rfds, &wfds, &xfds); + uae_sem_post (&slirp_sem2); + } + } + slirp_thread_active = -1; + return 0; +} + +bool slirp_start (void) +{ + slirp_end (); + uae_start_thread_fast (slirp_receive_func, NULL, &slirp_tid); + return true; +} +void slirp_end (void) +{ + if (slirp_thread_active > 0) { + slirp_thread_active = 0; + while (slirp_thread_active == 0) { + sleep_millis (10); + } + uae_end_thread (&slirp_tid); + } + slirp_thread_active = 0; +} diff --git a/od-win32/win32_uaenet.h b/od-win32/win32_uaenet.h index daefde5b..7b50eb3d 100644 --- a/od-win32/win32_uaenet.h +++ b/od-win32/win32_uaenet.h @@ -1,19 +1,13 @@ -struct netdriverdata -{ - TCHAR *name; - TCHAR *desc; - int mtu; - uae_u8 mac[6]; - int active; -}; + +#include "ethernet.h" typedef void (uaenet_gotfunc)(struct s2devstruct *dev, const uae_u8 *data, int len); typedef int (uaenet_getfunc)(struct s2devstruct *dev, uae_u8 *d, int *len); #define MAX_TOTAL_NET_DEVICES 10 -extern struct netdriverdata *uaenet_enumerate (struct netdriverdata **out, const TCHAR *name); -extern void uaenet_enumerate_free (struct netdriverdata *tcp); +extern struct netdriverdata *uaenet_enumerate (const TCHAR *name); +extern void uaenet_enumerate_free (void); extern void uaenet_close_driver (struct netdriverdata *tc); extern int uaenet_getdatalenght (void); diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index abc5b4a1..6f7a7c7a 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -1321,12 +1321,12 @@ static uae_u8 *gfx_lock_picasso2 (bool fullupdate) } uae_u8 *gfx_lock_picasso (bool fullupdate, bool doclear) { + static uae_u8 *p; if (rtg_locked) { - write_log (_T("rtg already locked!\n")); - abort (); + return p; } EnterCriticalSection (&screen_cs); - uae_u8 *p = gfx_lock_picasso2 (fullupdate); + p = gfx_lock_picasso2 (fullupdate); if (!p) { LeaveCriticalSection (&screen_cs); } else { @@ -1435,7 +1435,7 @@ static void close_hwnds (void) if (hAmigaWnd) { addnotifications (hAmigaWnd, TRUE, FALSE); #ifdef D3D - D3D_free (); + D3D_free (true); #endif ShowWindow (hAmigaWnd, SW_HIDE); DestroyWindow (hAmigaWnd); @@ -1620,7 +1620,7 @@ static int open_windows (bool mousecapture) updatewinfsmode (&currprefs); #ifdef D3D - D3D_free (); + D3D_free (false); #endif #ifdef OPENGL OGL_free (); @@ -1649,7 +1649,7 @@ static int open_windows (bool mousecapture) return ret; } - bool startactive = started || (!started && !currprefs.win32_start_uncaptured && !currprefs.win32_start_minimized); + bool startactive = (started && mouseactive) || (!started && !currprefs.win32_start_uncaptured && !currprefs.win32_start_minimized); bool startpaused = !started && ((currprefs.win32_start_minimized && currprefs.win32_iconified_pause) || (currprefs.win32_start_uncaptured && currprefs.win32_inactive_pause && isfullscreen () <= 0)); bool startminimized = !started && currprefs.win32_start_minimized && isfullscreen () <= 0; @@ -2256,7 +2256,7 @@ static int reopen (int full, bool unacquire) #if 0 currprefs.gfx_apmode[1].gfx_refreshrate = changed_prefs.gfx_apmode[1].gfx_refreshrate; #endif - config_changed = 1; + set_config_changed (); if (!quick) return 1; @@ -2349,7 +2349,7 @@ bool vsync_switchmode (int hz) if (!found) { changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_vsync = 0; if (currprefs.gfx_apmode[APMODE_NATIVE].gfx_vsync != changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_vsync) { - config_changed = 1; + set_config_changed (); } write_log (_T("refresh rate changed to %d%s but no matching screenmode found, vsync disabled\n"), hz, lace ? _T("i") : _T("p")); return false; @@ -2361,7 +2361,7 @@ bool vsync_switchmode (int hz) if (changed_prefs.gfx_size_fs.height != currprefs.gfx_size_fs.height || changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_refreshrate != currprefs.gfx_apmode[APMODE_NATIVE].gfx_refreshrate) { write_log (_T("refresh rate changed to %d%s, new screenmode %dx%d\n"), hz, lace ? _T("i") : _T("p"), w, newh); - config_changed = 1; + set_config_changed (); } return true; } @@ -4162,7 +4162,7 @@ static BOOL doInit (void) if (currentmode->flags & DM_D3D) { const TCHAR *err = D3D_init (hAmigaWnd, currentmode->native_width, currentmode->native_height, currentmode->current_depth, screen_is_picasso ? 1 : currprefs.gfx_filter_filtermode + 1); if (err) { - D3D_free (); + D3D_free (true); gui_message (err); changed_prefs.gfx_api = currprefs.gfx_api = 0; changed_prefs.gfx_filter = currprefs.gfx_filter = 0; @@ -4194,8 +4194,10 @@ oops: bool target_graphics_buffer_update (void) { + static bool graphicsbuffer_retry; int w, h; + graphicsbuffer_retry = false; if (screen_is_picasso) { w = picasso96_state.Width > picasso_vidinfo.width ? picasso96_state.Width : picasso_vidinfo.width; h = picasso96_state.Height > picasso_vidinfo.height ? picasso96_state.Height : picasso_vidinfo.height; @@ -4207,22 +4209,31 @@ bool target_graphics_buffer_update (void) } if (oldtex_w == w && oldtex_h == h && oldtex_rtg == screen_is_picasso) - return true; - oldtex_w = w; - oldtex_h = h; - oldtex_rtg = screen_is_picasso; - - if (!w || !h) return false; - write_log (_T("Buffer size (%d*%d) %s\n"), w, h, screen_is_picasso ? _T("RTG") : _T("Native")); + if (!w || !h) { + oldtex_w = w; + oldtex_h = h; + oldtex_rtg = screen_is_picasso; + return false; + } S2X_free (); if (currentmode->flags & DM_D3D) { - D3D_alloctexture (w, h); + if (!D3D_alloctexture (w, h)) { + graphicsbuffer_retry = true; + return false; + } } else { DirectDraw_ClearSurface (NULL); } + + oldtex_w = w; + oldtex_h = h; + oldtex_rtg = screen_is_picasso; + + write_log (_T("Buffer size (%d*%d) %s\n"), w, h, screen_is_picasso ? _T("RTG") : _T("Native")); + if ((currentmode->flags & DM_SWSCALE) && !screen_is_picasso) { if (!S2X_init (currentmode->native_width, currentmode->native_height, currentmode->native_depth)) return false; @@ -4265,7 +4276,7 @@ void updatewinfsmode (struct uae_prefs *p) p->gfx_size = p->gfx_size_win; } md = getdisplay (p); - config_changed = 1; + set_config_changed (); } void toggle_fullscreen (int mode) diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 58d966eb..d1dcf2e1 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -76,6 +76,7 @@ #include "cdtv.h" #include "gfxfilter.h" #include "driveclick.h" +#include "scsi.h" #ifdef PROWIZARD #include "moduleripper.h" #endif @@ -86,6 +87,7 @@ #include "rp.h" #include "statusline.h" #include "zarchive.h" +#include "gfxboard.h" #include "win32_uaenet.h" #ifdef RETROPLATFORM #include "rp.h" @@ -1934,7 +1936,8 @@ static const GUID diskselectionguids[] = { { 0x2412c4e7, 0xf608, 0x4333, { 0x83, 0xd2, 0xa1, 0x2f, 0xdf, 0x66, 0xac, 0xe5 } }, { 0xe3741dff, 0x11f2, 0x445f, { 0x94, 0xb0, 0xa3, 0xe7, 0x58, 0xe2, 0xcb, 0xb5 } }, { 0x2056d641, 0xba13, 0x4312, { 0xaa, 0x75, 0xc5, 0xeb, 0x52, 0xa8, 0x1c, 0xe3 } }, - { 0x05aa5db2, 0x470b, 0x4725, { 0x96, 0x03, 0xee, 0x61, 0x30, 0xfc, 0x54, 0x99 } } + { 0x05aa5db2, 0x470b, 0x4725, { 0x96, 0x03, 0xee, 0x61, 0x30, 0xfc, 0x54, 0x99 } }, + { 0x68366188, 0xa6d4, 0x4278, { 0xb7, 0x55, 0x6a, 0xb8, 0x17, 0xa6, 0x71, 0xd9 } } }; static void getfilter (int num, const TCHAR *name, int *filter, TCHAR *fname) @@ -2067,6 +2070,7 @@ static void setdpath (const TCHAR *name, const TCHAR *path) // flag = 15 for loading input // flag = 16 for recording input // flag = 17 for CD image +// flag = 18 for Tape image int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs, TCHAR *path_out, int *multi) { static int previousfilter[20]; @@ -2161,6 +2165,11 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs fetch_path (_T("CDPath"), init_path, sizeof (init_path) / sizeof (TCHAR)); guid = &diskselectionguids[6]; break; + case 18: + getfilter (flag, _T("TapePath"), previousfilter, filtername); + fetch_path (_T("TapePath"), init_path, sizeof (init_path) / sizeof (TCHAR)); + guid = &diskselectionguids[7]; + break; } } @@ -2288,6 +2297,9 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs memcpy (szFilter + _tcslen (szFilter), CD_FORMAT_STRING, sizeof (CD_FORMAT_STRING) + sizeof (TCHAR)); defext = _T("cue"); break; + case 18: + WIN32GUI_LoadUIString (IDS_SELECTTAPE, szTitle, MAX_DPATH); + break; } if (all) { p = szFilter; @@ -2469,6 +2481,12 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs *amiga_path = 0; setdpath (_T("CDPath"), openFileName.lpstrFile); } + } else if (flag == 18) { + amiga_path = _tcsstr (openFileName.lpstrFile, openFileName.lpstrFileTitle); + if (amiga_path && amiga_path != openFileName.lpstrFile) { + *amiga_path = 0; + setdpath (_T("TapePath"), openFileName.lpstrFile); + } } } if (!multi) @@ -3685,6 +3703,26 @@ static struct miscentry misclist[] = { { 0, NULL } }; +static void harddisktype (TCHAR *s, struct uaedev_config_info *ci) +{ + switch (ci->type) + { + case UAEDEV_CD: + _tcscpy (s, _T("CD")); + break; + case UAEDEV_TAPE: + _tcscpy (s, _T("TAPE")); + break; + case UAEDEV_HDF: + _tcscpy (s, _T("HDF")); + break; + default: + _tcscpy (s, _T("n/a")); + break; + } +} + + void InitializeListView (HWND hDlg) { int lv_type; @@ -3780,6 +3818,7 @@ void InitializeListView (HWND hDlg) WIN32GUI_LoadUIString (IDS_DEVICE, column_heading[1], MAX_COLUMN_HEADING_WIDTH); WIN32GUI_LoadUIString (IDS_PATH, column_heading[2], MAX_COLUMN_HEADING_WIDTH); list = GetDlgItem (hDlg, IDC_CDLIST); + } int flags = LVS_EX_DOUBLEBUFFER | extraflags; @@ -3982,7 +4021,7 @@ void InitializeListView (HWND hDlg) type = get_filesys_unitconfig (&workprefs, i, &mi); if (type < 0) { - type = ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD ? FILESYS_HARDFILE : FILESYS_VIRTUAL; + type = ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD || ci->type == UAEDEV_TAPE ? FILESYS_HARDFILE : FILESYS_VIRTUAL; nosize = 1; } if (mi.size < 0) @@ -4001,22 +4040,22 @@ void InitializeListView (HWND hDlg) if (ci->controller >= HD_CONTROLLER_IDE0 && ci->controller <= HD_CONTROLLER_IDE3) { _stprintf (blocksize_str, _T("%d"), ci->blocksize); _stprintf (devname_str, _T("*IDE%d*"), ci->controller - HD_CONTROLLER_IDE0); - _tcscpy (volname_str, _T("n/a")); + harddisktype (volname_str, ci); _tcscpy (bootpri_str, _T("n/a")); } else if (ci->controller >= HD_CONTROLLER_SCSI0 && ci->controller <= HD_CONTROLLER_SCSI6) { _stprintf (blocksize_str, _T("%d"), ci->blocksize); _stprintf (devname_str, _T("*SCSI%d*"), ci->controller - HD_CONTROLLER_SCSI0); - _tcscpy (volname_str, _T("n/a")); + harddisktype (volname_str, ci); _tcscpy (bootpri_str, _T("n/a")); } else if (ci->controller == HD_CONTROLLER_PCMCIA_SRAM) { _tcscpy (blocksize_str, _T("n/a")); - _tcscpy(devname_str, _T("*SCSRAM*")); - _tcscpy (volname_str, _T("n/a")); + _tcscpy(devname_str, _T("*SRAM*")); + _tcscpy (volname_str, _T("PCMCIA")); _tcscpy (bootpri_str, _T("n/a")); } else if (ci->controller == HD_CONTROLLER_PCMCIA_IDE) { _tcscpy (blocksize_str, _T("n/a")); - _tcscpy(devname_str, _T("*SCIDE*")); - _tcscpy (volname_str, _T("n/a")); + _tcscpy(devname_str, _T("*IDE*")); + _tcscpy (volname_str, _T("PCMCIA")); _tcscpy (bootpri_str, _T("n/a")); } else if (type == FILESYS_HARDFILE) { _stprintf (blocksize_str, _T("%d"), ci->blocksize); @@ -4030,6 +4069,11 @@ void InitializeListView (HWND hDlg) _tcscpy (bootpri_str, _T("n/a")); if (!_tcsncmp (rootdir, _T("HD_"), 3)) rootdir += 3; + } else if (type == FILESYS_TAPE) { + _stprintf (blocksize_str, _T("%d"), ci->blocksize); + _tcscpy (devname_str, _T("*UAE*")); + harddisktype (volname_str, ci); + _tcscpy (bootpri_str, _T("n/a")); } else { _tcscpy (blocksize_str, _T("n/a")); _tcscpy (devname_str, ci->devname); @@ -5715,7 +5759,7 @@ static INT_PTR CALLBACK AboutDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM static void enable_for_displaydlg (HWND hDlg) { - int rtg = (!workprefs.address_space_24 || !workprefs.rtgmem_type) && workprefs.rtgmem_size; + int rtg = ((!workprefs.address_space_24 || !gfxboard_is_z3 (workprefs.rtgmem_type)) && workprefs.rtgmem_size) || workprefs.rtgmem_type >= GFXBOARD_HARDWARE; #ifndef PICASSO96 rtg = FALSE; #endif @@ -6477,7 +6521,8 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l /* Set the Int boxes */ SetDlgItemInt (hDlg, IDC_XSIZE, workprefs.gfx_size_win.width, FALSE); SetDlgItemInt (hDlg, IDC_YSIZE, workprefs.gfx_size_win.height, FALSE); - init_frequency_combo (hDlg, dmode); + init_display_mode (hDlg); + //init_frequency_combo (hDlg, dmode); } else if (LOWORD (wParam) == IDC_REFRESHRATE && dmode >= 0) { LRESULT posn1; posn1 = SendDlgItemMessage (hDlg, IDC_REFRESHRATE, CB_GETCURSEL, 0, 0); @@ -6957,10 +7002,8 @@ static INT_PTR CALLBACK ChipsetDlgProc2 (HWND hDlg, UINT msg, WPARAM wParam, LPA static void enable_for_memorydlg (HWND hDlg) { - int z3 = true; int fast = workprefs.chipmem_size <= 0x200000; - int rtg = workprefs.rtgmem_size && full_property_sheet; - int rtg2 = workprefs.rtgmem_size; + int z3 = true; #ifndef AUTOCONFIG z3 = FALSE; @@ -6976,32 +7019,10 @@ static void enable_for_memorydlg (HWND hDlg) ew (hDlg, IDC_FASTMEMAUTOCONFIG, fast); ew (hDlg, IDC_FASTTEXT, fast); ew (hDlg, IDC_GFXCARDTEXT, z3); - ew (hDlg, IDC_P96RAM, z3); - ew (hDlg, IDC_P96MEM, z3); ew (hDlg, IDC_MBRAM1, z3); ew (hDlg, IDC_MBMEM1, z3); ew (hDlg, IDC_MBRAM2, z3); ew (hDlg, IDC_MBMEM2, z3); - - ew (hDlg, IDC_RTG_Z2Z3, z3); - ew (hDlg, IDC_RTG_8BIT, rtg); - ew (hDlg, IDC_RTG_16BIT, rtg); - ew (hDlg, IDC_RTG_24BIT, rtg); - ew (hDlg, IDC_RTG_32BIT, rtg); - ew (hDlg, IDC_RTG_MATCH_DEPTH, rtg2); - ew (hDlg, IDC_RTG_SCALE, rtg2); - ew (hDlg, IDC_RTG_CENTER, rtg2); - ew (hDlg, IDC_RTG_SCALE_ALLOW, rtg2); - ew (hDlg, IDC_RTG_SCALE_ASPECTRATIO, rtg2); - ew (hDlg, IDC_RTG_VBLANKRATE, rtg2); - ew (hDlg, IDC_RTG_BUFFERCNT, rtg2); - ew (hDlg, IDC_RTG_DISPLAYSELECT, rtg2); - ew (hDlg, IDC_RTG_VBINTERRUPT, rtg2); - if (!workprefs.gfx_api) { - workprefs.rtg_hardwaresprite = false; - CheckDlgButton (hDlg, IDC_RTG_HWSPRITE, FALSE); - } - ew (hDlg, IDC_RTG_HWSPRITE, rtg2 && workprefs.gfx_api); } extern uae_u32 natmem_size; @@ -7010,7 +7031,7 @@ static void setmax32bitram (HWND hDlg) TCHAR tmp[100]; uae_u32 size, rtgz3size; - rtgz3size = workprefs.rtgmem_type ? workprefs.rtgmem_size : 0; + rtgz3size = gfxboard_is_z3 (workprefs.rtgmem_type) ? workprefs.rtgmem_size : 0; size = workprefs.z3fastmem_size + workprefs.z3fastmem2_size + workprefs.z3chipmem_size + rtgz3size; if (workprefs.z3chipmem_size && workprefs.z3fastmem_size) @@ -7138,7 +7159,7 @@ static void values_to_memorydlg (HWND hDlg) else mem_size = 7; int max_mem = MAX_P96_MEM_Z3; - if (!workprefs.rtgmem_type) { + if (!gfxboard_is_z3 (workprefs.rtgmem_type)) { int v = workprefs.rtgmem_size; max_mem = 0; workprefs.rtgmem_size = 1024 * 1024; @@ -7146,11 +7167,22 @@ static void values_to_memorydlg (HWND hDlg) workprefs.rtgmem_size *= 2; max_mem++; } + if (workprefs.rtgmem_type >= GFXBOARD_HARDWARE && v > gfxboard_get_vram_max (workprefs.rtgmem_type)) + v = gfxboard_get_vram_max (workprefs.rtgmem_type); + if (workprefs.rtgmem_type >= GFXBOARD_HARDWARE && v < gfxboard_get_vram_min (workprefs.rtgmem_type)) + v = gfxboard_get_vram_min (workprefs.rtgmem_type); workprefs.rtgmem_size = v; if (workprefs.rtgmem_size > 8 * 1024 * 1024) mem_size = 8 * 1024 * 1024; while (getz2size (&workprefs) < 0 && workprefs.rtgmem_size > 0) workprefs.rtgmem_size -= 1024 * 1024; + } else { + int v = workprefs.rtgmem_size; + if (workprefs.rtgmem_type >= GFXBOARD_HARDWARE && v > gfxboard_get_vram_max (workprefs.rtgmem_type)) + v = gfxboard_get_vram_max (workprefs.rtgmem_type); + if (workprefs.rtgmem_type >= GFXBOARD_HARDWARE && v < gfxboard_get_vram_min (workprefs.rtgmem_type)) + v = gfxboard_get_vram_min (workprefs.rtgmem_type); + workprefs.rtgmem_size = v; } SendDlgItemMessage (hDlg, IDC_P96MEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_P96_MEM, max_mem)); SendDlgItemMessage (hDlg, IDC_Z3CHIPMEM, TBM_SETPOS, TRUE, mem_size); @@ -7174,7 +7206,7 @@ static void values_to_memorydlg (HWND hDlg) SendDlgItemMessage (hDlg, IDC_P96MEM, TBM_SETPOS, TRUE, mem_size); SetDlgItemText (hDlg, IDC_P96RAM, memsize_names[msi_gfx[mem_size]]); - SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_SETCURSEL, workprefs.rtgmem_type, 0); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_SETCURSEL, workprefs.rtgmem_size == 0 ? 0 : workprefs.rtgmem_type + 1, 0); SendDlgItemMessage (hDlg, IDC_RTG_8BIT, CB_SETCURSEL, (workprefs.picasso96_modeflags & RGBFF_CLUT) ? 1 : 0, 0); SendDlgItemMessage (hDlg, IDC_RTG_16BIT, CB_SETCURSEL, (manybits (workprefs.picasso96_modeflags, RGBFF_R5G6B5PC | RGBFF_R5G6B5PC | RGBFF_R5G6B5 | RGBFF_R5G5B5 | RGBFF_B5G6R5PC | RGBFF_B5G5R5PC)) ? 1 : @@ -7223,7 +7255,7 @@ static void values_to_memorydlg (HWND hDlg) SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_SETCURSEL, (workprefs.win32_rtgscaleaspectratio == 0) ? 0 : - (workprefs.win32_rtgscaleaspectratio == 1) ? 1 : + (workprefs.win32_rtgscaleaspectratio < 0) ? 1 : getaspectratioindex (workprefs.win32_rtgscaleaspectratio) + 2, 0); mem_size = 0; @@ -7304,7 +7336,7 @@ static void updatez3 (uae_u32 *size1p, uae_u32 *size2p) *size2p = s2; } -static struct netdriverdata *ndd; +static struct netdriverdata *ndd[MAX_TOTAL_NET_DEVICES + 1]; static void expansion_net (HWND hDlg) { @@ -7315,17 +7347,19 @@ static void expansion_net (HWND hDlg) SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_RESETCONTENT, 0, 0); WIN32GUI_LoadUIString (IDS_NETDISCONNECTED, tmp, sizeof tmp / sizeof (TCHAR)); SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_ADDSTRING, 0, (LPARAM)tmp); - if (!_tcscmp (workprefs.a2065name, _T("none"))) + if (!_tcsicmp (workprefs.a2065name, _T("none"))) { SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_SETCURSEL, 0, 0); + notset = false; + } cnt = 1; for (i = 0; ndd && i < MAX_TOTAL_NET_DEVICES; i++) { - if (ndd[i].active) { + if (ndd[i]) { TCHAR mac[20]; _stprintf (mac, _T("%02X:%02X:%02X:%02X:%02X:%02X"), - ndd[i].mac[0], ndd[i].mac[1], ndd[i].mac[2], ndd[i].mac[3], ndd[i].mac[4], ndd[i].mac[5]); - _stprintf (tmp, _T("%s %s"), mac, ndd[i].desc); + ndd[i]->mac[0], ndd[i]->mac[1], ndd[i]->mac[2], ndd[i]->mac[3], ndd[i]->mac[4], ndd[i]->mac[5]); + _stprintf (tmp, _T("%s %s"), mac, ndd[i]->desc); SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_ADDSTRING, 0, (LPARAM)tmp); - if (!_tcsicmp (workprefs.a2065name, mac) || !_tcsicmp (workprefs.a2065name, ndd[i].name)) { + if (!_tcsicmp (workprefs.a2065name, mac) || !_tcsicmp (workprefs.a2065name, ndd[i]->name)) { SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_SETCURSEL, cnt, 0); notset = false; } @@ -7338,6 +7372,7 @@ static void expansion_net (HWND hDlg) static void enable_for_expansiondlg (HWND hDlg) { + int z3 = true; int cw, en; en = !!full_property_sheet; @@ -7350,6 +7385,33 @@ static void enable_for_expansiondlg (HWND hDlg) ew (hDlg, IDC_SANA2, en); ew (hDlg, IDC_A2065, en); ew (hDlg, IDC_NETDEVICE, en && workprefs.a2065name[0]); + + int rtg = workprefs.rtgmem_size && full_property_sheet && workprefs.rtgmem_type < GFXBOARD_HARDWARE; + int rtg2 = workprefs.rtgmem_size || workprefs.rtgmem_type >= GFXBOARD_HARDWARE; + int rtg3 = workprefs.rtgmem_size && workprefs.rtgmem_type < GFXBOARD_HARDWARE; + int rtg4 = workprefs.rtgmem_type < GFXBOARD_HARDWARE; + + ew (hDlg, IDC_P96RAM, rtg2); + ew (hDlg, IDC_P96MEM, rtg2); + ew (hDlg, IDC_RTG_Z2Z3, z3); + ew (hDlg, IDC_RTG_8BIT, rtg); + ew (hDlg, IDC_RTG_16BIT, rtg); + ew (hDlg, IDC_RTG_24BIT, rtg); + ew (hDlg, IDC_RTG_32BIT, rtg); + ew (hDlg, IDC_RTG_MATCH_DEPTH, rtg3); + ew (hDlg, IDC_RTG_SCALE, rtg2); + ew (hDlg, IDC_RTG_CENTER, rtg2); + ew (hDlg, IDC_RTG_SCALE_ALLOW, rtg2); + ew (hDlg, IDC_RTG_SCALE_ASPECTRATIO, rtg2); + ew (hDlg, IDC_RTG_VBLANKRATE, rtg2); + ew (hDlg, IDC_RTG_BUFFERCNT, rtg2); + ew (hDlg, IDC_RTG_DISPLAYSELECT, rtg2); + ew (hDlg, IDC_RTG_VBINTERRUPT, rtg3); + if (!workprefs.gfx_api) { + workprefs.rtg_hardwaresprite = false; + CheckDlgButton (hDlg, IDC_RTG_HWSPRITE, FALSE); + } + ew (hDlg, IDC_RTG_HWSPRITE, rtg3 && workprefs.gfx_api); } static void values_to_expansiondlg (HWND hDlg) @@ -7382,14 +7444,26 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP currentpage = EXPANSION_ID; if (!enumerated) { - uaenet_enumerate (&ndd, NULL); + ethernet_enumerate (ndd, NULL); enumerated = 1; } expansion_net (hDlg); init_displays_combo (hDlg, true); SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_RESETCONTENT, 0, 0); - SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Zorro II")); - SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Zorro III (*)")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("-")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("UAE Zorro II")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("UAE Zorro III (*)")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Picasso II Zorro II")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Picasso II+ Zorro II")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Piccolo Zorro II")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Piccolo SD64 Zorro II")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Piccolo SD64 Zorro III")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Spectrum28/24 Zorro II")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Spectrum28/24 Zorro III")); +#if 0 + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Picasso IV Zorro II")); + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Picasso IV Zorro III")); +#endif WIN32GUI_LoadUIString(IDS_ALL, tmp, sizeof tmp / sizeof (TCHAR)); SendDlgItemMessage (hDlg, IDC_RTG_8BIT, CB_RESETCONTENT, 0, 0); SendDlgItemMessage (hDlg, IDC_RTG_8BIT, CB_ADDSTRING, 0, (LPARAM)_T("(8bit)")); @@ -7415,7 +7489,7 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("A8B8G8R8")); SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("R8G8B8A8")); SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("B8G8R8A8 (*)")); - SendDlgItemMessage (hDlg, IDC_P96MEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_P96_MEM, workprefs.rtgmem_type ? MAX_P96_MEM_Z3 : MAX_P96_MEM_Z2)); + SendDlgItemMessage (hDlg, IDC_P96MEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_P96_MEM, gfxboard_is_z3 (workprefs.rtgmem_type) ? MAX_P96_MEM_Z3 : MAX_P96_MEM_Z2)); SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_RESETCONTENT, 0, 0); WIN32GUI_LoadUIString (IDS_DISABLED, tmp, sizeof tmp / sizeof (TCHAR)); SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)tmp); @@ -7530,7 +7604,15 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP case IDC_RTG_Z2Z3: v = SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_GETCURSEL, 0, 0L); if (v != CB_ERR) { - workprefs.rtgmem_type = v; + if (v == 0) { + workprefs.rtgmem_type = 1; + workprefs.rtgmem_size = 0; + } else { + workprefs.rtgmem_type = v - 1; + if (workprefs.rtgmem_size == 0) + workprefs.rtgmem_size = 4096 * 1024; + } + enable_for_expansiondlg (hDlg); } break; case IDC_RTG_8BIT: @@ -7613,7 +7695,7 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP _tcscpy (workprefs.a2065name, _T("none")); } else if (ndd) { v--; - _tcscpy (workprefs.a2065name, ndd[v].name); + _tcscpy (workprefs.a2065name, ndd[v]->name); } } break; @@ -8489,12 +8571,12 @@ static void enable_for_cpudlg (HWND hDlg) SendDlgItemMessage (hDlg, IDC_SPEED, TBM_SETPAGESIZE, 0, 1); } -static int getcpufreq (int m) +static double getcpufreq (int m) { - int f; + double f; - f = workprefs.ntscmode ? 28636360 : 28375160; - return f * (m >> 8) / 8; + f = workprefs.ntscmode ? 28636360.0 : 28375160.0; + return f * (m >> 8) / 8.0; } static void values_to_cpudlg (HWND hDlg) @@ -8639,13 +8721,15 @@ static void values_from_cpudlg (HWND hDlg) } else if (jitena && !oldcache) { workprefs.cachesize = 8192; workprefs.cpu_cycle_exact = false; + if (!cachesize_prev) + trust_prev = 0; if (cachesize_prev) { workprefs.cachesize = cachesize_prev; - workprefs.comptrustbyte = trust_prev; - workprefs.comptrustword = trust_prev; - workprefs.comptrustlong = trust_prev; - workprefs.comptrustnaddr = trust_prev; } + workprefs.comptrustbyte = trust_prev; + workprefs.comptrustword = trust_prev; + workprefs.comptrustlong = trust_prev; + workprefs.comptrustnaddr = trust_prev; } if (oldcache == 0 && candirect && workprefs.cachesize > 0) canbang = 1; @@ -8666,13 +8750,9 @@ static void values_from_cpudlg (HWND hDlg) int m = workprefs.cpu_clock_multiplier; workprefs.cpu_frequency = 0; workprefs.cpu_clock_multiplier = 0; - if (idx == 0) - workprefs.cpu_clock_multiplier = 2 << 8; - if (idx == 1) - workprefs.cpu_clock_multiplier = 4 << 8; - if (idx == 2) - workprefs.cpu_clock_multiplier = 8 << 8; - if (idx == 3) { + if (idx < 4) { + workprefs.cpu_clock_multiplier = (1 << 8) << idx; + } else { TCHAR txt[20]; SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY2, WM_GETTEXT, (WPARAM)sizeof (txt) / sizeof (TCHAR), (LPARAM)txt); workprefs.cpu_clock_multiplier = 0; @@ -8701,22 +8781,19 @@ static INT_PTR CALLBACK CPUDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l SendDlgItemMessage (hDlg, IDC_CPUIDLE, TBM_SETPAGESIZE, 0, 1); SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_RESETCONTENT, 0, 0); - SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("A500")); - SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("A1200")); - SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("2x")); + SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("1x")); + SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("2x (A500)")); + SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("4x (A1200)")); + SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("8x")); SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("Custom")); - idx = 3; - if (workprefs.cpu_clock_multiplier == 2 << 8 || (workprefs.cpu_clock_multiplier == 0 && workprefs.cpu_frequency == 0 && workprefs.cpu_model <= 68010)) { - idx = 0; - workprefs.cpu_clock_multiplier = 2 << 8; - } - if (workprefs.cpu_clock_multiplier == 4 << 8 || (workprefs.cpu_clock_multiplier == 0 && workprefs.cpu_frequency == 0 && workprefs.cpu_model >= 68020)) { - idx = 1; - workprefs.cpu_clock_multiplier = 4 << 8; - } - if (workprefs.cpu_clock_multiplier == 8 << 8) { - idx = 2; + idx = 4; + if (workprefs.cpu_clock_multiplier >= 1 << 8) { + idx = (workprefs.cpu_clock_multiplier >> 8) - 1; + } else if (workprefs.cpu_clock_multiplier == 0 && workprefs.cpu_frequency == 0 && workprefs.cpu_model <= 68010) { + idx = 1; // A500 + } else if (workprefs.cpu_clock_multiplier == 0 && workprefs.cpu_frequency == 0 && workprefs.cpu_model >= 68020) { + idx = 2; // A1200 } if (!workprefs.cpu_cycle_exact) { idx = 3; @@ -9243,6 +9320,10 @@ struct cddlg_vals { struct uaedev_config_info ci; }; +struct tapedlg_vals +{ + struct uaedev_config_info ci; +}; struct fsvdlg_vals { struct uaedev_config_info ci; @@ -9259,6 +9340,7 @@ struct hfdlg_vals }; static struct cddlg_vals current_cddlg; +static struct tapedlg_vals current_tapedlg; static struct fsvdlg_vals current_fsvdlg; static struct hfdlg_vals current_hfdlg; static int archivehd; @@ -9304,6 +9386,11 @@ static void default_fsvdlg (struct fsvdlg_vals *f) memset (f, 0, sizeof (struct fsvdlg_vals)); f->ci.type = UAEDEV_DIR; } +static void default_tapedlg (struct tapedlg_vals *f) +{ + memset (f, 0, sizeof (struct tapedlg_vals)); + f->ci.type = UAEDEV_TAPE; +} static void default_hfdlg (struct hfdlg_vals *f, bool rdb) { int ctrl = f->ci.controller; @@ -9678,6 +9765,81 @@ static void hardfilecreatehdf (HWND hDlg, TCHAR *newpath) sethardfile (hDlg); } +static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int recursive = 0; + int posn, readonly; + + switch (msg) { + + case WM_INITDIALOG: + recursive++; + inithdcontroller (hDlg); + if (current_tapedlg.ci.controller < HD_CONTROLLER_IDE0) + current_tapedlg.ci.controller = (workprefs.cs_a2091 || workprefs.cs_cdtvscsi || workprefs.cs_mbdmac == 1) ? HD_CONTROLLER_SCSI0 : HD_CONTROLLER_IDE0; + SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_tapedlg.ci.controller, 0); + SetDlgItemText (hDlg, IDC_PATH_NAME, current_tapedlg.ci.rootdir); + readonly = my_existsfile (current_tapedlg.ci.rootdir); + CheckDlgButton (hDlg, IDC_TAPE_RW, current_tapedlg.ci.readonly == 0 && !readonly); + ew (hDlg, IDC_TAPE_RW, !readonly); + recursive--; + customDlgType = IDD_TAPEDRIVE; + customDlg = hDlg; + return TRUE; + case WM_COMMAND: + if (recursive) + break; + recursive++; + switch (LOWORD (wParam)) + { + case IDC_TAPE_SELECT_FILE: + DiskSelection (hDlg, IDC_PATH_NAME, 18, &workprefs, NULL); + GetDlgItemText (hDlg, IDC_PATH_NAME, current_tapedlg.ci.rootdir, sizeof current_tapedlg.ci.rootdir / sizeof (TCHAR)); + fullpath (current_tapedlg.ci.rootdir, sizeof current_tapedlg.ci.rootdir / sizeof (TCHAR)); + readonly = my_existsfile (current_tapedlg.ci.rootdir); + ew (hDlg, IDC_TAPE_RW, !readonly); + if (readonly) + CheckDlgButton (hDlg, IDC_TAPE_RW, FALSE); + break; + case IDC_TAPE_SELECT_DIR: + { + const GUID volumeguid = { 0xb95772a5, 0x8444, 0x48d8, { 0xab, 0x9a, 0xef, 0x3c, 0x62, 0x11, 0x3a, 0x37 } }; + TCHAR directory_path[MAX_DPATH]; + _tcscpy (directory_path, current_tapedlg.ci.rootdir); + if (directory_path[0] == 0) { + int out = sizeof directory_path / sizeof (TCHAR); + regquerystr (NULL, _T("TapeDirectoryPath"), directory_path, &out); + } + if (DirectorySelection (hDlg, &volumeguid, directory_path)) { + regsetstr (NULL, _T("TapeDirectoryPath"), directory_path); + SetDlgItemText (hDlg, IDC_PATH_NAME, directory_path); + } + _tcscpy (current_tapedlg.ci.rootdir, directory_path); + readonly = my_existsfile (current_tapedlg.ci.rootdir); + ew (hDlg, IDC_TAPE_RW, !readonly); + if (readonly) + CheckDlgButton (hDlg, IDC_TAPE_RW, FALSE); + break; + } + case IDOK: + EndDialog (hDlg, 1); + break; + case IDCANCEL: + EndDialog (hDlg, 0); + break; + case IDC_HDF_CONTROLLER: + posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_GETCURSEL, 0, 0); + if (posn != CB_ERR) + current_tapedlg.ci.controller = posn; + break; + } + current_tapedlg.ci.readonly = !ischecked (hDlg, IDC_TAPE_RW); + recursive--; + break; + } + return FALSE; +} + static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; @@ -10046,7 +10208,7 @@ static void new_filesys (HWND hDlg, int entry) static void new_cddrive (HWND hDlg, int entry) { struct uaedev_config_info ci = { 0 }; - ci.cd_emu_unit = 0; + ci.device_emu_unit = 0; ci.controller = current_cddlg.ci.controller; ci.type = UAEDEV_CD; ci.readonly = true; @@ -10054,6 +10216,21 @@ static void new_cddrive (HWND hDlg, int entry) add_filesys_config (&workprefs, entry, &ci); } +static void new_tapedrive (HWND hDlg, int entry) +{ + struct uaedev_config_data *uci; + struct uaedev_config_info ci = { 0 }; + ci.controller = current_tapedlg.ci.controller; + ci.readonly = current_tapedlg.ci.readonly; + _tcscpy (ci.rootdir, current_tapedlg.ci.rootdir); + ci.type = UAEDEV_TAPE; + ci.blocksize = 512; + uci = add_filesys_config (&workprefs, entry, &ci); + if (uci) { + tape_media_change (uci->unitnum, &ci); + } +} + static void new_hardfile (HWND hDlg, int entry) { struct uaedev_config_data *uci; @@ -10113,6 +10290,11 @@ static void harddisk_edit (HWND hDlg) if (CustomDialogBox (IDD_CDDRIVE, hDlg, CDDriveSettingsProc)) { new_cddrive (hDlg, entry); } + } else if (uci->ci.type == UAEDEV_TAPE) { + memcpy (¤t_tapedlg.ci, uci, sizeof (struct uaedev_config_info)); + if (CustomDialogBox (IDD_TAPEDRIVE, hDlg, TapeDriveSettingsProc)) { + new_tapedrive (hDlg, entry); + } } else if(type == FILESYS_HARDFILE || type == FILESYS_HARDFILE_RDB) { @@ -10206,6 +10388,12 @@ static int harddiskdlg_button (HWND hDlg, WPARAM wParam) new_cddrive (hDlg, -1); return 1; + case IDC_NEW_TAPE: + default_tapedlg (¤t_tapedlg); + if (CustomDialogBox (IDD_TAPEDRIVE, hDlg, TapeDriveSettingsProc)) + new_tapedrive (hDlg, -1); + return 1; + case IDC_NEW_HD: default_hfdlg (¤t_hfdlg, true); current_hfdlg.ci.type = UAEDEV_HDF; @@ -15677,7 +15865,7 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage) } } DragFinish (hd); - config_changed = 1; + set_config_changed (); return ret; } diff --git a/od-win32/winuae_msvc10/winuae_msvc.vcxproj b/od-win32/winuae_msvc10/winuae_msvc.vcxproj index 0fc75c2c..433d2254 100644 --- a/od-win32/winuae_msvc10/winuae_msvc.vcxproj +++ b/od-win32/winuae_msvc10/winuae_msvc.vcxproj @@ -174,12 +174,12 @@ /MACHINE:I386 %(AdditionalOptions) - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9d.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;prowizard.lib;lzmalib.lib;libFLAC_static.lib;Avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9d.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;prowizard.lib;lzmalib.lib;libFLAC_static.lib;Avrt.lib;hid.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) NotSet $(OutDir)$(TargetName)$(TargetExt) true LIBCMT;%(IgnoreSpecificDefaultLibraries) - wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;ddraw.dll;%(DelayLoadDLLs) + wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs) true .\Debug/winuae.pdb Windows @@ -234,7 +234,7 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true LIBCMT;%(IgnoreSpecificDefaultLibraries) @@ -273,7 +273,7 @@ Speed true false - ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\prowizard\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\prowizard\include;..\..\slirp;%(AdditionalIncludeDirectories) WINVER=0x0500;NDEBUG;_WIN32_IE=0x0700;WIN32;%(PreprocessorDefinitions) true Sync @@ -304,13 +304,13 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;Avrt.lib;hid.lib;zlibstat.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;Avrt.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true %(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\ %(AdditionalManifestDependencies) %(IgnoreSpecificDefaultLibraries) - wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;%(DelayLoadDLLs) + wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs) true .\Release/winuae.pdb Windows @@ -382,7 +382,7 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) NotSet $(OutDir)$(TargetName)$(TargetExt) true @@ -423,7 +423,7 @@ Speed true true - ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\prowizard\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\prowizard\include;..\..\slirp;%(AdditionalIncludeDirectories) WINVER=0x0500;NDEBUG;_WIN32_IE=0x0700;WIN32;%(PreprocessorDefinitions) true Sync @@ -454,13 +454,13 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;avrt.lib;enet.lib;prowizard.lib;lzmalib.lib;libFLAC_static.lib;Avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;avrt.lib;enet.lib;prowizard.lib;lzmalib.lib;libFLAC_static.lib;Avrt.lib;hid.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true %(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\ %(AdditionalManifestDependencies) %(IgnoreSpecificDefaultLibraries) - wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;%(DelayLoadDLLs) + wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs) true .\FullRelease/winuae.pdb Windows @@ -528,7 +528,7 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) NotSet $(OutDir)$(TargetName)$(TargetExt) true @@ -595,10 +595,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters b/od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters index 57403ea2..d274109b 100644 --- a/od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters +++ b/od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters @@ -44,6 +44,12 @@ {67d1b86d-3ebd-40fe-9fc2-c749eb7a890b} + + {04629b2c-8cce-42aa-a9a7-e000e87ad1c2} + + + {736531a2-213e-4aef-ab15-c2a3a0025147} + @@ -547,6 +553,81 @@ unpackers\chd + + common + + + common + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + qemu + + + qemu + + + qemu + + + common + + + common + diff --git a/od-win32/winuae_msvc11/winuae_msvc.vcxproj b/od-win32/winuae_msvc11/winuae_msvc.vcxproj index 58258992..68760254 100644 --- a/od-win32/winuae_msvc11/winuae_msvc.vcxproj +++ b/od-win32/winuae_msvc11/winuae_msvc.vcxproj @@ -219,12 +219,12 @@ /MACHINE:I386 %(AdditionalOptions) - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9d.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;prowizard.lib;lzmalib.lib;libFLAC_static.lib;Avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9d.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;prowizard.lib;lzmalib.lib;libFLAC_static.lib;Avrt.lib;hid.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) NotSet $(OutDir)$(TargetName)$(TargetExt) true LIBCMT;%(IgnoreSpecificDefaultLibraries) - wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;ddraw.dll;%(DelayLoadDLLs) + wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs) true .\Debug/winuae.pdb Windows @@ -319,7 +319,7 @@ Speed true false - ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\prowizard\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\prowizard\include;..\..\slirp;%(AdditionalIncludeDirectories) WINVER=0x0500;NDEBUG;_WIN32_IE=0x0700;WIN32;%(PreprocessorDefinitions) true Sync @@ -350,13 +350,13 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;Avrt.lib;hid.lib;zlibstat.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;Avrt.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true %(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\ %(AdditionalManifestDependencies) %(IgnoreSpecificDefaultLibraries) - wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;%(DelayLoadDLLs) + wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs) true .\Release/winuae.pdb Windows @@ -397,7 +397,7 @@ Neither false false - ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\prowizard\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\prowizard\include;..\..\slirp;%(AdditionalIncludeDirectories) WINVER=0x0500;NDEBUG;_WIN32_IE=0x0700;WIN32;%(PreprocessorDefinitions) true Sync @@ -428,13 +428,13 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;Avrt.lib;hid.lib;zlibstat.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;libpng15.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;Avrt.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true %(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\ %(AdditionalManifestDependencies) %(IgnoreSpecificDefaultLibraries) - wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;%(DelayLoadDLLs) + wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs) true .\Test/winuae.pdb Windows @@ -475,7 +475,7 @@ Speed true false - ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;%(AdditionalIncludeDirectories) + ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;%(AdditionalIncludeDirectories) WINVER=0x0500;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;%(PreprocessorDefinitions) true Sync @@ -505,13 +505,13 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;Iphlpapi.lib;luastatic.lib;%(AdditionalDependencies) NotSet $(OutDir)$(TargetName)$(TargetExt) true %(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\ LIBCMT;%(IgnoreSpecificDefaultLibraries) - wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x64.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;avrt.dll;Dwmapi.lib;%(DelayLoadDLLs) + wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x64.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;avrt.dll;Dwmapi.dll;Iphlpapi.dll;%(DelayLoadDLLs) true $(Platform)\$(Configuration)\winuae.pdb Windows @@ -789,10 +789,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/od-win32/winuae_msvc11/winuae_msvc.vcxproj.filters b/od-win32/winuae_msvc11/winuae_msvc.vcxproj.filters index c1c7459d..c51d5962 100644 --- a/od-win32/winuae_msvc11/winuae_msvc.vcxproj.filters +++ b/od-win32/winuae_msvc11/winuae_msvc.vcxproj.filters @@ -47,6 +47,9 @@ {7abef0b5-1d8e-4f43-baa6-ff61760bc330} + + {fc42f311-daf2-48de-a851-8ad3a4aad22e} + @@ -550,6 +553,81 @@ unpackers\chd + + common + + + common + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + slirp + + + qemu + + + qemu + + + qemu + + + common + + + common + diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index ab98e09a..821f0d90 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,6 +1,8 @@ - restore only single input target to default. +2.6.1 + Beta 4: - Added new level between pre and post shaders (0 in GUI, selected by default) which diff --git a/od-win32/writelog.cpp b/od-win32/writelog.cpp index d24e1322..41a87d24 100644 --- a/od-win32/writelog.cpp +++ b/od-win32/writelog.cpp @@ -464,6 +464,20 @@ void write_dlog (const TCHAR *format, ...) LeaveCriticalSection (&cs); } +void write_log (const char *format, ...) +{ + char buffer[WRITE_LOG_BUF_SIZE]; + va_list parms; + TCHAR *b; + + va_start (parms, format); + vsprintf (buffer, format, parms); + b = au (buffer); + write_log (b); + xfree (b); + va_end (parms); +} + void write_log (const TCHAR *format, ...) { int count; diff --git a/sana2.cpp b/sana2.cpp index 47c11fa9..1eb1bd0f 100644 --- a/sana2.cpp +++ b/sana2.cpp @@ -223,7 +223,7 @@ struct priv_s2devstruct { int tmp; }; -static struct netdriverdata *td; +static struct netdriverdata *td[MAX_TOTAL_NET_DEVICES + 1]; static struct s2devstruct devst[MAX_TOTAL_NET_DEVICES]; static struct priv_s2devstruct pdevst[MAX_OPEN_DEVICES]; static uae_u32 nscmd_cmd; @@ -286,7 +286,7 @@ static uae_u32 REGPARAM2 dev_close_2 (TrapContext *context) CallLib (context, get_long (4), -0xD2); /* FreeMem */ pdev->tempbuf = 0; } - uaenet_close (dev->sysdata); + ethernet_close (pdev->td, dev->sysdata); xfree (dev->sysdata); dev->sysdata = NULL; write_comm_pipe_u32 (&dev->requests, 0, 1); @@ -377,7 +377,7 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context) pdev->unit = unit; pdev->flags = flags; pdev->inuse = 1; - pdev->td = td ? &td[unit] : NULL; + pdev->td = td ? td[unit] : NULL; pdev->promiscuous = (flags & SANA2OPF_PROM) ? 1 : 0; if (pdev->td == NULL || pdev->td->active == 0) @@ -385,8 +385,8 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context) if (dev->opencnt == 0) { dev->unit = unit; - dev->sysdata = xcalloc (uae_u8, uaenet_getdatalenght ()); - if (!uaenet_open (dev->sysdata, pdev->td, dev, uaenet_gotdata, uaenet_getdata, pdev->promiscuous)) { + dev->sysdata = xcalloc (uae_u8, ethernet_getdatalenght (pdev->td)); + if (!ethernet_open (pdev->td, dev->sysdata, dev, uaenet_gotdata, uaenet_getdata, pdev->promiscuous)) { xfree (dev->sysdata); dev->sysdata = NULL; return openfail (ioreq, IOERR_OPENFAIL); @@ -450,7 +450,7 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context) pdev->tempbuf = CallLib (context, get_long (4), -0xC6); /* AllocMem */ if (!pdev->tempbuf) { if (dev->opencnt == 0) { - uaenet_close (dev->sysdata); + ethernet_close (pdev->td, dev->sysdata); xfree (dev->sysdata); dev->sysdata = NULL; } @@ -1357,7 +1357,7 @@ static void *dev_thread (void *devs) rem_async_packet (dev, request); } else { add_async_request (dev, request); - uaenet_trigger (dev->sysdata); + ethernet_trigger (dev->sysdata); } uae_sem_post (&change_sem); } @@ -1615,8 +1615,8 @@ void netdev_install (void) if (log_net) write_log (_T("netdev_install(): 0x%x\n"), here ()); - uaenet_enumerate_free (td); - uaenet_enumerate (&td, NULL); + ethernet_enumerate_free (); + ethernet_enumerate (td, NULL); ROM_netdev_resname = ds (getdevname()); ROM_netdev_resid = ds (_T("UAE net.device 0.2")); diff --git a/savestate.cpp b/savestate.cpp index e263bfa6..9da2e44a 100644 --- a/savestate.cpp +++ b/savestate.cpp @@ -514,7 +514,7 @@ void restore_state (const TCHAR *filename) goto error; } write_log (_T("STATERESTORE: '%s'\n"), filename); - config_changed = 1; + set_config_changed (); savestate_file = f; restore_header (chunk); xfree (chunk); @@ -682,7 +682,7 @@ void restore_state (const TCHAR *filename) else if (!_tcscmp (name, _T("DMC2"))) end = restore_scsi_dmac (chunk); else if (!_tcscmp (name, _T("SCSI"))) - end = restore_scsi_hd (chunk); + end = restore_scsi_device (chunk); else if (!_tcscmp (name, _T("GAYL"))) end = restore_gayle (chunk); else if (!_tcscmp (name, _T("IDE "))) @@ -971,7 +971,7 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c save_chunk (f, dst, len, _T("DMC2"), 0); xfree (dst); for (i = 0; i < 8; i++) { - dst = save_scsi_hd (i, &len, NULL); + dst = save_scsi_device (i, &len, NULL); save_chunk (f, dst, len, _T("SCSI"), 0); xfree (dst); } diff --git a/scsi.cpp b/scsi.cpp index f126be2a..9b337c7d 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -14,10 +14,11 @@ #include "scsi.h" #include "filesys.h" #include "blkdev.h" +#include "zfile.h" static int outcmd[] = { 0x0a, 0x2a, 0x2f, 0xaa, 0x15, 0x55, -1 }; -static int incmd[] = { 0x03, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, -1 }; -static int nonecmd[] = { 0x00, 0x1b, 0x1e, 0x35, -1 }; +static int incmd[] = { 0x01, 0x03, 0x05, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, -1 }; +static int nonecmd[] = { 0x00, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x35, -1 }; static int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 10 }; static int scsi_data_dir(struct scsi_data *sd) @@ -73,13 +74,51 @@ void scsi_illegal_lun(struct scsi_data *sd) uae_u8 *s = sd->sense; memset (s, 0, sizeof (sd->sense)); - sd->status = 2; /* CHECK CONDITION */ + sd->status = SCSI_STATUS_CHECK_CONDITION; s[0] = 0x70; - s[2] = 5; /* ILLEGAL REQUEST */ - s[12] = 0x25; /* INVALID LUN */ + s[2] = SCSI_SK_ILLEGAL_REQ; + s[12] = SCSI_INVALID_LUN; sd->sense_len = 0x12; } +void scsi_clear_sense(struct scsi_data *sd) +{ + memset (sd->sense, 0, sizeof (sd->sense)); + memset (sd->reply, 0, sizeof (sd->reply)); + sd->sense[0] = 0x70; +} +static void showsense(struct scsi_data *sd) +{ +#if 1 + write_log (_T("REQUEST SENSE %d, "), sd->data_len); + for (int i = 0; i < sd->data_len; i++) { + if (i > 0) + write_log (_T(".")); + write_log (_T("%02X"), sd->buffer[i]); + } + write_log (_T("\n")); +#endif +} +static void copysense(struct scsi_data *sd) +{ + int len = sd->cmd[4]; + memset(sd->buffer, 0, len); + memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len); + if (sd->sense_len == 0) + sd->buffer[0] = 0x70; + sd->data_len = len; + showsense (sd); + scsi_clear_sense(sd); +} +static void copyreply(struct scsi_data *sd) +{ + if (sd->status == 0 && sd->reply_len > 0) { + memset(sd->buffer, 0, 256); + memcpy(sd->buffer, sd->reply, sd->reply_len); + sd->data_len = sd->reply_len; + } +} + void scsi_emulate_cmd(struct scsi_data *sd) { sd->status = 0; @@ -91,39 +130,35 @@ void scsi_emulate_cmd(struct scsi_data *sd) sd->cmd[1] |= lun << 5; } //write_log (_T("CMD=%02x\n"), sd->cmd[0]); - if (sd->cd_emu_unit >= 0) { + if (sd->device_type == UAEDEV_CD && sd->cd_emu_unit >= 0) { if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */ - int len = sd->cmd[4]; scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, 0, 0, 0, 0, 0, 0, 0, sd->atapi); /* ack request sense */ - memset(sd->buffer, 0, len); - memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len); - sd->data_len = len; + copysense(sd); } else { + scsi_clear_sense(sd); sd->status = scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len, sd->atapi); - if (sd->status == 0) { - if (sd->reply_len > 0) { - memset(sd->buffer, 0, 256); - memcpy(sd->buffer, sd->reply, sd->reply_len); - } - } + copyreply(sd); } - } else if (sd->nativescsiunit < 0) { + } else if (sd->device_type == UAEDEV_HDF && sd->nativescsiunit < 0) { if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */ - int len = sd->cmd[4]; - memset(sd->buffer, 0, len); - memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len); - sd->data_len = len; + copysense(sd); } else { + scsi_clear_sense(sd); sd->status = scsi_hd_emulate(&sd->hfd->hfd, sd->hfd, sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len); - if (sd->status == 0) { - if (sd->reply_len > 0) { - memset(sd->buffer, 0, 256); - memcpy(sd->buffer, sd->reply, sd->reply_len); - } - } + copyreply(sd); } - } else { + } else if (sd->device_type == UAEDEV_TAPE && sd->nativescsiunit < 0) { + if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */ + scsi_tape_emulate(sd->tape, sd->cmd, 0, 0, 0, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len); /* get request sense extra bits */ + copysense(sd); + } else { + scsi_clear_sense(sd); + sd->status = scsi_tape_emulate(sd->tape, + sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len); + copyreply(sd); + } + } else if (sd->nativescsiunit >= 0) { struct amigascsi as; memset(sd->sense, 0, 256); @@ -136,7 +171,7 @@ void scsi_emulate_cmd(struct scsi_data *sd) as.cmd_len = sd->cmd_len; as.data = sd->buffer; as.len = sd->direction < 0 ? DEVICE_SCSI_BUFSIZE : sd->data_len; - sys_command_scsi_direct_native(sd->nativescsiunit, &as); + sys_command_scsi_direct_native(sd->nativescsiunit, -1, &as); sd->status = as.status; sd->data_len = as.len; if (sd->status) { @@ -156,6 +191,7 @@ struct scsi_data *scsi_alloc_hd(int id, struct hd_hardfiledata *hfd) sd->nativescsiunit = -1; sd->cd_emu_unit = -1; sd->blocksize = hfd->hfd.ci.blocksize; + sd->device_type = UAEDEV_HDF; return sd; } @@ -172,6 +208,23 @@ struct scsi_data *scsi_alloc_cd(int id, int unitnum, bool atapi) sd->nativescsiunit = -1; sd->atapi = atapi; sd->blocksize = 2048; + sd->device_type = UAEDEV_CD; + return sd; +} + +struct scsi_data *scsi_alloc_tape(int id, const TCHAR *tape_directory, bool readonly) +{ + struct scsi_data_tape *tape; + tape = tape_alloc (id, tape_directory, readonly); + if (!tape) + return NULL; + struct scsi_data *sd = xcalloc (struct scsi_data, 1); + sd->id = id; + sd->nativescsiunit = -1; + sd->cd_emu_unit = -1; + sd->blocksize = tape->blocksize; + sd->tape = tape; + sd->device_type = UAEDEV_TAPE; return sd; } @@ -187,6 +240,7 @@ struct scsi_data *scsi_alloc_native(int id, int nativeunit) sd->nativescsiunit = nativeunit; sd->cd_emu_unit = -1; sd->blocksize = 2048; + sd->device_type = 0; return sd; } @@ -207,6 +261,7 @@ void scsi_free(struct scsi_data *sd) sys_command_close (sd->cd_emu_unit); sd->cd_emu_unit = -1; } + tape_free (sd->tape); xfree(sd); } diff --git a/scsiemul.cpp b/scsiemul.cpp index 864e11a3..05ecf0a1 100644 --- a/scsiemul.cpp +++ b/scsiemul.cpp @@ -65,6 +65,8 @@ struct devstruct { smp_comm_pipe requests; int thread_running; uae_sem_t sync_sem; + TCHAR *tape_directory; + bool readonly; }; struct priv_devstruct { @@ -196,7 +198,7 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context, int type) uae_u32 flags = m68k_dreg (regs, 1); struct devstruct *dev = getdevstruct (unit); struct priv_devstruct *pdev = 0; - int i; + int i, v; if (log_scsi) write_log (_T("opening %s:%d ioreq=%08X\n"), getdevname (type), unit, ioreq); @@ -210,7 +212,12 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context, int type) if (pdev->inuse == 0) break; } - if (!sys_command_open (dev->unitnum)) + if (dev->drivetype == INQ_SEQD) { + v = sys_command_open_tape (dev->unitnum, dev->tape_directory, dev->readonly); + } else { + v = sys_command_open (dev->unitnum); + } + if (!v) return openfail (ioreq, IOERR_OPENFAIL); pdev->type = type; pdev->unit = unit; @@ -504,7 +511,45 @@ static int command_cd_read (struct devstruct *dev, uaecptr data, uae_u64 offset, return 0; } -static int dev_do_io (struct devstruct *dev, uaecptr request) +static int dev_do_io_tape (struct devstruct *dev, uaecptr request) +{ + uae_u32 command; + uae_u32 io_data = get_long (request + 40); // 0x28 + uae_u32 io_length = get_long (request + 36); // 0x24 + uae_u32 io_actual = get_long (request + 32); // 0x20 + uae_u32 io_offset = get_long (request + 44); // 0x2c + uae_u32 io_error = 0; + struct priv_devstruct *pdev = getpdevstruct (request); + + if (!pdev) + return 0; + command = get_word (request + 28); + + if (log_scsi) + write_log (_T("TAPE %d: DATA=%08X LEN=%08X OFFSET=%08X ACTUAL=%08X\n"), + command, io_data, io_length, io_offset, io_actual); + switch (command) + { + case HD_SCSICMD: + { + uae_u32 sdd = get_long (request + 40); + io_error = sys_command_scsi_direct (dev->unitnum, INQ_SEQD, sdd); + if (log_scsi) + write_log (_T("scsidev tape: did io: sdd %08x request %08x error %d\n"), sdd, request, get_byte (request + 31)); + } + break; + default: + io_error = IOERR_NOCMD; + break; + } + + put_long (request + 32, io_actual); + put_byte (request + 31, io_error); + io_log (_T("dev_io_tape"),request); + return 0; +} + +static int dev_do_io_cd (struct devstruct *dev, uaecptr request) { uae_u32 command; uae_u32 io_data = get_long (request + 40); // 0x28 @@ -522,7 +567,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) command = get_word (request + 28); if (log_scsi) - write_log (_T("%d: DATA=%08X LEN=%08X OFFSET=%08X ACTUAL=%08X\n"), + write_log (_T("CD %d: DATA=%08X LEN=%08X OFFSET=%08X ACTUAL=%08X\n"), command, io_data, io_length, io_offset, io_actual); switch (command) @@ -857,9 +902,9 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) case HD_SCSICMD: { uae_u32 sdd = get_long (request + 40); - io_error = sys_command_scsi_direct (dev->unitnum, sdd); + io_error = sys_command_scsi_direct (dev->unitnum, INQ_ROMD, sdd); if (log_scsi) - write_log (_T("scsidev: did io: sdd %08x request %08x error %d\n"), sdd, request, get_byte (request + 31)); + write_log (_T("scsidev cd: did io: sdd %08x request %08x error %d\n"), sdd, request, get_byte (request + 31)); } break; case NSCMD_DEVICEQUERY: @@ -885,10 +930,19 @@ no_media: } put_long (request + 32, io_actual); put_byte (request + 31, io_error); - io_log (_T("dev_io"),request); + io_log (_T("dev_io_tape"),request); return async; } +static int dev_do_io (struct devstruct *dev, uaecptr request) +{ + if (dev->drivetype == INQ_SEQD) { + return dev_do_io_tape (dev, request); + } else { + return dev_do_io_cd (dev, request); + } +} + static int dev_can_quick (uae_u32 command) { switch (command) @@ -1039,6 +1093,23 @@ uae_u32 scsi_get_cd_drive_media_mask (void) } return mask; } +int scsi_add_tape (struct uaedev_config_info *uci) +{ + for (int i = 4; i < MAX_TOTAL_SCSI_DEVICES; i++) { + struct devstruct *dev = &devst[i]; + if (dev->unitnum >= 0 || dev->drivetype > 0) + continue; + if (sys_command_open_tape (i, uci->rootdir, uci->readonly)) { + dev->drivetype = INQ_SEQD; + dev->aunit = i; + dev->unitnum = i; + dev->tape_directory = my_strdup (uci->rootdir); + write_log (_T("%s:%d = '%s''\n"), UAEDEV_SCSI, dev->aunit, uci->rootdir); + return i; + } + } + return -1; +} static void dev_reset (void) { int i, j; @@ -1054,9 +1125,11 @@ static void dev_reset (void) abort_async (dev, request, 0, 0); } dev->opencnt = 1; - sys_command_close (dev->unitnum); + if (dev->unitnum >= 0) + sys_command_close (dev->unitnum); } memset (dev, 0, sizeof (struct devstruct)); + xfree (dev->tape_directory); dev->unitnum = dev->aunit = -1; } for (i = 0; i < MAX_OPEN_DEVICES; i++) diff --git a/scsitape.cpp b/scsitape.cpp new file mode 100644 index 00000000..28f5c9a3 --- /dev/null +++ b/scsitape.cpp @@ -0,0 +1,618 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* SCSI tape emulation +* +* Copyright 2013 Toni Wilen +* +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "filesys.h" +#include "scsi.h" +#include "blkdev.h" +#include "zfile.h" +#include "memory.h" +#include "a2091.h" +#include "fsdb.h" + +int log_tapeemu = 1; + +#define TAPE_INDEX _T("index.tape") + +static struct scsi_data_tape *tapeunits[MAX_FILESYSTEM_UNITS]; + +static bool notape (struct scsi_data_tape *tape) +{ + return tape->tape_dir[0] == 0 || tape->nomedia; +} + +static int rl (uae_u8 *p) +{ + return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]); +} +static void wl (uae_u8 *p, int v) +{ + p[0] = v >> 24; + p[1] = v >> 16; + p[2] = v >> 8; + p[3] = v; +} + +void tape_free (struct scsi_data_tape *tape) +{ + if (!tape) + return; + zfile_fclose (tape->zf); + zfile_fclose (tape->index); + zfile_closedir_archive (tape->zd); + xfree(tape); + for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) { + if (tapeunits[i] == tape) + tapeunits[i] = NULL; + } +} + +static void tape_init (int unit, struct scsi_data_tape *tape, const TCHAR *tape_directory, bool readonly) +{ + TCHAR path[MAX_DPATH]; + + memset (tape, 0, sizeof (struct scsi_data_tape)); + _tcscpy (tape->tape_dir, tape_directory); + + tape->blocksize = 512; + tape->wp = readonly; + tape->beom = -1; + tape->nomedia = false; + + if (my_existsdir (tape->tape_dir)) { + tape->realdir = true; + } else { + tape->zd = zfile_opendir_archive (tape_directory, ZFD_ARCHIVE | ZFD_NORECURSE); + if (!tape->zd) + tape->nomedia = true; + } + + _tcscpy (path, tape_directory); + _tcscat (path, FSDB_DIR_SEPARATOR_S); + _tcscat (path, TAPE_INDEX); + tape->index = zfile_fopen (path, _T("rb"), ZFD_NORMAL); + tapeunits[unit] = tape; +} + +struct scsi_data_tape *tape_alloc (int unitnum, const TCHAR *tape_directory, bool readonly) +{ + struct scsi_data_tape *tape = xcalloc (struct scsi_data_tape, 1); + + tape_init (unitnum, tape, tape_directory, readonly); + return tape; +} + +void tape_media_change (int unitnum, struct uaedev_config_info *ci) +{ + struct scsi_data_tape *tape = tapeunits[unitnum]; + if (!tape) + return; + tape_init (unitnum, tape, ci->rootdir, ci->readonly); +} + +bool tape_get_info (int unitnum, struct device_info *di) +{ + struct scsi_data_tape *tape = tapeunits[unitnum]; + memset (di, 0, sizeof (struct device_info)); + if (!tape) + return false; + di->media_inserted = notape (tape) == false; + _tcscpy (di->label, tape->tape_dir); + return true; +} + +static void rewind (struct scsi_data_tape *tape) +{ + zfile_fclose (tape->zf); + tape->zf = NULL; + my_closedir (tape->od); + tape->file_number = 0; + tape->file_offset = 0; + tape->od = NULL; + tape->beom = -1; + if (tape->index) + zfile_fseek (tape->index, 0, SEEK_SET); + if (tape->zd) + zfile_resetdir_archive (tape->zd); +} + +static void erase (struct scsi_data_tape *tape) +{ + struct my_opendir_s *od; + if (!tape->realdir) + return; + rewind (tape); + od = my_opendir (tape->tape_dir); + if (od) { + for (;;) { + TCHAR path[MAX_DPATH], filename[MAX_DPATH]; + if (!my_readdir (od, filename)) + break; + TCHAR *ext = _tcsrchr (filename, '.'); + if (ext && !_tcsicmp (ext, _T(".tape"))) { + _stprintf (path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, filename); + if (my_existsfile (path)) + my_unlink (path); + } + } + my_closedir (od); + } +} + +static bool next_file (struct scsi_data_tape *tape) +{ + zfile_fclose (tape->zf); + tape->zf = NULL; + tape->file_offset = 0; + if (tape->index) { + TCHAR path[MAX_DPATH]; + TCHAR name[256]; + name[0] = 0; + zfile_fgets (name, sizeof name / sizeof (TCHAR), tape->index); + my_trim (name); + if (name[0] == 0) + goto end; + _tcscpy (path, tape->tape_dir); + _tcscat (path, FSDB_DIR_SEPARATOR_S); + _tcscat (path, name); + tape->zf = zfile_fopen (path, _T("rb"), ZFD_NORMAL); + write_log (_T("TAPEEMU: File '%s'\n"), path); + } else if (tape->realdir) { + TCHAR path[MAX_DPATH], filename[MAX_DPATH]; + if (tape->od == NULL) + tape->od = my_opendir (tape->tape_dir); + if (!tape->od) { + tape_free (tape); + goto end; + } + for (;;) { + if (!my_readdir (tape->od, filename)) + goto end; + if (_tcsicmp (filename, TAPE_INDEX)) + continue; + _stprintf (path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, filename); + if (!my_existsfile (path)) + continue; + tape->zf = zfile_fopen (path, _T("rb"), 0); + if (!tape->zf) + continue; + break; + } + if (tape->zf) + write_log (_T("TAPEEMU DIR: File '%s'\n"), zfile_getname (tape->zf)); + } else { + tape->zf = zfile_readdir_archive_open (tape->zd, _T("rb")); + if (tape->zf) + write_log (_T("TAPEEMU ARC: File '%s'\n"), zfile_getname (tape->zf)); + } + if (tape->zf) { + tape->file_number++; + return true; + } +end: + write_log (_T("TAPEEMU: end of tape\n")); + return false; +} + +static int tape_read (struct scsi_data_tape *tape, uae_u8 *scsi_data, int len) +{ + int got; + + if (!tape->zf) { + rewind (tape); + if (!next_file (tape)) + return -1; + } + zfile_fseek (tape->zf, tape->file_offset, SEEK_SET); + got = zfile_fread (scsi_data, 1, len, tape->zf); + tape->file_offset += got; + if (got < len) + next_file (tape); + return got; +} + +static int tape_write (struct scsi_data_tape *tape, uae_u8 *scsi_data, int len) +{ + TCHAR path[MAX_DPATH], numname[30]; + int exists; + + if (!tape->realdir) + return -1; + _stprintf (numname, _T("%05d.tape"), tape->file_number); + _stprintf (path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, numname); + exists = my_existsfile (path); + struct zfile *zf = zfile_fopen (path, _T("a+b")); + if (!zf) + return -1; + zfile_fseek (zf, 0, SEEK_END); + len = zfile_fwrite (scsi_data, 1, len, zf); + zfile_fclose (zf); + if (!exists) { + _stprintf (path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, TAPE_INDEX); + zf = zfile_fopen (path, _T("a+b")); + if (zf) { + zfile_fputs (zf, numname); + zfile_fputs (zf, _T("\n")); + } + zfile_fclose (zf); + } + return len; +} + +int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd_len, + uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len) +{ + uae_s64 len; + int lr = 0, ls = 0; + int scsi_len = -1; + int status = 0; + int lun; + + if (log_tapeemu) + write_log (_T("TAPEEMU: scsi command 0x%02X.%02X.%02X.%02X.%02X.%02X\n"), + cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5]); + + if (cmdbuf[0] == 3) { + s[0] = 0x70; + if (tape->beom < 0) + s[9] |= 0x8; + if (tape->beom > 0) + s[2] |= 0x40; + *sense_len = 0x12; + return 0; + } + + *reply_len = *sense_len = 0; + memset (r, 0, 256); + memset (s, 0, 256); + s[0] = 0x70; + + lun = cmdbuf[1] >> 5; + if (cmdbuf[0] != 0x03 && cmdbuf[0] != 0x12 && lun) { + status = 2; /* CHECK CONDITION */ + s[0] = 0x70; + s[2] = 5; /* ILLEGAL REQUEST */ + s[12] = 0x25; /* INVALID LUN */ + ls = 0x12; + goto err; + } + + switch (cmdbuf[0]) + { + case 0x00: /* TEST UNIT READY */ + if (notape (tape)) + goto notape; + scsi_len = 0; + break; + + case 0x19: /* ERASE */ + if (log_tapeemu) + write_log (_T("TAPEEMU ERASE\n")); + if (notape (tape)) + goto notape; + if (tape->wp) + goto writeprot; + erase (tape); + rewind (tape); + tape->beom = 1; + scsi_len = 0; + break; + + case 0x1b: /* LOAD/UNLOAD */ + { + bool load = (cmdbuf[4] & 1) != 0; + bool ret = (cmdbuf[4] & 2) != 0; + bool eot = (cmdbuf[4] & 4) != 0; + if (log_tapeemu) + write_log (_T("TAPEEMU LOAD/UNLOAD %d:%d:%d\n"), eot, ret, load); + if (notape (tape)) + goto notape; + if (load && (ret || eot)) + goto errreq; + rewind (tape); + if (eot) { + tape->beom = 1; + } else { + tape->beom = -1; + } + scsi_len = 0; + break; + } + + case 0x01: /* REWIND */ + if (log_tapeemu) + write_log (_T("TAPEEMU: REWIND. IMMED=%d\n"), cmdbuf[1] & 1); + if (notape (tape)) + goto notape; + rewind (tape); + scsi_len = 0; + break; + + case 0x11: /* SPACE */ + { + int code = cmdbuf[1] & 15; + int count = rl (cmdbuf + 1) & 0xffffff; + if (log_tapeemu) + write_log (_T("TAPEEMU: SPACE code=%d count=%d\n"), code, count); + if (code >= 2) + goto errreq; + if (code == 1) { + if (!next_file (tape)) + goto endoftape; + } + scsi_len = 0; + } + break; + + case 0x10: /* WRITE FILEMARK */ + len = rl (cmdbuf + 1) & 0xffffff; + if (log_tapeemu) + write_log (_T("TAPEEMU WRITE FILEMARK %d\n"), len); + if (notape (tape)) + goto notape; + if (tape->wp) + goto writeprot; + if (len > 0) { + tape->file_number++; + tape_write (tape, scsi_data, 0); + } + scsi_len = 0; + break; + + case 0x0a: /* WRITE (6) */ + len = rl (cmdbuf + 1) & 0xffffff; + if (cmdbuf[1] & 1) + len *= tape->blocksize; + if (log_tapeemu) + write_log (_T("TAPEEMU WRITE %d (%d, %d)\n"), len, rl (cmdbuf + 1) & 0xffffff, cmdbuf[1] & 1); + if (notape (tape)) + goto notape; + if (tape->wp) + goto writeprot; + if (tape->beom < 0) + tape->beom = 0; + scsi_len = tape_write (tape, scsi_data, len); + if (scsi_len < 0) + goto writeprot; + break; + + case 0x08: /* READ (6) */ + len = rl (cmdbuf + 1) & 0xffffff; + if (cmdbuf[1] & 1) + len *= tape->blocksize; + if (log_tapeemu) + write_log (_T("TAPEEMU READ %d (%d, %d)\n"), len, rl (cmdbuf + 1) & 0xffffff, cmdbuf[1] & 1); + if (notape (tape)) + goto notape; + if (tape->beom < 0) + tape->beom = 0; + scsi_len = tape_read (tape, scsi_data, len); + if (scsi_len < 0) { + tape->beom = 1; + status = SCSI_STATUS_CHECK_CONDITION; + s[0] = 0x70; + s[2] = 0x80 | 0x40 | 0; /* File Mark Detected + End of Media + NO SENSE */ + s[12] = 0; + s[13] = 2; /* End-of-partition/medium detected */ + ls = 0x12; + } else if (scsi_len < len) { + status = SCSI_STATUS_CHECK_CONDITION; + s[0] = 0x70; + s[2] = 0x80 | 0; /* File Mark Detected + NO SENSE */ + wl (&s[3], len - scsi_len); + s[12] = 0; + s[13] = 1; /* File Mark detected */ + ls = 0x12; + if (log_tapeemu) + write_log (_T("TAPEEMU READ FILE END, %d remaining\n"), len - scsi_len); + } + scsi_len = len; + + break; + + case 0x5a: // MODE SENSE(10) + case 0x1a: /* MODE SENSE(6) */ + { + uae_u8 *p; + int maxlen; + bool pcodeloop = false; + bool sense10 = cmdbuf[0] == 0x5a; + int totalsize, bdsize; + int pc = cmdbuf[2] >> 6; + int pcode = cmdbuf[2] & 0x3f; + int dbd = cmdbuf[1] & 8; + if (cmdbuf[0] == 0x5a) + dbd = 1; + if (log_tapeemu) + write_log (_T("TAPEEMU MODE SENSE PC=%d CODE=%d DBD=%d\n"), pc, pcode, dbd); + p = r; + if (sense10) { + totalsize = 8 - 2; + maxlen = (cmdbuf[7] << 8) | cmdbuf[8]; + p[2] = 0; + p[3] = 0; + p[4] = 0; + p[5] = 0; + p[6] = 0; + p[7] = 0; + p += 8; + } else { + totalsize = 4 - 1; + maxlen = cmdbuf[4]; + p[1] = 0; + p[2] = tape->wp ? 0x80 : 0; + p[3] = 0; + p += 4; + } + bdsize = 0; + if (!dbd) { + wl(p + 0, 0); + wl(p + 4, tape->blocksize); + bdsize = 8; + p += bdsize; + } + if (pcode) + goto errreq; + if (sense10) { + totalsize += bdsize; + r[6] = bdsize >> 8; + r[7] = bdsize & 0xff; + r[0] = totalsize >> 8; + r[1] = totalsize & 0xff; + } else { + totalsize += bdsize; + r[3] = bdsize & 0xff; + r[0] = totalsize & 0xff; + } + lr = totalsize + 1; + if (lr > maxlen) + lr = maxlen; + } + break; + + case 0x55: // MODE SELECT(10) + case 0x15: // MODE SELECT(6) + { + uae_u8 *p; + bool mode10 = cmdbuf[0] == 0x55; + int nb = 0, bl = 512; + p = scsi_data + 4; + if (mode10) + p += 4; + if (scsi_data[3] >= 8) { + nb = rl (p) & 0xffffff; + bl = rl (p + 4) & 0xffffff; + } + if (log_tapeemu) + write_log (_T("TAPEEMU MODE SELECT BUFM=%d BDL=%d Density=%d NB=%d BL=%d\n"), (scsi_data[2] & 0x10) != 0, scsi_data[3], p[0], nb, bl); + if (nb || bl != 512) + goto err; + scsi_len = 0; + break; + } + + case 0x05: /* READ BLOCK LIMITS */ + if (log_tapeemu) + write_log (_T("TAPEEMU READ BLOCK LIMITS\n")); + r[0] = 0; + r[1] = 0; + r[2] = 2; // 0x200 = 512 + r[3] = 0; + r[4] = 2; // 0x200 = 512 + r[5] = 0; + lr = 6; + break; + + case 0x16: /* RESERVE UNIT */ + if (log_tapeemu) + write_log (_T("TAPEEMU RESERVE UNIT\n")); + scsi_len = 0; + break; + + case 0x17: /* RELEASE UNIT */ + if (log_tapeemu) + write_log (_T("TAPEEMU RELEASE UNIT\n")); + scsi_len = 0; + break; + + case 0x1e: /* PREVENT/ALLOW MEDIUM REMOVAL */ + if (log_tapeemu) + write_log (_T("TAPEEMU PREVENT/ALLOW MEDIUM REMOVAL\n")); + scsi_len = 0; + break; + + case 0x12: /* INQUIRY */ + { + if (log_tapeemu) + write_log (_T("TAPEEMU INQUIRY\n")); + if ((cmdbuf[1] & 1) || cmdbuf[2] != 0) + goto err; + len = cmdbuf[4]; + if (cmdbuf[1] >> 5) { + r[0] = 0x7f; + } else { + r[0] = INQ_SEQD; + } + r[1] |= 0x80; // removable + r[2] = 2; /* supports SCSI-2 */ + r[3] = 2; /* response data format */ + r[4] = 32; /* additional length */ + r[7] = 0; + scsi_len = lr = len < 36 ? len : 36; + r[2] = 2; + r[3] = 2; + char *s = ua (_T("UAE")); + memcpy (r + 8, s, strlen (s)); + xfree (s); + s = ua (_T("SCSI TAPE")); + memcpy (r + 16, s, strlen (s)); + xfree (s); + s = ua (_T("0.1")); + memcpy (r + 32, s, strlen (s)); + xfree (s); + for (int i = 8; i < 36; i++) { + if (r[i] == 0) + r[i] = 32; + } + } + break; + default: + write_log (_T("TAPEEMU: unsupported scsi command 0x%02X\n"), cmdbuf[0]); +err: + status = SCSI_STATUS_CHECK_CONDITION; + s[0] = 0x70; + s[2] = SCSI_SK_ILLEGAL_REQ; + s[12] = SCSI_INVALID_COMMAND; + ls = 0x12; + break; +writeprot: + status = 2; /* CHECK CONDITION */ + s[0] = 0x70; + s[2] = 7; /* DATA PROTECT */ + s[12] = 0x27; /* WRITE PROTECTED */ + ls = 0x12; + break; +errreq: + lr = -1; + status = SCSI_STATUS_CHECK_CONDITION; + s[0] = 0x70; + s[2] = SCSI_SK_ILLEGAL_REQ; + s[12] = SCSI_INVALID_FIELD; + ls = 0x12; + break; +endoftape: + status = SCSI_STATUS_CHECK_CONDITION; + s[0] = 0x70; + s[2] = SCSI_SK_MED_ERR; + s[12] = 0; + s[13] = 2; /* End-of-partition/medium detected */ + ls = 0x12; + break; +notape: + status = SCSI_STATUS_CHECK_CONDITION; + s[0] = 0x70; + s[2] = SCSI_SK_NOT_READY; + s[12] = SCSI_MEDIUM_NOT_PRESENT; + ls = 0x12; + break; + } + *data_len = scsi_len; + *reply_len = lr; + *sense_len = ls; + if (ls > 0) { + if (tape->beom > 0) + s[2] |= 0x40; + if (tape->beom < 0) + s[9] |= 0x8; + } + return status; +} \ No newline at end of file diff --git a/zfile.cpp b/zfile.cpp index c4d2499a..45c1ed94 100644 --- a/zfile.cpp +++ b/zfile.cpp @@ -3282,6 +3282,16 @@ int zfile_readdir_archive (struct zdirectory *zd, TCHAR *out) { return zfile_readdir_archive (zd, out, false); } + +struct zfile *zfile_readdir_archive_open (struct zdirectory *zd, const TCHAR *mode) +{ + TCHAR path[MAX_DPATH]; + if (!zfile_readdir_archive (zd, path, true)) + return NULL; + return zfile_fopen (path, mode, ZFD_ARCHIVE | ZFD_NORECURSE); +} + + void zfile_resetdir_archive (struct zdirectory *zd) { zd->offset = 0;