From: Toni Wilen Date: Sun, 13 Jul 2008 10:26:24 +0000 (+0300) Subject: imported winuaesrc1510b5.zip X-Git-Tag: 2100~134 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=5de89a044415ef3068d0c61f9aea5ec5125248a1;p=francis%2Fwinuae.git imported winuaesrc1510b5.zip --- diff --git a/a2091.c b/a2091.c index ba9c0d08..cf7ce78b 100755 --- a/a2091.c +++ b/a2091.c @@ -548,7 +548,7 @@ void wdscsi_put (uae_u8 d) { #if WD33C93_DEBUG > 1 if (WD33C93_DEBUG > 3 || sasr != WD_DATA) - write_log ("W %s REG %02.2X (%d) = %02.2X (%d) PC=%08X\n", WD33C93, sasr, sasr, d, d, M68K_GETPC); + write_log ("W %s REG %02X (%d) = %02X (%d) PC=%08X\n", WD33C93, sasr, sasr, d, d, M68K_GETPC); #endif if (!writeonlyreg (sasr)) wdregs[sasr] = d; @@ -586,7 +586,7 @@ void wdscsi_put (uae_u8 d) wd_cmd_trans_info (); break; default: - write_log ("%s unimplemented/unknown command %02.X\n", WD33C93, d); + write_log ("%s unimplemented/unknown command %02X\n", WD33C93, d); break; } } @@ -629,7 +629,7 @@ uae_u8 wdscsi_get(void) incsasr (0); #if WD33C93_DEBUG > 1 if (WD33C93_DEBUG > 3 || osasr != WD_DATA) - write_log ("R %s REG %02.2X (%d) = %02.2X (%d) PC=%08X\n", WD33C93, osasr, osasr, v, v, M68K_GETPC); + write_log ("R %s REG %02X (%d) = %02X (%d) PC=%08X\n", WD33C93, osasr, osasr, v, v, M68K_GETPC); #endif return v; } @@ -701,7 +701,7 @@ static uae_u32 dmac_bget2 (uaecptr addr) break; } #if A2091_DEBUG > 0 - write_log ("dmac_bget %04.4X=%02.2X PC=%08.8X\n", addr, v, M68K_GETPC); + write_log ("dmac_bget %04X=%02X PC=%08X\n", addr, v, M68K_GETPC); #endif return v; } @@ -786,7 +786,7 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b) break; } #if A2091_DEBUG > 0 - write_log ("dmac_bput %04.4X=%02.2X PC=%08.8X\n", addr, b & 255, M68K_GETPC); + write_log ("dmac_bput %04X=%02X PC=%08X\n", addr, b & 255, M68K_GETPC); #endif } @@ -805,7 +805,7 @@ static uae_u32 REGPARAM2 dmac_lget (uaecptr addr) v |= dmac_bget2 (addr + 3); #ifdef A2091_DEBUG if (addr >= 0x40 && addr < ROM_OFFSET) - write_log ("dmac_lget %08.8X=%08.8X PC=%08.8X\n", addr, v, M68K_GETPC); + write_log ("dmac_lget %08X=%08X PC=%08X\n", addr, v, M68K_GETPC); #endif return v; } @@ -821,7 +821,7 @@ static uae_u32 REGPARAM2 dmac_wget (uaecptr addr) v |= dmac_bget2 (addr + 1); #if A2091_DEBUG > 0 if (addr >= 0x40 && addr < ROM_OFFSET) - write_log ("dmac_wget %08.8X=%04.4X PC=%08.8X\n", addr, v, M68K_GETPC); + write_log ("dmac_wget %08X=%04X PC=%08X\n", addr, v, M68K_GETPC); #endif return v; } @@ -847,7 +847,7 @@ static void REGPARAM2 dmac_lput (uaecptr addr, uae_u32 l) addr &= 65535; #if A2091_DEBUG > 0 if (addr >= 0x40 && addr < ROM_OFFSET) - write_log ("dmac_lput %08.8X=%08.8X PC=%08.8X\n", addr, l, M68K_GETPC); + write_log ("dmac_lput %08X=%08X PC=%08X\n", addr, l, M68K_GETPC); #endif dmac_bput2 (addr, l >> 24); dmac_bput2 (addr + 1, l >> 16); @@ -863,7 +863,7 @@ static void REGPARAM2 dmac_wput (uaecptr addr, uae_u32 w) addr &= 65535; #if A2091_DEBUG > 0 if (addr >= 0x40 && addr < ROM_OFFSET) - write_log ("dmac_wput %04.4X=%04.4X PC=%08.8X\n", addr, w & 65535, M68K_GETPC); + write_log ("dmac_wput %04X=%04X PC=%08X\n", addr, w & 65535, M68K_GETPC); #endif dmac_bput2 (addr, w >> 8); dmac_bput2 (addr + 1, w); @@ -878,7 +878,7 @@ static void REGPARAM2 dmac_bput (uaecptr addr, uae_u32 b) addr &= 65535; if (addr == 0x48 && !configured) { map_banks (&dmaca2091_bank, b, 0x10000 >> 16, 0x10000); - write_log ("A590/A2091 Z2 autoconfigured at %02.2X0000\n", b); + write_log ("A590/A2091 Z2 autoconfigured at %02X0000\n", b); configured = 1; expamem_next (); return; @@ -940,7 +940,7 @@ static void mbdmac_write (uae_u32 addr, uae_u32 val, int mode) if (currprefs.cs_mbdmac > 1) return; #if A3000_DEBUG > 1 - write_log ("DMAC_WRITE %08.8X=%02.2X PC=%08.8X\n", addr, val & 0xff, M68K_GETPC); + write_log ("DMAC_WRITE %08X=%02X PC=%08X\n", addr, val & 0xff, M68K_GETPC); #endif addr &= 0xffff; switch (addr) @@ -1068,7 +1068,7 @@ static uae_u32 mbdmac_read (uae_u32 addr, int mode) break; } #if A3000_DEBUG > 1 - write_log ("DMAC_READ %08.8X=%02.2X PC=%X\n", vaddr, v & 0xff, M68K_GETPC); + write_log ("DMAC_READ %08X=%02X PC=%X\n", vaddr, v & 0xff, M68K_GETPC); #endif return v; } diff --git a/akiko.c b/akiko.c index d561c59e..09a1ea59 100755 --- a/akiko.c +++ b/akiko.c @@ -126,9 +126,9 @@ static void i2c_do (void) nvram_write (nvram_address & ~(NVRAM_PAGE_SIZE - 1), NVRAM_PAGE_SIZE); direction = -1; #if AKIKO_DEBUG_NVRAM - write_log ("NVRAM write address %04.4X:", nvram_address & ~(NVRAM_PAGE_SIZE - 1)); + write_log ("NVRAM write address %04X:", nvram_address & ~(NVRAM_PAGE_SIZE - 1)); for (i = 0; i < NVRAM_PAGE_SIZE; i++) - write_log ("%02.2X", nvram_writetmp[i]); + write_log ("%02X", nvram_writetmp[i]); write_log ("\n"); #endif @@ -142,7 +142,7 @@ static void i2c_do (void) if (scl_out && !oscl) { if (bitcounter == 8) { #if AKIKO_DEBUG_NVRAM - write_log ("RB %02.2X ", nvram_byte, M68K_GETPC); + write_log ("RB %02X ", nvram_byte, M68K_GETPC); #endif sda_in = 0; /* ACK */ if (direction > 0) { @@ -171,7 +171,7 @@ static void i2c_do (void) bitcounter++; if (bitcounter == 8) { #if AKIKO_DEBUG_NVRAM - write_log ("NVRAM sent byte %02.2X address %04.4X PC=%08.8X\n", cd32_nvram[nvram_address], nvram_address, M68K_GETPC); + write_log ("NVRAM sent byte %02X address %04X PC=%08X\n", cd32_nvram[nvram_address], nvram_address, M68K_GETPC); #endif nvram_address++; nvram_address &= NVRAM_SIZE - 1; @@ -205,14 +205,14 @@ static void i2c_do (void) } bitcounter = 0; #if AKIKO_DEBUG_NVRAM - write_log ("I2C_DEVICEADDR: rw %d, address %02.2Xxx PC=%08.8X\n", nvram_rw, nvram_address >> 8, M68K_GETPC); + write_log ("I2C_DEVICEADDR: rw %d, address %02Xxx PC=%08X\n", nvram_rw, nvram_address >> 8, M68K_GETPC); #endif break; case I2C_WORDADDR: nvram_address &= 0x300; nvram_address |= nvram_byte; #if AKIKO_DEBUG_NVRAM - write_log ("I2C_WORDADDR: address %04.4X PC=%08.8X\n", nvram_address, M68K_GETPC); + write_log ("I2C_WORDADDR: address %04X PC=%08X\n", nvram_address, M68K_GETPC); #endif if (direction < 0) { memcpy (nvram_writetmp, cd32_nvram + (nvram_address & ~(NVRAM_PAGE_SIZE - 1)), NVRAM_PAGE_SIZE); @@ -684,12 +684,12 @@ static void cdrom_return_data (int len) checksum -= cdrom_result_buffer[i]; put_byte (cmd_buf + ((cdrom_result_complete + i) & 0xff), cdrom_result_buffer[i]); #if AKIKO_DEBUG_IO_CMD - write_log ("%02.2X ", cdrom_result_buffer[i]); + write_log ("%02X ", cdrom_result_buffer[i]); #endif } put_byte (cmd_buf + ((cdrom_result_complete + len) & 0xff), checksum); #if AKIKO_DEBUG_IO_CMD - write_log ("%02.2X\n", checksum); + write_log ("%02X\n", checksum); #endif cdrom_result_complete += len + 1; set_status(CDSTATUS_DATA_AVAILABLE); @@ -789,7 +789,7 @@ static int cdrom_command_multi (void) int cdrom_data_offset_end = msf2lsn (endpos); cdrom_data_offset = msf2lsn (seekpos); #if AKIKO_DEBUG_IO_CMD - write_log ("READ DATA %06.6X (%d) - %06.6X (%d) SPD=%dx PC=%08X\n", + write_log ("READ DATA %06X (%d) - %06X (%d) SPD=%dx PC=%08X\n", seekpos, cdrom_data_offset, endpos, cdrom_data_offset_end, cdrom_speed, M68K_GETPC); #endif cdrom_result_buffer[1] |= 0x02; @@ -800,7 +800,7 @@ static int cdrom_command_multi (void) else if (cdrom_command_buffer[7] & 0x08) scan = -1; #if AKIKO_DEBUG_IO_CMD - write_log ("PLAY FROM %06.6X (%d) to %06.6X (%d) SCAN=%d\n", + write_log ("PLAY FROM %06X (%d) to %06X (%d) SCAN=%d\n", seekpos, msf2lsn (seekpos), endpos, msf2lsn (endpos), scan); #endif if (!cd_play_audio (seekpos, endpos, 0)) { @@ -811,7 +811,7 @@ static int cdrom_command_multi (void) } } else { #if AKIKO_DEBUG_IO_CMD - write_log ("SEEKTO %06.6X\n",seekpos); + write_log ("SEEKTO %06X\n",seekpos); #endif if (seekpos < 150) cdrom_toc_counter = 0; @@ -861,7 +861,7 @@ static void cdrom_run_command (void) cdrom_command_buffer[i] = get_byte (cmd_buf + ((cdrom_command_offset_complete + i) & 0xff)); checksum += cdrom_command_buffer[i]; #if AKIKO_DEBUG_IO_CMD - write_log ("%02.2X ", cdrom_command_buffer[i]); + write_log ("%02X ", cdrom_command_buffer[i]); #endif } if (checksum!=0xff) { @@ -1263,14 +1263,14 @@ static uae_u32 akiko_bget2 (uaecptr addr, int msg) } default: - write_log ("akiko_bget: unknown address %08.8X\n", addr); + write_log ("akiko_bget: unknown address %08X\n", addr); v = 0; break; } akiko_internal (); uae_sem_post (&akiko_sem); if (msg && addr < 0x30 && AKIKO_DEBUG_IO) - write_log ("akiko_bget %08.8X: %08.8X %02.2X\n", M68K_GETPC, addr, v & 0xff); + write_log ("akiko_bget %08X: %08X %02X\n", M68K_GETPC, addr, v & 0xff); return v; } @@ -1292,7 +1292,7 @@ static uae_u32 REGPARAM2 akiko_wget (uaecptr addr) v = akiko_bget2 (addr + 1, 0); v |= akiko_bget2 (addr + 0, 0) << 8; if (addr < 0x30 && AKIKO_DEBUG_IO) - write_log ("akiko_wget %08.8X: %08.8X %04.4X\n", M68K_GETPC, addr, v & 0xffff); + write_log ("akiko_wget %08X: %08X %04X\n", M68K_GETPC, addr, v & 0xffff); return v; } @@ -1309,7 +1309,7 @@ static uae_u32 REGPARAM2 akiko_lget (uaecptr addr) v |= akiko_bget2 (addr + 1, 0) << 16; v |= akiko_bget2 (addr + 0, 0) << 24; if (addr < 0x30 && (addr != 4 && addr != 8) && AKIKO_DEBUG_IO) - write_log ("akiko_lget %08.8X: %08.8X %08.8X\n", M68K_GETPC, addr, v); + write_log ("akiko_lget %08: %08X %08X\n", M68K_GETPC, addr, v); return v; } @@ -1335,7 +1335,7 @@ static void akiko_bput2 (uaecptr addr, uae_u32 v, int msg) v &= 0xff; if(msg && addr < 0x30 && AKIKO_DEBUG_IO) - write_log ("akiko_bput %08.8X: %08.8X=%02.2X\n", M68K_GETPC, addr, v & 0xff); + write_log ("akiko_bput %08X: %08X=%02X\n", M68K_GETPC, addr, v & 0xff); switch (addr) { @@ -1426,7 +1426,7 @@ static void akiko_bput2 (uaecptr addr, uae_u32 v, int msg) } default: - write_log ("akiko_bput: unknown address %08.8X\n", addr); + write_log ("akiko_bput: unknown address %08X\n", addr); break; } akiko_internal (); @@ -1448,7 +1448,7 @@ static void REGPARAM2 akiko_wput (uaecptr addr, uae_u32 v) #endif addr &= 0xfff; if((addr < 0x30 && AKIKO_DEBUG_IO)) - write_log ("akiko_wput %08.8X: %08.8X=%04.4X\n", M68K_GETPC, addr, v & 0xffff); + write_log ("akiko_wput %08X: %08X=%04X\n", M68K_GETPC, addr, v & 0xffff); akiko_bput2 (addr + 1, v & 0xff, 0); akiko_bput2 (addr + 0, v >> 8, 0); } @@ -1460,7 +1460,7 @@ static void REGPARAM2 akiko_lput (uaecptr addr, uae_u32 v) #endif addr &= 0xffff; if(addr < 0x30 && AKIKO_DEBUG_IO) - write_log ("akiko_lput %08.8X: %08.8X=%08.8X\n", M68K_GETPC, addr, v); + write_log ("akiko_lput %08X: %08X=%08X\n", M68K_GETPC, addr, v); akiko_bput2 (addr + 3, (v >> 0) & 0xff, 0); akiko_bput2 (addr + 2, (v >> 8) & 0xff, 0); akiko_bput2 (addr + 1, (v >> 16) & 0xff, 0); diff --git a/akiko2.c b/akiko2.c index 1cb4b89a..f8e1b477 100755 --- a/akiko2.c +++ b/akiko2.c @@ -114,9 +114,9 @@ static void i2c_do (void) nvram_write (nvram_address & ~(NVRAM_PAGE_SIZE - 1), NVRAM_PAGE_SIZE); direction = -1; #if AKIKO_DEBUG_NVRAM - write_log ("NVRAM write address %04.4X:", nvram_address & ~(NVRAM_PAGE_SIZE - 1)); + write_log ("NVRAM write address %04X:", nvram_address & ~(NVRAM_PAGE_SIZE - 1)); for (i = 0; i < NVRAM_PAGE_SIZE; i++) - write_log ("%02.2X", nvram_writetmp[i]); + write_log ("%02X", nvram_writetmp[i]); write_log ("\n"); #endif @@ -130,7 +130,7 @@ static void i2c_do (void) if (scl_out && !oscl) { if (bitcounter == 8) { #if AKIKO_DEBUG_NVRAM - write_log ("RB %02.2X ", nvram_byte, m68k_getpc ()); + write_log ("RB %02X ", nvram_byte, m68k_getpc ()); #endif sda_in = 0; /* ACK */ if (direction > 0) { @@ -159,7 +159,7 @@ static void i2c_do (void) bitcounter++; if (bitcounter == 8) { #if AKIKO_DEBUG_NVRAM - write_log ("NVRAM sent byte %02.2X address %04.4X PC=%08.8X\n", cd32_nvram[nvram_address], nvram_address, m68k_getpc ()); + write_log ("NVRAM sent byte %02X address %04X PC=%08X\n", cd32_nvram[nvram_address], nvram_address, m68k_getpc ()); #endif nvram_address++; nvram_address &= NVRAM_SIZE - 1; @@ -193,14 +193,14 @@ static void i2c_do (void) } bitcounter = 0; #if AKIKO_DEBUG_NVRAM - write_log ("I2C_DEVICEADDR: rw %d, address %02.2Xxx PC=%08.8X\n", nvram_rw, nvram_address >> 8, m68k_getpc ()); + write_log ("I2C_DEVICEADDR: rw %d, address %02Xxx PC=%08X\n", nvram_rw, nvram_address >> 8, m68k_getpc ()); #endif break; case I2C_WORDADDR: nvram_address &= 0x300; nvram_address |= nvram_byte; #if AKIKO_DEBUG_NVRAM - write_log ("I2C_WORDADDR: address %04.4X PC=%08.8X\n", nvram_address, m68k_getpc ()); + write_log ("I2C_WORDADDR: address %04X PC=%08X\n", nvram_address, m68k_getpc ()); #endif if (direction < 0) { memcpy (nvram_writetmp, cd32_nvram + (nvram_address & ~(NVRAM_PAGE_SIZE - 1)), NVRAM_PAGE_SIZE); @@ -563,12 +563,12 @@ static void cdrom_return_data (int len) checksum -= cdrom_result_buffer[i]; put_byte (cmd_buf + ((cdrom_result_complete + i) & 0xff), cdrom_result_buffer[i]); #if AKIKO_DEBUG_IO_CMD - write_log ("%02.2X ", cdrom_result_buffer[i]); + write_log ("%02X ", cdrom_result_buffer[i]); #endif } put_byte (cmd_buf + ((cdrom_result_complete + len) & 0xff), checksum); #if AKIKO_DEBUG_IO_CMD - write_log ("%02.2X\n", checksum); + write_log ("%02X\n", checksum); #endif cdrom_result_complete += len + 1; cdrom_status1 |= CDSTATUS_DATA_AVAILABLE; @@ -668,7 +668,7 @@ static int cdrom_command_multi (void) int cdrom_data_offset_end = msf2lsn (endpos); cdrom_data_offset = msf2lsn (seekpos); #if AKIKO_DEBUG_IO_CMD - write_log ("READ DATA FROM %06.6X (%d) TO %06.6X (%d) SPEED=%dx\n", seekpos, cdrom_data_offset, endpos, cdrom_data_offset_end, cdrom_speed); + write_log ("READ DATA FROM %06X (%d) TO %06X (%d) SPEED=%dx\n", seekpos, cdrom_data_offset, endpos, cdrom_data_offset_end, cdrom_speed); #endif cdrom_result_buffer[1] |= 0x02; } else if (cdrom_command_buffer[10] & 4) { /* play audio */ @@ -678,7 +678,7 @@ static int cdrom_command_multi (void) else if (cdrom_command_buffer[7] & 0x08) scan = -1; #if AKIKO_DEBUG_IO_CMD - write_log ("PLAY FROM %06.6X to %06.6X SCAN=%d\n", seekpos, endpos, scan); + write_log ("PLAY FROM %06X to %06X SCAN=%d\n", seekpos, endpos, scan); #endif if (!cd_play_audio (seekpos, endpos, 0)) { cdrom_result_buffer[1] = CDS_ERROR; @@ -688,7 +688,7 @@ static int cdrom_command_multi (void) } } else { #if AKIKO_DEBUG_IO_CMD - write_log ("SEEKTO %06.6X\n",seekpos); + write_log ("SEEKTO %06X\n",seekpos); #endif if (seekpos < 150) cdrom_toc_counter = 0; @@ -738,7 +738,7 @@ static void cdrom_run_command (void) cdrom_command_buffer[i] = get_byte (cmd_buf + ((cdrom_command_offset_complete + i) & 0xff)); checksum += cdrom_command_buffer[i]; #if AKIKO_DEBUG_IO_CMD - write_log ("%02.2X ", cdrom_command_buffer[i]); + write_log ("%02X ", cdrom_command_buffer[i]); #endif } if (checksum!=0xff) { @@ -1048,14 +1048,14 @@ uae_u32 akiko_bget2 (uaecptr addr, int msg) break; default: - write_log ("akiko_bget: unknown address %08.8X\n", addr); + write_log ("akiko_bget: unknown address %08X\n", addr); v = 0; break; } akiko_internal (); uae_sem_post (&akiko_sem); if (msg && addr < 0x30 && AKIKO_DEBUG_IO) - write_log ("akiko_bget %08.8X: %08.8X %02.2X\n", m68k_getpc (), addr, v & 0xff); + write_log ("akiko_bget %08X: %08X %02X\n", m68k_getpc (), addr, v & 0xff); return v; } @@ -1071,7 +1071,7 @@ uae_u32 akiko_wget (uaecptr addr) v = akiko_bget2 (addr + 1, 0); v |= akiko_bget2 (addr + 0, 0) << 8; if (addr < 0x30 && AKIKO_DEBUG_IO) - write_log ("akiko_wget %08.8X: %08.8X %04.4X\n", m68k_getpc (), addr, v & 0xffff); + write_log ("akiko_wget %08X: %08X %04X\n", m68k_getpc (), addr, v & 0xffff); return v; } @@ -1085,7 +1085,7 @@ uae_u32 akiko_lget (uaecptr addr) v |= akiko_bget2 (addr + 1, 0) << 16; v |= akiko_bget2 (addr + 0, 0) << 24; if (addr < 0x30 && (addr != 4 && addr != 8) && AKIKO_DEBUG_IO) - write_log ("akiko_lget %08.8X: %08.8X %08.8X\n", m68k_getpc (), addr, v); + write_log ("akiko_lget %08X: %08X %08X\n", m68k_getpc (), addr, v); return v; } @@ -1096,7 +1096,7 @@ void akiko_bput2 (uaecptr addr, uae_u32 v, int msg) addr &= 0xffff; v &= 0xff; if(msg && addr < 0x30 && AKIKO_DEBUG_IO) - write_log ("akiko_bput %08.8X: %08.8X=%02.2X\n", m68k_getpc (), addr, v & 0xff); + write_log ("akiko_bput %08X: %08X=%02X\n", m68k_getpc (), addr, v & 0xff); uae_sem_wait (&akiko_sem); switch (addr) { @@ -1174,7 +1174,7 @@ void akiko_bput2 (uaecptr addr, uae_u32 v, int msg) break; default: - write_log ("akiko_bput: unknown address %08.8X\n", addr); + write_log ("akiko_bput: unknown address %08X\n", addr); break; } akiko_internal (); @@ -1190,7 +1190,7 @@ void akiko_wput (uaecptr addr, uae_u32 v) { addr &= 0xfff; if((addr < 0x30 && AKIKO_DEBUG_IO)) - write_log ("akiko_wput %08.8X: %08.8X=%04.4X\n", m68k_getpc (), addr, v & 0xffff); + write_log ("akiko_wput %08X: %08X=%04X\n", m68k_getpc (), addr, v & 0xffff); akiko_bput2 (addr + 1, v & 0xff, 0); akiko_bput2 (addr + 0, v >> 8, 0); } @@ -1199,7 +1199,7 @@ void akiko_lput (uaecptr addr, uae_u32 v) { addr &= 0xffff; if(addr < 0x30 && AKIKO_DEBUG_IO) - write_log ("akiko_lput %08.8X: %08.8X=%08.8X\n", m68k_getpc (), addr, v); + write_log ("akiko_lput %08X: %08X=%08X\n", m68k_getpc (), addr, v); akiko_bput2 (addr + 3, (v >> 0) & 0xff, 0); akiko_bput2 (addr + 2, (v >> 8) & 0xff, 0); akiko_bput2 (addr + 1, (v >> 16) & 0xff, 0); diff --git a/ar.c b/ar.c index 4adafc7a..b471289d 100755 --- a/ar.c +++ b/ar.c @@ -686,19 +686,19 @@ static uae_u32 REGPARAM2 arram_lget (uaecptr addr) addr &= arram_mask; m = (uae_u32 *)(armemory_ram + addr); if (strncmp ("T8", (char*)m, 2) == 0) - write_log_debug ("Reading T8 from addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Reading T8 from addr %088x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("LAME", (char*)m, 4) == 0) - write_log_debug ("Reading LAME from addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Reading LAME from addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("RES1", (char*)m, 4) == 0) - write_log_debug ("Reading RES1 from addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Reading RES1 from addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("ARON", (char*)m, 4) == 0) - write_log_debug ("Reading ARON from addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Reading ARON from addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("KILL", (char*)m, 4) == 0) - write_log_debug ("Reading KILL from addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Reading KILL from addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("BRON", (char*)m, 4) == 0) - write_log_debug ("Reading BRON from addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Reading BRON from addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("PRIN", (char*)m, 4) == 0) - write_log_debug ("Reading PRIN from addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Reading PRIN from addr %08x PC=%p\n", addr, m68k_getpc (®s)); return do_get_mem_long (m); } @@ -735,19 +735,19 @@ void REGPARAM2 arram_lput (uaecptr addr, uae_u32 l) addr &= arram_mask; m = (uae_u32 *)(armemory_ram + addr); if (strncmp ("T8", (char*)m, 2) == 0) - write_log_debug ("Writing T8 to addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Writing T8 to addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("LAME", (char*)m, 4) == 0) - write_log_debug ("Writing LAME to addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Writing LAME to addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("RES1", (char*)m, 4) == 0) - write_log_debug ("Writing RES1 to addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Writing RES1 to addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("ARON", (char*)m, 4) == 0) - write_log_debug ("Writing ARON to addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Writing ARON to addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("KILL", (char*)m, 4) == 0) - write_log_debug ("Writing KILL to addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Writing KILL to addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("BRON", (char*)m, 4) == 0) - write_log_debug ("Writing BRON to addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Writing BRON to addr %08x PC=%p\n", addr, m68k_getpc (®s)); if (strncmp ("PRIN", (char*)m, 4) == 0) - write_log_debug ("Writing PRIN to addr %08.08x PC=%p\n", addr, m68k_getpc (®s)); + write_log_debug ("Writing PRIN to addr %08x PC=%p\n", addr, m68k_getpc (®s)); do_put_mem_long (m, l); } @@ -1612,7 +1612,7 @@ static int superiv_init (struct romdata *rd, struct zfile *f) } hrtmon_flag = ACTION_REPLAY_IDLE; - write_log ("%s installed at %08.8X\n", cart_memnames[cart_type], hrtmem_start); + write_log ("%s installed at %08X\n", cart_memnames[cart_type], hrtmem_start); return 1; } @@ -1688,7 +1688,7 @@ int action_replay_load (void) arram_mask = arram_size - 1; arrom_mask = arrom_size - 1; armemory_ram = (uae_u8*)xcalloc (arram_size, 1); - write_log ("Action Replay %d installed at %08.8X, size %08.8X\n", armodel, arrom_start, arrom_size); + write_log ("Action Replay %d installed at %08X, size %08X\n", armodel, arrom_start, arrom_size); action_replay_version(); return armodel; } @@ -1845,7 +1845,7 @@ int hrtmon_load (void) #endif hrtmem_bank.baseaddr = hrtmemory; hrtmon_flag = ACTION_REPLAY_IDLE; - write_log ("%s installed at %08.8X\n", cart_memnames[cart_type], hrtmem_start); + write_log ("%s installed at %08X\n", cart_memnames[cart_type], hrtmem_start); return 1; } diff --git a/audio.c b/audio.c index 24780cc4..7b0a3a3e 100755 --- a/audio.c +++ b/audio.c @@ -35,6 +35,7 @@ #ifdef AHI #include "traps.h" #include "ahidsound.h" +#include "ahidsound_new.h" #endif #include "threaddep/thread.h" @@ -260,7 +261,7 @@ static void do_samplerip (struct audio_channel_data *adp) memcpy(rs->sample, smp, len); rs->next = NULL; rs->changed = 1; - write_log ("SAMPLERIPPER: sample added (%06.6X, %d bytes), total %d samples\n", adp->pt, len, ++cnt); + write_log ("SAMPLERIPPER: sample added (%06X, %d bytes), total %d samples\n", adp->pt, len, ++cnt); audio_sampleripper (0); } @@ -1271,6 +1272,7 @@ void audio_reset (void) #ifdef AHI ahi_close_sound (); + free_ahi_v2 (); #endif reset_sound (); memset(sound_filter_state, 0, sizeof sound_filter_state); diff --git a/blitter.c b/blitter.c index 3318fe3b..44e34980 100755 --- a/blitter.c +++ b/blitter.c @@ -222,10 +222,10 @@ void build_blitfilltable (void) static void blitter_dump (void) { - write_log ("APT=%08.8X BPT=%08.8X CPT=%08.8X DPT=%08.8X\n", bltapt, bltbpt, bltcpt, bltdpt); - write_log ("CON0=%04.4X CON1=%04.4X ADAT=%04.4X BDAT=%04.4X CDAT=%04.4X\n", + write_log ("APT=%08X BPT=%08X CPT=%08X DPT=%08X\n", bltapt, bltbpt, bltcpt, bltdpt); + write_log ("CON0=%04X CON1=%04X ADAT=%04X BDAT=%04X CDAT=%04X\n", bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); - write_log ("AFWM=%04.4X ALWM=%04.4X AMOD=%04.4X BMOD=%04.4X CMOD=%04.4X DMOD=%04.4X\n", + write_log ("AFWM=%04X ALWM=%04X AMOD=%04X BMOD=%04X CMOD=%04X DMOD=%04X\n", blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); } @@ -1062,7 +1062,7 @@ void do_blitter (int hpos) if (1) { if (oldstate != BLT_done) write_log ("blitter was already active!\n"); - write_log ("blitstart: v=%03.3d h=%03.3d %dx%d %d (%d) d=%d f=%02.2X n=%d pc=%p l=%d dma=%04.4X\n", + write_log ("blitstart: v=%03.3d h=%03.3d %dx%d %d (%d) d=%d f=%02X n=%d pc=%p l=%d dma=%04X\n", vpos, hpos, blt_info.hblitsize, blt_info.vblitsize, cycles, blit_ch, blitdesc ? 1 : 0, blitfill, dmaen (DMA_BLITPRI) ? 1 : 0, M68K_GETPC, blitline, dmacon); diff --git a/blitter2.c b/blitter2.c deleted file mode 100755 index fd2d3202..00000000 --- a/blitter2.c +++ /dev/null @@ -1,1067 +0,0 @@ - /* - * UAE - The Un*x Amiga Emulator - * - * Custom chip emulation - * - * (c) 1995 Bernd Schmidt, Alessandro Bissacco - * (c) 2002 - 2003 Toni Wilen - */ - -//#define BLITTER_DEBUG -//#define BLITTER_SLOWDOWNDEBUG 4 - -#define SPEEDUP - -#include "sysconfig.h" -#include "sysdeps.h" - -#include "config.h" -#include "options.h" -#include "uae.h" -#include "memory.h" -#include "custom.h" -#include "events.h" -#include "newcpu.h" -#include "blitter.h" -#include "blit.h" -#include "savestate.h" - -uae_u16 oldvblts; -uae_u16 bltcon0,bltcon1; -uae_u32 bltapt,bltbpt,bltcpt,bltdpt; - -int blinea_shift; -static uae_u16 blinea, blineb; -static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc; -static int blitonedot,blitsign; -static int blit_add; -static int blit_modadda, blit_modaddb, blit_modaddc, blit_modaddd; -static int blit_ch; -int blit_singlechannel; - -#ifdef BLITTER_DEBUG -static int blitter_dontdo; -#endif -#ifdef BLITTER_SLOWDOWNDEBUG -static int blitter_slowdowndebug; -#endif - -struct bltinfo blt_info; - -static uae_u8 blit_filltable[256][4][2]; -uae_u32 blit_masktable[BLITTER_MAX_WORDS]; -static uae_u16 blit_trashtable[BLITTER_MAX_WORDS]; -enum blitter_states bltstate; - -static int blit_cyclecounter, blit_maxcyclecounter, blit_slowdown; -static int blit_linecyclecounter, blit_misscyclecounter; - -#ifdef CPUEMU_6 -extern uae_u8 cycle_line[]; -#endif - -static long blit_firstline_cycles; -static long blit_first_cycle; -static int blit_last_cycle, blit_dmacount, blit_dmacount2; -static int blit_linecycles, blit_extracycles; -static uae_u8 *blit_diag; - -static uae_u16 ddat1, ddat2; -static int ddat1use, ddat2use; - -static uae_u8 blit_cycle_diagram_finald[] = - { 0, 2, 0,4 }; - -static uae_u8 blit_cycle_diagram[][10] = -{ - { 0, 2, 0,0 }, /* 0 */ - { 0, 2, 4,0 }, /* 1 */ - { 0, 2, 3,0 }, /* 2 */ - { 2, 3, 0,3,4, 3,0 }, /* 3 */ - { 0, 3, 2,0,0 }, /* 4 */ - { 2, 3, 0,2,4, 2,0 }, /* 5 */ - { 0, 3, 2,3,0 }, /* 6 */ - { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ - { 0, 2, 1,0 }, /* 8 */ - { 2, 2, 1,4, 1,0 }, /* 9 */ - { 0, 2, 1,3 }, /* A */ - { 3, 3, 1,3,4, 1,3,0 }, /* B */ - { 2, 3, 0,1,2, 1,2 }, /* C */ - { 3, 3, 1,2,4, 1,2,0 }, /* D */ - { 0, 3, 1,2,3 }, /* E */ - { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ -}; - -/* fill mode always adds C-channel to cycle-diagram */ -/* Reflect - Sound Vision freezes without this */ -static uae_u8 blit_cycle_diagram_fill[][10] = -{ - { 0, 2, 0,0 }, /* 0 */ - { 0, 3, 0,3,4 }, /* 1 */ - { 0, 2, 3,0 }, /* 2 */ - { 2, 3, 0,3,4, 3,0 }, /* 3 */ - { 0, 3, 2,0,0 }, /* 4 */ - { 3, 4, 0,2,0,4, 2,0,0 }, /* 5 */ - { 0, 3, 2,3,0 }, /* 6 */ - { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ - { 0, 2, 1,0 }, /* 8 */ - { 3, 3, 1,0,4, 1,0,0}, /* 9 */ - { 0, 2, 1,3 }, /* A */ - { 3, 3, 1,3,4, 1,3,0 }, /* B */ - { 2, 3, 0,1,2, 1,2 }, /* C */ - { 4, 4, 1,2,0,4, 1,2,0,0 }, /* D */ - { 0, 3, 1,2,3 }, /* E */ - { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ -}; - -static uae_u8 blit_cycle_diagram_line[] = -{ - 0, 4, 0,0,0,4 /* total guess.. */ -}; - -void build_blitfilltable(void) -{ - unsigned int d, fillmask; - int i; - - for (i = 0; i < BLITTER_MAX_WORDS; i++) - blit_masktable[i] = 0xFFFF; - - for (d = 0; d < 256; d++) { - for (i = 0; i < 4; i++) { - int fc = i & 1; - uae_u8 data = d; - for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) { - uae_u16 tmp = data; - if (fc) { - if (i & 2) - data |= fillmask; - else - data ^= fillmask; - } - if (tmp & fillmask) fc = !fc; - } - blit_filltable[d][i][0] = data; - blit_filltable[d][i][1] = fc; - } - } -} - -static void blitter_dump (void) -{ - write_log ("APT=%08.8X BPT=%08.8X CPT=%08.8X DPT=%08.8X\n", bltapt, bltbpt, bltcpt, bltdpt); - write_log ("CON0=%04.4X CON1=%04.4X ADAT=%04.4X BDAT=%04.4X CDAT=%04.4X\n", - bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); - write_log ("AFWM=%04.4X ALWM=%04.4X AMOD=%04.4X BMOD=%04.4X CMOD=%04.4X DMOD=%04.4X\n", - blt_info.bltafwm, blt_info.bltalwm, - blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); -} - -STATIC_INLINE uae_u8 *blit_xlateptr(uaecptr bltpt, int bytecount) -{ - if (!chipmem_bank.check(bltpt,bytecount)) return NULL; - return chipmem_bank.xlateaddr(bltpt); -} - -STATIC_INLINE uae_u8 *blit_xlateptr_desc(uaecptr bltpt, int bytecount) -{ - if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL; - return chipmem_bank.xlateaddr(bltpt); -} - -static void blitter_done (void) -{ - ddat1use = ddat2use = 0; - bltstate = BLT_done; - blitter_done_notify (); - INTREQ(0x8040); - eventtab[ev_blitter].active = 0; - unset_special (SPCFLAG_BLTNASTY); -#ifdef BLITTER_DEBUG - write_log ("vpos=%d, cycles %d, missed %d, total %d\n", - vpos, blit_cyclecounter, blit_misscyclecounter, blit_cyclecounter + blit_misscyclecounter); -#endif -} - -static void blitter_dofast(void) -{ - int i,j; - uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; - uae_u8 mt = bltcon0 & 0xFF; - - blit_masktable[0] = blt_info.bltafwm; - blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; - - if (bltcon0 & 0x800) { - bltadatptr = bltapt; - bltapt += (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; - } - if (bltcon0 & 0x400) { - bltbdatptr = bltbpt; - bltbpt += (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; - } - if (bltcon0 & 0x200) { - bltcdatptr = bltcpt; - bltcpt += (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; - } - if (bltcon0 & 0x100) { - bltddatptr = bltdpt; - bltdpt += (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; - } - -#ifdef SPEEDUP - if (blitfunc_dofast[mt] && !blitfill) { - (*blitfunc_dofast[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); - } else -#endif - { - uae_u32 blitbhold = blt_info.bltbhold; - uae_u32 preva = 0, prevb = 0; - uaecptr dstp = 0; - int dodst = 0; - - /*if (!blitfill) write_log ("minterm %x not present\n",mt); */ - for (j = 0; j < blt_info.vblitsize; j++) { - blitfc = !!(bltcon1 & 0x4); - for (i = 0; i < blt_info.hblitsize; i++) { - uae_u32 bltadat, blitahold; - uae_u16 bltbdat; - if (bltadatptr) { - blt_info.bltadat = bltadat = chipmem_agnus_wget (bltadatptr); - bltadatptr += 2; - } else - bltadat = blt_info.bltadat; - bltadat &= blit_masktable[i]; - blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; - preva = bltadat; - - if (bltbdatptr) { - blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); - bltbdatptr += 2; - blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift; - prevb = bltbdat; - } - - if (bltcdatptr) { - blt_info.bltcdat = chipmem_agnus_wget (bltcdatptr); - bltcdatptr += 2; - } - if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); - blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; - if (blitfill) { - uae_u16 d = blt_info.bltddat; - int ifemode = blitife ? 2 : 0; - int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; - blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] - + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); - blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; - } - if (blt_info.bltddat) - blt_info.blitzero = 0; - if (bltddatptr) { - dodst = 1; - dstp = bltddatptr; - bltddatptr += 2; - } - } - if (bltadatptr) bltadatptr += blt_info.bltamod; - if (bltbdatptr) bltbdatptr += blt_info.bltbmod; - if (bltcdatptr) bltcdatptr += blt_info.bltcmod; - if (bltddatptr) bltddatptr += blt_info.bltdmod; - } - if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); - blt_info.bltbhold = blitbhold; - } - blit_masktable[0] = 0xFFFF; - blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; - - bltstate = BLT_done; -} - -static void blitter_dofast_desc(void) -{ - int i,j; - uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; - uae_u8 mt = bltcon0 & 0xFF; - - blit_masktable[0] = blt_info.bltafwm; - blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; - - if (bltcon0 & 0x800) { - bltadatptr = bltapt; - bltapt -= (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; - } - if (bltcon0 & 0x400) { - bltbdatptr = bltbpt; - bltbpt -= (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; - } - if (bltcon0 & 0x200) { - bltcdatptr = bltcpt; - bltcpt -= (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; - } - if (bltcon0 & 0x100) { - bltddatptr = bltdpt; - bltdpt -= (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; - } -#ifdef SPEEDUP - if (blitfunc_dofast_desc[mt] && !blitfill) { - (*blitfunc_dofast_desc[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); - } else -#endif - { - uae_u32 blitbhold = blt_info.bltbhold; - uae_u32 preva = 0, prevb = 0; - uaecptr dstp = 0; - int dodst = 0; - - for (j = 0; j < blt_info.vblitsize; j++) { - blitfc = !!(bltcon1 & 0x4); - for (i = 0; i < blt_info.hblitsize; i++) { - uae_u32 bltadat, blitahold; - uae_u16 bltbdat; - if (bltadatptr) { - bltadat = blt_info.bltadat = chipmem_agnus_wget (bltadatptr); - bltadatptr -= 2; - } else - bltadat = blt_info.bltadat; - bltadat &= blit_masktable[i]; - blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; - preva = bltadat; - - if (bltbdatptr) { - blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); - bltbdatptr -= 2; - blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift; - prevb = bltbdat; - } - - if (bltcdatptr) { - blt_info.bltcdat = blt_info.bltbdat = chipmem_agnus_wget (bltcdatptr); - bltcdatptr -= 2; - } - if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); - blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; - if (blitfill) { - uae_u16 d = blt_info.bltddat; - int ifemode = blitife ? 2 : 0; - int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; - blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] - + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); - blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; - } - if (blt_info.bltddat) - blt_info.blitzero = 0; - if (bltddatptr) { - dstp = bltddatptr; - dodst = 1; - bltddatptr -= 2; - } - } - if (bltadatptr) bltadatptr -= blt_info.bltamod; - if (bltbdatptr) bltbdatptr -= blt_info.bltbmod; - if (bltcdatptr) bltcdatptr -= blt_info.bltcmod; - if (bltddatptr) bltddatptr -= blt_info.bltdmod; - } - if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); - blt_info.bltbhold = blitbhold; - } - blit_masktable[0] = 0xFFFF; - blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; - - bltstate = BLT_done; -} - -STATIC_INLINE int blitter_read(void) -{ - if (bltcon0 & 0x200) { - if (!dmaen(DMA_BLITTER)) - return 1; - blt_info.bltcdat = chipmem_bank.wget(bltcpt); - } - bltstate = BLT_work; - return (bltcon0 & 0x200) != 0; -} - -STATIC_INLINE int blitter_write(void) -{ - if (blt_info.bltddat) - blt_info.blitzero = 0; - /* D-channel state has no effect on linedraw, but C must be enabled or nothing is drawn! */ - if (bltcon0 & 0x200) { - if (!dmaen(DMA_BLITTER)) return 1; - chipmem_bank.wput(bltdpt, blt_info.bltddat); - bltdpt = bltcpt; /* believe it or not but try Cardamon or Cardamom without this.. */ - } - bltstate = BLT_next; - return (bltcon0 & 0x200) != 0; -} - -STATIC_INLINE void blitter_line_incx(void) -{ - if (++blinea_shift == 16) { - blinea_shift = 0; - bltcpt += 2; - } -} - -STATIC_INLINE void blitter_line_decx(void) -{ - if (blinea_shift-- == 0) { - blinea_shift = 15; - bltcpt -= 2; - } -} - -STATIC_INLINE void blitter_line_decy(void) -{ - bltcpt -= blt_info.bltcmod; - blitonedot = 0; -} - -STATIC_INLINE void blitter_line_incy(void) -{ - bltcpt += blt_info.bltcmod; - blitonedot = 0; -} - -static void blitter_line(void) -{ - uae_u16 blitahold = blinea >> blinea_shift; - uae_u16 blitbhold = blineb & 1 ? 0xFFFF : 0; - uae_u16 blitchold = blt_info.bltcdat; - blt_info.bltddat = 0; - - if (blitsing && blitonedot) - blitahold = 0; - blitonedot = 1; - blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF); - if (!blitsign){ - if (bltcon0 & 0x800) - bltapt += (uae_s16)blt_info.bltamod; - if (bltcon1 & 0x10){ - if (bltcon1 & 0x8) - blitter_line_decy(); - else - blitter_line_incy(); - } else { - if (bltcon1 & 0x8) - blitter_line_decx(); - else - blitter_line_incx(); - } - } else { - if (bltcon0 & 0x800) - bltapt += (uae_s16)blt_info.bltbmod; - } - if (bltcon1 & 0x10){ - if (bltcon1 & 0x4) - blitter_line_decx(); - else - blitter_line_incx(); - } else { - if (bltcon1 & 0x4) - blitter_line_decy(); - else - blitter_line_incy(); - } - blitsign = 0 > (uae_s16)bltapt; - bltstate = BLT_write; -} - -STATIC_INLINE void blitter_nxline(void) -{ - blineb = (blineb << 1) | (blineb >> 15); - if (--blt_info.vblitsize == 0) { - bltstate = BLT_done; - } else { - bltstate = BLT_read; - } -} - -static void actually_do_blit(void) -{ - if (blitline) { - do { - blitter_read(); - blitter_line(); - blitter_write(); - blitter_nxline(); - } while (bltstate != BLT_done); - } else { - if (blitdesc) - blitter_dofast_desc(); - else - blitter_dofast(); - bltstate = BLT_done; - } -} - -void blitter_handler(void) -{ - if (!dmaen(DMA_BLITTER)) { - eventtab[ev_blitter].active = 1; - eventtab[ev_blitter].oldcycles = get_cycles (); - eventtab[ev_blitter].evtime = 10 * CYCLE_UNIT + get_cycles (); /* wait a little */ - return; /* gotta come back later. */ - } - if (blit_slowdown > 0) { - eventtab[ev_blitter].active = 1; - eventtab[ev_blitter].oldcycles = get_cycles (); - eventtab[ev_blitter].evtime = blit_slowdown * CYCLE_UNIT + get_cycles (); - blit_slowdown = -1; - return; - } -#ifdef BLITTER_DEBUG - if (!blitter_dontdo) - actually_do_blit(); - else - bltstate = BLT_done; -#else - actually_do_blit (); -#endif - blitter_done (); -} - -STATIC_INLINE int channel_state (int cycles) -{ - if (cycles < 0) - return 0; - if (cycles < blit_diag[0]) - return blit_diag[blit_diag[1] + 2 + cycles]; - return blit_diag[((cycles - blit_diag[0]) % blit_diag[1]) + 2]; -} - -int is_bitplane_dma (int hpos); -STATIC_INLINE int canblit (int hpos) -{ - if ((cycle_line[hpos] == 0 || cycle_line[hpos] == CYCLE_NOCPU) && !is_bitplane_dma (hpos)) - return 1; - return 0; -} - -#ifdef CPUEMU_6 - -static int blit_last_hpos; - -static int blitter_dma_cycles_line, blitter_dma_cycles_line_count; -static int blitter_cyclecounter; -static int blitter_hcounter1, blitter_hcounter2; -static int blitter_vcounter1, blitter_vcounter2; - - -static uae_u32 preva, prevb; -STATIC_INLINE uae_u16 blitter_doblit (void) -{ - uae_u32 blitahold; - uae_u16 bltadat, ddat; - uae_u8 mt = bltcon0 & 0xFF; - - bltadat = blt_info.bltadat; - if (blitter_hcounter1 == 0) - bltadat &= blt_info.bltafwm; - if (blitter_hcounter1 == blt_info.hblitsize - 1) - bltadat &= blt_info.bltalwm; - if (blitdesc) - blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; - else - blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; - preva = bltadat; - - ddat = blit_func (blitahold, blt_info.bltbhold, blt_info.bltcdat, mt) & 0xFFFF; - - if (bltcon1 & 0x18) { - uae_u16 d = ddat; - int ifemode = blitife ? 2 : 0; - int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; - ddat = (blit_filltable[d & 255][ifemode + blitfc][0] - + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); - blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; - } - - if (ddat) - blt_info.blitzero = 0; - - return ddat; -} - - -STATIC_INLINE int blitter_doddma (void) -{ - int wd; - uae_u16 d; - - wd = 0; - if (blit_dmacount2 == 0) { - d = blitter_doblit (); - wd = -1; - } else if (ddat2use) { - d = ddat2; - ddat2use = 0; - wd = 2; - } else if (ddat1use) { - d = ddat1; - ddat1use = 0; - wd = 1; - } - if (wd) { - chipmem_agnus_wput (bltdpt, d); - bltdpt += blit_add; - blitter_hcounter2++; - if (blitter_hcounter2 == blt_info.hblitsize) { - blitter_hcounter2 = 0; - bltdpt += blit_modaddd; - blitter_vcounter2++; - if (blitter_vcounter2 > blitter_vcounter1) - blitter_vcounter1 = blitter_vcounter2; - } - if (blit_ch == 1) - blitter_hcounter1 = blitter_hcounter2; - } - return wd; -} - -STATIC_INLINE void blitter_dodma (int ch) -{ - - switch (ch) - { - case 1: - blt_info.bltadat = chipmem_agnus_wget (bltapt); - bltapt += blit_add; - break; - case 2: - blt_info.bltbdat = chipmem_agnus_wget (bltbpt); - bltbpt += blit_add; - if (blitdesc) - blt_info.bltbhold = (((uae_u32)blt_info.bltbdat << 16) | prevb) >> blt_info.blitdownbshift; - else - blt_info.bltbhold = (((uae_u32)prevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift; - prevb = blt_info.bltbdat; - break; - case 3: - blt_info.bltcdat = chipmem_agnus_wget (bltcpt); - bltcpt += blit_add; - break; - } - - blitter_cyclecounter++; - if (blitter_cyclecounter >= blit_dmacount2) { - blitter_cyclecounter = 0; - ddat2 = ddat1; - ddat2use = ddat1use; - ddat1use = 0; - ddat1 = blitter_doblit (); - if (bltcon0 & 0x100) - ddat1use = 1; - blitter_hcounter1++; - if (blitter_hcounter1 == blt_info.hblitsize) { - blitter_hcounter1 = 0; - if (bltcon0 & 0x800) - bltapt += blit_modadda; - if (bltcon0 & 0x400) - bltbpt += blit_modaddb; - if (bltcon0 & 0x200) - bltcpt += blit_modaddc; - blitter_vcounter1++; - blitfc = !!(bltcon1 & 0x4); - } - } -} - -static void decide_blitter_line (int hpos) -{ - hpos++; - if (dmaen (DMA_BLITTER)) { - while (blit_last_hpos < hpos) { - int c = channel_state (blit_cyclecounter); - for (;;) { - if (c && !canblit (blit_last_hpos)) - break; - if (c) - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blit_cyclecounter++; - blit_linecyclecounter++; - if (blit_linecyclecounter >= blit_diag[1]) { - blit_linecyclecounter = 0; - blitter_read(); - blitter_line(); - blitter_write(); - blitter_nxline(); - if (bltstate == BLT_done) { - blitter_done (); - return; - } - } - break; - } - blit_last_hpos++; - } - } else { - blit_last_hpos = hpos; - } - if (blit_last_hpos > maxhpos) - blit_last_hpos = 0; -} - -void decide_blitter (int hpos) -{ - if (bltstate == BLT_done) - return; - if (!currprefs.blitter_cycle_exact) - return; - if (blitline) { - decide_blitter_line (hpos); - return; - } - hpos++; - if (dmaen (DMA_BLITTER)) { - while (blit_last_hpos < hpos) { - int c = channel_state (blit_cyclecounter); -#ifdef BLITTER_SLOWDOWNDEBUG - blitter_slowdowndebug--; - if (blitter_slowdowndebug < 0) { - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blitter_slowdowndebug = BLITTER_SLOWDOWNDEBUG; - } -#endif - for (;;) { - if (c && !canblit (blit_last_hpos)) { - blit_misscyclecounter++; - break; - } - if (c == 4) { - if (blitter_doddma ()) { - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blit_cyclecounter++; - } - } else if (c) { - if (blitter_vcounter1 < blt_info.vblitsize) { - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blitter_dodma (c); - } - blit_cyclecounter++; - } else { - blit_cyclecounter++; - /* check if blit with zero channels has ended */ - if (blit_cyclecounter >= blit_maxcyclecounter) { - blitter_done (); - return; - } - } - if (blitter_vcounter1 >= blt_info.vblitsize && blitter_vcounter2 >= blt_info.vblitsize) { - if (!ddat1use && !ddat2use) { - blitter_done (); - return; - } - if (blit_diag != blit_cycle_diagram_finald) { - blit_cyclecounter = 0; - blit_diag = blit_cycle_diagram_finald; - } - } - break; - } - blit_last_hpos++; - } - } else { - blit_last_hpos = hpos; - } - if (blit_last_hpos > maxhpos) - blit_last_hpos = 0; -} -#else -void decide_blitter (int hpos) { } -#endif - -static void blitter_force_finish (void) -{ - uae_u16 odmacon; - if (bltstate == BLT_done) - return; - if (bltstate != BLT_done) { - /* blitter is currently running - * force finish (no blitter state support yet) - */ - odmacon = dmacon; - dmacon |= DMA_MASTER | DMA_BLITTER; - write_log ("forcing blitter finish\n"); - if (currprefs.blitter_cycle_exact) { - int rounds = 10000; - while (bltstate != BLT_done && rounds > 0) { - memset (cycle_line, 0, maxhpos); - decide_blitter (maxhpos); - rounds--; - } - if (rounds == 0) - write_log ("blitter froze!?\n"); - } else { - actually_do_blit (); - } - blitter_done (); - dmacon = odmacon; - } -} - -static void blit_bltset (int con) -{ - int i; - - blitline = bltcon1 & 1; - blitfill = bltcon1 & 0x18; - blitdesc = bltcon1 & 2; - blit_ch = (bltcon0 & 0x0f00) >> 8; - - blit_singlechannel = 0; - if (blit_ch == 0 || blit_ch == 1 || blit_ch == 2 || blit_ch == 4 || blit_ch == 8) - blit_singlechannel = 1; - if (blitline) { - if (blt_info.hblitsize != 2) - write_log ("weird hblitsize in linemode: %d vsize=%d PC%=%x\n", blt_info.hblitsize, blt_info.vblitsize, m68k_getpc()); - blit_diag = blit_cycle_diagram_line; - blit_singlechannel = 1; - } else { - if (con & 2) { - blitfc = !!(bltcon1 & 0x4); - blitife = bltcon1 & 0x8; - if ((bltcon1 & 0x18) == 0x18) { - /* Digital "Trash" demo does this; others too. Apparently, no - * negative effects. */ - static int warn = 1; - if (warn) - write_log ("warning: weird fill mode (further messages suppressed) PC=%x\n", m68k_getpc ()); - warn = 0; - blitife = 0; - } - } - if (blitfill && !blitdesc) { - static int warn = 1; - if (warn) - write_log ("warning: blitter fill without desc (further messages suppressed) PC=%x\n", m68k_getpc()); - warn = 0; - } - blit_diag = blitfill ? blit_cycle_diagram_fill[blit_ch] : blit_cycle_diagram[blit_ch]; - } - if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - write_log("warning: BLTCON1 DOFF-bit set\n"); - - ddat1use = ddat2use = 0; - blit_dmacount = blit_dmacount2 = 0; - for (i = 0; i < blit_diag[1]; i++) { - int v = blit_diag[2 + i]; - if (v) - blit_dmacount++; - if (v > 0 && v < 4) - blit_dmacount2++; - } - - blt_info.blitashift = bltcon0 >> 12; - blt_info.blitdownashift = 16 - blt_info.blitashift; - blt_info.blitbshift = bltcon1 >> 12; - blt_info.blitdownbshift = 16 - blt_info.blitbshift; -} - -void blit_modset (void) -{ - int mult; - - blit_add = blitdesc ? -2 : 2; - mult = blitdesc ? -1 : 1; - blit_modadda = mult * blt_info.bltamod; - blit_modaddb = mult * blt_info.bltbmod; - blit_modaddc = mult * blt_info.bltcmod; - blit_modaddd = mult * blt_info.bltdmod; -} - -void reset_blit (int bltcon) -{ - if (bltstate == BLT_done) - return; - if (bltcon) - blit_bltset (bltcon); - blit_modset (); -} - -void do_blitter (int hpos) -{ - int cycles; -#ifdef BLITTER_DEBUG - int oldstate = bltstate; -#endif - blt_info.blitzero = 1; - bltstate = BLT_init; - preva = 0; - prevb = 0; - - blit_firstline_cycles = blit_first_cycle = get_cycles (); - blit_cyclecounter = -1; - blit_misscyclecounter = 0; - blit_last_cycle = 0; - blit_maxcyclecounter = 0; - blit_last_hpos = hpos; - - reset_blit (1|2); - - if (blitline) { - blitsing = bltcon1 & 0x2; - blinea = blt_info.bltadat; - blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16 - blt_info.blitbshift)); - blitsign = bltcon1 & 0x40; - blitonedot = 0; - cycles = blt_info.vblitsize; - } else { - blit_firstline_cycles = blit_first_cycle + blit_diag[1] * blt_info.hblitsize * CYCLE_UNIT; - cycles = blt_info.vblitsize * blt_info.hblitsize; - } - -#ifdef BLITTER_DEBUG - blitter_dontdo = 0; - if (1) { - if (oldstate != BLT_done) - write_log ("blitter was already active!\n"); - write_log ("blitstart: v=%03.3d h=%03.3d %dx%d %d (%d) d=%d f=%02.2X n=%d pc=%p l=%d dma=%d\n", - vpos, hpos, blt_info.hblitsize, blt_info.vblitsize, cycles, blit_ch, - blitdesc ? 1 : 0, blitfill, - dmaen(DMA_BLITPRI) ? 1 : 0, m68k_getpc (), blitline, dmaen(DMA_BLITTER)); - blitter_dump (); - } -#endif - blit_slowdown = 0; - - unset_special (SPCFLAG_BLTNASTY); - if (dmaen(DMA_BLITPRI)) - set_special (SPCFLAG_BLTNASTY); - - if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) { - blitter_done (); - return; - } - - if (dmaen(DMA_BLITTER)) - bltstate = BLT_work; - - blit_maxcyclecounter = 0x7fffffff; - if (currprefs.blitter_cycle_exact) { - blitter_dma_cycles_line_count = 0; - blitter_hcounter1 = blitter_hcounter2 = 0; - blitter_vcounter1 = blitter_vcounter2 = 0; - if (blit_dmacount2 == blit_dmacount) - blitter_vcounter2 = blt_info.vblitsize; - blit_linecyclecounter = 0; - blitter_dma_cycles_line = blt_info.hblitsize * blit_dmacount2; - if (blit_ch == 0) - blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize; - return; - } - - if (currprefs.immediate_blits) - cycles = 1; - - eventtab[ev_blitter].active = 1; - eventtab[ev_blitter].oldcycles = get_cycles (); - eventtab[ev_blitter].evtime = cycles * blit_diag[1] * CYCLE_UNIT + get_cycles (); - events_schedule(); -} - - -void maybe_blit (int hpos, int hack) -{ - static int warned; - - if (bltstate == BLT_done) - return; - - if (!warned && dmaen (DMA_BLITTER)) { -#ifndef BLITTER_DEBUG - warned = 1; -#endif - write_log ("warning: Program does not wait for blitter %p vpos=%d tc=%d\n", - m68k_getpc (), vpos, blit_cyclecounter); - } - - if (currprefs.blitter_cycle_exact) { - decide_blitter (hpos); - return; - } - - if (!eventtab[ev_blitter].active) - write_log ("FOO!!?\n"); - if (hack == 1 && get_cycles() < blit_firstline_cycles) - return; - - blitter_handler (); -} - -int blitnasty (void) -{ - int cycles, ccnt; - if (bltstate == BLT_done) - return 0; - if (!dmaen(DMA_BLITTER)) - return 0; - if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[1]) - return 0; - cycles = (get_cycles () - blit_first_cycle) / CYCLE_UNIT; - ccnt = 0; - while (blit_last_cycle < cycles) { - int c = channel_state (blit_last_cycle++); - if (!c) - ccnt++; - } - return ccnt; -} - -/* very approximate emulation of blitter slowdown caused by bitplane DMA */ -void blitter_slowdown (int ddfstrt, int ddfstop, int totalcycles, int freecycles) -{ - static int oddfstrt, oddfstop, ototal, ofree; - static int slow; - - if (!totalcycles || ddfstrt < 0 || ddfstop < 0) - return; - if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { - int linecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles; - int freelinecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles; - int dmacycles = (linecycles * blit_dmacount) / blit_diag[1]; - oddfstrt = ddfstrt; - oddfstop = ddfstop; - ototal = totalcycles; - ofree = freecycles; - slow = 0; - if (dmacycles > freelinecycles) - slow = dmacycles - freelinecycles; - } - if (blit_slowdown < 0 || blitline) - return; - blit_slowdown += slow; - blit_misscyclecounter += slow; -} - -uae_u8 *restore_blitter (uae_u8 *src) -{ - uae_u32 flags = restore_u32(); - - bltstate = (flags & 1) ? BLT_init : BLT_done; - if (bltstate == BLT_init) { - write_log ("blitter was started but DMA was inactive during save\n"); - do_blitter (0); - } - return src; -} - -uae_u8 *save_blitter (int *len, uae_u8 *dstptr) -{ - uae_u8 *dstbak,*dst; - - if (bltstate != BLT_done && bltstate != BLT_init) { - write_log ("blitter was running, forcing immediate finish\n"); - /* blitter is active just now but we don't have blitter state support yet */ - blitter_force_finish (); - } - if (dstptr) - dstbak = dst = dstptr; - else - dstbak = dst = malloc (16); - save_u32((bltstate != BLT_done) ? 0 : 1); - *len = dst - dstbak; - return dstbak; - -} diff --git a/blitter3.c b/blitter3.c deleted file mode 100755 index 24d7789e..00000000 --- a/blitter3.c +++ /dev/null @@ -1,1093 +0,0 @@ - /* - * UAE - The Un*x Amiga Emulator - * - * Custom chip emulation - * - * (c) 1995 Bernd Schmidt, Alessandro Bissacco - * (c) 2002 - 2003 Toni Wilen - */ - -//#define BLITTER_DEBUG -//#define BLITTER_SLOWDOWNDEBUG 4 - -#define SPEEDUP - -#include "sysconfig.h" -#include "sysdeps.h" - -#include "config.h" -#include "options.h" -#include "uae.h" -#include "memory.h" -#include "custom.h" -#include "events.h" -#include "newcpu.h" -#include "blitter.h" -#include "blit.h" -#include "savestate.h" - -uae_u16 oldvblts; -uae_u16 bltcon0,bltcon1; -uae_u32 bltapt,bltbpt,bltcpt,bltdpt; - -int blinea_shift; -static uae_u16 blinea, blineb; -static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc; -static int blitonedot,blitsign; -static int blit_add; -static int blit_modadda, blit_modaddb, blit_modaddc, blit_modaddd; -static int blit_ch; -int blit_singlechannel; - -#ifdef BLITTER_DEBUG -static int blitter_dontdo; -static int blitter_delayed_debug; -#endif -#ifdef BLITTER_SLOWDOWNDEBUG -static int blitter_slowdowndebug; -#endif - -struct bltinfo blt_info; - -static uae_u8 blit_filltable[256][4][2]; -uae_u32 blit_masktable[BLITTER_MAX_WORDS]; -static uae_u16 blit_trashtable[BLITTER_MAX_WORDS]; -enum blitter_states bltstate; - -static int blit_cyclecounter, blit_maxcyclecounter, blit_slowdown; -static int blit_linecyclecounter, blit_misscyclecounter; - -#ifdef CPUEMU_6 -extern uae_u8 cycle_line[]; -#endif - -static long blit_firstline_cycles; -static long blit_first_cycle; -static int blit_last_cycle, blit_dmacount, blit_dmacount2; -static int blit_linecycles, blit_extracycles; -static uae_u8 *blit_diag; - -static uae_u16 ddat1, ddat2; -static int ddat1use, ddat2use; - -static uae_u8 blit_cycle_diagram_finald[] = - { 0, 2, 0,4 }; - -static uae_u8 blit_cycle_diagram[][10] = -{ - { 0, 2, 0,0 }, /* 0 */ - { 0, 2, 4,0 }, /* 1 */ - { 0, 2, 3,0 }, /* 2 */ - { 2, 3, 0,3,4, 3,0 }, /* 3 */ - { 0, 3, 2,0,0 }, /* 4 */ - { 2, 3, 0,2,4, 2,0 }, /* 5 */ - { 0, 3, 2,3,0 }, /* 6 */ - { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ - { 0, 2, 1,0 }, /* 8 */ - { 2, 2, 1,4, 1,0 }, /* 9 */ - { 0, 2, 1,3 }, /* A */ - { 3, 3, 1,3,4, 1,3,0 }, /* B */ - { 2, 3, 0,1,2, 1,2 }, /* C */ - { 3, 3, 1,2,4, 1,2,0 }, /* D */ - { 0, 3, 1,2,3 }, /* E */ - { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ -}; - -/* fill mode always adds C-channel to cycle-diagram */ -/* Reflect - Sound Vision freezes without this */ -static uae_u8 blit_cycle_diagram_fill[][10] = -{ - { 0, 2, 0,0 }, /* 0 */ - { 0, 3, 0,3,4 }, /* 1 */ - { 0, 2, 3,0 }, /* 2 */ - { 2, 3, 0,3,4, 3,0 }, /* 3 */ - { 0, 3, 2,0,0 }, /* 4 */ - { 3, 4, 0,2,0,4, 2,0,0 }, /* 5 */ - { 0, 3, 2,3,0 }, /* 6 */ - { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ - { 0, 2, 1,0 }, /* 8 */ - { 3, 3, 1,0,4, 1,0,0}, /* 9 */ - { 0, 2, 1,3 }, /* A */ - { 3, 3, 1,3,4, 1,3,0 }, /* B */ - { 2, 3, 0,1,2, 1,2 }, /* C */ - { 4, 4, 1,2,0,4, 1,2,0,0 }, /* D */ - { 0, 3, 1,2,3 }, /* E */ - { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ -}; - -static uae_u8 blit_cycle_diagram_line[] = -{ - 0, 4, 0,0,0,4 /* total guess.. */ -}; - -void build_blitfilltable(void) -{ - unsigned int d, fillmask; - int i; - - for (i = 0; i < BLITTER_MAX_WORDS; i++) - blit_masktable[i] = 0xFFFF; - - for (d = 0; d < 256; d++) { - for (i = 0; i < 4; i++) { - int fc = i & 1; - uae_u8 data = d; - for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) { - uae_u16 tmp = data; - if (fc) { - if (i & 2) - data |= fillmask; - else - data ^= fillmask; - } - if (tmp & fillmask) fc = !fc; - } - blit_filltable[d][i][0] = data; - blit_filltable[d][i][1] = fc; - } - } -} - -static void blitter_dump (void) -{ - write_log ("APT=%08.8X BPT=%08.8X CPT=%08.8X DPT=%08.8X\n", bltapt, bltbpt, bltcpt, bltdpt); - write_log ("CON0=%04.4X CON1=%04.4X ADAT=%04.4X BDAT=%04.4X CDAT=%04.4X\n", - bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); - write_log ("AFWM=%04.4X ALWM=%04.4X AMOD=%04.4X BMOD=%04.4X CMOD=%04.4X DMOD=%04.4X\n", - blt_info.bltafwm, blt_info.bltalwm, - blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); -} - -STATIC_INLINE uae_u8 *blit_xlateptr(uaecptr bltpt, int bytecount) -{ - if (!chipmem_bank.check(bltpt,bytecount)) return NULL; - return chipmem_bank.xlateaddr(bltpt); -} - -STATIC_INLINE uae_u8 *blit_xlateptr_desc(uaecptr bltpt, int bytecount) -{ - if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL; - return chipmem_bank.xlateaddr(bltpt); -} - -static void blitter_done (void) -{ - ddat1use = ddat2use = 0; - bltstate = BLT_done; - blitter_done_notify (); - INTREQ(0x8040); - eventtab[ev_blitter].active = 0; - unset_special (SPCFLAG_BLTNASTY); -#ifdef BLITTER_DEBUG - write_log ("vpos=%d, cycles %d, missed %d, total %d\n", - vpos, blit_cyclecounter, blit_misscyclecounter, blit_cyclecounter + blit_misscyclecounter); -#endif -} - -static void blitter_dofast(void) -{ - int i,j; - uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; - uae_u8 mt = bltcon0 & 0xFF; - - blit_masktable[0] = blt_info.bltafwm; - blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; - - if (bltcon0 & 0x800) { - bltadatptr = bltapt; - bltapt += (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; - } - if (bltcon0 & 0x400) { - bltbdatptr = bltbpt; - bltbpt += (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; - } - if (bltcon0 & 0x200) { - bltcdatptr = bltcpt; - bltcpt += (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; - } - if (bltcon0 & 0x100) { - bltddatptr = bltdpt; - bltdpt += (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; - } - -#ifdef SPEEDUP - if (blitfunc_dofast[mt] && !blitfill) { - (*blitfunc_dofast[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); - } else -#endif - { - uae_u32 blitbhold = blt_info.bltbhold; - uae_u32 preva = 0, prevb = 0; - uaecptr dstp = 0; - int dodst = 0; - - /*if (!blitfill) write_log ("minterm %x not present\n",mt); */ - for (j = 0; j < blt_info.vblitsize; j++) { - blitfc = !!(bltcon1 & 0x4); - for (i = 0; i < blt_info.hblitsize; i++) { - uae_u32 bltadat, blitahold; - uae_u16 bltbdat; - if (bltadatptr) { - blt_info.bltadat = bltadat = chipmem_agnus_wget (bltadatptr); - bltadatptr += 2; - } else - bltadat = blt_info.bltadat; - bltadat &= blit_masktable[i]; - blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; - preva = bltadat; - - if (bltbdatptr) { - blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); - bltbdatptr += 2; - blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift; - prevb = bltbdat; - } - - if (bltcdatptr) { - blt_info.bltcdat = chipmem_agnus_wget (bltcdatptr); - bltcdatptr += 2; - } - if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); - blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; - if (blitfill) { - uae_u16 d = blt_info.bltddat; - int ifemode = blitife ? 2 : 0; - int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; - blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] - + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); - blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; - } - if (blt_info.bltddat) - blt_info.blitzero = 0; - if (bltddatptr) { - dodst = 1; - dstp = bltddatptr; - bltddatptr += 2; - } - } - if (bltadatptr) bltadatptr += blt_info.bltamod; - if (bltbdatptr) bltbdatptr += blt_info.bltbmod; - if (bltcdatptr) bltcdatptr += blt_info.bltcmod; - if (bltddatptr) bltddatptr += blt_info.bltdmod; - } - if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); - blt_info.bltbhold = blitbhold; - } - blit_masktable[0] = 0xFFFF; - blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; - - bltstate = BLT_done; -} - -static void blitter_dofast_desc(void) -{ - int i,j; - uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; - uae_u8 mt = bltcon0 & 0xFF; - - blit_masktable[0] = blt_info.bltafwm; - blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; - - if (bltcon0 & 0x800) { - bltadatptr = bltapt; - bltapt -= (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; - } - if (bltcon0 & 0x400) { - bltbdatptr = bltbpt; - bltbpt -= (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; - } - if (bltcon0 & 0x200) { - bltcdatptr = bltcpt; - bltcpt -= (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; - } - if (bltcon0 & 0x100) { - bltddatptr = bltdpt; - bltdpt -= (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; - } -#ifdef SPEEDUP - if (blitfunc_dofast_desc[mt] && !blitfill) { - (*blitfunc_dofast_desc[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); - } else -#endif - { - uae_u32 blitbhold = blt_info.bltbhold; - uae_u32 preva = 0, prevb = 0; - uaecptr dstp = 0; - int dodst = 0; - - for (j = 0; j < blt_info.vblitsize; j++) { - blitfc = !!(bltcon1 & 0x4); - for (i = 0; i < blt_info.hblitsize; i++) { - uae_u32 bltadat, blitahold; - uae_u16 bltbdat; - if (bltadatptr) { - bltadat = blt_info.bltadat = chipmem_agnus_wget (bltadatptr); - bltadatptr -= 2; - } else - bltadat = blt_info.bltadat; - bltadat &= blit_masktable[i]; - blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; - preva = bltadat; - - if (bltbdatptr) { - blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); - bltbdatptr -= 2; - blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift; - prevb = bltbdat; - } - - if (bltcdatptr) { - blt_info.bltcdat = blt_info.bltbdat = chipmem_agnus_wget (bltcdatptr); - bltcdatptr -= 2; - } - if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); - blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; - if (blitfill) { - uae_u16 d = blt_info.bltddat; - int ifemode = blitife ? 2 : 0; - int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; - blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] - + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); - blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; - } - if (blt_info.bltddat) - blt_info.blitzero = 0; - if (bltddatptr) { - dstp = bltddatptr; - dodst = 1; - bltddatptr -= 2; - } - } - if (bltadatptr) bltadatptr -= blt_info.bltamod; - if (bltbdatptr) bltbdatptr -= blt_info.bltbmod; - if (bltcdatptr) bltcdatptr -= blt_info.bltcmod; - if (bltddatptr) bltddatptr -= blt_info.bltdmod; - } - if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); - blt_info.bltbhold = blitbhold; - } - blit_masktable[0] = 0xFFFF; - blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; - - bltstate = BLT_done; -} - -STATIC_INLINE void blitter_read(void) -{ - if (bltcon0 & 0x200) { - if (!dmaen(DMA_BLITTER)) - return; - blt_info.bltcdat = chipmem_bank.wget(bltcpt); - } - bltstate = BLT_work; -} - -STATIC_INLINE void blitter_write(void) -{ - if (blt_info.bltddat) - blt_info.blitzero = 0; - /* D-channel state has no effect on linedraw, but C must be enabled or nothing is drawn! */ - if (bltcon0 & 0x200) { - if (!dmaen(DMA_BLITTER)) - return; - chipmem_bank.wput(bltdpt, blt_info.bltddat); - bltdpt = bltcpt; /* believe it or not but try Cardamon or Cardamom without this.. */ - } - bltstate = BLT_next; -} - -STATIC_INLINE void blitter_line_incx(void) -{ - if (++blinea_shift == 16) { - blinea_shift = 0; - bltcpt += 2; - } -} - -STATIC_INLINE void blitter_line_decx(void) -{ - if (blinea_shift-- == 0) { - blinea_shift = 15; - bltcpt -= 2; - } -} - -STATIC_INLINE void blitter_line_decy(void) -{ - bltcpt -= blt_info.bltcmod; - blitonedot = 0; -} - -STATIC_INLINE void blitter_line_incy(void) -{ - bltcpt += blt_info.bltcmod; - blitonedot = 0; -} - -static void blitter_line(void) -{ - uae_u16 blitahold = blinea >> blinea_shift; - uae_u16 blitbhold = blineb & 1 ? 0xFFFF : 0; - uae_u16 blitchold = blt_info.bltcdat; - - if (blitsing && blitonedot) - blitahold = 0; - blitonedot = 1; - blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF); - if (!blitsign){ - if (bltcon0 & 0x800) - bltapt += (uae_s16)blt_info.bltamod; - if (bltcon1 & 0x10){ - if (bltcon1 & 0x8) - blitter_line_decy(); - else - blitter_line_incy(); - } else { - if (bltcon1 & 0x8) - blitter_line_decx(); - else - blitter_line_incx(); - } - } else { - if (bltcon0 & 0x800) - bltapt += (uae_s16)blt_info.bltbmod; - } - if (bltcon1 & 0x10){ - if (bltcon1 & 0x4) - blitter_line_decx(); - else - blitter_line_incx(); - } else { - if (bltcon1 & 0x4) - blitter_line_decy(); - else - blitter_line_incy(); - } - blitsign = 0 > (uae_s16)bltapt; - bltstate = BLT_write; -} - -STATIC_INLINE void blitter_nxline(void) -{ - blineb = (blineb << 1) | (blineb >> 15); - if (blt_info.vblitsize > 0) - blt_info.vblitsize--; - bltstate = BLT_read; -} - -static void actually_do_blit(void) -{ - if (blitline) { - do { - blitter_read(); - blitter_line(); - blitter_write(); - blitter_nxline(); - if (blt_info.vblitsize == 0) - bltstate = BLT_done; - } while (bltstate != BLT_done); - } else { - if (blitdesc) - blitter_dofast_desc(); - else - blitter_dofast(); - bltstate = BLT_done; - } -} - -void blitter_handler(void) -{ - if (!dmaen(DMA_BLITTER)) { - eventtab[ev_blitter].active = 1; - eventtab[ev_blitter].oldcycles = get_cycles (); - eventtab[ev_blitter].evtime = 10 * CYCLE_UNIT + get_cycles (); /* wait a little */ - return; /* gotta come back later. */ - } - if (blit_slowdown > 0) { - eventtab[ev_blitter].active = 1; - eventtab[ev_blitter].oldcycles = get_cycles (); - eventtab[ev_blitter].evtime = blit_slowdown * CYCLE_UNIT + get_cycles (); - blit_slowdown = -1; - return; - } -#ifdef BLITTER_DEBUG - if (!blitter_dontdo) - actually_do_blit(); - else - bltstate = BLT_done; -#else - actually_do_blit (); -#endif - blitter_done (); -} - -STATIC_INLINE int channel_state (int cycles) -{ - if (cycles < 0) - return 0; - if (cycles < blit_diag[0]) - return blit_diag[blit_diag[1] + 2 + cycles]; - return blit_diag[((cycles - blit_diag[0]) % blit_diag[1]) + 2]; -} - -int is_bitplane_dma (int hpos); -STATIC_INLINE int canblit (int hpos) -{ - if ((cycle_line[hpos] == 0 || cycle_line[hpos] == CYCLE_NOCPU) && !is_bitplane_dma (hpos)) - return 1; - return 0; -} - -#ifdef CPUEMU_6 - -static int blit_last_hpos; - -static int blitter_dma_cycles_line, blitter_dma_cycles_line_count; -static int blitter_cyclecounter; -static int blitter_hcounter1, blitter_hcounter2; -static int blitter_vcounter1, blitter_vcounter2; - - -static uae_u32 preva, prevb; -STATIC_INLINE uae_u16 blitter_doblit (void) -{ - uae_u32 blitahold; - uae_u16 bltadat, ddat; - uae_u8 mt = bltcon0 & 0xFF; - - bltadat = blt_info.bltadat; - if (blitter_hcounter1 == 0) - bltadat &= blt_info.bltafwm; - if (blitter_hcounter1 == blt_info.hblitsize - 1) - bltadat &= blt_info.bltalwm; - if (blitdesc) - blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; - else - blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; - preva = bltadat; - - ddat = blit_func (blitahold, blt_info.bltbhold, blt_info.bltcdat, mt) & 0xFFFF; - - if (bltcon1 & 0x18) { - uae_u16 d = ddat; - int ifemode = blitife ? 2 : 0; - int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; - ddat = (blit_filltable[d & 255][ifemode + blitfc][0] - + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); - blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; - } - - if (ddat) - blt_info.blitzero = 0; - - return ddat; -} - - -STATIC_INLINE int blitter_doddma (void) -{ - int wd; - uae_u16 d; - - wd = 0; - if (blit_dmacount2 == 0) { - d = blitter_doblit (); - wd = -1; - } else if (ddat2use) { - d = ddat2; - ddat2use = 0; - wd = 2; - } else if (ddat1use) { - d = ddat1; - ddat1use = 0; - wd = 1; - } - if (wd) { - chipmem_agnus_wput (bltdpt, d); - bltdpt += blit_add; - blitter_hcounter2++; - if (blitter_hcounter2 == blt_info.hblitsize) { - blitter_hcounter2 = 0; - bltdpt += blit_modaddd; - blitter_vcounter2++; - if (blitter_vcounter2 > blitter_vcounter1) - blitter_vcounter1 = blitter_vcounter2; - } - if (blit_ch == 1) - blitter_hcounter1 = blitter_hcounter2; - } - return wd; -} - -STATIC_INLINE void blitter_dodma (int ch) -{ - - switch (ch) - { - case 1: - blt_info.bltadat = chipmem_agnus_wget (bltapt); - bltapt += blit_add; - break; - case 2: - blt_info.bltbdat = chipmem_agnus_wget (bltbpt); - bltbpt += blit_add; - if (blitdesc) - blt_info.bltbhold = (((uae_u32)blt_info.bltbdat << 16) | prevb) >> blt_info.blitdownbshift; - else - blt_info.bltbhold = (((uae_u32)prevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift; - prevb = blt_info.bltbdat; - break; - case 3: - blt_info.bltcdat = chipmem_agnus_wget (bltcpt); - bltcpt += blit_add; - break; - } - - blitter_cyclecounter++; - if (blitter_cyclecounter >= blit_dmacount2) { - blitter_cyclecounter = 0; - ddat2 = ddat1; - ddat2use = ddat1use; - ddat1use = 0; - ddat1 = blitter_doblit (); - if (bltcon0 & 0x100) - ddat1use = 1; - blitter_hcounter1++; - if (blitter_hcounter1 == blt_info.hblitsize) { - blitter_hcounter1 = 0; - if (bltcon0 & 0x800) - bltapt += blit_modadda; - if (bltcon0 & 0x400) - bltbpt += blit_modaddb; - if (bltcon0 & 0x200) - bltcpt += blit_modaddc; - blitter_vcounter1++; - blitfc = !!(bltcon1 & 0x4); - } - } -} - -static void decide_blitter_line (int hpos) -{ - hpos++; - if (dmaen (DMA_BLITTER)) { - while (blit_last_hpos < hpos) { - int c = channel_state (blit_cyclecounter); - for (;;) { - if (blit_cyclecounter < 0) { - blit_cyclecounter++; - break; - } - if (c && !canblit (blit_last_hpos)) - break; - if (c) - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blit_cyclecounter++; - blit_linecyclecounter++; - if (blit_linecyclecounter >= blit_diag[1]) { - blit_linecyclecounter = 0; - ddat1use = ddat2use; - ddat1 = ddat2; - ddat2use = 0; - if (blt_info.vblitsize > 0) { - blitter_read(); - blitter_line(); - ddat2use = 1; - ddat2 = blt_info.bltddat; - } - if (ddat1use) { - blt_info.bltddat = ddat1; - ddat1use = 0; - blitter_write(); - } - blitter_nxline(); - if (!ddat1use && !ddat2use && blt_info.vblitsize == 0) { - bltstate = BLT_done; - blitter_done (); - return; - } - } - break; - } - blit_last_hpos++; - } - } else { - blit_last_hpos = hpos; - } - if (blit_last_hpos > maxhpos) - blit_last_hpos = 0; -} - -void decide_blitter (int hpos) -{ - if (bltstate == BLT_done) - return; -#ifdef BLITTER_DEBUG - if (blitter_delayed_debug) { - blitter_delayed_debug = 0; - blitter_dump(); - } -#endif - if (!currprefs.blitter_cycle_exact) - return; - if (blitline) { - decide_blitter_line (hpos); - return; - } - hpos++; - if (dmaen (DMA_BLITTER)) { - while (blit_last_hpos < hpos) { - int c = channel_state (blit_cyclecounter); -#ifdef BLITTER_SLOWDOWNDEBUG - blitter_slowdowndebug--; - if (blitter_slowdowndebug < 0) { - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blitter_slowdowndebug = BLITTER_SLOWDOWNDEBUG; - } -#endif - for (;;) { - if (c && !canblit (blit_last_hpos)) { - blit_misscyclecounter++; - break; - } - if (c == 4) { - if (blitter_doddma ()) { - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blit_cyclecounter++; - } - } else if (c) { - if (blitter_vcounter1 < blt_info.vblitsize) { - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blitter_dodma (c); - } - blit_cyclecounter++; - } else { - blit_cyclecounter++; - /* check if blit with zero channels has ended */ - if (blit_cyclecounter >= blit_maxcyclecounter) { - blitter_done (); - return; - } - } - if (blitter_vcounter1 >= blt_info.vblitsize && blitter_vcounter2 >= blt_info.vblitsize) { - if (!ddat1use && !ddat2use) { - blitter_done (); - return; - } - if (blit_diag != blit_cycle_diagram_finald) { - blit_cyclecounter = 0; - blit_diag = blit_cycle_diagram_finald; - } - } - break; - } - blit_last_hpos++; - } - } else { - blit_last_hpos = hpos; - } - if (blit_last_hpos > maxhpos) - blit_last_hpos = 0; -} -#else -void decide_blitter (int hpos) { } -#endif - -static void blitter_force_finish (void) -{ - uae_u16 odmacon; - if (bltstate == BLT_done) - return; - if (bltstate != BLT_done) { - /* blitter is currently running - * force finish (no blitter state support yet) - */ - odmacon = dmacon; - dmacon |= DMA_MASTER | DMA_BLITTER; - write_log ("forcing blitter finish\n"); - if (currprefs.blitter_cycle_exact) { - int rounds = 10000; - while (bltstate != BLT_done && rounds > 0) { - memset (cycle_line, 0, maxhpos); - decide_blitter (maxhpos); - rounds--; - } - if (rounds == 0) - write_log ("blitter froze!?\n"); - } else { - actually_do_blit (); - } - blitter_done (); - dmacon = odmacon; - } -} - -static void blit_bltset (int con) -{ - int i; - - blitline = bltcon1 & 1; - blitfill = bltcon1 & 0x18; - blitdesc = bltcon1 & 2; - blit_ch = (bltcon0 & 0x0f00) >> 8; - - blit_singlechannel = 0; - if (blit_ch == 0 || blit_ch == 1 || blit_ch == 2 || blit_ch == 4 || blit_ch == 8) - blit_singlechannel = 1; - if (blitline) { - if (blt_info.hblitsize != 2) - write_log ("weird hblitsize in linemode: %d vsize=%d PC%=%x\n", blt_info.hblitsize, blt_info.vblitsize, m68k_getpc()); - blit_diag = blit_cycle_diagram_line; - blit_singlechannel = 1; - } else { - if (con & 2) { - blitfc = !!(bltcon1 & 0x4); - blitife = bltcon1 & 0x8; - if ((bltcon1 & 0x18) == 0x18) { - /* Digital "Trash" demo does this; others too. Apparently, no - * negative effects. */ - static int warn = 1; - if (warn) - write_log ("warning: weird fill mode (further messages suppressed) PC=%x\n", m68k_getpc ()); - warn = 0; - blitife = 0; - } - } - if (blitfill && !blitdesc) { - static int warn = 1; - if (warn) - write_log ("warning: blitter fill without desc (further messages suppressed) PC=%x\n", m68k_getpc()); - warn = 0; - } - blit_diag = blitfill ? blit_cycle_diagram_fill[blit_ch] : blit_cycle_diagram[blit_ch]; - } - if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - write_log("warning: BLTCON1 DOFF-bit set\n"); - - ddat1use = ddat2use = 0; - blit_dmacount = blit_dmacount2 = 0; - for (i = 0; i < blit_diag[1]; i++) { - int v = blit_diag[2 + i]; - if (v) - blit_dmacount++; - if (v > 0 && v < 4) - blit_dmacount2++; - } - - blt_info.blitashift = bltcon0 >> 12; - blt_info.blitdownashift = 16 - blt_info.blitashift; - blt_info.blitbshift = bltcon1 >> 12; - blt_info.blitdownbshift = 16 - blt_info.blitbshift; -} - -void blit_modset (void) -{ - int mult; - - blit_add = blitdesc ? -2 : 2; - mult = blitdesc ? -1 : 1; - blit_modadda = mult * blt_info.bltamod; - blit_modaddb = mult * blt_info.bltbmod; - blit_modaddc = mult * blt_info.bltcmod; - blit_modaddd = mult * blt_info.bltdmod; -} - -void reset_blit (int bltcon) -{ - if (bltstate == BLT_done) - return; - if (bltcon) - blit_bltset (bltcon); - blit_modset (); -} - -void do_blitter (int hpos) -{ - int cycles; -#ifdef BLITTER_DEBUG - int oldstate = bltstate; -#endif - blt_info.blitzero = 1; - bltstate = BLT_init; - preva = 0; - prevb = 0; - - blit_firstline_cycles = blit_first_cycle = get_cycles (); - blit_misscyclecounter = 0; - blit_last_cycle = 0; - blit_maxcyclecounter = 0; - blit_last_hpos = hpos; - - reset_blit (1|2); - - if (blitline) { - blit_cyclecounter = -1; - blitsing = bltcon1 & 0x2; - blinea = blt_info.bltadat; - blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16 - blt_info.blitbshift)); - blitsign = bltcon1 & 0x40; - blitonedot = 0; - cycles = blt_info.vblitsize; - } else { - blit_cyclecounter = -1; - blit_firstline_cycles = blit_first_cycle + blit_diag[1] * blt_info.hblitsize * CYCLE_UNIT; - cycles = blt_info.vblitsize * blt_info.hblitsize; - } - -#ifdef BLITTER_DEBUG - blitter_dontdo = 0; - if (1) { - if (oldstate != BLT_done) - write_log ("blitter was already active!\n"); - write_log ("blitstart: v=%03.3d h=%03.3d %dx%d %d (%d) d=%d f=%02.2X n=%d pc=%p l=%d dma=%d\n", - vpos, hpos, blt_info.hblitsize, blt_info.vblitsize, cycles, blit_ch, - blitdesc ? 1 : 0, blitfill, - dmaen(DMA_BLITPRI) ? 1 : 0, m68k_getpc (), blitline, dmaen(DMA_BLITTER)); - blitter_dump (); - } -#endif - blit_slowdown = 0; - - unset_special (SPCFLAG_BLTNASTY); - if (dmaen(DMA_BLITPRI)) - set_special (SPCFLAG_BLTNASTY); - - if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) { - blitter_done (); - return; - } - - if (dmaen(DMA_BLITTER)) - bltstate = BLT_work; - - blit_maxcyclecounter = 0x7fffffff; - if (currprefs.blitter_cycle_exact) { - blitter_dma_cycles_line_count = 0; - blitter_hcounter1 = blitter_hcounter2 = 0; - blitter_vcounter1 = blitter_vcounter2 = 0; - if (blit_dmacount2 == blit_dmacount) - blitter_vcounter2 = blt_info.vblitsize; - blit_linecyclecounter = 0; - blitter_dma_cycles_line = blt_info.hblitsize * blit_dmacount2; - if (blit_ch == 0) - blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize; - return; - } - - if (currprefs.immediate_blits) - cycles = 1; - - eventtab[ev_blitter].active = 1; - eventtab[ev_blitter].oldcycles = get_cycles (); - eventtab[ev_blitter].evtime = cycles * blit_diag[1] * CYCLE_UNIT + get_cycles (); - events_schedule(); -} - - -void maybe_blit (int hpos, int hack) -{ - static int warned; - - if (bltstate == BLT_done) - return; - - if (!warned && dmaen (DMA_BLITTER)) { -#ifndef BLITTER_DEBUG - warned = 1; -#endif - write_log ("warning: Program does not wait for blitter %p vpos=%d tc=%d\n", - m68k_getpc (), vpos, blit_cyclecounter); - } - - if (currprefs.blitter_cycle_exact) { - decide_blitter (hpos); - goto end; - } - - if (!eventtab[ev_blitter].active) - write_log ("FOO!!?\n"); - if (hack == 1 && get_cycles() < blit_firstline_cycles) - goto end; - - blitter_handler (); -end:; -#ifdef BLITTER_DEBUG - blitter_delayed_debug = 1; -#endif -} - -int blitnasty (void) -{ - int cycles, ccnt; - if (bltstate == BLT_done) - return 0; - if (!dmaen(DMA_BLITTER)) - return 0; - if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[1]) - return 0; - cycles = (get_cycles () - blit_first_cycle) / CYCLE_UNIT; - ccnt = 0; - while (blit_last_cycle < cycles) { - int c = channel_state (blit_last_cycle++); - if (!c) - ccnt++; - } - return ccnt; -} - -/* very approximate emulation of blitter slowdown caused by bitplane DMA */ -void blitter_slowdown (int ddfstrt, int ddfstop, int totalcycles, int freecycles) -{ - static int oddfstrt, oddfstop, ototal, ofree; - static int slow; - - if (!totalcycles || ddfstrt < 0 || ddfstop < 0) - return; - if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { - int linecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles; - int freelinecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles; - int dmacycles = (linecycles * blit_dmacount) / blit_diag[1]; - oddfstrt = ddfstrt; - oddfstop = ddfstop; - ototal = totalcycles; - ofree = freecycles; - slow = 0; - if (dmacycles > freelinecycles) - slow = dmacycles - freelinecycles; - } - if (blit_slowdown < 0 || blitline) - return; - blit_slowdown += slow; - blit_misscyclecounter += slow; -} - -uae_u8 *restore_blitter (uae_u8 *src) -{ - uae_u32 flags = restore_u32(); - - bltstate = (flags & 1) ? BLT_init : BLT_done; - if (bltstate == BLT_init) { - write_log ("blitter was started but DMA was inactive during save\n"); - do_blitter (0); - } - return src; -} - -uae_u8 *save_blitter (int *len, uae_u8 *dstptr) -{ - uae_u8 *dstbak,*dst; - - if (bltstate != BLT_done && bltstate != BLT_init) { - write_log ("blitter was running, forcing immediate finish\n"); - /* blitter is active just now but we don't have blitter state support yet */ - blitter_force_finish (); - } - if (dstptr) - dstbak = dst = dstptr; - else - dstbak = dst = malloc (16); - save_u32((bltstate != BLT_done) ? 0 : 1); - *len = dst - dstbak; - return dstbak; - -} diff --git a/blkdev.c b/blkdev.c index 0761e7e1..bc0b1b86 100755 --- a/blkdev.c +++ b/blkdev.c @@ -397,13 +397,13 @@ void scsi_log_before (uae_u8 *cdb, int cdblen, uae_u8 *data, int datalen) { int i; for (i = 0; i < cdblen; i++) { - write_log ("%s%02.2X", i > 0 ? "." : "", cdb[i]); + write_log ("%s%02X", i > 0 ? "." : "", cdb[i]); } write_log ("\n"); if (data) { write_log ("DATAOUT: %d\n", datalen); for (i = 0; i < datalen && i < 100; i++) - write_log ("%s%02.2X", i > 0 ? "." : "", data[i]); + write_log ("%s%02X", i > 0 ? "." : "", data[i]); if (datalen > 0) write_log ("\n"); } @@ -414,13 +414,13 @@ void scsi_log_after (uae_u8 *data, int datalen, uae_u8 *sense, int senselen) int i; write_log ("DATAIN: %d\n", datalen); for (i = 0; i < datalen && i < 100 && data; i++) - write_log ("%s%02.2X", i > 0 ? "." : "", data[i]); + write_log ("%s%02X", i > 0 ? "." : "", data[i]); if (data && datalen > 0) write_log ("\n"); if (senselen > 0) { write_log ("SENSE: %d,", senselen); for (i = 0; i < senselen && i < 32; i++) { - write_log ("%s%02.2X", i > 0 ? "." : "", sense[i]); + write_log ("%s%02X", i > 0 ? "." : "", sense[i]); } write_log ("\n"); } diff --git a/bsdsocket.c b/bsdsocket.c index dcf74601..9b3b51b8 100755 --- a/bsdsocket.c +++ b/bsdsocket.c @@ -1283,7 +1283,7 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context) sb->herrnosize = 4; break; default: - write_log ("bsdsocket: WARNING: Unsupported tag type (%08.8x) in SocketBaseTagList(%x)\n", + write_log ("bsdsocket: WARNING: Unsupported tag type (%08x) in SocketBaseTagList(%x)\n", currtag, m68k_areg (&context->regs, 0)); break; } @@ -1291,7 +1291,7 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context) TRACE (("TAG_UNKNOWN(0x%x)", currtag)); /* Aminetradio uses 0x00004e55 as an ending tag */ if ((currtag & 0xffff8000) == 0) { - write_log ("bsdsocket: WARNING: Corrupted SocketBaseTagList(%x) tag detected (%08.8x)\n", + write_log ("bsdsocket: WARNING: Corrupted SocketBaseTagList(%x) tag detected (%08x)\n", m68k_areg (&context->regs, 0), currtag); goto done; } diff --git a/build68k.c b/build68k.c index 7f1ae16b..a3d4a5a2 100755 --- a/build68k.c +++ b/build68k.c @@ -236,13 +236,13 @@ int main(int argc, char **argv) while (!isspace(*p++)); *p = 0; printf("/* %s */\n", tmp); - printf("{0x%04.4X,%2d,{", bitpattern, n_variable); + printf("{0x%04X,%2d,{", bitpattern, n_variable); for (j = 0; j < 16; j++) { printf("%2d", bitpos[j]); if (j < 15) printf(","); } - printf ("},0x%04.4X,%d,%d,{", bitmask, cpulevel, plevel); + printf ("},0x%04X,%d,%d,{", bitmask, cpulevel, plevel); for(i = 0; i < 5; i++) { printf("{%d,%d}%s", flaguse[i], flagset[i], i == 4 ? "" : ","); } diff --git a/catweasel.c b/catweasel.c index 81c68354..5f10cc02 100755 --- a/catweasel.c +++ b/catweasel.c @@ -285,7 +285,7 @@ uae_u32 catweasel_do_bget (uaecptr addr) } else { buf2[0] = ioport_read (cwc.iobase + addr); } - //write_log ("G %02.2X %02.2X %d\n", buf1[0], buf2[0], did_read); + //write_log ("G %02X %02X %d\n", buf1[0], buf2[0], did_read); return buf2[0]; } @@ -304,7 +304,7 @@ void catweasel_do_bput (uaecptr addr, uae_u32 b) } else { ioport_write (cwc.iobase + addr, b); } - //write_log ("P %02.2X %02.2X %d\n", (uae_u8)addr, (uae_u8)b, did_read); + //write_log ("P %02X %02X %d\n", (uae_u8)addr, (uae_u8)b, did_read); } #include "core.cw4.c" diff --git a/cdtv.c b/cdtv.c index 26ef5c4b..84c889d0 100755 --- a/cdtv.c +++ b/cdtv.c @@ -416,12 +416,12 @@ static void cdrom_command_accepted (int size, uae_u8 *cdrom_command_input, int * #ifdef CDTV_DEBUG_CMD tmp[0] = 0; for (i = 0; i < *cdrom_command_cnt_in; i++) - sprintf(tmp + i * 3, "%02.2X%c", cdrom_command_input[i], i < *cdrom_command_cnt_in - 1 ? '.' : ' '); + sprintf(tmp + i * 3, "%02X%c", cdrom_command_input[i], i < *cdrom_command_cnt_in - 1 ? '.' : ' '); write_log ("CD<-: %s\n", tmp); if (size > 0) { tmp[0] = 0; for (i = 0; i < size; i++) - sprintf(tmp + i * 3, "%02.2X%c", cdrom_command_output[i], i < size - 1 ? '.' : ' '); + sprintf(tmp + i * 3, "%02X%c", cdrom_command_output[i], i < size - 1 ? '.' : ' '); write_log ("CD->: %s\n", tmp); } #endif @@ -552,7 +552,7 @@ static void cdrom_command_thread (uae_u8 b) } break; default: - write_log ("unknown CDROM command %02.2X!\n", s[0]); + write_log ("unknown CDROM command %02X!\n", s[0]); cd_error = 1; cdrom_command_accepted (0, s, &cdrom_command_cnt_in); break; @@ -617,7 +617,7 @@ static void dma_do_thread(void) if (!cdtv_sectorsize) return; cnt = dmac_wtc; - write_log ("DMAC DMA: sector=%d, addr=%08.8X, words=%d (of %d)\n", + write_log ("DMAC DMA: sector=%d, addr=%08X, words=%d (of %d)\n", cdrom_offset / cdtv_sectorsize, dmac_acr, cnt, cdrom_length / 2); dma_wait += cnt * (uae_u64)312 * 50 / 75 + 1; while (cnt > 0 && dmac_dma) { @@ -728,7 +728,7 @@ static void tp_bput (int addr, uae_u8 v) { static int volstrobe1, volstrobe2; #ifdef CDTV_DEBUG_6525 - write_log ("6525 write %x=%02.2X PC=%x\n", addr, v, M68K_GETPC); + write_log ("6525 write %x=%02X PC=%x\n", addr, v, M68K_GETPC); #endif switch (addr) { @@ -824,7 +824,7 @@ static uae_u8 tp_bget(int addr) #ifdef CDTV_DEBUG_6525 if (addr < 7) - write_log ("6525 read %x=%02.2X PC=%x\n", addr, v, M68K_GETPC); + write_log ("6525 read %x=%02X PC=%x\n", addr, v, M68K_GETPC); #endif return v; } @@ -1080,7 +1080,7 @@ static uae_u32 dmac_bget2 (uaecptr addr) #ifdef CDTV_DEBUG if (addr != 0x41) - write_log ("dmac_bget %04.4X=%02.2X PC=%08.8X\n", addr, v, M68K_GETPC); + write_log ("dmac_bget %04X=%02X PC=%08X\n", addr, v, M68K_GETPC); #endif return v; @@ -1094,7 +1094,7 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b) } #ifdef CDTV_DEBUG - write_log ("dmac_bput %04.4X=%02.2X PC=%08.8X\n", addr, b & 255, M68K_GETPC); + write_log ("dmac_bput %04X=%02X PC=%08X\n", addr, b & 255, M68K_GETPC); #endif switch (addr) @@ -1195,7 +1195,7 @@ static uae_u32 REGPARAM2 dmac_lget (uaecptr addr) v = (dmac_bget2 (addr) << 24) | (dmac_bget2 (addr + 1) << 16) | (dmac_bget2 (addr + 2) << 8) | (dmac_bget2 (addr + 3)); #ifdef CDTV_DEBUG - write_log ("dmac_lget %08.8X=%08.8X PC=%08.8X\n", addr, v, M68K_GETPC); + write_log ("dmac_lget %08X=%08X PC=%08X\n", addr, v, M68K_GETPC); #endif return v; } @@ -1209,7 +1209,7 @@ static uae_u32 REGPARAM2 dmac_wget (uaecptr addr) addr &= 65535; v = (dmac_bget2 (addr) << 8) | dmac_bget2 (addr + 1); #ifdef CDTV_DEBUG - write_log ("dmac_wget %08.8X=%04.4X PC=%08.8X\n", addr, v, M68K_GETPC); + write_log ("dmac_wget %08X=%04X PC=%08X\n", addr, v, M68K_GETPC); #endif return v; } @@ -1234,7 +1234,7 @@ static void REGPARAM2 dmac_lput (uaecptr addr, uae_u32 l) #endif addr &= 65535; #ifdef CDTV_DEBUG - write_log ("dmac_lput %08.8X=%08.8X PC=%08.8X\n", addr, l, M68K_GETPC); + write_log ("dmac_lput %08X=%08X PC=%08X\n", addr, l, M68K_GETPC); #endif dmac_bput2 (addr, l >> 24); dmac_bput2 (addr + 1, l >> 16); @@ -1249,7 +1249,7 @@ static void REGPARAM2 dmac_wput (uaecptr addr, uae_u32 w) #endif addr &= 65535; #ifdef CDTV_DEBUG - write_log ("dmac_wput %04.4X=%04.4X PC=%08.8X\n", addr, w & 65535, M68K_GETPC); + write_log ("dmac_wput %04X=%04X PC=%08X\n", addr, w & 65535, M68K_GETPC); #endif dmac_bput2 (addr, w >> 8); dmac_bput2 (addr + 1, w); diff --git a/cfgfile.c b/cfgfile.c index 41f08406..4c879b27 100755 --- a/cfgfile.c +++ b/cfgfile.c @@ -165,10 +165,10 @@ static const char *maxvert[] = { "nointerlace", "interlace", 0 }; static const char *obsolete[] = { "accuracy", "gfx_opengl", "gfx_32bit_blits", "32bit_blits", "gfx_immediate_blits", "gfx_ntsc", "win32", "gfx_filter_bits", - "sound_pri_cutoff", "sound_pri_time", "sound_min_buff", + "sound_pri_cutoff", "sound_pri_time", "sound_min_buff", "sound_bits", "gfx_test_speed", "gfxlib_replacement", "enforcer", "catweasel_io", "kickstart_key_file", "fast_copper", "sound_adjust", - "serial_hardware_dtrdsr", "gfx_filter_upscale", + "serial_hardware_dtrdsr", "gfx_filter_upscale", 0 }; @@ -431,7 +431,6 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write (f, "sana2=%s\n", p->sana2 ? "true" : "false"); cfgfile_write (f, "sound_output=%s\n", soundmode1[p->produce_sound]); - cfgfile_write (f, "sound_bits=%d\n", p->sound_bits); cfgfile_write (f, "sound_channels=%s\n", stereomode[p->sound_stereo]); cfgfile_write (f, "sound_stereo_separation=%d\n", p->sound_stereo_separation); cfgfile_write (f, "sound_stereo_mixing_delay=%d\n", p->sound_mixed_stereo_delay >= 0 ? p->sound_mixed_stereo_delay : 0); @@ -857,7 +856,6 @@ static int cfgfile_parse_host (struct uae_prefs *p, char *option, char *value) if (cfgfile_intval (option, value, "sound_latency", &p->sound_latency, 1) || cfgfile_intval (option, value, "sound_max_buff", &p->sound_maxbsiz, 1) - || cfgfile_intval (option, value, "sound_bits", &p->sound_bits, 1) || cfgfile_intval (option, value, "state_replay_rate", &p->statecapturerate, 1) || cfgfile_intval (option, value, "state_replay_buffer", &p->statecapturebuffersize, 1) || cfgfile_intval (option, value, "sound_frequency", &p->sound_freq, 1) @@ -2081,8 +2079,6 @@ static void parse_sound_spec (struct uae_prefs *p, char *spec) else p->sound_stereo = SND_MONO; } - if (x2) - p->sound_bits = atoi (x2); if (x3) p->sound_freq = atoi (x3); if (x4) @@ -2844,7 +2840,6 @@ void default_prefs (struct uae_prefs *p, int type) p->sound_stereo = SND_STEREO; p->sound_stereo_separation = 7; p->sound_mixed_stereo_delay = 0; - p->sound_bits = DEFAULT_SOUND_BITS; p->sound_freq = DEFAULT_SOUND_FREQ; p->sound_maxbsiz = DEFAULT_SOUND_MAXB; p->sound_latency = 100; diff --git a/cia.c b/cia.c index b33eb17b..98ceaa83 100755 --- a/cia.c +++ b/cia.c @@ -520,7 +520,7 @@ void CIA_vsync_handler (void) if (tod_hack_delay == 0) { tod_hack_reset (); tod_hack_delay = 0; - write_log ("TOD_HACK re-initialized CIATOD=%06.6X\n", ciaatod); + write_log ("TOD_HACK re-initialized CIATOD=%06X\n", ciaatod); } } if (tod_hack_delay == 0) { @@ -573,7 +573,7 @@ static uae_u8 ReadCIAA (unsigned int addr) compute_passed_time (); #ifdef CIAA_DEBUG_R - write_log ("R_CIAA: bfe%x01 %08.8X\n", addr, M68K_GETPC); + write_log ("R_CIAA: bfe%x01 %08X\n", addr, M68K_GETPC); #endif switch (addr & 0xf) { @@ -590,7 +590,7 @@ static uae_u8 ReadCIAA (unsigned int addr) tmp = (tmp & ~0x80) | (ciaapra & 0x80); #ifdef DONGLE_DEBUG if (notinrom()) - write_log ("BFE001 R %02.2X %s\n", tmp, debuginfo(0)); + write_log ("BFE001 R %02X %s\n", tmp, debuginfo(0)); #endif return tmp; case 1: @@ -611,7 +611,7 @@ static uae_u8 ReadCIAA (unsigned int addr) tmp = handle_parport_joystick (0, ciaaprb, ciaadrb); #ifdef DONGLE_DEBUG if (notinrom()) - write_log ("BFE101 R %02.2X %s\n", tmp, debuginfo(0)); + write_log ("BFE101 R %02X %s\n", tmp, debuginfo(0)); #endif } if (ciaacrb & 2) { @@ -632,13 +632,13 @@ static uae_u8 ReadCIAA (unsigned int addr) case 2: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFE201 R %02.2X %s\n", ciaadra, debuginfo(0)); + write_log ("BFE201 R %02X %s\n", ciaadra, debuginfo(0)); #endif return ciaadra; case 3: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFE301 R %02.2X %s\n", ciaadrb, debuginfo(0)); + write_log ("BFE301 R %02X %s\n", ciaadrb, debuginfo(0)); #endif return ciaadrb; case 4: @@ -689,7 +689,7 @@ static uae_u8 ReadCIAB (unsigned int addr) #ifdef CIAB_DEBUG_R if (addr >= 8 && addr <= 10) - write_log ("R_CIAB: bfd%x00 %08.8X\n", addr, M68K_GETPC); + write_log ("R_CIAB: bfd%x00 %08X\n", addr, M68K_GETPC); #endif compute_passed_time (); @@ -714,13 +714,13 @@ static uae_u8 ReadCIAB (unsigned int addr) #endif #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFD000 R %02.2X %s\n", tmp, debuginfo(0)); + write_log ("BFD000 R %02X %s\n", tmp, debuginfo(0)); #endif return tmp; case 1: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFD100 R %02.2X %s\n", ciabprb, debuginfo(0)); + write_log ("BFD100 R %02X %s\n", ciabprb, debuginfo(0)); #endif tmp = ciabprb; if (ciabcrb & 2) { @@ -785,7 +785,7 @@ static uae_u8 ReadCIAB (unsigned int addr) static void WriteCIAA (uae_u16 addr,uae_u8 val) { #ifdef CIAA_DEBUG_W - write_log ("W_CIAA: bfe%x01 %02.2X %08.8X\n", addr, val, M68K_GETPC); + write_log ("W_CIAA: bfe%x01 %02X %08X\n", addr, val, M68K_GETPC); #endif #ifdef ACTION_REPLAY ar_ciaa[addr & 0xf] = val; @@ -798,7 +798,7 @@ static void WriteCIAA (uae_u16 addr,uae_u8 val) case 0: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFE001 W %02.2X %s\n", val, debuginfo(0)); + write_log ("BFE001 W %02X %s\n", val, debuginfo(0)); #endif ciaapra = (ciaapra & ~0xc3) | (val & 0xc3); bfe001_change (); @@ -811,7 +811,7 @@ static void WriteCIAA (uae_u16 addr,uae_u8 val) case 1: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFE101 W %02.2X %s\n", val, debuginfo(0)); + write_log ("BFE101 W %02X %s\n", val, debuginfo(0)); #endif ciaaprb = val; #ifdef PARALLEL_PORT @@ -831,14 +831,14 @@ static void WriteCIAA (uae_u16 addr,uae_u8 val) case 2: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFE201 W %02.2X %s\n", val, debuginfo(0)); + write_log ("BFE201 W %02X %s\n", val, debuginfo(0)); #endif ciaadra = val; bfe001_change (); break; case 3: ciaadrb = val; #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFE301 W %02.2X %s\n", val, debuginfo(0)); + write_log ("BFE301 W %02X %s\n", val, debuginfo(0)); #endif #ifdef ARCADIA if (arcadia_bios) @@ -948,7 +948,7 @@ static void WriteCIAB (uae_u16 addr,uae_u8 val) { #ifdef CIAB_DEBUG_W if (addr >= 8 && addr <= 10) - write_log ("W_CIAB: bfd%x00 %02.2X %08.8X\n", addr, val, M68K_GETPC); + write_log ("W_CIAB: bfd%x00 %02X %08X\n", addr, val, M68K_GETPC); #endif #ifdef ACTION_REPLAY ar_ciab[addr & 0xf] = val; @@ -957,7 +957,7 @@ static void WriteCIAB (uae_u16 addr,uae_u8 val) case 0: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFD000 W %02.2X %s\n", val, debuginfo(0)); + write_log ("BFD000 W %02X %s\n", val, debuginfo(0)); #endif ciabpra = val; #ifdef SERIAL_PORT @@ -972,13 +972,13 @@ static void WriteCIAB (uae_u16 addr,uae_u8 val) case 1: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFD100 W %02.2X %s\n", val, debuginfo(0)); + write_log ("BFD100 W %02X %s\n", val, debuginfo(0)); #endif ciabprb = val; DISK_select(val); break; case 2: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFD200 W %02.2X %s\n", val, debuginfo(0)); + write_log ("BFD200 W %02X %s\n", val, debuginfo(0)); #endif ciabdra = val; #ifdef SERIAL_PORT @@ -989,7 +989,7 @@ static void WriteCIAB (uae_u16 addr,uae_u8 val) case 3: #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("BFD300 W %02.2X %s\n", val, debuginfo(0)); + write_log ("BFD300 W %02X %s\n", val, debuginfo(0)); #endif ciabdrb = val; break; case 4: diff --git a/custom.c b/custom.c index 6ce16b9d..a283a099 100755 --- a/custom.c +++ b/custom.c @@ -1878,7 +1878,7 @@ static void do_sprite_collisions (void) { static int olx; if (clxdat != olx) - write_log ("%d: %04.4X\n", vpos, clxdat); + write_log ("%d: %04X\n", vpos, clxdat); olx = clxdat; } #endif @@ -2350,10 +2350,10 @@ static void dumpsync (void) if (cnt < 0) return; cnt--; - write_log ("BEAMCON0=%04.4X VTOTAL=%04.4X HTOTAL=%04.4X\n", new_beamcon0, vtotal, htotal); - write_log ("HSSTOP=%04.4X HBSTRT=%04.4X HBSTOP=%04.4X\n", hsstop, hbstrt, hbstop); - write_log ("VSSTOP=%04.4X VBSTRT=%04.4X VBSTOP=%04.4X\n", vsstop, vbstrt, vbstop); - write_log ("HSSTRT=%04.4X VSSTRT=%04.4X HCENTER=%04.4X\n", hsstrt, vsstrt, hcenter); + write_log ("BEAMCON0=%04X VTOTAL=%04X HTOTAL=%04X\n", new_beamcon0, vtotal, htotal); + write_log ("HSSTOP=%04X HBSTRT=%04X HBSTOP=%04X\n", hsstop, hbstrt, hbstop); + write_log ("VSSTOP=%04X VBSTRT=%04X VBSTOP=%04X\n", vsstop, vbstrt, vbstop); + write_log ("HSSTRT=%04X VSSTRT=%04X HCENTER=%04X\n", hsstrt, vsstrt, hcenter); } /* set PAL/NTSC or custom timing variables */ @@ -2608,8 +2608,15 @@ STATIC_INLINE uae_u16 VHPOSR (void) { uae_u16 vp = GETVPOS (); uae_u16 hp = GETHPOS (); + hp++; // hack.. + if (hp >= maxhpos) { + hp -= maxhpos; + vp++; + if (vp >= maxvpos) + vp = 0; + } vp <<= 8; - vp |= hp ^ 1; // hack.. + vp |= hp; if (currprefs.cpu_model >= 68020) hsyncdelay (); return vp; @@ -2804,7 +2811,7 @@ STATIC_INLINE void INTENA (uae_u16 v) setclr (&intena,v); #if 0 if (v & 0x40) - write_log ("INTENA %04.4X (%04.4X) %p\n", intena, v, M68K_GETPC); + write_log ("INTENA %04X (%04X) %p\n", intena, v, M68K_GETPC); #endif if (v & 0x8000) { if (!use_eventmode()) @@ -2879,7 +2886,7 @@ static void BEAMCON0 (uae_u16 v) if (v != new_beamcon0) { new_beamcon0 = v; if (v & ~0x20) - write_log ("warning: %04.4X written to BEAMCON0\n", v); + write_log ("warning: %04X written to BEAMCON0\n", v); } } } @@ -2934,7 +2941,7 @@ static void BPLxPTH (int hpos, uae_u16 v, int num) decide_line (hpos); decide_fetch (hpos); bplpt[num] = (bplpt[num] & 0xffff) | ((uae_u32)v << 16); - //write_log ("%d:%d:BPL%dPTH %08.8X\n", hpos, vpos, num, v); + //write_log ("%d:%d:BPL%dPTH %08X\n", hpos, vpos, num, v); } static void BPLxPTL (int hpos, uae_u16 v, int num) { @@ -2946,7 +2953,7 @@ static void BPLxPTL (int hpos, uae_u16 v, int num) if (is_bitplane_dma(hpos - 1) == num + 1 && num > 0) delta = 2 << fetchmode; bplpt[num] = (bplpt[num] & ~0xffff) | ((v + delta) & 0xfffe); - //write_log ("%d:%d:BPL%dPTL %08.8X\n", hpos, vpos, num, v); + //write_log ("%d:%d:BPL%dPTL %08X\n", hpos, vpos, num, v); } static void BPLCON0_do (int hpos, uae_u16 v) @@ -3378,7 +3385,7 @@ STATIC_INLINE void SPRxCTL_1 (uae_u16 v, int num, int hpos) SPRxCTLPOS (num); #if SPRITE_DEBUG > 0 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dCTL %04.4X P=%06.6X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n", + write_log ("%d:%d:SPR%dCTL %04X P=%06X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n", vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, M68K_GETPC); } #endif @@ -3391,7 +3398,7 @@ STATIC_INLINE void SPRxPOS_1 (uae_u16 v, int num, int hpos) SPRxCTLPOS (num); #if SPRITE_DEBUG > 0 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dPOS %04.4X P=%06.6X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n", + write_log ("%d:%d:SPR%dPOS %04X P=%06X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n", vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, M68K_GETPC); } #endif @@ -3407,7 +3414,7 @@ STATIC_INLINE void SPRxDATA_1 (uae_u16 v, int num, int hpos) spr_arm (num, 1); #if SPRITE_DEBUG > 1 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dDATA %04.4X P=%06.6X D=%d A=%d PC=%x\n", + write_log ("%d:%d:SPR%dDATA %04X P=%06X D=%d A=%d PC=%x\n", vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, M68K_GETPC); } #endif @@ -3422,7 +3429,7 @@ STATIC_INLINE void SPRxDATB_1 (uae_u16 v, int num, int hpos) #endif #if SPRITE_DEBUG > 1 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dDATB %04.4X P=%06.6X D=%d A=%d PC=%x\n", + write_log ("%d:%d:SPR%dDATB %04X P=%06X D=%d A=%d PC=%x\n", vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, M68K_GETPC); } #endif @@ -3438,7 +3445,7 @@ static void SPRxPTH (int hpos, uae_u16 v, int num) spr[num].pt |= (uae_u32)v << 16; #if SPRITE_DEBUG > 0 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dPTH %06.6X\n", vpos, hpos, num, spr[num].pt); + write_log ("%d:%d:SPR%dPTH %06X\n", vpos, hpos, num, spr[num].pt); } #endif } @@ -3449,7 +3456,7 @@ static void SPRxPTL (int hpos, uae_u16 v, int num) spr[num].pt |= v; #if SPRITE_DEBUG > 0 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dPTL %06.6X\n", vpos, hpos, num, spr[num].pt); + write_log ("%d:%d:SPR%dPTL %06X\n", vpos, hpos, num, spr[num].pt); } #endif } @@ -3492,7 +3499,7 @@ void dump_aga_custom (void) rgb2 = current_colors.color_regs_aga[c2] | (color_regs_aga_genlock[c2] << 31); rgb3 = current_colors.color_regs_aga[c3] | (color_regs_aga_genlock[c3] << 31); rgb4 = current_colors.color_regs_aga[c4] | (color_regs_aga_genlock[c4] << 31); - console_out_f ("%3d %08.8X %3d %08.8X %3d %08.8X %3d %08.8X\n", + console_out_f ("%3d %08X %3d %08X %3d %08X %3d %08X\n", c1, rgb1, c2, rgb2, c3, rgb3, c4, rgb4); } } @@ -3661,7 +3668,7 @@ static void perform_copper_write (int old_hpos) cop_state.last_write_hpos = old_hpos; old_hpos++; if (!nocustom () && cop_state.saved_i1 >= 0x140 && cop_state.saved_i1 < 0x180 && old_hpos >= SPR0_HPOS && old_hpos < SPR0_HPOS + 4 * MAX_SPRITES) { - //write_log ("%d:%d %04.4X:%04.4X\n", vpos, old_hpos, cop_state.saved_i1, cop_state.saved_i2); + //write_log ("%d:%d %04X:%04X\n", vpos, old_hpos, cop_state.saved_i1, cop_state.saved_i2); do_sprites (old_hpos); } } @@ -3691,7 +3698,7 @@ static void dump_copper (char *error, int until_hpos) { write_log ("%s: vpos=%d until_hpos=%d\n", error, vpos, until_hpos); - write_log ("cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04.4X ci2=%04.4X\n", + write_log ("cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04X ci2=%04X\n", cop_state.vcmp,cop_state.hcmp,cop_state.hpos,cop_state.vpos,cop_state.saved_i1,cop_state.saved_i2); write_log ("cstate=%d ip=%x SPCFLAGS=%x\n", cop_state.state, cop_state.ip, regs.spcflags); @@ -4055,10 +4062,10 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) } #if SPRITE_DEBUG > 1 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:dma:P=%06.6X ", vpos, hpos, s->pt); + write_log ("%d:%d:dma:P=%06X ", vpos, hpos, s->pt); } #endif - //write_log ("%d:%d: %04.4X=%04.4X\n", vpos, hpos, 0x140 + cycle * 2 + num * 8, data); + //write_log ("%d:%d: %04X=%04X\n", vpos, hpos, 0x140 + cycle * 2 + num * 8, data); if (cycle == 0) { SPRxPOS_1 (data, num, hpos); s->dmacycle = 1; @@ -4074,7 +4081,7 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) data = sprite_fetch (s, dma, hpos, cycle, 1); #if SPRITE_DEBUG > 1 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:dma:P=%06.6X ", vpos, hpos, s->pt); + write_log ("%d:%d:dma:P=%06X ", vpos, hpos, s->pt); } #endif if (cycle == 0) { @@ -4404,10 +4411,6 @@ static void vsync_handler (void) #ifdef PICASSO96 picasso_handle_vsync (); #endif - { - void ahi_vsync (void); - ahi_vsync (); - } if (quit_program > 0) { /* prevent possible infinite loop at wait_cycles().. */ @@ -4572,6 +4575,10 @@ static void hsync_handler (void) #ifdef PICASSO96 picasso_handle_hsync (); #endif + { + void ahi_hsync (void); + ahi_hsync (); + } if ((currprefs.chipset_mask & CSMASK_AGA) || (!currprefs.chipset_mask & CSMASK_ECS_AGNUS)) last_custom_value = uaerand (); @@ -5161,7 +5168,7 @@ STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (uaecptr addr, int noput) #endif addr &= 0xfff; #ifdef CUSTOM_DEBUG - write_log ("%d:%d:wget: %04.4X=%04.4X pc=%p\n", current_hpos(), vpos, addr, addr & 0x1fe, m68k_getpc ()); + write_log ("%d:%d:wget: %04X=%04X pc=%p\n", current_hpos(), vpos, addr, addr & 0x1fe, m68k_getpc ()); #endif switch (addr & 0x1fe) { case 0x002: v = DMACONR (); break; @@ -5468,7 +5475,7 @@ static void REGPARAM2 custom_wput (uaecptr addr, uae_u32 value) special_mem |= S_WRITE; #endif #ifdef CUSTOM_DEBUG - write_log ("%d:%d:wput: %04.4X %04.4X pc=%p\n", hpos, vpos, addr & 0x01fe, value & 0xffff, m68k_getpc ()); + write_log ("%d:%d:wput: %04X %04X pc=%p\n", hpos, vpos, addr & 0x01fe, value & 0xffff, m68k_getpc ()); #endif sync_copper_with_cpu (hpos, 1); if (addr & 1) { @@ -5498,7 +5505,7 @@ static void REGPARAM2 custom_bput (uaecptr addr, uae_u32 value) } if (warned < 10) { if (M68K_GETPC < 0xe00000 || M68K_GETPC >= 0x10000000) { - write_log ("Byte put to custom register %04.4X PC=%08.8X\n", addr, M68K_GETPC); + write_log ("Byte put to custom register %04X PC=%08X\n", addr, M68K_GETPC); warned++; } } diff --git a/custom2.c b/custom2.c deleted file mode 100755 index d5f399ad..00000000 --- a/custom2.c +++ /dev/null @@ -1,5755 +0,0 @@ - /* - * UAE - The Un*x Amiga Emulator - * - * Custom chip emulation - * - * Copyright 1995-2002 Bernd Schmidt - * Copyright 1995 Alessandro Bissacco - * Copyright 2000-2004 Toni Wilen - */ - -//#define CUSTOM_DEBUG -#define DEBUG_COPPER 0 -#define SPRITE_DEBUG 0 -#define SPRITE_DEBUG_MINY 0 -#define SPRITE_DEBUG_MAXY 100 -//#define SPRITE_MASK 0 -#define SPRITE_MASK (1|2|4|8|16|32|64|128) -#define SPR0_HPOS 0x15 -#define MAX_SPRITES 8 -#define SPRITE_COLLISIONS -#define SPEEDUP - -#include "sysconfig.h" -#include "sysdeps.h" - -#include -#include - -#include "config.h" -#include "options.h" -#include "threaddep/thread.h" -#include "uae.h" -#include "gensound.h" -#include "sounddep/sound.h" -#include "events.h" -#include "memory.h" -#include "custom.h" -#include "newcpu.h" -#include "cia.h" -#include "disk.h" -#include "blitter.h" -#include "xwin.h" -#include "inputdevice.h" -#include "audio.h" -#include "keybuf.h" -#include "serial.h" -#include "osemu.h" -#include "autoconf.h" -#include "gui.h" -#include "picasso96.h" -#include "drawing.h" -#include "savestate.h" -#include "ar.h" -#include "avioutput.h" -#include "debug.h" -#include "akiko.h" -#if defined(ENFORCER) -#include "enforcer.h" -#endif - -void uae_abort (const char *format,...) -{ - static int nomore; - va_list parms; - char buffer[1000]; - - va_start (parms, format); - _vsnprintf( buffer, sizeof (buffer) -1, format, parms ); - va_end (parms); - if (nomore) { - write_log (buffer); - return; - } - gui_message (buffer); - nomore = 1; -} - -#if 0 -void customhack_put (struct customhack *ch, uae_u16 v, int hpos) -{ - ch->v = v; - ch->vpos = vpos; - ch->hpos = hpos; -} - -uae_u16 customhack_get (struct customhack *ch, int hpos) -{ - if (ch->vpos == vpos && ch->hpos == hpos) { - ch->vpos = -1; - return 0xffff; - } - return ch->v; -} -#endif - -static uae_u16 last_custom_value; - -static unsigned int n_consecutive_skipped = 0; -static unsigned int total_skipped = 0; - -STATIC_INLINE void sync_copper (int hpos); - -/* Events */ - -unsigned long int event_cycles, nextevent, is_lastline, currcycle; -long cycles_to_next_event; -long max_cycles_to_next_event; -long cycles_to_hsync_event; - -static int rpt_did_reset; -struct ev eventtab[ev_max]; - -volatile frame_time_t vsynctime, vsyncmintime; - -#ifdef JIT -extern uae_u8* compiled_code; -#endif - -int vpos; -int hack_vpos; -static uae_u16 lof; -static int next_lineno; -static enum nln_how nextline_how; -static int lof_changed = 0; - -static uae_u32 sprtaba[256],sprtabb[256]; -static uae_u32 sprite_ab_merge[256]; -/* Tables for collision detection. */ -static uae_u32 sprclx[16], clxmask[16]; - -/* - * Hardware registers of all sorts. - */ - -static int custom_wput_1 (int, uaecptr, uae_u32, int) REGPARAM; - -static uae_u16 cregs[256]; - -uae_u16 intena,intreq; -uae_u16 dmacon; -uae_u16 adkcon; /* used by audio code */ - -static uae_u32 cop1lc,cop2lc,copcon; - -int maxhpos = MAXHPOS_PAL; -int maxvpos = MAXVPOS_PAL; -int minfirstline = VBLANK_ENDLINE_PAL; -int vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_skip; -unsigned long syncbase; -static int fmode; -unsigned int beamcon0, new_beamcon0; -uae_u16 vtotal = MAXVPOS_PAL, htotal = MAXHPOS_PAL; -static uae_u16 hsstop, hbstrt, hbstop, vsstop, vbstrt, vbstop, hsstrt, vsstrt, hcenter; - -#define HSYNCTIME (maxhpos * CYCLE_UNIT); - -/* This is but an educated guess. It seems to be correct, but this stuff - * isn't documented well. */ -struct sprite { - uaecptr pt; - int xpos; - int vstart; - int vstop; - int armed; - int dmastate; - int dmacycle; -}; - -static struct sprite spr[MAX_SPRITES]; - -static int sprite_vblank_endline = VBLANK_SPRITE_PAL; - -static unsigned int sprctl[MAX_SPRITES], sprpos[MAX_SPRITES]; -#ifdef AGA -static uae_u16 sprdata[MAX_SPRITES][4], sprdatb[MAX_SPRITES][4]; -#else -static uae_u16 sprdata[MAX_SPRITES][1], sprdatb[MAX_SPRITES][1]; -#endif -static int sprite_last_drawn_at[MAX_SPRITES]; -static int last_sprite_point, nr_armed; -static int sprite_width, sprres, sprite_buffer_res; - -#ifdef CPUEMU_6 -uae_u8 cycle_line[256]; -#endif - -static uae_u32 bpl1dat; -#if 0 /* useless */ -static uae_u32 bpl2dat, bpl3dat, bpl4dat, bpl5dat, bpl6dat, bpl7dat, bpl8dat; -#endif -static uae_s16 bpl1mod, bpl2mod; - -static uaecptr bplpt[8]; -uae_u8 *real_bplpt[8]; -/* Used as a debugging aid, to offset any bitplane temporarily. */ -int bpl_off[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -/*static int blitcount[256]; blitter debug */ - -static struct color_entry current_colors; -static unsigned int bplcon0, bplcon1, bplcon2, bplcon3, bplcon4; -static unsigned int diwstrt, diwstop, diwhigh; -static int diwhigh_written; -static unsigned int ddfstrt, ddfstop, ddfstrt_old_hpos, ddfstrt_old_vpos; -static int ddf_change; -static unsigned int bplcon0_at_start; - -/* The display and data fetch windows */ - -enum diw_states -{ - DIW_waiting_start, DIW_waiting_stop -}; - -int plffirstline, plflastline; -int plfstrt, plfstop; -static int last_diw_pix_hpos, last_ddf_pix_hpos; -static int last_decide_line_hpos, last_sprite_decide_line_hpos; -static int last_fetch_hpos, last_sprite_hpos; -int diwfirstword, diwlastword; -static enum diw_states diwstate, hdiwstate, ddfstate; - -/* Sprite collisions */ -static unsigned int clxdat, clxcon, clxcon2, clxcon_bpl_enable, clxcon_bpl_match; - -enum copper_states { - COP_stop, - COP_read1_in2, - COP_read1_wr_in4, - COP_read1_wr_in2, - COP_read1, - COP_read2_wr_in2, - COP_read2, - COP_bltwait, - COP_wait_in4, - COP_wait_in2, - COP_skip_in4, - COP_skip_in2, - COP_wait1, - COP_wait, - COP_skip1, - COP_strobe_delay -}; - -struct copper { - /* The current instruction words. */ - unsigned int i1, i2; - unsigned int saved_i1, saved_i2; - enum copper_states state; - /* Instruction pointer. */ - uaecptr ip, saved_ip; - int hpos, vpos; - unsigned int ignore_next; - int vcmp, hcmp; - - /* When we schedule a copper event, knowing a few things about the future - of the copper list can reduce the number of sync_with_cpu calls - dramatically. */ - unsigned int first_sync; - unsigned int regtypes_modified; - int strobe; /* COPJMP1 / COPJMP2 accessed */ - int last_write, last_write_hpos; -}; - -#define REGTYPE_NONE 0 -#define REGTYPE_COLOR 1 -#define REGTYPE_SPRITE 2 -#define REGTYPE_PLANE 4 -#define REGTYPE_BLITTER 8 -#define REGTYPE_JOYPORT 16 -#define REGTYPE_DISK 32 -#define REGTYPE_POS 64 -#define REGTYPE_AUDIO 128 - -#define REGTYPE_ALL 255 -/* Always set in regtypes_modified, to enable a forced update when things like - DMACON, BPLCON0, COPJMPx get written. */ -#define REGTYPE_FORCE 256 - - -static unsigned int regtypes[512]; - -static struct copper cop_state; -static int copper_enabled_thisline; -static int cop_min_waittime; - -/* - * Statistics - */ - -/* Used also by bebox.cpp */ -unsigned long int frametime = 0, lastframetime = 0, timeframes = 0, hsync_counter = 0; -unsigned long int idletime; -int bogusframe; - -#if DEBUG_COPPER -/* 10000 isn't enough! */ -#define NR_COPPER_RECORDS 40000 -#else -#define NR_COPPER_RECORDS 1 -#endif - -/* Record copper activity for the debugger. */ -struct cop_record -{ - int hpos, vpos; - uaecptr addr; -}; -static struct cop_record cop_record[2][NR_COPPER_RECORDS]; -static int nr_cop_records[2]; -static int curr_cop_set; - -/* Recording of custom chip register changes. */ -static int current_change_set; - -#ifdef OS_WITHOUT_MEMORY_MANAGEMENT -/* sam: Those arrays uses around 7Mb of BSS... That seems */ -/* too much for AmigaDOS (uae crashes as soon as one loads */ -/* it. So I use a different strategy here (realloc the */ -/* arrays when needed. That strategy might be usefull for */ -/* computer with low memory. */ -struct sprite_entry *sprite_entries[2]; -struct color_change *color_changes[2]; -static int max_sprite_entry = 400; -static int delta_sprite_entry = 0; -static int max_color_change = 400; -static int delta_color_change = 0; -#else -struct sprite_entry sprite_entries[2][MAX_SPR_PIXELS / 16]; -struct color_change color_changes[2][MAX_REG_CHANGE]; -#endif - -struct decision line_decisions[2 * (MAXVPOS + 1) + 1]; -struct draw_info line_drawinfo[2][2 * (MAXVPOS + 1) + 1]; -struct color_entry color_tables[2][(MAXVPOS + 1) * 2]; - -static int next_sprite_entry = 0; -static int prev_next_sprite_entry; -static int next_sprite_forced = 1; - -struct sprite_entry *curr_sprite_entries, *prev_sprite_entries; -struct color_change *curr_color_changes, *prev_color_changes; -struct draw_info *curr_drawinfo, *prev_drawinfo; -struct color_entry *curr_color_tables, *prev_color_tables; - -static int next_color_change; -static int next_color_entry, remembered_color_entry; -static int color_src_match, color_dest_match, color_compare_result; - -static uae_u32 thisline_changed; - -#ifdef SMART_UPDATE -#define MARK_LINE_CHANGED do { thisline_changed = 1; } while (0) -#else -#define MARK_LINE_CHANGED do { ; } while (0) -#endif - -static struct decision thisline_decision; -static int passed_plfstop, fetch_cycle; - -enum fetchstate { - fetch_not_started, - fetch_started, - fetch_was_plane0 -} fetch_state; - -/* - * helper functions - */ - -STATIC_INLINE int nodraw (void) -{ - return !currprefs.cpu_cycle_exact && framecnt != 0; -} - -uae_u32 get_copper_address (int copno) -{ - switch (copno) { - case 1: return cop1lc; - case 2: return cop2lc; - default: return 0; - } -} - -STATIC_INLINE void record_copper (uaecptr addr, int hpos, int vpos) -{ -#if DEBUG_COPPER - int t = nr_cop_records[curr_cop_set]; - if (t < NR_COPPER_RECORDS) { - cop_record[curr_cop_set][t].addr = addr; - cop_record[curr_cop_set][t].hpos = hpos; - cop_record[curr_cop_set][t].vpos = vpos; - nr_cop_records[curr_cop_set] = t + 1; - } -#endif -} - -int find_copper_record (uaecptr addr, int *phpos, int *pvpos) -{ - int s = curr_cop_set ^ 1; - int t = nr_cop_records[s]; - int i; - for (i = 0; i < t; i++) { - if (cop_record[s][i].addr == addr) { - *phpos = cop_record[s][i].hpos; - *pvpos = cop_record[s][i].vpos; - return 1; - } - } - return 0; -} - -int rpt_available = 0; - -void reset_frame_rate_hack (void) -{ - if (currprefs.m68k_speed != -1) - return; - - if (! rpt_available) { - currprefs.m68k_speed = 0; - return; - } - - rpt_did_reset = 1; - is_lastline = 0; - vsyncmintime = read_processor_time() + vsynctime; - write_log ("Resetting frame rate hack\n"); -} - -STATIC_INLINE void setclr (uae_u16 *p, uae_u16 val) -{ - if (val & 0x8000) - *p |= val & 0x7FFF; - else - *p &= ~val; -} - -STATIC_INLINE int current_hpos (void) -{ - return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT; -} - -STATIC_INLINE uae_u8 *pfield_xlateptr (uaecptr plpt, int bytecount) -{ - if (!chipmem_bank.check (plpt, bytecount)) { - static int count = 0; - if (!count) - count++, write_log ("Warning: Bad playfield pointer\n"); - return NULL; - } - return chipmem_bank.xlateaddr (plpt); -} - -STATIC_INLINE void docols (struct color_entry *colentry) -{ - int i; - -#ifdef AGA - if (currprefs.chipset_mask & CSMASK_AGA) { - for (i = 0; i < 256; i++) { - int v = color_reg_get (colentry, i); - if (v < 0 || v > 16777215) - continue; - colentry->acolors[i] = CONVERT_RGB (v); - } - } else { -#endif - for (i = 0; i < 32; i++) { - int v = color_reg_get (colentry, i); - if (v < 0 || v > 4095) - continue; - colentry->acolors[i] = xcolors[v]; - } -#ifdef AGA - } -#endif -} - -void notice_new_xcolors (void) -{ - int i; - - docols(¤t_colors); -/* docols(&colors_for_drawing);*/ - for (i = 0; i < (MAXVPOS + 1)*2; i++) { - docols(color_tables[0]+i); - docols(color_tables[1]+i); - } -} - -static void do_sprites (int currhp); - -static void remember_ctable (void) -{ - if (remembered_color_entry == -1) { - /* The colors changed since we last recorded a color map. Record a - * new one. */ - color_reg_cpy (curr_color_tables + next_color_entry, ¤t_colors); - remembered_color_entry = next_color_entry++; - } - thisline_decision.ctable = remembered_color_entry; - if (color_src_match == -1 || color_dest_match != remembered_color_entry - || line_decisions[next_lineno].ctable != color_src_match) - { - /* The remembered comparison didn't help us - need to compare again. */ - int oldctable = line_decisions[next_lineno].ctable; - int changed = 0; - - if (oldctable == -1) { - changed = 1; - color_src_match = color_dest_match = -1; - } else { - color_compare_result = color_reg_cmp (&prev_color_tables[oldctable], ¤t_colors) != 0; - if (color_compare_result) - changed = 1; - color_src_match = oldctable; - color_dest_match = remembered_color_entry; - } - thisline_changed |= changed; - } else { - /* We know the result of the comparison */ - if (color_compare_result) - thisline_changed = 1; - } -} - -static void remember_ctable_for_border (void) -{ - remember_ctable (); -} - -/* Called to determine the state of the horizontal display window state - * machine at the current position. It might have changed since we last - * checked. */ -static void decide_diw (int hpos) -{ - int pix_hpos = coord_diw_to_window_x (hpos == 227 ? 455 : hpos * 2); /* (227.5*2 = 455) */ - if (hdiwstate == DIW_waiting_start && thisline_decision.diwfirstword == -1 - && pix_hpos >= diwfirstword && last_diw_pix_hpos < diwfirstword) - { - thisline_decision.diwfirstword = diwfirstword < 0 ? 0 : diwfirstword; - hdiwstate = DIW_waiting_stop; - } - if (hdiwstate == DIW_waiting_stop && thisline_decision.diwlastword == -1 - && pix_hpos >= diwlastword && last_diw_pix_hpos < diwlastword) - { - thisline_decision.diwlastword = diwlastword < 0 ? 0 : diwlastword; - hdiwstate = DIW_waiting_start; - } - last_diw_pix_hpos = pix_hpos; -} - -static int fetchmode; -static int maxplanes_ocs[]={ 6,4,0,0 }; -static int maxplanes_ecs[]={ 6,4,2,0 }; -static int maxplanes_aga[]={ 8,4,2,0, 8,8,4,0, 8,8,8,0 }; - -static int get_maxplanes (int res) -{ - int *planes; - if (currprefs.chipset_mask & CSMASK_AGA) - planes = maxplanes_aga; - else if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE)) - planes = maxplanes_ocs; - else - planes = maxplanes_ecs; - return planes[fetchmode * 4 + res]; -} - -/* Disable bitplane DMA if planes > maxplanes. This is needed e.g. by the - Sanity WOC demo (at the "Party Effect"). */ -STATIC_INLINE int GET_PLANES_LIMIT (uae_u16 v) -{ - if (GET_PLANES(v) > get_maxplanes (GET_RES(v))) - v &= ~0x7010; - return GET_PLANES (v); -} - -/* The HRM says 0xD8, but that can't work... */ -#define HARD_DDF_STOP 0xd4 -#define HARD_DDF_START 0x18 - -static void add_modulos (void) -{ - int m1, m2; - - if (fmode & 0x4000) { - if (((diwstrt >> 8) ^ vpos) & 1) - m1 = m2 = bpl2mod; - else - m1 = m2 = bpl1mod; - } else { - m1 = bpl1mod; - m2 = bpl2mod; - } - - switch (GET_PLANES_LIMIT (bplcon0)) { -#ifdef AGA - case 8: bplpt[7] += m2; - case 7: bplpt[6] += m1; -#endif - case 6: bplpt[5] += m2; - case 5: bplpt[4] += m1; - case 4: bplpt[3] += m2; - case 3: bplpt[2] += m1; - case 2: bplpt[1] += m2; - case 1: bplpt[0] += m1; - } -} - -static void finish_playfield_line (void) -{ - /* The latter condition might be able to happen in interlaced frames. */ - if (vpos >= minfirstline && (thisframe_first_drawn_line == -1 || vpos < thisframe_first_drawn_line)) - thisframe_first_drawn_line = vpos; - thisframe_last_drawn_line = vpos; - - /* These are for comparison. */ - thisline_decision.bplcon0 = bplcon0; - thisline_decision.bplcon2 = bplcon2; -#ifdef AGA - thisline_decision.bplcon3 = bplcon3; - thisline_decision.bplcon4 = bplcon4; -#endif - -#ifdef SMART_UPDATE - if (line_decisions[next_lineno].plflinelen != thisline_decision.plflinelen - || line_decisions[next_lineno].plfleft != thisline_decision.plfleft - || line_decisions[next_lineno].bplcon0 != thisline_decision.bplcon0 - || line_decisions[next_lineno].bplcon2 != thisline_decision.bplcon2 -#ifdef AGA - || line_decisions[next_lineno].bplcon3 != thisline_decision.bplcon3 - || line_decisions[next_lineno].bplcon4 != thisline_decision.bplcon4 -#endif - ) -#endif /* SMART_UPDATE */ - thisline_changed = 1; -} - -/* The fetch unit mainly controls ddf stop. It's the number of cycles that - are contained in an indivisible block during which ddf is active. E.g. - if DDF starts at 0x30, and fetchunit is 8, then possible DDF stops are - 0x30 + n * 8. */ -static int fetchunit, fetchunit_mask; -/* The delay before fetching the same bitplane again. Can be larger than - the number of bitplanes; in that case there are additional empty cycles - with no data fetch (this happens for high fetchmodes and low - resolutions). */ -static int fetchstart, fetchstart_shift, fetchstart_mask; -/* fm_maxplane holds the maximum number of planes possible with the current - fetch mode. This selects the cycle diagram: - 8 planes: 73516240 - 4 planes: 3120 - 2 planes: 10. */ -static int fm_maxplane, fm_maxplane_shift; - -/* The corresponding values, by fetchmode and display resolution. */ -static int fetchunits[] = { 8,8,8,0, 16,8,8,0, 32,16,8,0 }; -static int fetchstarts[] = { 3,2,1,0, 4,3,2,0, 5,4,3,0 }; -static int fm_maxplanes[] = { 3,2,1,0, 3,3,2,0, 3,3,3,0 }; - -static uae_u8 cycle_diagram_table[3][3][9][32]; -static uae_u8 cycle_diagram_free_cycles[3][3][9]; -static uae_u8 cycle_diagram_total_cycles[3][3][9]; -static uae_u8 *curr_diagram; -static uae_u8 cycle_sequences[3*8] = { 2,1,2,1,2,1,2,1, 4,2,3,1,4,2,3,1, 8,4,6,2,7,3,5,1 }; - -static void debug_cycle_diagram(void) -{ - int fm, res, planes, cycle, v; - char aa; - - for (fm = 0; fm < 3; fm++) { - write_log ("FMODE %d\n=======\n", fm); - for (res = 0; res <= 2; res++) { - for (planes = 0; planes <= 8; planes++) { - write_log ("%d: ",planes); - for (cycle = 0; cycle < 32; cycle++) { - v=cycle_diagram_table[fm][res][planes][cycle]; - if (v==0) aa='-'; else if(v>0) aa='1'; else aa='X'; - write_log ("%c",aa); - } - write_log (" %d:%d\n", - cycle_diagram_free_cycles[fm][res][planes], cycle_diagram_total_cycles[fm][res][planes]); - } - write_log ("\n"); - } - } - fm=0; -} - -static void create_cycle_diagram_table(void) -{ - int fm, res, cycle, planes, v; - int fetch_start, max_planes, freecycles; - uae_u8 *cycle_sequence; - - for (fm = 0; fm <= 2; fm++) { - for (res = 0; res <= 2; res++) { - max_planes = fm_maxplanes[fm * 4 + res]; - fetch_start = 1 << fetchstarts[fm * 4 + res]; - cycle_sequence = &cycle_sequences[(max_planes - 1) * 8]; - max_planes = 1 << max_planes; - for (planes = 0; planes <= 8; planes++) { - freecycles = 0; - for (cycle = 0; cycle < 32; cycle++) - cycle_diagram_table[fm][res][planes][cycle] = -1; - if (planes <= max_planes) { - for (cycle = 0; cycle < fetch_start; cycle++) { - if (cycle < max_planes && planes >= cycle_sequence[cycle & 7]) { - v = cycle_sequence[cycle & 7]; - } else { - v = 0; - freecycles++; - } - cycle_diagram_table[fm][res][planes][cycle] = v; - } - } - cycle_diagram_free_cycles[fm][res][planes] = freecycles; - cycle_diagram_total_cycles[fm][res][planes] = fetch_start; - } - } - } -#if 0 - debug_cycle_diagram (); -#endif -} - - -/* Used by the copper. */ -static int estimated_last_fetch_cycle; -static int cycle_diagram_shift; - -static void estimate_last_fetch_cycle (int hpos) -{ - int fetchunit = fetchunits[fetchmode * 4 + GET_RES (bplcon0)]; - - if (! passed_plfstop) { - int stop = plfstop < hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop; - /* We know that fetching is up-to-date up until hpos, so we can use fetch_cycle. */ - int fetch_cycle_at_stop = fetch_cycle + (stop - hpos); - int starting_last_block_at = (fetch_cycle_at_stop + fetchunit - 1) & ~(fetchunit - 1); - - estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit; - } else { - int starting_last_block_at = (fetch_cycle + fetchunit - 1) & ~(fetchunit - 1); - if (passed_plfstop == 2) - starting_last_block_at -= fetchunit; - - estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit; - } -} - -static uae_u32 outword[MAX_PLANES]; -static int out_nbits, out_offs; -static uae_u32 todisplay[MAX_PLANES][4]; -static uae_u32 fetched[MAX_PLANES]; -#ifdef AGA -static uae_u32 fetched_aga0[MAX_PLANES]; -static uae_u32 fetched_aga1[MAX_PLANES]; -#endif - -/* Expansions from bplcon0/bplcon1. */ -static int toscr_res, toscr_res_first, toscr_nr_planes, fetchwidth; -static int toscr_delay1x, toscr_delay2x, toscr_delay1, toscr_delay2; - -/* The number of bits left from the last fetched words. - This is an optimization - conceptually, we have to make sure the result is - the same as if toscr is called in each clock cycle. However, to speed this - up, we accumulate display data; this variable keeps track of how much. - Thus, once we do call toscr_nbits (which happens at least every 16 bits), - we can do more work at once. */ -static int toscr_nbits; - -static int delayoffset; - -STATIC_INLINE void compute_delay_offset (void) -{ - delayoffset = (((plfstrt - HARD_DDF_START) & fetchstart_mask) << 1) & ~7; - if (delayoffset == 8) - delayoffset = 8; - else if (delayoffset == 16) /* Overkill AGA */ - delayoffset = 48; - else if (delayoffset == 24) /* AB 2 */ - delayoffset = 8; - else if (delayoffset == 32) - delayoffset = 32; - else if (delayoffset == 48) /* Pinball Illusions AGA, ingame */ - delayoffset = 16; - else /* what about 40 and 56? */ - delayoffset = 0; -} - -static void expand_fmodes (void) -{ - int res = GET_RES(bplcon0); - int fm = fetchmode; - fetchunit = fetchunits[fm * 4 + res]; - fetchunit_mask = fetchunit - 1; - fetchstart_shift = fetchstarts[fm * 4 + res]; - fetchstart = 1 << fetchstart_shift; - fetchstart_mask = fetchstart - 1; - fm_maxplane_shift = fm_maxplanes[fm * 4 + res]; - fm_maxplane = 1 << fm_maxplane_shift; - curr_diagram = cycle_diagram_table[fm][res][GET_PLANES_LIMIT (bplcon0)]; -} - -/* Expand bplcon0/bplcon1 into the toscr_xxx variables. */ -static void compute_toscr_delay_1 (void) -{ - int delay1 = (bplcon1 & 0x0f) | ((bplcon1 & 0x0c00) >> 6); - int delay2 = ((bplcon1 >> 4) & 0x0f) | (((bplcon1 >> 4) & 0x0c00) >> 6); - int delaymask; - int fetchwidth = 16 << fetchmode; - - delay1 += delayoffset; - delay2 += delayoffset; - delaymask = (fetchwidth - 1) >> toscr_res; - toscr_delay1x = (delay1 & delaymask) << toscr_res; - toscr_delay2x = (delay2 & delaymask) << toscr_res; -} - -static void compute_toscr_delay (int hpos) -{ - toscr_res = GET_RES (bplcon0); - toscr_nr_planes = GET_PLANES_LIMIT (bplcon0); - compute_toscr_delay_1 (); -} - -STATIC_INLINE void maybe_first_bpl1dat (int hpos) -{ - if (thisline_decision.plfleft == -1) { - thisline_decision.plfleft = hpos; - compute_delay_offset (); - compute_toscr_delay_1 (); - } -} - -STATIC_INLINE void fetch (int nr, int fm) -{ - uaecptr p; - if (nr >= toscr_nr_planes) - return; - p = bplpt[nr] + bpl_off[nr]; - switch (fm) { - case 0: - fetched[nr] = last_custom_value = chipmem_agnus_wget (p); - bplpt[nr] += 2; - break; -#ifdef AGA - case 1: - fetched_aga0[nr] = chipmem_lget (p); - last_custom_value = (uae_u16)fetched_aga0[nr]; - bplpt[nr] += 4; - break; - case 2: - fetched_aga1[nr] = chipmem_lget (p); - fetched_aga0[nr] = chipmem_lget (p + 4); - last_custom_value = (uae_u16)fetched_aga0[nr]; - bplpt[nr] += 8; - break; -#endif - } - if (passed_plfstop == 2 && fetch_cycle >= (fetch_cycle & ~fetchunit_mask) + fetchunit - fetchstart) { - int mod; - if (fmode & 0x4000) { - if (((diwstrt >> 8) ^ vpos) & 1) - mod = bpl2mod; - else - mod = bpl1mod; - } else if (nr & 1) - mod = bpl2mod; - else - mod = bpl1mod; - bplpt[nr] += mod; - } - if (nr == 0) - fetch_state = fetch_was_plane0; -} - -static void clear_fetchbuffer (uae_u32 *ptr, int nwords) -{ - int i; - - if (! thisline_changed) - for (i = 0; i < nwords; i++) - if (ptr[i]) { - thisline_changed = 1; - break; - } - - memset (ptr, 0, nwords * 4); -} - -static void update_toscr_planes (void) -{ - if (toscr_nr_planes > thisline_decision.nr_planes) { - int j; - for (j = thisline_decision.nr_planes; j < toscr_nr_planes; j++) - clear_fetchbuffer ((uae_u32 *)(line_data[next_lineno] + 2 * MAX_WORDS_PER_LINE * j), out_offs); -#if 0 - if (thisline_decision.nr_planes > 0) - printf ("Planes from %d to %d\n", thisline_decision.nr_planes, toscr_nr_planes); -#endif - thisline_decision.nr_planes = toscr_nr_planes; - } -} - -STATIC_INLINE void toscr_3_ecs (int nbits) -{ - int delay1 = toscr_delay1; - int delay2 = toscr_delay2; - int i; - uae_u32 mask = 0xFFFF >> (16 - nbits); - - for (i = 0; i < toscr_nr_planes; i += 2) { - outword[i] <<= nbits; - outword[i] |= (todisplay[i][0] >> (16 - nbits + delay1)) & mask; - todisplay[i][0] <<= nbits; - } - for (i = 1; i < toscr_nr_planes; i += 2) { - outword[i] <<= nbits; - outword[i] |= (todisplay[i][0] >> (16 - nbits + delay2)) & mask; - todisplay[i][0] <<= nbits; - } -} - -STATIC_INLINE void shift32plus (uae_u32 *p, int n) -{ - uae_u32 t = p[1]; - t <<= n; - t |= p[0] >> (32 - n); - p[1] = t; -} - -#ifdef AGA -STATIC_INLINE void aga_shift (uae_u32 *p, int n, int fm) -{ - if (fm == 2) { - shift32plus (p + 2, n); - shift32plus (p + 1, n); - } - shift32plus (p + 0, n); - p[0] <<= n; -} - -STATIC_INLINE void toscr_3_aga (int nbits, int fm) -{ - int delay1 = toscr_delay1; - int delay2 = toscr_delay2; - int i; - uae_u32 mask = 0xFFFF >> (16 - nbits); - - { - int offs = (16 << fm) - nbits + delay1; - int off1 = offs >> 5; - if (off1 == 3) - off1 = 2; - offs -= off1 * 32; - for (i = 0; i < toscr_nr_planes; i += 2) { - uae_u32 t0 = todisplay[i][off1]; - uae_u32 t1 = todisplay[i][off1 + 1]; - uae_u64 t = (((uae_u64)t1) << 32) | t0; - outword[i] <<= nbits; - outword[i] |= (t >> offs) & mask; - aga_shift (todisplay[i], nbits, fm); - } - } - { - int offs = (16 << fm) - nbits + delay2; - int off1 = offs >> 5; - if (off1 == 3) - off1 = 2; - offs -= off1 * 32; - for (i = 1; i < toscr_nr_planes; i += 2) { - uae_u32 t0 = todisplay[i][off1]; - uae_u32 t1 = todisplay[i][off1 + 1]; - uae_u64 t = (((uae_u64)t1) << 32) | t0; - outword[i] <<= nbits; - outword[i] |= (t >> offs) & mask; - aga_shift (todisplay[i], nbits, fm); - } - } -} - -#endif - -static void toscr_2_0 (int nbits) { toscr_3_ecs (nbits); } -#ifdef AGA -static void toscr_2_1 (int nbits) { toscr_3_aga (nbits, 1); } -static void toscr_2_2 (int nbits) { toscr_3_aga (nbits, 2); } -#endif - -STATIC_INLINE void toscr_1 (int nbits, int fm) -{ - switch (fm) { - case 0: - toscr_2_0 (nbits); - break; -#ifdef AGA - case 1: - toscr_2_1 (nbits); - break; - case 2: - toscr_2_2 (nbits); - break; -#endif - } - out_nbits += nbits; - if (out_nbits == 32) { - int i; - uae_u8 *dataptr = line_data[next_lineno] + out_offs * 4; - for (i = 0; i < thisline_decision.nr_planes; i++) { - uae_u32 *dataptr32 = (uae_u32 *)dataptr; - if (i >= toscr_nr_planes) - outword[i] = 0; - if (*dataptr32 != outword[i]) - thisline_changed = 1; - *dataptr32 = outword[i]; - dataptr += MAX_WORDS_PER_LINE * 2; - } - out_offs++; - out_nbits = 0; - } -} - -static void toscr_fm0 (int); -static void toscr_fm1 (int); -static void toscr_fm2 (int); - -STATIC_INLINE void toscr (int nbits, int fm) -{ - switch (fm) { - case 0: toscr_fm0 (nbits); break; -#ifdef AGA - case 1: toscr_fm1 (nbits); break; - case 2: toscr_fm2 (nbits); break; -#endif - } -} - -STATIC_INLINE void toscr_0 (int nbits, int fm) -{ - int t; - - if (nbits > 16) { - toscr (16, fm); - nbits -= 16; - } - - t = 32 - out_nbits; - if (t < nbits) { - toscr_1 (t, fm); - nbits -= t; - } - toscr_1 (nbits, fm); -} - -static void toscr_fm0 (int nbits) { toscr_0 (nbits, 0); } -static void toscr_fm1 (int nbits) { toscr_0 (nbits, 1); } -static void toscr_fm2 (int nbits) { toscr_0 (nbits, 2); } - -static int flush_plane_data (int fm) -{ - int i = 0; - int fetchwidth = 16 << fm; - - if (out_nbits <= 16) { - i += 16; - toscr_1 (16, fm); - } - if (out_nbits != 0) { - i += 32 - out_nbits; - toscr_1 (32 - out_nbits, fm); - } - i += 32; - - toscr_1 (16, fm); - toscr_1 (16, fm); - return i >> (1 + toscr_res); -} - -STATIC_INLINE void flush_display (int fm) -{ - if (toscr_nbits > 0 && thisline_decision.plfleft != -1) - toscr (toscr_nbits, fm); - toscr_nbits = 0; -} - -/* Called when all planes have been fetched, i.e. when a new block - of data is available to be displayed. The data in fetched[] is - moved into todisplay[]. */ -STATIC_INLINE void beginning_of_plane_block (int pos, int fm) -{ - int i; - - flush_display (fm); - if (fm == 0) - for (i = 0; i < MAX_PLANES; i++) - todisplay[i][0] |= fetched[i]; -#ifdef AGA - else - for (i = 0; i < MAX_PLANES; i++) { - if (fm == 2) - todisplay[i][1] = fetched_aga1[i]; - todisplay[i][0] = fetched_aga0[i]; - } -#endif - maybe_first_bpl1dat (pos); - toscr_delay1 = toscr_delay1x; - toscr_delay2 = toscr_delay2x; -} - -#ifdef SPEEDUP - -/* The usual inlining tricks - don't touch unless you know what you are doing. */ -STATIC_INLINE void long_fetch_ecs (int plane, int nwords, int weird_number_of_bits, int dma) -{ - uae_u16 *real_pt = (uae_u16 *)pfield_xlateptr (bplpt[plane] + bpl_off[plane], nwords * 2); - int delay = (plane & 1) ? toscr_delay2 : toscr_delay1; - int tmp_nbits = out_nbits; - uae_u32 shiftbuffer = todisplay[plane][0]; - uae_u32 outval = outword[plane]; - uae_u32 fetchval = fetched[plane]; - uae_u32 *dataptr = (uae_u32 *)(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs); - - if (dma) - bplpt[plane] += nwords * 2; - - if (real_pt == 0) - /* @@@ Don't do this, fall back on chipmem_wget instead. */ - return; - - while (nwords > 0) { - int bits_left = 32 - tmp_nbits; - uae_u32 t; - - shiftbuffer |= fetchval; - - t = (shiftbuffer >> delay) & 0xFFFF; - - if (weird_number_of_bits && bits_left < 16) { - outval <<= bits_left; - outval |= t >> (16 - bits_left); - thisline_changed |= *dataptr ^ outval; - *dataptr++ = outval; - - outval = t; - tmp_nbits = 16 - bits_left; - shiftbuffer <<= 16; - } else { - outval = (outval << 16) | t; - shiftbuffer <<= 16; - tmp_nbits += 16; - if (tmp_nbits == 32) { - thisline_changed |= *dataptr ^ outval; - *dataptr++ = outval; - tmp_nbits = 0; - } - } - nwords--; - if (dma) { - fetchval = do_get_mem_word (real_pt); - real_pt++; - } - } - fetched[plane] = fetchval; - todisplay[plane][0] = shiftbuffer; - outword[plane] = outval; -} - -#ifdef AGA -STATIC_INLINE void long_fetch_aga (int plane, int nwords, int weird_number_of_bits, int fm, int dma) -{ - uae_u32 *real_pt = (uae_u32 *)pfield_xlateptr (bplpt[plane] + bpl_off[plane], nwords * 2); - int delay = (plane & 1) ? toscr_delay2 : toscr_delay1; - int tmp_nbits = out_nbits; - uae_u32 *shiftbuffer = todisplay[plane]; - uae_u32 outval = outword[plane]; - uae_u32 fetchval0 = fetched_aga0[plane]; - uae_u32 fetchval1 = fetched_aga1[plane]; - uae_u32 *dataptr = (uae_u32 *)(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs); - int offs = (16 << fm) - 16 + delay; - int off1 = offs >> 5; - if (off1 == 3) - off1 = 2; - offs -= off1 * 32; - - if (dma) - bplpt[plane] += nwords * 2; - - if (real_pt == 0) - /* @@@ Don't do this, fall back on chipmem_wget instead. */ - return; - - while (nwords > 0) { - int i; - - shiftbuffer[0] = fetchval0; - if (fm == 2) - shiftbuffer[1] = fetchval1; - - for (i = 0; i < (1 << fm); i++) { - int bits_left = 32 - tmp_nbits; - - uae_u32 t0 = shiftbuffer[off1]; - uae_u32 t1 = shiftbuffer[off1 + 1]; - uae_u64 t = (((uae_u64)t1) << 32) | t0; - - t0 = (uae_u32)((t >> offs) & 0xFFFF); - - if (weird_number_of_bits && bits_left < 16) { - outval <<= bits_left; - outval |= t0 >> (16 - bits_left); - - thisline_changed |= *dataptr ^ outval; - *dataptr++ = outval; - - outval = t0; - tmp_nbits = 16 - bits_left; - aga_shift (shiftbuffer, 16, fm); - } else { - outval = (outval << 16) | t0; - aga_shift (shiftbuffer, 16, fm); - tmp_nbits += 16; - if (tmp_nbits == 32) { - thisline_changed |= *dataptr ^ outval; - *dataptr++ = outval; - tmp_nbits = 0; - } - } - } - - nwords -= 1 << fm; - - if (dma) { - if (fm == 1) - fetchval0 = do_get_mem_long (real_pt); - else { - fetchval1 = do_get_mem_long (real_pt); - fetchval0 = do_get_mem_long (real_pt + 1); - } - real_pt += fm; - } - } - fetched_aga0[plane] = fetchval0; - fetched_aga1[plane] = fetchval1; - outword[plane] = outval; -} -#endif - -static void long_fetch_ecs_0 (int hpos, int nwords, int dma) { long_fetch_ecs (hpos, nwords, 0, dma); } -static void long_fetch_ecs_1 (int hpos, int nwords, int dma) { long_fetch_ecs (hpos, nwords, 1, dma); } -#ifdef AGA -static void long_fetch_aga_1_0 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords, 0, 1, dma); } -static void long_fetch_aga_1_1 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords, 1, 1, dma); } -static void long_fetch_aga_2_0 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords, 0, 2, dma); } -static void long_fetch_aga_2_1 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords, 1, 2, dma); } -#endif - -static void do_long_fetch (int hpos, int nwords, int dma, int fm) -{ - int i; - - flush_display (fm); - switch (fm) { - case 0: - if (out_nbits & 15) { - for (i = 0; i < toscr_nr_planes; i++) - long_fetch_ecs_1 (i, nwords, dma); - } else { - for (i = 0; i < toscr_nr_planes; i++) - long_fetch_ecs_0 (i, nwords, dma); - } - break; -#ifdef AGA - case 1: - if (out_nbits & 15) { - for (i = 0; i < toscr_nr_planes; i++) - long_fetch_aga_1_1 (i, nwords, dma); - } else { - for (i = 0; i < toscr_nr_planes; i++) - long_fetch_aga_1_0 (i, nwords, dma); - } - break; - case 2: - if (out_nbits & 15) { - for (i = 0; i < toscr_nr_planes; i++) - long_fetch_aga_2_1 (i, nwords, dma); - } else { - for (i = 0; i < toscr_nr_planes; i++) - long_fetch_aga_2_0 (i, nwords, dma); - } - break; -#endif - } - - out_nbits += nwords * 16; - out_offs += out_nbits >> 5; - out_nbits &= 31; - - if (dma && toscr_nr_planes > 0) - fetch_state = fetch_was_plane0; -} - -#endif - -/* make sure fetch that goes beyond maxhpos is finished */ -static void finish_final_fetch (int i, int fm) -{ - if (thisline_decision.plfleft == -1) - return; - if (passed_plfstop == 3) - return; - passed_plfstop = 3; - ddfstate = DIW_waiting_start; - i += flush_plane_data (fm); - thisline_decision.plfright = i; - thisline_decision.plflinelen = out_offs; - thisline_decision.bplres = toscr_res_first; - finish_playfield_line (); -} - -STATIC_INLINE int one_fetch_cycle_0 (int i, int ddfstop_to_test, int dma, int fm) -{ - if (! passed_plfstop && i == ddfstop_to_test) - passed_plfstop = 1; - - if ((fetch_cycle & fetchunit_mask) == 0) { - if (passed_plfstop == 2) { - finish_final_fetch (i, fm); - return 1; - } - if (passed_plfstop) - passed_plfstop++; - } - - if (dma) { - /* fetchstart_mask can be larger than fm_maxplane if FMODE > 0. This means - that the remaining cycles are idle; we'll fall through the whole switch - without doing anything. */ - int cycle_start = fetch_cycle & fetchstart_mask; - switch (fm_maxplane) { - case 8: - switch (cycle_start) { - case 0: fetch (7, fm); break; - case 1: fetch (3, fm); break; - case 2: fetch (5, fm); break; - case 3: fetch (1, fm); break; - case 4: fetch (6, fm); break; - case 5: fetch (2, fm); break; - case 6: fetch (4, fm); break; - case 7: fetch (0, fm); break; - } - break; - case 4: - switch (cycle_start) { - case 0: fetch (3, fm); break; - case 1: fetch (1, fm); break; - case 2: fetch (2, fm); break; - case 3: fetch (0, fm); break; - } - break; - case 2: - switch (cycle_start) { - case 0: fetch (1, fm); break; - case 1: fetch (0, fm); break; - } - break; - } - } - fetch_cycle++; - toscr_nbits += 2 << toscr_res; - - if (toscr_nbits == 16) - flush_display (fm); - if (toscr_nbits > 16) - uae_abort ("toscr_nbits > 16 (%d)", toscr_nbits); - - return 0; -} - -static int one_fetch_cycle_fm0 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 0); } -static int one_fetch_cycle_fm1 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 1); } -static int one_fetch_cycle_fm2 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 2); } - -STATIC_INLINE int one_fetch_cycle (int i, int ddfstop_to_test, int dma, int fm) -{ - switch (fm) { - case 0: return one_fetch_cycle_fm0 (i, ddfstop_to_test, dma); -#ifdef AGA - case 1: return one_fetch_cycle_fm1 (i, ddfstop_to_test, dma); - case 2: return one_fetch_cycle_fm2 (i, ddfstop_to_test, dma); -#endif - default: uae_abort ("fm corrupt"); return 0; - } -} - -STATIC_INLINE void update_fetch (int until, int fm) -{ - int pos; - int dma = dmaen (DMA_BITPLANE); - - int ddfstop_to_test; - - if (nodraw() || passed_plfstop == 3) - return; - - /* We need an explicit test against HARD_DDF_STOP here to guard against - programs that move the DDFSTOP before our current position before we - reach it. */ - ddfstop_to_test = HARD_DDF_STOP; - if (ddfstop >= last_fetch_hpos && plfstop < ddfstop_to_test) - ddfstop_to_test = plfstop; - - compute_toscr_delay (last_fetch_hpos); - update_toscr_planes (); - - pos = last_fetch_hpos; - cycle_diagram_shift = last_fetch_hpos - fetch_cycle; - - /* First, a loop that prepares us for the speedup code. We want to enter - the SPEEDUP case with fetch_state == fetch_was_plane0, and then unroll - whole blocks, so that we end on the same fetch_state again. */ - for (; ; pos++) { - if (pos == until) { - if (until >= maxhpos) { - finish_final_fetch (pos, fm); - return; - } - flush_display (fm); - return; - } - - if (fetch_state == fetch_was_plane0) - break; - - fetch_state = fetch_started; - if (one_fetch_cycle (pos, ddfstop_to_test, dma, fm)) - return; - } - -#ifdef SPEEDUP - /* Unrolled version of the for loop below. */ - if (! passed_plfstop && ddf_change != vpos && ddf_change + 1 != vpos - && dma - && (fetch_cycle & fetchstart_mask) == (fm_maxplane & fetchstart_mask) - && toscr_delay1 == toscr_delay1x && toscr_delay2 == toscr_delay2x - # if 0 - /* @@@ We handle this case, but the code would be simpler if we - * disallowed it - it may even be possible to guarantee that - * this condition never is false. Later. */ - && (out_nbits & 15) == 0 -# endif - && toscr_nr_planes == thisline_decision.nr_planes) - { - int offs = (pos - fetch_cycle) & fetchunit_mask; - int ddf2 = ((ddfstop_to_test - offs + fetchunit - 1) & ~fetchunit_mask) + offs; - int ddf3 = ddf2 + fetchunit; - int stop = until < ddf2 ? until : until < ddf3 ? ddf2 : ddf3; - int count; - - count = stop - pos; - - if (count >= fetchstart) { - count &= ~fetchstart_mask; - - if (thisline_decision.plfleft == -1) { - compute_delay_offset (); - compute_toscr_delay_1 (); - } - - do_long_fetch (pos, count >> (3 - toscr_res), dma, fm); - - /* This must come _after_ do_long_fetch so as not to confuse flush_display - into thinking the first fetch has produced any output worth emitting to - the screen. But the calculation of delay_offset must happen _before_. */ - maybe_first_bpl1dat (pos); - - if (pos <= ddfstop_to_test && pos + count > ddfstop_to_test) - passed_plfstop = 1; - if (pos <= ddfstop_to_test && pos + count > ddf2) - passed_plfstop = 2; - if (pos <= ddf2 && pos + count >= ddf2 + fm_maxplane) - add_modulos (); - pos += count; - fetch_cycle += count; - } - } else { -#endif - //maybe_first_bpl1dat (pos); -#ifdef SPEEDUP - } -#endif - for (; pos < until; pos++) { - if (fetch_state == fetch_was_plane0) - beginning_of_plane_block (pos, fm); - fetch_state = fetch_started; - - if (one_fetch_cycle (pos, ddfstop_to_test, dma, fm)) - return; - } - if (until >= maxhpos) { - finish_final_fetch (pos, fm); - return; - } - flush_display (fm); -} - -static void update_fetch_0 (int hpos) { update_fetch (hpos, 0); } -static void update_fetch_1 (int hpos) { update_fetch (hpos, 1); } -static void update_fetch_2 (int hpos) { update_fetch (hpos, 2); } - -STATIC_INLINE void decide_fetch (int hpos) -{ - if (fetch_state != fetch_not_started && hpos > last_fetch_hpos) { - switch (fetchmode) { - case 0: update_fetch_0 (hpos); break; -#ifdef AGA - case 1: update_fetch_1 (hpos); break; - case 2: update_fetch_2 (hpos); break; -#endif - default: uae_abort ("fetchmode corrupt"); - } - } - last_fetch_hpos = hpos; -} - -static void start_bpl_dma (int hpos, int hstart) -{ - fetch_state = fetch_started; - fetch_cycle = 0; - last_fetch_hpos = hstart; - out_nbits = 0; - out_offs = 0; - toscr_nbits = 0; - toscr_res_first = GET_RES (bplcon0); - - ddfstate = DIW_waiting_stop; - compute_toscr_delay (last_fetch_hpos); - - /* If someone already wrote BPL1DAT, clear the area between that point and - the real fetch start. */ - if (!nodraw ()) { - if (thisline_decision.plfleft != -1) { - out_nbits = (plfstrt - thisline_decision.plfleft) << (1 + toscr_res); - out_offs = out_nbits >> 5; - out_nbits &= 31; - } - update_toscr_planes (); - } -} - -/* this may turn on datafetch if program turns dma on during the ddf */ -static void maybe_start_bpl_dma (int hpos) -{ - /* OCS: BPL DMA never restarts if DMA is turned on during DDF - * ECS/AGA: BPL DMA restarts but only if DMA was turned off - outside of DDF or during current line, otherwise display - processing jumps immediately to "DDFSTOP passed"-condition */ - if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - return; - if (fetch_state != fetch_not_started) - return; - if (diwstate != DIW_waiting_stop) - return; - if (hpos <= plfstrt) - return; - if (hpos > plfstop) - return; - if (ddfstate != DIW_waiting_start) - passed_plfstop = 1; - start_bpl_dma (hpos, hpos); -} - -/* This function is responsible for turning on datafetch if necessary. */ -STATIC_INLINE void decide_line (int hpos) -{ - /* Take care of the vertical DIW. */ - if (vpos == plffirstline) - diwstate = DIW_waiting_stop; - if (vpos == plflastline) - diwstate = DIW_waiting_start; - - if (hpos <= last_decide_line_hpos) - return; - if (fetch_state != fetch_not_started) - return; - - if (dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) { - int ok = 0; - /* Test if we passed the start of the DDF window. */ - if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { - ok = 1; - /* hack warning.. Writing to DDFSTRT when DMA should start must be ignored - * (correct fix would be emulate this delay for every custom register, but why bother..) */ - if (hpos - 2 == ddfstrt_old_hpos && ddfstrt_old_vpos == vpos) - ok = 0; - if (ok) { - start_bpl_dma (hpos, plfstrt); - estimate_last_fetch_cycle (plfstrt); - last_decide_line_hpos = hpos; -#ifndef CUSTOM_SIMPLE - do_sprites (plfstrt); -#endif - return; - } - } - } - -#ifndef CUSTOM_SIMPLE - if (last_sprite_decide_line_hpos < SPR0_HPOS + 4 * MAX_SPRITES) - do_sprites (hpos); -#endif - last_sprite_decide_line_hpos = hpos; - - last_decide_line_hpos = hpos; -} - -/* Called when a color is about to be changed (write to a color register), - * but the new color has not been entered into the table yet. */ -static void record_color_change (int hpos, int regno, unsigned long value) -{ - if (regno == -1 && value) { - thisline_decision.ham_seen = 1; - if (hpos < HARD_DDF_START) - thisline_decision.ham_at_start = 1; - } - - /* Early positions don't appear on-screen. */ - if (nodraw () || vpos < minfirstline || hpos < HARD_DDF_START - /*|| currprefs.emul_accuracy == 0*/) - return; - - decide_diw (hpos); - decide_line (hpos); - - if (thisline_decision.ctable == -1) - remember_ctable (); - -#ifdef OS_WITHOUT_MEMORY_MANAGEMENT - if (next_color_change >= max_color_change) { - ++delta_color_change; - return; - } -#endif - curr_color_changes[next_color_change].linepos = hpos; - curr_color_changes[next_color_change].regno = regno; - curr_color_changes[next_color_change++].value = value; -} - -typedef int sprbuf_res_t, cclockres_t, hwres_t, bplres_t; - -/* handle very rarely needed playfield collision (CLXDAT bit 0) */ -static void do_playfield_collisions (void) -{ - int bplres = GET_RES (bplcon0); - hwres_t ddf_left = thisline_decision.plfleft * 2 << bplres; - hwres_t hw_diwlast = coord_window_to_diw_x (thisline_decision.diwlastword); - hwres_t hw_diwfirst = coord_window_to_diw_x (thisline_decision.diwfirstword); - int i, collided, minpos, maxpos; -#ifdef AGA - int planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6; -#else - int planes = 6; -#endif - - if (clxcon_bpl_enable == 0) { - clxdat |= 1; - return; - } - if (clxdat & 1) - return; - - collided = 0; - minpos = thisline_decision.plfleft * 2; - if (minpos < hw_diwfirst) - minpos = hw_diwfirst; - maxpos = thisline_decision.plfright * 2; - if (maxpos > hw_diwlast) - maxpos = hw_diwlast; - for (i = minpos; i < maxpos && !collided; i+= 32) { - int offs = ((i << bplres) - ddf_left) >> 3; - int j; - uae_u32 total = 0xffffffff; - for (j = 0; j < planes; j++) { - int ena = (clxcon_bpl_enable >> j) & 1; - int match = (clxcon_bpl_match >> j) & 1; - uae_u32 t = 0xffffffff; - if (ena) { - if (j < thisline_decision.nr_planes) { - t = *(uae_u32 *)(line_data[next_lineno] + offs + 2 * j * MAX_WORDS_PER_LINE); - t ^= (match & 1) - 1; - } else { - t = (match & 1) - 1; - } - } - total &= t; - } - if (total) { - collided = 1; -#if 0 - { - int k; - for (k = 0; k < 1; k++) { - uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + offs + 2 * k * MAX_WORDS_PER_LINE); - *ldata ^= 0x5555555555; - } - } -#endif - - } - } - if (collided) - clxdat |= 1; -} - -/* Sprite-to-sprite collisions are taken care of in record_sprite. This one does - playfield/sprite collisions. */ -static void do_sprite_collisions (void) -{ - int nr_sprites = curr_drawinfo[next_lineno].nr_sprites; - int first = curr_drawinfo[next_lineno].first_sprite_entry; - int i; - unsigned int collision_mask = clxmask[clxcon >> 12]; - int bplres = GET_RES (bplcon0); - hwres_t ddf_left = thisline_decision.plfleft * 2 << bplres; - hwres_t hw_diwlast = coord_window_to_diw_x (thisline_decision.diwlastword); - hwres_t hw_diwfirst = coord_window_to_diw_x (thisline_decision.diwfirstword); - - if (clxcon_bpl_enable == 0) { - clxdat |= 0x1FE; - return; - } - - for (i = 0; i < nr_sprites; i++) { - struct sprite_entry *e = curr_sprite_entries + first + i; - sprbuf_res_t j; - sprbuf_res_t minpos = e->pos; - sprbuf_res_t maxpos = e->max; - hwres_t minp1 = minpos >> sprite_buffer_res; - hwres_t maxp1 = maxpos >> sprite_buffer_res; - - if (maxp1 > hw_diwlast) - maxpos = hw_diwlast << sprite_buffer_res; - if (maxp1 > thisline_decision.plfright * 2) - maxpos = thisline_decision.plfright * 2 << sprite_buffer_res; - if (minp1 < hw_diwfirst) - minpos = hw_diwfirst << sprite_buffer_res; - if (minp1 < thisline_decision.plfleft * 2) - minpos = thisline_decision.plfleft * 2 << sprite_buffer_res; - - for (j = minpos; j < maxpos; j++) { - int sprpix = spixels[e->first_pixel + j - e->pos] & collision_mask; - int k, offs, match = 1; - - if (sprpix == 0) - continue; - - offs = ((j << bplres) >> sprite_buffer_res) - ddf_left; - sprpix = sprite_ab_merge[sprpix & 255] | (sprite_ab_merge[sprpix >> 8] << 2); - sprpix <<= 1; - - /* Loop over number of playfields. */ - for (k = 1; k >= 0; k--) { - int l; -#ifdef AGA - int planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6; -#else - int planes = 6; -#endif - if (bplcon0 & 0x400) - match = 1; - for (l = k; match && l < planes; l += 2) { - int t = 0; - if (l < thisline_decision.nr_planes) { - uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE); - uae_u32 word = ldata[offs >> 5]; - t = (word >> (31 - (offs & 31))) & 1; -#if 0 /* debug: draw collision mask */ - if (1) { - int m; - for (m = 0; m < 5; m++) { - ldata = (uae_u32 *)(line_data[next_lineno] + 2 * m * MAX_WORDS_PER_LINE); - ldata[(offs >> 5) + 1] |= 15 << (31 - (offs & 31)); - } - } -#endif - } - if (clxcon_bpl_enable & (1 << l)) { - if (t != ((clxcon_bpl_match >> l) & 1)) - match = 0; - } - } - if (match) { -#if 0 /* debug: mark lines where collisions are detected */ - if (0) { - int l; - for (l = 0; l < 5; l++) { - uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE); - ldata[(offs >> 5) + 1] |= 15 << (31 - (offs & 31)); - } - } -#endif - clxdat |= sprpix << (k * 4); - } - } - } - } -#if 0 - { - static int olx; - if (clxdat != olx) - write_log ("%d: %04.4X\n", vpos, clxdat); - olx = clxdat; - } -#endif -} - -static void expand_sprres (void) -{ - switch ((bplcon3 >> 6) & 3) { - case 0: /* ECS defaults (LORES,HIRES=140ns,SHRES=70ns) */ - if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && GET_RES (bplcon0) == RES_SUPERHIRES) - sprres = RES_HIRES; - else - sprres = RES_LORES; - break; - case 1: - sprres = RES_LORES; - break; - case 2: - sprres = RES_HIRES; - break; - case 3: - sprres = RES_SUPERHIRES; - break; - } -} - -STATIC_INLINE void record_sprite_1 (uae_u16 *buf, uae_u32 datab, int num, int dbl, - unsigned int mask, int do_collisions, uae_u32 collision_mask) -{ - int j = 0; - while (datab) { - unsigned int tmp = *buf; - unsigned int col = (datab & 3) << (2 * num); - tmp |= col; - if ((j & mask) == 0) - *buf++ = tmp; - if (dbl) - *buf++ = tmp; - j++; - datab >>= 2; - if (do_collisions) { - tmp &= collision_mask; - if (tmp) { - unsigned int shrunk_tmp = sprite_ab_merge[tmp & 255] | (sprite_ab_merge[tmp >> 8] << 2); - clxdat |= sprclx[shrunk_tmp]; - } - } - } -} - -/* DATAB contains the sprite data; 16 pixels in two-bit packets. Bits 0/1 - determine the color of the leftmost pixel, bits 2/3 the color of the next - etc. - This function assumes that for all sprites in a given line, SPRXP either - stays equal or increases between successive calls. - - The data is recorded either in lores pixels (if ECS), or in hires pixels - (if AGA). No support for SHRES sprites. */ - -static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 *datb, unsigned int ctl) -{ - struct sprite_entry *e = curr_sprite_entries + next_sprite_entry; - int i; - int word_offs; - uae_u16 *buf; - uae_u32 collision_mask; - int width = sprite_width; - int dbl = 0, half = 0; - unsigned int mask = 0; - - if (sprres != RES_LORES) - thisline_decision.any_hires_sprites = 1; - -#ifdef AGA - if (currprefs.chipset_mask & CSMASK_AGA) { - width = (width << 1) >> sprres; - dbl = sprite_buffer_res - sprres; - if (dbl < 0) { - half = -dbl; - dbl = 0; - } - mask = sprres == RES_SUPERHIRES ? 1 : 0; - } -#endif - - /* Try to coalesce entries if they aren't too far apart. */ - if (! next_sprite_forced && e[-1].max + 16 >= sprxp) { - e--; - } else { - next_sprite_entry++; - e->pos = sprxp; - e->has_attached = 0; - } - - if (sprxp < e->pos) - uae_abort ("sprxp < e->pos"); - - e->max = sprxp + width; - e[1].first_pixel = e->first_pixel + ((e->max - e->pos + 3) & ~3); - next_sprite_forced = 0; - - collision_mask = clxmask[clxcon >> 12]; - word_offs = e->first_pixel + sprxp - e->pos; - - for (i = 0; i < sprite_width; i += 16) { - unsigned int da = *data; - unsigned int db = *datb; - uae_u32 datab = ((sprtaba[da & 0xFF] << 16) | sprtaba[da >> 8] - | (sprtabb[db & 0xFF] << 16) | sprtabb[db >> 8]); - - buf = spixels + word_offs + ((i << dbl) >> half); - if (currprefs.collision_level > 0 && collision_mask) - record_sprite_1 (buf, datab, num, dbl, mask, 1, collision_mask); - else - record_sprite_1 (buf, datab, num, dbl, mask, 0, collision_mask); - data++; - datb++; - } - - /* We have 8 bits per pixel in spixstate, two for every sprite pair. The - low order bit records whether the attach bit was set for this pair. */ - - if ((sprctl[num] & 0x80) || (sprctl[num ^ 1] & 0x80)) { -// if (ctl & 0x80) { - uae_u32 state = 0x01010101 << (num & ~1); - uae_u32 *stbuf = spixstate.words + (word_offs >> 2); - uae_u8 *stb1 = spixstate.bytes + word_offs; - for (i = 0; i < width; i += 8) { - stb1[0] |= state; - stb1[1] |= state; - stb1[2] |= state; - stb1[3] |= state; - stb1[4] |= state; - stb1[5] |= state; - stb1[6] |= state; - stb1[7] |= state; - stb1 += 8; - } - e->has_attached = 1; - } -} - -static void decide_sprites (int hpos) -{ - int nrs[MAX_SPRITES], posns[MAX_SPRITES]; - int count, i; - /* apparantly writes to custom registers happen in the 3/4th of cycle - * and sprite xpos comparator sees it immediately */ - int point = hpos * 2 - 4; - int width = sprite_width; - int window_width = (width << lores_shift) >> sprres; - - if (nodraw () || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point) - return; - - decide_diw (hpos); - decide_line (hpos); - - count = 0; - for (i = 0; i < MAX_SPRITES; i++) { - int sprxp = spr[i].xpos; - int hw_xp = (sprxp >> sprite_buffer_res); - int window_xp = coord_hw_to_window_x (hw_xp) + (DIW_DDF_OFFSET << lores_shift); - int j, bestp; - -#if (SPRITE_MASK) != 255 - if (!((SPRITE_MASK) & (1 << i))) - continue; -#endif - if (! spr[i].armed || sprxp < 0 || hw_xp <= last_sprite_point || hw_xp > point) - continue; - if ( !(bplcon3 & 2) && /* sprites outside playfields enabled? */ - ((thisline_decision.diwfirstword >= 0 && window_xp + window_width < thisline_decision.diwfirstword) - || (thisline_decision.diwlastword >= 0 && window_xp > thisline_decision.diwlastword))) - continue; - - /* Sort the sprites in order of ascending X position before recording them. */ - for (bestp = 0; bestp < count; bestp++) { - if (posns[bestp] > sprxp) - break; - if (posns[bestp] == sprxp && nrs[bestp] < i) - break; - } - for (j = count; j > bestp; j--) { - posns[j] = posns[j-1]; - nrs[j] = nrs[j-1]; - } - posns[j] = sprxp; - nrs[j] = i; - count++; - } - for (i = 0; i < count; i++) { - int nr = nrs[i]; - record_sprite (next_lineno, nr, spr[nr].xpos, sprdata[nr], sprdatb[nr], sprctl[nr]); - } - last_sprite_point = point; -} - -STATIC_INLINE int sprites_differ (struct draw_info *dip, struct draw_info *dip_old) -{ - struct sprite_entry *this_first = curr_sprite_entries + dip->first_sprite_entry; - struct sprite_entry *this_last = curr_sprite_entries + dip->last_sprite_entry; - struct sprite_entry *prev_first = prev_sprite_entries + dip_old->first_sprite_entry; - int npixels; - int i; - - if (dip->nr_sprites != dip_old->nr_sprites) - return 1; - - if (dip->nr_sprites == 0) - return 0; - - for (i = 0; i < dip->nr_sprites; i++) - if (this_first[i].pos != prev_first[i].pos - || this_first[i].max != prev_first[i].max - || this_first[i].has_attached != prev_first[i].has_attached) - return 1; - - npixels = this_last->first_pixel + (this_last->max - this_last->pos) - this_first->first_pixel; - if (memcmp (spixels + this_first->first_pixel, spixels + prev_first->first_pixel, - npixels * sizeof (uae_u16)) != 0) - return 1; - if (memcmp (spixstate.bytes + this_first->first_pixel, spixstate.bytes + prev_first->first_pixel, npixels) != 0) - return 1; - return 0; -} - -STATIC_INLINE int color_changes_differ (struct draw_info *dip, struct draw_info *dip_old) -{ - if (dip->nr_color_changes != dip_old->nr_color_changes) - return 1; - - if (dip->nr_color_changes == 0) - return 0; - if (memcmp (curr_color_changes + dip->first_color_change, - prev_color_changes + dip_old->first_color_change, - dip->nr_color_changes * sizeof *curr_color_changes) != 0) - return 1; - return 0; -} - -/* End of a horizontal scan line. Finish off all decisions that were not - * made yet. */ -static void finish_decisions (void) -{ - struct draw_info *dip; - struct draw_info *dip_old; - struct decision *dp; - int changed; - int hpos = current_hpos (); - - if (nodraw ()) - return; - - decide_diw (hpos); - decide_line (hpos); - decide_fetch (hpos); - - if (thisline_decision.plfleft != -1 && thisline_decision.plflinelen == -1) { - if (fetch_state != fetch_not_started) { - write_log ("fetch_state=%d plfleft=%d\n",fetch_state,thisline_decision.plfleft); - uae_abort ("fetch_state != fetch_not_started"); - } - thisline_decision.plfright = thisline_decision.plfleft; - thisline_decision.plflinelen = 0; - thisline_decision.bplres = RES_LORES; - } - - /* Large DIWSTOP values can cause the stop position never to be - * reached, so the state machine always stays in the same state and - * there's a more-or-less full-screen DIW. */ - if (hdiwstate == DIW_waiting_stop || thisline_decision.diwlastword > max_diwlastword) - thisline_decision.diwlastword = max_diwlastword; - - if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword) - MARK_LINE_CHANGED; - if (thisline_decision.diwlastword != line_decisions[next_lineno].diwlastword) - MARK_LINE_CHANGED; - - dip = curr_drawinfo + next_lineno; - dip_old = prev_drawinfo + next_lineno; - dp = line_decisions + next_lineno; - changed = thisline_changed; - - if (thisline_decision.plfleft != -1) - record_diw_line (thisline_decision.plfleft, diwfirstword, diwlastword); - - if (thisline_decision.plfleft != -1 || (bplcon3 & 2)) - decide_sprites (hpos); - - dip->last_sprite_entry = next_sprite_entry; - dip->last_color_change = next_color_change; - - if (thisline_decision.ctable == -1) { - if (thisline_decision.plfleft == -1) - remember_ctable_for_border (); - else - remember_ctable (); - } - - dip->nr_color_changes = next_color_change - dip->first_color_change; - dip->nr_sprites = next_sprite_entry - dip->first_sprite_entry; - - if (thisline_decision.plfleft != line_decisions[next_lineno].plfleft) - changed = 1; - if (! changed && color_changes_differ (dip, dip_old)) - changed = 1; - if (!changed && thisline_decision.plfleft != -1 && sprites_differ (dip, dip_old)) - changed = 1; - - if (changed) { - thisline_changed = 1; - *dp = thisline_decision; - } else - /* The only one that may differ: */ - dp->ctable = thisline_decision.ctable; -} - -/* Set the state of all decisions to "undecided" for a new scanline. */ -static void reset_decisions (void) -{ - if (nodraw ()) - return; - toscr_res_first = 0; - - thisline_decision.any_hires_sprites = 0; - thisline_decision.nr_planes = 0; - - thisline_decision.plfleft = -1; - thisline_decision.plflinelen = -1; - thisline_decision.ham_seen = !! (bplcon0 & 0x800); - thisline_decision.ham_at_start = !! (bplcon0 & 0x800); - - /* decided_res shouldn't be touched before it's initialized by decide_line(). */ - thisline_decision.diwfirstword = -1; - thisline_decision.diwlastword = -1; - if (hdiwstate == DIW_waiting_stop) { - thisline_decision.diwfirstword = 0; - if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword) - MARK_LINE_CHANGED; - } - thisline_decision.ctable = -1; - - thisline_changed = 0; - curr_drawinfo[next_lineno].first_color_change = next_color_change; - curr_drawinfo[next_lineno].first_sprite_entry = next_sprite_entry; - next_sprite_forced = 1; - - /* memset(sprite_last_drawn_at, 0, sizeof sprite_last_drawn_at); */ - last_sprite_point = 0; - fetch_state = fetch_not_started; - passed_plfstop = 0; - - memset (todisplay, 0, sizeof todisplay); - memset (fetched, 0, sizeof fetched); -#ifdef AGA - memset (fetched_aga0, 0, sizeof fetched_aga0); - memset (fetched_aga1, 0, sizeof fetched_aga1); -#endif - memset (outword, 0, sizeof outword); - - last_decide_line_hpos = -1; - last_sprite_decide_line_hpos = -1; - last_diw_pix_hpos = -1; - last_ddf_pix_hpos = -1; - last_sprite_hpos = -1; - last_fetch_hpos = -1; - -} - -static int isvsync (void) -{ - return currprefs.gfx_vsync && currprefs.gfx_afullscreen; -} - -int vsynctime_orig; -int turbo_emulation; - -void compute_vsynctime (void) -{ - fake_vblank_hz = 0; - if (currprefs.chipset_refreshrate) { - vblank_hz = currprefs.chipset_refreshrate; - if (isvsync()) { - vblank_skip = 1; - if (!fake_vblank_hz && vblank_hz > 85) { - vblank_hz /= 2; - vblank_skip = -1; - } - } - } - if (!fake_vblank_hz) - fake_vblank_hz = vblank_hz; - if (turbo_emulation) - vsynctime = vsynctime_orig = 1; - else - vsynctime = vsynctime_orig = syncbase / fake_vblank_hz; -#ifdef OPENGL - OGL_refresh (); -#endif -#ifdef D3D - D3D_refresh (); -#endif - if (currprefs.produce_sound > 1) - update_sound (fake_vblank_hz); -} - - -/* set PAL or NTSC timing variables */ -void init_hz (void) -{ - int isntsc; - - if ((currprefs.chipset_refreshrate == 50 && !currprefs.ntscmode) || - (currprefs.chipset_refreshrate == 60 && currprefs.ntscmode)) { - currprefs.chipset_refreshrate = 0; - changed_prefs.chipset_refreshrate = 0; - } - if (currprefs.gfx_vsync && currprefs.gfx_afullscreen) { - currprefs.chipset_refreshrate = abs (currprefs.gfx_refreshrate); - changed_prefs.chipset_refreshrate = abs (currprefs.gfx_refreshrate); - } - - beamcon0 = new_beamcon0; - isntsc = beamcon0 & 0x20 ? 0 : 1; - if (hack_vpos > 0) { - if (maxvpos == hack_vpos) - return; - maxvpos = hack_vpos; - vblank_hz = 15600 / hack_vpos; - hack_vpos = -1; - } else if (hack_vpos < 0) { - hack_vpos = 0; - } - if (hack_vpos == 0) { - if (!isntsc) { - maxvpos = MAXVPOS_PAL; - maxhpos = MAXHPOS_PAL; - minfirstline = VBLANK_ENDLINE_PAL; - vblank_hz = VBLANK_HZ_PAL; - sprite_vblank_endline = VBLANK_SPRITE_PAL; - } else { - maxvpos = MAXVPOS_NTSC; - maxhpos = MAXHPOS_NTSC; - minfirstline = VBLANK_ENDLINE_NTSC; - vblank_hz = VBLANK_HZ_NTSC; - sprite_vblank_endline = VBLANK_SPRITE_NTSC; - } - } - if (beamcon0 & 0x80) { - if (vtotal >= MAXVPOS) - vtotal = MAXVPOS - 1; - maxvpos = vtotal + 1; - if (htotal >= MAXHPOS) - htotal = MAXHPOS - 1; - maxhpos = htotal + 1; - vblank_hz = 227 * 312 * 50 / (maxvpos * maxhpos); - } - /* limit to sane values */ - if (vblank_hz < 10) - vblank_hz = 10; - if (vblank_hz > 300) - vblank_hz = 300; - eventtab[ev_hsync].oldcycles = get_cycles (); - eventtab[ev_hsync].evtime = get_cycles() + HSYNCTIME; - events_schedule (); - compute_vsynctime (); -#ifdef OPENGL - OGL_refresh (); -#endif -#ifdef PICASSO96 - init_hz_p96 (); -#endif - write_log ("%s mode, %dHz (h=%d v=%d)\n", - isntsc ? "NTSC" : "PAL", vblank_hz, maxhpos, maxvpos); -} - -static void calcdiw (void) -{ - int hstrt = diwstrt & 0xFF; - int hstop = diwstop & 0xFF; - int vstrt = diwstrt >> 8; - int vstop = diwstop >> 8; - - if (diwhigh_written) { - hstrt |= ((diwhigh >> 5) & 1) << 8; - hstop |= ((diwhigh >> 13) & 1) << 8; - vstrt |= (diwhigh & 7) << 8; - vstop |= ((diwhigh >> 8) & 7) << 8; - } else { - hstop += 0x100; - if ((vstop & 0x80) == 0) - vstop |= 0x100; - } - - diwfirstword = coord_diw_to_window_x (hstrt); - diwlastword = coord_diw_to_window_x (hstop); - if (diwfirstword >= diwlastword) { - diwfirstword = 0; - diwlastword = max_diwlastword; - } - if (diwfirstword < 0) - diwfirstword = 0; - - plffirstline = vstrt; - plflastline = vstop; - -#if 0 - /* This happens far too often. */ - if (plffirstline < minfirstline_bpl) { - write_log ("Warning: Playfield begins before line %d (%d)!\n", minfirstline_bpl, plffirstline); - } -#endif - -#if 0 /* this comparison is not needed but previous is.. */ - if (plflastline > 313) { - /* Turrican does this */ - write_log ("Warning: Playfield out of range!\n"); - plflastline = 313; - } -#endif - - plfstrt = ddfstrt; - plfstop = ddfstop; - /* probably not the correct place.. */ - if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { - if (ddfstop > maxhpos) - plfstrt = 0; - if (plfstrt < HARD_DDF_START) - plfstrt = HARD_DDF_START; - } -} - -/* display mode changed (lores, doubling etc..), recalculate everything */ -void init_custom (void) -{ - reset_drawing (); - init_hz (); - calcdiw (); -} - -static int timehack_alive = 0; - -static uae_u32 timehack_helper (void) -{ -#ifdef HAVE_GETTIMEOFDAY - struct timeval tv; - if (m68k_dreg (regs, 0) == 0) - return timehack_alive; - - timehack_alive = 10; - - gettimeofday (&tv, NULL); - put_long (m68k_areg (regs, 0), tv.tv_sec - (((365 * 8 + 2) * 24) * 60 * 60)); - put_long (m68k_areg (regs, 0) + 4, tv.tv_usec); - return 0; -#else - return 2; -#endif -} - - /* - * register functions - */ -STATIC_INLINE uae_u16 DENISEID (void) -{ -#ifdef AGA - if (currprefs.chipset_mask & CSMASK_AGA) - return 0xF8; -#endif - if (currprefs.chipset_mask & CSMASK_ECS_DENISE) - return 0xFC; - return 0xffff; -} -STATIC_INLINE uae_u16 DMACONR (void) -{ - uae_u16 v; - decide_blitter (current_hpos ()); - v = dmacon | (bltstate == BLT_done ? 0 : 0x4000) - | (blt_info.blitzero ? 0x2000 : 0); -#if 0 - if (!dmaen (DMA_BLITTER)) - v &= ~0x4000; -#endif - return v; -} -STATIC_INLINE uae_u16 INTENAR (void) -{ - return intena; -} -uae_u16 INTREQR (void) -{ - return intreq; -} -STATIC_INLINE uae_u16 ADKCONR (void) -{ - return adkcon; -} -STATIC_INLINE uae_u16 VPOSR (void) -{ - unsigned int csbit = currprefs.ntscmode ? 0x1000 : 0; - int vp = (vpos >> 8) & 7; -#ifdef AGA - csbit |= (currprefs.chipset_mask & CSMASK_AGA) ? 0x2300 : 0; -#endif - csbit |= (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0x2000 : 0; - if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - vp &= 1; - vp = vp | lof | csbit; - return vp; -} -static void VPOSW (uae_u16 v) -{ -#if 0 - write_log ("vposw %x at %x\n", v, m68k_getpc ()); -#endif - if (lof != (v & 0x8000)) - lof_changed = 1; - lof = v & 0x8000; - if ( (v & 1) && vpos > 0) - hack_vpos = vpos; -} - -STATIC_INLINE uae_u16 VHPOSR (void) -{ - uae_u16 v = vpos << 8; - uae_u16 hp = current_hpos (); - v |= hp; - return v; -} - -STATIC_INLINE void COP1LCH (uae_u16 v) { cop1lc = (cop1lc & 0xffff) | ((uae_u32)v << 16); } -STATIC_INLINE void COP1LCL (uae_u16 v) { cop1lc = (cop1lc & ~0xffff) | (v & 0xfffe); } -STATIC_INLINE void COP2LCH (uae_u16 v) { cop2lc = (cop2lc & 0xffff) | ((uae_u32)v << 16); } -STATIC_INLINE void COP2LCL (uae_u16 v) { cop2lc = (cop2lc & ~0xffff) | (v & 0xfffe); } - -static void COPJMP (int num) -{ - int was_active = eventtab[ev_copper].active; - int oldstrobe = cop_state.strobe; - - eventtab[ev_copper].active = 0; - if (was_active) - events_schedule (); - - cop_state.ignore_next = 0; - cop_state.state = COP_read1; - cop_state.vpos = vpos; - cop_state.hpos = current_hpos () & ~1; - copper_enabled_thisline = 0; - cop_state.strobe = num; - - if (dmaen (DMA_COPPER)) { - copper_enabled_thisline = 1; - set_special (SPCFLAG_COPPER); - } else if (oldstrobe != num) { - /* dma disabled and accessing both COPxJMPs -> copper stops! */ - cop_state.state = COP_stop; - copper_enabled_thisline = 0; - unset_special (SPCFLAG_COPPER); - } -} - -STATIC_INLINE void COPCON (uae_u16 a) -{ - copcon = a; -} - -static void compute_spcflag_copper (void); -static void DMACON (int hpos, uae_u16 v) -{ - int oldcop, newcop; - uae_u16 changed; - - uae_u16 oldcon = dmacon; - - decide_line (hpos); - decide_fetch (hpos); - decide_blitter (hpos); - - setclr (&dmacon, v); - dmacon &= 0x1FFF; - - changed = dmacon ^ oldcon; - - oldcop = (oldcon & DMA_COPPER) && (oldcon & DMA_MASTER); - newcop = (dmacon & DMA_COPPER) && (dmacon & DMA_MASTER); - - if (oldcop != newcop) { - eventtab[ev_copper].active = 0; - if (newcop && !oldcop) { - compute_spcflag_copper (); - } else if (!newcop) { - copper_enabled_thisline = 0; - unset_special (SPCFLAG_COPPER); - } - } - if ((dmacon & DMA_BLITPRI) > (oldcon & DMA_BLITPRI) && bltstate != BLT_done) { - static int count = 0; - if (!count) { - count = 1; - write_log ("warning: program is doing blitpri hacks.\n"); - } - set_special (SPCFLAG_BLTNASTY); - decide_blitter (hpos); - } - if (dmaen (DMA_BLITTER) && bltstate == BLT_init) - bltstate = BLT_work; - if ((dmacon & (DMA_BLITPRI | DMA_BLITTER | DMA_MASTER)) != (DMA_BLITPRI | DMA_BLITTER | DMA_MASTER)) { - unset_special (SPCFLAG_BLTNASTY); - decide_blitter (hpos); - } - if (changed & (DMA_MASTER | 0x0f)) - audio_hsync (0); - if (changed & (DMA_MASTER | DMA_BITPLANE)) { - ddf_change = vpos; - if (dmaen (DMA_BITPLANE)) - maybe_start_bpl_dma (hpos); - } - - events_schedule(); -} - - -#define INTDELAY - -static int intlev_2 (void) -{ - uae_u16 imask = intreq & intena; - unsigned long cycles = get_cycles (); - int c = 4; - int i; - - if (!(imask && (intena & 0x4000))) { - unset_special (SPCFLAG_INT); - return -1; - } - for (i = 14; i >= 0; i--) { - if (imask & (1 << i)) { -#ifdef INTDELAY - if (!(irqdelay[i] && (cycles - irqcycles[i]) < c * CYCLE_UNIT)) { -#endif - irqdelay[i] = 0; - if (i == 13 || i == 14) - return 6; - else if (i == 11 || i == 12) - return 5; - else if (i >= 7 && i <= 10) - return 4; - else if (i >= 4 && i <= 6) - return 3; - else if (i == 3) - return 2; - else - return 1; - } -#ifdef INTDELAY - } -#endif - } - return -1; -} - -int intlev (void) -{ - int il = -1; -#ifdef JIT - if (currprefs.cachesize) { - uae_u16 imask = intreq & intena; - if (imask && (intena & 0x4000)) { - if (imask & 0x6000) - il = 6; - if (imask & 0x1800) - il = 5; - if (imask & 0x0780) - il = 4; - if (imask & 0x0070) - il = 3; - if (imask & 0x0008) - il = 2; - if (imask & 0x0007) - il = 1; - } - } else { -#endif - il = intlev_2 (); - if (il >= 0 && il <= regs.intmask) - unset_special (SPCFLAG_INT); -#ifdef JIT - } -#endif - return il; -} - -static void doint (void) -{ - int i; - uae_u16 imask; - - set_special (SPCFLAG_INT); -#ifdef JIT - if (currprefs.cachesize) - return; -#endif - imask = intreq & intena; - if (imask && (intena & 0x4000)) { - for (i = 0; i < 14; i++) { - if ((imask & (1 << i)) && irqdelay[i] == 0) { - irqdelay[i] = 1; - irqcycles[i] = get_cycles (); - } - } - } -} - -STATIC_INLINE void INTENA (uae_u16 v) -{ - setclr (&intena,v); -#if 0 - if (v & 0x40) - write_log ("INTENA %04.4X (%04.4X) %p\n", intena, v, m68k_getpc ()); -#endif - if (v & 0x8000) - doint (); -} - -void INTREQ_0 (uae_u16 v) -{ - setclr (&intreq,v); - doint (); -} - -void INTREQ (uae_u16 v) -{ - INTREQ_0 (v); - serial_check_irq (); - rethink_cias (); -#if 0 - if (0 || (v & (0x8010)) == 0x8010) - write_log ("%d INTREQ %04.4X (%04.4X) %x %x %x\n", - vpos, intreq, v, m68k_getpc (), cop1lc, cop2lc); -#endif -} - -static void ADKCON (int hpos, uae_u16 v) -{ - if (currprefs.produce_sound > 0) - update_audio (); - - setclr (&adkcon,v); - update_adkmasks (); - DISK_update (hpos); - if ((v >> 11) & 1) - serial_uartbreak ((adkcon >> 11) & 1); -} - -static void BEAMCON0 (uae_u16 v) -{ - if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { - if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) - v &= 0x20; - if (v != new_beamcon0) { - new_beamcon0 = v; - if (v & ~0x20) - write_log ("warning: %04.4X written to BEAMCON0\n", v); - } - } -} - -#ifndef CUSTOM_SIMPLE - -static void dumpsync (void) -{ -#if 0 - write_log ("BEAMCON0 = %04.4X VTOTAL=%04.4X HTOTAL=%04.4X\n", new_beamcon0, vtotal, htotal); - write_log ("HSSTOP=%04.4X HBSTRT=%04.4X HBSTOP=%04.4X\n", hsstop, hbstrt, hbstop); - write_log ("VSSTOP=%04.4X VBSTRT=%04.4X VBSTOP=%04.4X\n", vsstop, vbstrt, vbstop); - write_log ("HSSTRT=%04.4X VSSTRT=%04.4X HCENTER=%04.4X\n", hsstrt, vsstrt, hcenter); -#endif -} - -static void varsync (void) -{ -#ifdef PICASSO96 - if (p96refresh_active) - { - extern int p96hack_vpos2; - static int p96hack_vpos_old; - if (p96hack_vpos_old == p96hack_vpos2) return; - vtotal = p96hack_vpos2; - p96hack_vpos_old = p96hack_vpos2; - hack_vpos = -1; - return; - } -#endif - if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) - return; - if (!(beamcon0 & 0x80)) - return; - hack_vpos = -1; - dumpsync (); -} -#endif - -int is_bitplane_dma (int hpos) -{ - if (fetch_state == fetch_not_started || hpos < thisline_decision.plfleft) - return 0; - if ((passed_plfstop == 3 && hpos >= thisline_decision.plfright) - || hpos >= estimated_last_fetch_cycle) - return 0; - return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; -} - -STATIC_INLINE int is_bitplane_dma_inline (int hpos) -{ - if (fetch_state == fetch_not_started || hpos < thisline_decision.plfleft) - return 0; - if ((passed_plfstop == 3 && hpos >= thisline_decision.plfright) - || hpos >= estimated_last_fetch_cycle) - return 0; - return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; -} - -static void BPLxPTH (int hpos, uae_u16 v, int num) -{ - decide_line (hpos); - decide_fetch (hpos); - bplpt[num] = (bplpt[num] & 0xffff) | ((uae_u32)v << 16); - //write_log ("%d:%d:BPL%dPTH %08.8X\n", hpos, vpos, num, v); -} -static void BPLxPTL (int hpos, uae_u16 v, int num) -{ - int delta = 0; - decide_line (hpos); - decide_fetch (hpos); - /* fix for "bitplane dma fetch at the same time while updating BPLxPTL" */ - /* fixes "3v Demo" by Cave and "New Year Demo" by Phoenix */ - if (is_bitplane_dma(hpos - 1) == num + 1) - delta = 2 << fetchmode; - bplpt[num] = (bplpt[num] & ~0xffff) | ((v + delta) & 0xfffe); - //write_log ("%d:%d:BPL%dPTL %08.8X\n", hpos, vpos, num, v); -} - -static void BPLCON0 (int hpos, uae_u16 v) -{ - if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE)) - v &= ~0x00F1; - else if (! (currprefs.chipset_mask & CSMASK_AGA)) - v &= ~0x00B1; - - if (bplcon0 == v) - return; - - ddf_change = vpos; - decide_line (hpos); - decide_fetch (hpos); - decide_blitter (hpos); - - /* HAM change? */ - if ((bplcon0 ^ v) & 0x800) { - record_color_change (hpos, -1, !! (v & 0x800)); - } - bplcon0 = v; - -#ifdef AGA - if (currprefs.chipset_mask & CSMASK_AGA) { - decide_sprites (hpos); - expand_sprres (); - } -#endif - - expand_fmodes (); - calcdiw (); - estimate_last_fetch_cycle (hpos); -} - -STATIC_INLINE void BPLCON1 (int hpos, uae_u16 v) -{ - if (!(currprefs.chipset_mask & CSMASK_AGA)) - v &= 0xff; - if (bplcon1 == v) - return; - ddf_change = vpos; - decide_line (hpos); - decide_fetch (hpos); - bplcon1 = v; -} - -STATIC_INLINE void BPLCON2 (int hpos, uae_u16 v) -{ - if (!(currprefs.chipset_mask & CSMASK_AGA)) - v &= 0x7f; - if (bplcon2 == v) - return; - decide_line (hpos); - bplcon2 = v; -} - -#ifdef AGA -STATIC_INLINE void BPLCON3 (int hpos, uae_u16 v) -{ - if (! (currprefs.chipset_mask & CSMASK_AGA)) - return; - if (bplcon3 == v) - return; - decide_line (hpos); - decide_sprites (hpos); - bplcon3 = v; - expand_sprres (); -} - -STATIC_INLINE void BPLCON4 (int hpos, uae_u16 v) -{ - if (! (currprefs.chipset_mask & CSMASK_AGA)) - return; - if (bplcon4 == v) - return; - decide_line (hpos); - bplcon4 = v; -} -#endif - -static void BPL1MOD (int hpos, uae_u16 v) -{ - v &= ~1; - if ((uae_s16)bpl1mod == (uae_s16)v) - return; - decide_line (hpos); - decide_fetch (hpos); - bpl1mod = v; -} - -static void BPL2MOD (int hpos, uae_u16 v) -{ - v &= ~1; - if ((uae_s16)bpl2mod == (uae_s16)v) - return; - decide_line (hpos); - decide_fetch (hpos); - bpl2mod = v; -} - -STATIC_INLINE void BPL1DAT (int hpos, uae_u16 v) -{ - decide_line (hpos); - bpl1dat = v; - - maybe_first_bpl1dat (hpos); -} - -#if 0 -/* We could do as well without those... */ -STATIC_INLINE void BPL2DAT (uae_u16 v) { bpl2dat = v; } -STATIC_INLINE void BPL3DAT (uae_u16 v) { bpl3dat = v; } -STATIC_INLINE void BPL4DAT (uae_u16 v) { bpl4dat = v; } -STATIC_INLINE void BPL5DAT (uae_u16 v) { bpl5dat = v; } -STATIC_INLINE void BPL6DAT (uae_u16 v) { bpl6dat = v; } -STATIC_INLINE void BPL7DAT (uae_u16 v) { bpl7dat = v; } -STATIC_INLINE void BPL8DAT (uae_u16 v) { bpl8dat = v; } -#endif - -static void DIWSTRT (int hpos, uae_u16 v) -{ - if (diwstrt == v && ! diwhigh_written) - return; - decide_line (hpos); - diwhigh_written = 0; - diwstrt = v; - calcdiw (); -} - -static void DIWSTOP (int hpos, uae_u16 v) -{ - if (diwstop == v && ! diwhigh_written) - return; - decide_line (hpos); - diwhigh_written = 0; - diwstop = v; - calcdiw (); -} - -static void DIWHIGH (int hpos, uae_u16 v) -{ - if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - return; - if (diwhigh_written && diwhigh == v) - return; - decide_line (hpos); - diwhigh_written = 1; - diwhigh = v; - calcdiw (); -} - -static void DDFSTRT (int hpos, uae_u16 v) -{ - v &= 0xfe; - if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - v &= 0xfc; - if (ddfstrt == v && hpos != plfstrt - 2) - return; - ddf_change = vpos; - decide_line (hpos); - ddfstrt_old_hpos = hpos; - ddfstrt_old_vpos = vpos; - ddfstrt = v; - calcdiw (); - if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) { - static int last_warned; - last_warned = (last_warned + 1) & 4095; - if (last_warned == 0) - write_log ("WARNING! Very strange DDF values (%x %x).\n", ddfstrt, ddfstop); - } -} - -static void DDFSTOP (int hpos, uae_u16 v) -{ - v &= 0xfe; - if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - v &= 0xfc; - if (ddfstop == v) - return; - decide_line (hpos); - decide_fetch (hpos); - decide_blitter (hpos); - ddfstop = v; - calcdiw (); - if (fetch_state != fetch_not_started) - estimate_last_fetch_cycle (hpos); - if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) { - static int last_warned; - if (last_warned == 0) - write_log ("WARNING! Very strange DDF values (%x).\n", ddfstop); - last_warned = (last_warned + 1) & 4095; - } -} - -static void FMODE (uae_u16 v) -{ - if (! (currprefs.chipset_mask & CSMASK_AGA)) - v = 0; - ddf_change = vpos; - fmode = v; - sprite_width = GET_SPRITEWIDTH (fmode); - switch (fmode & 3) { - case 0: - fetchmode = 0; - break; - case 1: - case 2: - fetchmode = 1; - break; - case 3: - fetchmode = 2; - break; - } - expand_fmodes (); - calcdiw (); -} - -static void BLTADAT (uae_u16 v) -{ - maybe_blit (current_hpos(), 0); - - blt_info.bltadat = v; -} -/* - * "Loading data shifts it immediately" says the HRM. Well, that may - * be true for BLTBDAT, but not for BLTADAT - it appears the A data must be - * loaded for every word so that AFWM and ALWM can be applied. - */ -static void BLTBDAT (uae_u16 v) -{ - maybe_blit (current_hpos(), 0); - - if (bltcon1 & 2) - blt_info.bltbhold = v << (bltcon1 >> 12); - else - blt_info.bltbhold = v >> (bltcon1 >> 12); - blt_info.bltbdat = v; -} -static void BLTCDAT (uae_u16 v) { maybe_blit (current_hpos(), 0); blt_info.bltcdat = v; reset_blit (0); } - -static void BLTAMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltamod = (uae_s16)(v & 0xFFFE); reset_blit (0); } -static void BLTBMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltbmod = (uae_s16)(v & 0xFFFE); reset_blit (0); } -static void BLTCMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltcmod = (uae_s16)(v & 0xFFFE); reset_blit (0); } -static void BLTDMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltdmod = (uae_s16)(v & 0xFFFE); reset_blit (0); } - -static void BLTCON0 (uae_u16 v) { maybe_blit (current_hpos(), 2); bltcon0 = v; blinea_shift = v >> 12; reset_blit (1); } -/* The next category is "Most useless hardware register". - * And the winner is... */ -static void BLTCON0L (uae_u16 v) -{ - if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - return; - maybe_blit (current_hpos(), 2); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); - reset_blit (1); -} -static void BLTCON1 (uae_u16 v) { maybe_blit (current_hpos(), 2); bltcon1 = v; reset_blit (2); } - -static void BLTAFWM (uae_u16 v) { maybe_blit (current_hpos(), 2); blt_info.bltafwm = v; reset_blit (0); } -static void BLTALWM (uae_u16 v) { maybe_blit (current_hpos(), 2); blt_info.bltalwm = v; reset_blit (0); } - -static void BLTAPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltapt = (bltapt & 0xffff) | ((uae_u32)v << 16); } -static void BLTAPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltapt = (bltapt & ~0xffff) | (v & 0xFFFE); } -static void BLTBPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltbpt = (bltbpt & 0xffff) | ((uae_u32)v << 16); } -static void BLTBPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltbpt = (bltbpt & ~0xffff) | (v & 0xFFFE); } -static void BLTCPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltcpt = (bltcpt & 0xffff) | ((uae_u32)v << 16); } -static void BLTCPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltcpt = (bltcpt & ~0xffff) | (v & 0xFFFE); } -static void BLTDPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltdpt = (bltdpt & 0xffff) | ((uae_u32)v << 16); } -static void BLTDPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltdpt = (bltdpt & ~0xffff) | (v & 0xFFFE); } - -static void BLTSIZE (uae_u16 v) -{ - maybe_blit (current_hpos(), 0); - - blt_info.vblitsize = v >> 6; - blt_info.hblitsize = v & 0x3F; - if (!blt_info.vblitsize) blt_info.vblitsize = 1024; - if (!blt_info.hblitsize) blt_info.hblitsize = 64; - do_blitter (current_hpos()); -} - -static void BLTSIZV (uae_u16 v) -{ - if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - return; - maybe_blit (current_hpos(), 0); - blt_info.vblitsize = v & 0x7FFF; -} - -static void BLTSIZH (uae_u16 v) -{ - if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - return; - maybe_blit (current_hpos(), 0); - blt_info.hblitsize = v & 0x7FF; - if (!blt_info.vblitsize) - blt_info.vblitsize = 32768; - if (!blt_info.hblitsize) - blt_info.hblitsize = 0x800; - do_blitter (current_hpos()); -} - -STATIC_INLINE spr_arm (int num, int state) -{ - switch (state) - { - case 0: - nr_armed -= spr[num].armed; - spr[num].armed = 0; - break; - default: - nr_armed += 1 - spr[num].armed; - spr[num].armed = 1; - break; - } -} - -STATIC_INLINE void sprstartstop (struct sprite *s) -{ - if (vpos == s->vstart) - s->dmastate = 1; - if (vpos == s->vstop) - s->dmastate = 0; -} - -STATIC_INLINE void SPRxCTLPOS (int num) -{ - int sprxp; - struct sprite *s = &spr[num]; - - sprstartstop (s); - sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1); - /* Quite a bit salad in this register... */ -#ifdef AGA - if (currprefs.chipset_mask & CSMASK_AGA) { - /* We ignore the SHRES 35ns increment for now; SHRES support doesn't - work anyway, so we may as well restrict AGA sprites to a 70ns - resolution. */ - sprxp <<= 1; - sprxp |= (sprctl[num] >> 4) & 1; - } -#endif - s->xpos = sprxp; - s->vstart = (sprpos[num] >> 8) | ((sprctl[num] << 6) & 0x100); - s->vstop = (sprctl[num] >> 8) | ((sprctl[num] << 7) & 0x100); - if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { - s->vstart |= (sprctl[num] << 3) & 0x200; - s->vstop |= (sprctl[num] << 4) & 0x200; - } - sprstartstop (s); -} - -STATIC_INLINE void SPRxCTL_1 (uae_u16 v, int num, int hpos) -{ - struct sprite *s = &spr[num]; - sprctl[num] = v; - spr_arm (num, 0); - SPRxCTLPOS (num); -#if SPRITE_DEBUG > 0 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dCTL %04.4X P=%06.6X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n", - vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, m68k_getpc ()); - } -#endif - -} -STATIC_INLINE void SPRxPOS_1 (uae_u16 v, int num, int hpos) -{ - struct sprite *s = &spr[num]; - sprpos[num] = v; - SPRxCTLPOS (num); -#if SPRITE_DEBUG > 0 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dPOS %04.4X P=%06.6X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n", - vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, m68k_getpc()); - } -#endif -} -STATIC_INLINE void SPRxDATA_1 (uae_u16 v, int num, int hpos) -{ - sprdata[num][0] = v; -#ifdef AGA - sprdata[num][1] = v; - sprdata[num][2] = v; - sprdata[num][3] = v; -#endif - spr_arm (num, 1); -#if SPRITE_DEBUG > 1 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dDATA %04.4X P=%06.6X D=%d A=%d PC=%x\n", - vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, m68k_getpc()); - } -#endif -} -STATIC_INLINE void SPRxDATB_1 (uae_u16 v, int num, int hpos) -{ - sprdatb[num][0] = v; -#ifdef AGA - sprdatb[num][1] = v; - sprdatb[num][2] = v; - sprdatb[num][3] = v; -#endif -#if SPRITE_DEBUG > 1 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dDATB %04.4X P=%06.6X D=%d A=%d PC=%x\n", - vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, m68k_getpc()); - } -#endif -} -static void SPRxDATA (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxDATA_1 (v, num, hpos); } -static void SPRxDATB (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxDATB_1 (v, num, hpos); } -static void SPRxCTL (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxCTL_1 (v, num, hpos); } -static void SPRxPOS (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxPOS_1 (v, num, hpos); } -static void SPRxPTH (int hpos, uae_u16 v, int num) -{ - decide_sprites (hpos); - spr[num].pt &= 0xffff; - spr[num].pt |= (uae_u32)v << 16; -#if SPRITE_DEBUG > 0 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dPTH %06.6X\n", vpos, hpos, num, spr[num].pt); - } -#endif -} -static void SPRxPTL (int hpos, uae_u16 v, int num) -{ - decide_sprites (hpos); - spr[num].pt &= ~0xffff; - spr[num].pt |= v; -#if SPRITE_DEBUG > 0 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:SPR%dPTL %06.6X\n", vpos, hpos, num, spr[num].pt); - } -#endif -} - -static void CLXCON (uae_u16 v) -{ - clxcon = v; - clxcon_bpl_enable = (v >> 6) & 63; - clxcon_bpl_match = v & 63; - //write_log ("CLXCON: %04.4X PC=%x\n", v, m68k_getpc ()); -} - -static void CLXCON2 (uae_u16 v) -{ - if (!(currprefs.chipset_mask & CSMASK_AGA)) - return; - clxcon2 = v; - clxcon_bpl_enable |= v & (0x40|0x80); - clxcon_bpl_match |= (v & (0x01|0x02)) << 6; - //write_log ("CLXCON2: %04.4X\n", v); -} - -static uae_u16 CLXDAT (void) -{ - uae_u16 v = clxdat | 0x8000; - //write_log ("%d:CLXDAT %04.4X PC=%x\n", vpos, v, m68k_getpc ()); - clxdat = 0; - return v; -} - -#ifdef AGA -static uae_u16 COLOR_READ (int num) -{ - int cr, cg, cb, colreg; - uae_u16 cval; - - if (!(currprefs.chipset_mask & CSMASK_AGA) || !(bplcon2 & 0x0100)) - return 0xffff; - - colreg = ((bplcon3 >> 13) & 7) * 32 + num; - cr = current_colors.color_regs_aga[colreg] >> 16; - cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF; - cb = current_colors.color_regs_aga[colreg] & 0xFF; - if (bplcon3 & 0x200) - cval = ((cr & 15) << 8) | ((cg & 15) << 4) | ((cb & 15) << 0); - else - cval = ((cr >> 4) << 8) | ((cg >> 4) << 4) | ((cb >> 4) << 0); - return cval; -} -#endif - -static void COLOR_WRITE (int hpos, uae_u16 v, int num) -{ - v &= 0xFFF; -#ifdef AGA - if (currprefs.chipset_mask & CSMASK_AGA) { - int r,g,b; - int cr,cg,cb; - int colreg; - uae_u32 cval; - - /* writing is disabled when RDRAM=1 */ - if (bplcon2 & 0x0100) - return; - - colreg = ((bplcon3 >> 13) & 7) * 32 + num; - r = (v & 0xF00) >> 8; - g = (v & 0xF0) >> 4; - b = (v & 0xF) >> 0; - cr = current_colors.color_regs_aga[colreg] >> 16; - cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF; - cb = current_colors.color_regs_aga[colreg] & 0xFF; - - if (bplcon3 & 0x200) { - cr &= 0xF0; cr |= r; - cg &= 0xF0; cg |= g; - cb &= 0xF0; cb |= b; - } else { - cr = r + (r << 4); - cg = g + (g << 4); - cb = b + (b << 4); - } - cval = (cr << 16) | (cg << 8) | cb; - if (cval == current_colors.color_regs_aga[colreg]) - return; - - /* Call this with the old table still intact. */ - record_color_change (hpos, colreg, cval); - remembered_color_entry = -1; - current_colors.color_regs_aga[colreg] = cval; - current_colors.acolors[colreg] = CONVERT_RGB (cval); - } else { -#endif - if (current_colors.color_regs_ecs[num] == v) - return; - /* Call this with the old table still intact. */ - record_color_change (hpos, num, v); - remembered_color_entry = -1; - current_colors.color_regs_ecs[num] = v; - current_colors.acolors[num] = xcolors[v]; -#ifdef AGA - } -#endif -} - -/* The copper code. The biggest nightmare in the whole emulator. - - Alright. The current theory: - 1. Copper moves happen 2 cycles after state READ2 is reached. - It can't happen immediately when we reach READ2, because the - data needs time to get back from the bus. An additional 2 - cycles are needed for non-Agnus registers, to take into account - the delay for moving data from chip to chip. - 2. As stated in the HRM, a WAIT really does need an extra cycle - to wake up. This is implemented by _not_ falling through from - a successful wait to READ1, but by starting the next cycle. - (Note: the extra cycle for the WAIT apparently really needs a - free cycle; i.e. contention with the bitplane fetch can slow - it down). - 3. Apparently, to compensate for the extra wake up cycle, a WAIT - will use the _incremented_ horizontal position, so the WAIT - cycle normally finishes two clocks earlier than the position - it was waiting for. The extra cycle then takes us to the - position that was waited for. - If the earlier cycle is busy with a bitplane, things change a bit. - E.g., waiting for position 0x50 in a 6 plane display: In cycle - 0x4e, we fetch BPL5, so the wait wakes up in 0x50, the extra cycle - takes us to 0x54 (since 0x52 is busy), then we have READ1/READ2, - and the next register write is at 0x5c. - 4. The last cycle in a line is not usable for the copper. - 5. A 4 cycle delay also applies to the WAIT instruction. This means - that the second of two back-to-back WAITs (or a WAIT whose - condition is immediately true) takes 8 cycles. - 6. This also applies to a SKIP instruction. The copper does not - fetch the next instruction while waiting for the second word of - a WAIT or a SKIP to arrive. - 7. A SKIP also seems to need an unexplained additional two cycles - after its second word arrives; this is _not_ a memory cycle (I - think, the documentation is pretty clear on this). - 8. Two additional cycles are inserted when writing to COPJMP1/2. */ - -/* Determine which cycles are available for the copper in a display - * with a agiven number of planes. */ - -STATIC_INLINE int copper_cant_read (int hpos) -{ - if (hpos + 1 >= maxhpos) - return 1; - return is_bitplane_dma_inline (hpos); -} - -STATIC_INLINE int dangerous_reg (int reg) -{ - /* Safe: - * Bitplane pointers, control registers, modulos and data. - * Sprite pointers, control registers, and data. - * Color registers. */ - if (reg >= 0xE0 && reg < 0x1C0) - return 0; - return 1; -} - -#define FAST_COPPER 1 - -/* The future, Conan? - We try to look ahead in the copper list to avoid doing continuous calls - to updat_copper (which is what happens when SPCFLAG_COPPER is set). If - we find that the same effect can be achieved by setting a delayed event - and then doing multiple copper insns in one batch, we can get a massive - speedup. - - We don't try to be precise here. All copper reads take exactly 2 cycles, - the effect of bitplane contention is ignored. Trying to get it exactly - right would be much more complex and as such carry a huge risk of getting - it subtly wrong; and it would also be more expensive - we want this code - to be fast. */ -static void predict_copper (void) -{ - uaecptr ip = cop_state.ip; - unsigned int c_hpos = cop_state.hpos; - enum copper_states state = cop_state.state; - unsigned int w1, w2, cycle_count; - - switch (state) { - case COP_read1_wr_in2: - case COP_read2_wr_in2: - case COP_read1_wr_in4: - if (dangerous_reg (cop_state.saved_i1)) - return; - state = state == COP_read2_wr_in2 ? COP_read2 : COP_read1; - break; - - case COP_read1_in2: - c_hpos += 2; - state = COP_read1; - break; - - case COP_stop: - case COP_bltwait: - case COP_wait1: - case COP_skip_in4: - case COP_skip_in2: - case COP_skip1: - case COP_strobe_delay: - return; - - case COP_wait_in4: - c_hpos += 2; - /* fallthrough */ - case COP_wait_in2: - c_hpos += 2; - /* fallthrough */ - case COP_wait: - state = COP_wait; - break; - - default: - break; - } - - /* Only needed for COP_wait, but let's shut up the compiler. */ - w1 = cop_state.saved_i1; - w2 = cop_state.saved_i2; - cop_state.first_sync = c_hpos; - cop_state.regtypes_modified = REGTYPE_FORCE; - - /* Get this case out of the way, so that the loop below only has to deal - with read1 and wait. */ - if (state == COP_read2) { - w1 = cop_state.i1; - if (w1 & 1) { - w2 = chipmem_agnus_wget (ip); - if (w2 & 1) - goto done; - state = COP_wait; - c_hpos += 4; - } else if (dangerous_reg (w1)) { - c_hpos += 4; - goto done; - } else { - cop_state.regtypes_modified |= regtypes[w1 & 0x1FE]; - state = COP_read1; - c_hpos += 2; - } - ip += 2; - } - - while (c_hpos + 1 < maxhpos) { - if (state == COP_read1) { - w1 = chipmem_agnus_wget (ip); - if (w1 & 1) { - w2 = chipmem_agnus_wget (ip + 2); - if (w2 & 1) - break; - state = COP_wait; - c_hpos += 6; - } else if (dangerous_reg (w1)) { - c_hpos += 6; - break; - } else { - cop_state.regtypes_modified |= regtypes[w1 & 0x1FE]; - c_hpos += 4; - } - ip += 4; - } else if (state == COP_wait) { - if ((w2 & 0xFE) != 0xFE) - break; - else { - unsigned int vcmp = (w1 & (w2 | 0x8000)) >> 8; - unsigned int hcmp = (w1 & 0xFE); - - unsigned int vp = vpos & (((w2 >> 8) & 0x7F) | 0x80); - if (vp < vcmp) { - /* Whee. We can wait until the end of the line! */ - c_hpos = maxhpos; - } else if (vp > vcmp || hcmp <= c_hpos) { - state = COP_read1; - /* minimum wakeup time */ - c_hpos += 2; - } else { - state = COP_read1; - c_hpos = hcmp; - } - /* If this is the current instruction, remember that we don't - need to sync CPU and copper anytime soon. */ - if (cop_state.ip == ip) { - cop_state.first_sync = c_hpos; - } - } - } else - uae_abort ("predict copper %d", state); - } - - done: - cycle_count = c_hpos - cop_state.hpos; - if (cycle_count >= 8) { - unset_special (SPCFLAG_COPPER); - eventtab[ev_copper].active = 1; - eventtab[ev_copper].oldcycles = get_cycles (); - eventtab[ev_copper].evtime = get_cycles () + cycle_count * CYCLE_UNIT; - events_schedule (); - } -} - -static int test_copper_dangerous (unsigned int address) -{ - if ((address & 0x1fe) < (copcon & 2 ? ((currprefs.chipset_mask & CSMASK_AGA) ? 0 : 0x40u) : 0x80u)) { - cop_state.state = COP_stop; - copper_enabled_thisline = 0; - unset_special (SPCFLAG_COPPER); - return 1; - } - return 0; -} - -static void perform_copper_write (int old_hpos) -{ - unsigned int address = cop_state.saved_i1 & 0x1FE; - - record_copper (cop_state.saved_ip - 4, old_hpos, vpos); - - if (test_copper_dangerous (address)) - return; - if (address == 0x88) { - cop_state.ip = cop1lc; - cop_state.state = COP_strobe_delay; - } else if (address == 0x8A) { - cop_state.ip = cop2lc; - cop_state.state = COP_strobe_delay; - } else { - custom_wput_1 (old_hpos, cop_state.saved_i1, cop_state.saved_i2, 0); - cop_state.last_write = cop_state.saved_i1; - cop_state.last_write_hpos = old_hpos; - old_hpos++; - if (cop_state.saved_i1 >= 0x140 && cop_state.saved_i1 < 0x180 && old_hpos >= SPR0_HPOS && old_hpos < SPR0_HPOS + 4 * MAX_SPRITES) { - //write_log ("%d:%d %04.4X:%04.4X\n", vpos, old_hpos, cop_state.saved_i1, cop_state.saved_i2); - do_sprites (old_hpos); - } - } -} - -static int isagnus[]= { - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 27 0x40 - 0x74 */ - - 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 21 */ - 1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0, /* 32 0xa0 - 0xde - /* BPLxPTH/BPLxPTL */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */ - /* BPLCON0-3,BPLMOD1-2 */ - 0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, /* 16 */ - /* SPRxPTH/SPRxPTL */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */ - /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - /* COLORxx */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - /* RESERVED */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -static void dump_copper (char *error, int until_hpos) -{ - write_log("%s: vpos=%d until_hpos=%d\n", - error, vpos, until_hpos); - write_log("cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04.4X ci2=%04.4X\n", - cop_state.vcmp,cop_state.hcmp,cop_state.hpos,cop_state.vpos,cop_state.saved_i1,cop_state.saved_i2); - write_log("cstate=%d ip=%08.8X ev_copper=%d\n", - cop_state.state,cop_state.ip,eventtab[ev_copper].active); -} - -static void update_copper (int until_hpos) -{ - int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); - int c_hpos = cop_state.hpos; - - if (eventtab[ev_copper].active) { - static int warned; - if (!warned) { - dump_copper ("error1",until_hpos); - warned = 1; - } - eventtab[ev_copper].active = 0; - return; - uae_abort ("update_copper1"); - } - - if (cop_state.state == COP_wait && vp < cop_state.vcmp) { - static int warned; - if (!warned) { - dump_copper ("error2",until_hpos); - warned = 1; - } - copper_enabled_thisline = 0; - return; - uae_abort ("update_copper2"); - } - - until_hpos &= ~1; - - if (until_hpos > (maxhpos & ~1)) - until_hpos = maxhpos & ~1; - - until_hpos += 2; - for (;;) { - int old_hpos = c_hpos; - int hp; - - if (c_hpos >= until_hpos) - break; - - /* So we know about the fetch state. */ - decide_line (c_hpos); - - switch (cop_state.state) { - case COP_read1_in2: - cop_state.state = COP_read1; - break; - case COP_read1_wr_in2: - cop_state.state = COP_read1; - perform_copper_write (old_hpos); - /* That could have turned off the copper. */ - if (! copper_enabled_thisline) - goto out; - - break; - case COP_read1_wr_in4: - cop_state.state = COP_read1_wr_in2; - break; - case COP_read2_wr_in2: - cop_state.state = COP_read2; - perform_copper_write (old_hpos); - /* That could have turned off the copper. */ - if (! copper_enabled_thisline) - goto out; - - break; - case COP_wait_in2: - cop_state.state = COP_wait1; - break; - case COP_wait_in4: - cop_state.state = COP_wait_in2; - break; - case COP_skip_in2: - cop_state.state = COP_skip1; - break; - case COP_skip_in4: - cop_state.state = COP_skip_in2; - break; - case COP_strobe_delay: - cop_state.state = COP_read1_in2; - break; - - default: - break; - } - - c_hpos += 2; -#if 0 - if (copper_cant_read (old_hpos)) - continue; -#endif - if (cop_state.strobe) { - if (cop_state.strobe > 0) - cop_state.ip = cop_state.strobe == 1 ? cop1lc : cop2lc; - cop_state.strobe = 0; - } - - switch (cop_state.state) { - - case COP_read1_wr_in4: - uae_abort ("COP_read1_wr_in4"); - - case COP_read1_wr_in2: - case COP_read1: - if (copper_cant_read (old_hpos)) - continue; - cop_state.i1 = chipmem_agnus_wget (cop_state.ip); -#ifdef CPUEMU_6 - cycle_line[old_hpos] |= CYCLE_COPPER; -#endif - cop_state.ip += 2; - cop_state.state = cop_state.state == COP_read1 ? COP_read2 : COP_read2_wr_in2; - break; - - case COP_read2_wr_in2: - uae_abort ("read2_wr_in2"); - - case COP_read2: - if (copper_cant_read (old_hpos)) - continue; - cop_state.i2 = chipmem_agnus_wget (cop_state.ip); -#ifdef CPUEMU_6 - cycle_line[old_hpos] |= CYCLE_COPPER; -#endif - cop_state.ip += 2; - if (cop_state.ignore_next) { - cop_state.ignore_next = 0; - cop_state.state = COP_read1; - break; - } - - cop_state.saved_i1 = cop_state.i1; - cop_state.saved_i2 = cop_state.i2; - cop_state.saved_ip = cop_state.ip; - - if (cop_state.i1 & 1) { - if (cop_state.i2 & 1) - cop_state.state = COP_skip_in4; - else - cop_state.state = COP_wait_in4; - } else { - unsigned int reg = cop_state.i1 & 0x1FE; - cop_state.state = isagnus[reg >> 1] ? COP_read1_wr_in2 : COP_read1_wr_in4; - } - break; - - case COP_wait1: - /* There's a nasty case here. As stated in the "Theory" comment above, we - test against the incremented copper position. I believe this means that - we have to increment the _vertical_ position at the last cycle in the line, - and set the horizontal position to 0. - Normally, this isn't going to make a difference, since we consider these - last cycles unavailable for the copper, so waking up in the last cycle has - the same effect as waking up at the start of the line. However, there is - one possible problem: If we're at 0xFFE0, any wait for an earlier position - must _not_ complete (since, in effect, the current position will be back - at 0/0). This can be seen in the Superfrog copper list. - Things get monstrously complicated if we try to handle this "properly" by - incrementing vpos and setting c_hpos to 0. Especially the various speedup - hacks really assume that vpos remains constant during one line. Hence, - this hack: defer the entire decision until the next line if necessary. */ - if (c_hpos >= (maxhpos & ~1)) - break; - - cop_state.state = COP_wait; - - cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; - cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xFE); - - vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); - - if (cop_state.saved_i1 == 0xFFFF && cop_state.saved_i2 == 0xFFFE) { - cop_state.state = COP_stop; - copper_enabled_thisline = 0; - unset_special (SPCFLAG_COPPER); - goto out; - } - if (vp < cop_state.vcmp) { - copper_enabled_thisline = 0; - unset_special (SPCFLAG_COPPER); - goto out; - } - - /* fall through */ - case COP_wait: - if (vp < cop_state.vcmp) - uae_abort ("vp < cop_state.vcmp"); - if (copper_cant_read (old_hpos)) - continue; - - hp = c_hpos & (cop_state.saved_i2 & 0xFE); - if (vp == cop_state.vcmp && hp < cop_state.hcmp) { - /* Position not reached yet. */ - if (currprefs.fast_copper && FAST_COPPER && (cop_state.saved_i2 & 0xFE) == 0xFE) { - int wait_finish = cop_state.hcmp - 2; - /* This will leave c_hpos untouched if it's equal to wait_finish. */ - if (wait_finish < c_hpos) - uae_abort ("wait_finish < c_hpos"); - else if (wait_finish <= until_hpos) { - c_hpos = wait_finish; - } else - c_hpos = until_hpos; - } - break; - } - - /* Now we know that the comparisons were successful. We might still - have to wait for the blitter though. */ - if ((cop_state.saved_i2 & 0x8000) == 0 && (DMACONR() & 0x4000)) { - /* We need to wait for the blitter. */ - cop_state.state = COP_bltwait; - copper_enabled_thisline = 0; - unset_special (SPCFLAG_COPPER); - goto out; - } - - record_copper (cop_state.ip - 4, old_hpos, vpos); - - cop_state.state = COP_read1; - break; - - case COP_skip1: - { - static int skipped_before; - unsigned int vcmp, hcmp, vp1, hp1; - - if (! skipped_before) { - skipped_before = 1; - write_log ("Program uses Copper SKIP instruction.\n"); - } - - if (c_hpos >= (maxhpos & ~1)) - break; - - vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; - hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xFE); - vp1 = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); - hp1 = c_hpos & (cop_state.saved_i2 & 0xFE); - - if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) - && ((cop_state.saved_i2 & 0x8000) != 0 || ! (DMACONR() & 0x4000))) - cop_state.ignore_next = 1; - if (chipmem_agnus_wget (cop_state.ip) & 1) { /* FIXME: HACK!!! */ - /* copper never skips if following instruction is WAIT or another SKIP... */ - cop_state.ignore_next = 0; - } - - cop_state.state = COP_read1; - - if (cop_state.ignore_next && (chipmem_agnus_wget (cop_state.ip) & 1) == 0) { - /* another undocumented copper feature: - copper stops if skipped instruction is MOVE to dangerous register... - */ - test_copper_dangerous (chipmem_agnus_wget(cop_state.ip)); - } - - record_copper (cop_state.ip - 4, old_hpos, vpos); - - break; - } - default: - break; - } - } - - out: - cop_state.hpos = c_hpos; - - /* The test against maxhpos also prevents us from calling predict_copper - when we are being called from hsync_handler, which would not only be - stupid, but actively harmful. */ - if (currprefs.fast_copper && FAST_COPPER && (regs.spcflags & SPCFLAG_COPPER) && c_hpos + 8 < maxhpos) - predict_copper (); -} - -static void compute_spcflag_copper (void) -{ - copper_enabled_thisline = 0; - unset_special (SPCFLAG_COPPER); - if (! dmaen (DMA_COPPER) || cop_state.state == COP_stop || cop_state.state == COP_bltwait) - return; - - if (cop_state.state == COP_wait) { - int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); - - if (vp < cop_state.vcmp) - return; - } - copper_enabled_thisline = 1; - - if (currprefs.fast_copper && FAST_COPPER) - predict_copper (); - - if (! eventtab[ev_copper].active) - set_special (SPCFLAG_COPPER); -} - -static void copper_handler (void) -{ - /* This will take effect immediately, within the same cycle. */ - set_special (SPCFLAG_COPPER); - - if (! copper_enabled_thisline) - uae_abort ("copper_handler"); - - eventtab[ev_copper].active = 0; -} - -void blitter_done_notify (void) -{ - if (cop_state.state != COP_bltwait) - return; - - cop_state.hpos = current_hpos () & ~1; - cop_state.vpos = vpos; - cop_state.state = COP_wait; - compute_spcflag_copper (); -} - -void do_copper (void) -{ - int hpos = current_hpos (); - update_copper (hpos); -} - -/* ADDR is the address that is going to be read/written; this access is - the reason why we want to update the copper. This function is also - used from hsync_handler to finish up the line; for this case, we check - hpos against maxhpos. */ -STATIC_INLINE void sync_copper_with_cpu (int hpos, int do_schedule, unsigned int addr) -{ - /* Need to let the copper advance to the current position. */ - if (eventtab[ev_copper].active) { - if (hpos != maxhpos) { - /* There might be reasons why we don't actually need to bother - updating the copper. */ - if (hpos < cop_state.first_sync) - return; - - if ((cop_state.regtypes_modified & regtypes[addr & 0x1FE]) == 0) - return; - } - - eventtab[ev_copper].active = 0; - if (do_schedule) - events_schedule (); - set_special (SPCFLAG_COPPER); - } - if (copper_enabled_thisline) - update_copper (hpos); -} - -STATIC_INLINE uae_u16 sprite_fetch (struct sprite *s, int dma, int hpos, int cycle, int mode) -{ - uae_u16 data = last_custom_value; - if (dma) { - data = last_custom_value = chipmem_agnus_wget (s->pt); -#ifdef CPUEMU_6 - cycle_line[hpos] |= CYCLE_SPRITE; -#endif - } - s->pt += 2; - return data; -} - -STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) -{ - struct sprite *s = &spr[num]; - int dma, posctl = 0; - uae_u16 data; - - if (vpos == sprite_vblank_endline) - spr_arm (num, 0); - -#if SPRITE_DEBUG > 3 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) - write_log ("%d:%d:slot%d:%d\n", vpos, hpos, num, cycle); -#endif - if (vpos == s->vstart) { -#if SPRITE_DEBUG > 0 - if (!s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) - write_log ("%d:%d:SPR%d START\n", vpos, hpos, num); -#endif - s->dmastate = 1; - } - if (vpos == s->vstop || vpos == sprite_vblank_endline) { -#if SPRITE_DEBUG > 0 - if (s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) - write_log ("%d:%d:SPR%d STOP\n", vpos, hpos, num); -#endif - s->dmastate = 0; - } - if (!dmaen (DMA_SPRITE)) - return; - if (cycle && !s->dmacycle) - return; /* Superfrog intro flashing bee fix */ - - - dma = hpos < plfstrt || diwstate != DIW_waiting_stop || !dmaen (DMA_BITPLANE); - if (vpos == s->vstop || vpos == sprite_vblank_endline) { - s->dmastate = 0; - posctl = 1; - if (dma) { - data = sprite_fetch (s, dma, hpos, cycle, 0); - switch (sprite_width) - { - case 64: - sprite_fetch (s, dma, hpos, cycle, 0); - sprite_fetch (s, dma, hpos, cycle, 0); - case 32: - sprite_fetch (s, dma, hpos, cycle, 0); - break; - } - } else { - data = cycle == 0 ? sprpos[num] : sprctl[num]; - } -#if SPRITE_DEBUG > 1 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:dma:P=%06.6X ", vpos, hpos, s->pt); - } -#endif - //write_log ("%d:%d: %04.4X=%04.4X\n", vpos, hpos, 0x140 + cycle * 2 + num * 8, data); - if (cycle == 0) { - SPRxPOS_1 (data, num, hpos); - s->dmacycle = 1; - } else { - SPRxCTL_1 (data, num, hpos); - s->dmastate = 0; - sprstartstop (s); - } - } - if (s->dmastate && !posctl) { - uae_u16 data; - - data = sprite_fetch (s, dma, hpos, cycle, 1); - /* Hack for X mouse auto-calibration */ - if (num == 0 && cycle == 0) - mousehack_handle (sprctl[0], sprpos[0]); -#if SPRITE_DEBUG > 1 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { - write_log ("%d:%d:dma:P=%06.6X ", vpos, hpos, s->pt); - } -#endif - if (cycle == 0) { - SPRxDATA_1 (dma ? data : sprdata[num][0], num, hpos); - s->dmacycle = 1; - } else { - SPRxDATB_1 (dma ? data : sprdatb[num][0], num, hpos); - spr_arm (num, 1); - } -#ifdef AGA - switch (sprite_width) - { - case 64: - { - uae_u16 data32 = sprite_fetch (s, dma, hpos, cycle, 1); - uae_u16 data641 = sprite_fetch (s, dma, hpos, cycle, 1); - uae_u16 data642 = sprite_fetch (s, dma, hpos, cycle, 1); - if (dma) { - if (cycle == 0) { - sprdata[num][3] = data642; - sprdata[num][2] = data641; - sprdata[num][1] = data32; - } else { - sprdatb[num][3] = data642; - sprdatb[num][2] = data641; - sprdatb[num][1] = data32; - } - } - } - break; - case 32: - { - uae_u16 data32 = sprite_fetch (s, dma, hpos, cycle, 1); - if (dma) { - if (cycle == 0) - sprdata[num][1] = data32; - else - sprdatb[num][1] = data32; - } - } - break; - } -#endif - } -} - -static void do_sprites (int hpos) -{ - int maxspr, minspr; - int i; - - /* I don't know whether this is right. Some programs write the sprite pointers - * directly at the start of the copper list. With the test against currvp, the - * first two words of data are read on the second line in the frame. The problem - * occurs when the program jumps to another copperlist a few lines further down - * which _also_ writes the sprite pointer registers. This means that a) writing - * to the sprite pointers sets the state to SPR_restart; or b) that sprite DMA - * is disabled until the end of the vertical blanking interval. The HRM - * isn't clear - it says that the vertical sprite position can be set to any - * value, but this wouldn't be the first mistake... */ - /* Update: I modified one of the programs to write the sprite pointers the - * second time only _after_ the VBlank interval, and it showed the same behaviour - * as it did unmodified under UAE with the above check. This indicates that the - * solution below is correct. */ - /* Another update: seems like we have to use the NTSC value here (see Sanity Turmoil - * demo). */ - /* Maximum for Sanity Turmoil: 27. - Minimum for Sanity Arte: 22. */ - if (vpos < sprite_vblank_endline) - return; - -#ifndef CUSTOM_SIMPLE - maxspr = hpos; - minspr = last_sprite_hpos; - - if (minspr >= SPR0_HPOS + MAX_SPRITES * 4 || maxspr < SPR0_HPOS) - return; - - if (maxspr > SPR0_HPOS + MAX_SPRITES * 4) - maxspr = SPR0_HPOS + MAX_SPRITES * 4; - if (minspr < SPR0_HPOS) - minspr = SPR0_HPOS; - - for (i = minspr; i < maxspr; i++) { - int cycle = -1; - int num = (i - SPR0_HPOS) / 4; - switch ((i - SPR0_HPOS) & 3) - { - case 0: - cycle = 0; - spr[num].dmacycle = 0; - break; - case 2: - cycle = 1; - break; - } - if (cycle >= 0) - do_sprites_1 (num, cycle, i); - } - last_sprite_hpos = hpos; -#else - for (i = 0; i < MAX_SPRITES * 2; i++) { - spr[i / 2].dmacycle = 1; - do_sprites_1 (i / 2, i & 1, 0); - } -#endif -} - -static void init_sprites (void) -{ - memset (sprpos, 0, sizeof sprpos); - memset (sprctl, 0, sizeof sprctl); -} - -static void adjust_array_sizes (void) -{ -#ifdef OS_WITHOUT_MEMORY_MANAGEMENT - if (delta_sprite_entry) { - void *p1,*p2; - int mcc = max_sprite_entry + 50 + delta_sprite_entry; - delta_sprite_entry = 0; - p1 = realloc (sprite_entries[0], mcc * sizeof (struct sprite_entry)); - p2 = realloc (sprite_entries[1], mcc * sizeof (struct sprite_entry)); - if (p1) sprite_entries[0] = p1; - if (p2) sprite_entries[1] = p2; - if (p1 && p2) { - write_log ("new max_sprite_entry=%d\n",mcc); - max_sprite_entry = mcc; - } - } - if (delta_color_change) { - void *p1,*p2; - int mcc = max_color_change + 200 + delta_color_change; - delta_color_change = 0; - p1 = realloc (color_changes[0], mcc * sizeof (struct color_change)); - p2 = realloc (color_changes[1], mcc * sizeof (struct color_change)); - if (p1) color_changes[0] = p1; - if (p2) color_changes[1] = p2; - if (p1 && p2) { - write_log ("new max_color_change=%d\n",mcc); - max_color_change = mcc; - } - } -#endif -} - -static void init_hardware_frame (void) -{ - next_lineno = 0; - nextline_how = nln_normal; - diwstate = DIW_waiting_start; - hdiwstate = DIW_waiting_start; - ddfstate = DIW_waiting_start; -} - -void init_hardware_for_drawing_frame (void) -{ - adjust_array_sizes (); - - /* Avoid this code in the first frame after a customreset. */ - if (prev_sprite_entries) { - int first_pixel = prev_sprite_entries[0].first_pixel; - int npixels = prev_sprite_entries[prev_next_sprite_entry].first_pixel - first_pixel; - memset (spixels + first_pixel, 0, npixels * sizeof *spixels); - memset (spixstate.bytes + first_pixel, 0, npixels * sizeof *spixstate.bytes); - } - prev_next_sprite_entry = next_sprite_entry; - - next_color_change = 0; - next_sprite_entry = 0; - next_color_entry = 0; - remembered_color_entry = -1; - - prev_sprite_entries = sprite_entries[current_change_set]; - curr_sprite_entries = sprite_entries[current_change_set ^ 1]; - prev_color_changes = color_changes[current_change_set]; - curr_color_changes = color_changes[current_change_set ^ 1]; - prev_color_tables = color_tables[current_change_set]; - curr_color_tables = color_tables[current_change_set ^ 1]; - - prev_drawinfo = line_drawinfo[current_change_set]; - curr_drawinfo = line_drawinfo[current_change_set ^ 1]; - current_change_set ^= 1; - - color_src_match = color_dest_match = -1; - - /* Use both halves of the array in alternating fashion. */ - curr_sprite_entries[0].first_pixel = current_change_set * MAX_SPR_PIXELS; - next_sprite_forced = 1; -} - -static void do_savestate(void); - -static int rpt_vsync (void) -{ - int v = read_processor_time () - vsyncmintime; - if (v > (int)syncbase || v < -((int)syncbase)) { - vsyncmintime = read_processor_time(); - v = 0; - } - return v; -} - -static void framewait (void) -{ - frame_time_t curr_time; - int start; - - for (;;) { - double v = rpt_vsync () / (syncbase / 1000.0); - if (v >= -4) - break; - sleep_millis_busy (2); - } - curr_time = start = read_processor_time(); - if (!isvsync()) { - do { - curr_time = read_processor_time (); - } while (rpt_vsync () < 0); - } - vsyncmintime = curr_time + vsynctime; - idletime += read_processor_time() - start; -} - -static int frametime2; - -void fpscounter_reset (void) -{ - timeframes = 0; - frametime2 = 0; - bogusframe = 2; - lastframetime = read_processor_time (); - idletime = 0; -} - -static void fpscounter (void) -{ - int now, last; - - now = read_processor_time (); - last = now - lastframetime; - lastframetime = now; - - if (bogusframe) - return; - - frametime += last; - frametime2 += last; - timeframes++; - if ((timeframes & 31) == 0) { - double idle = 1000 - (idletime == 0 ? 0.0 : (double)idletime * 1000.0 / (vsynctime * 32.0)); - int fps = frametime2 == 0 ? 0 : syncbase * 32 / (frametime2 / 10); - if (fps > 9999) - fps = 9999; - if (idle < 0) - idle = 0; - if (idle > 100 * 10) - idle = 100 * 10; - if (fake_vblank_hz * 10 > fps) { - double mult = (double)fake_vblank_hz * 10.0 / fps; - idle *= mult; - } - if (turbo_emulation && idle < 100 * 10) - idle = 100 * 10; - gui_fps (fps, (int)idle); - frametime2 = 0; - idletime = 0; - } -} - -static void vsync_handler (void) -{ - fpscounter (); - - if (!isvsync() -#ifdef AVIOUTPUT - && ((avioutput_framelimiter && avioutput_enabled) || !avioutput_enabled) -#endif - ) { -#ifdef JIT - if (!compiled_code) { -#endif - if (currprefs.m68k_speed == -1) { - frame_time_t curr_time = read_processor_time (); - vsyncmintime += vsynctime; - /* @@@ Mathias? How do you think we should do this? */ - /* If we are too far behind, or we just did a reset, adjust the - * needed time. */ - if ((long int)(curr_time - vsyncmintime) > 0 || rpt_did_reset) - vsyncmintime = curr_time + vsynctime; - rpt_did_reset = 0; - } else if (rpt_available) { - framewait (); - } -#ifdef JIT - } else { - if (rpt_available && currprefs.m68k_speed == 0) { - framewait (); - } - } -#endif - } - - if (bogusframe > 0) - bogusframe--; - - handle_events (); - - INTREQ (0x8020); - if (bplcon0 & 4) - lof ^= 0x8000; - -#ifdef PICASSO96 - /* And now let's update the Picasso palette, if required */ - DX_SetPalette_vsync(); - if (picasso_on) - picasso_handle_vsync (); -#endif - - vsync_handle_redraw (lof, lof_changed); - - if (quit_program > 0) { - /* prevent possible infinite loop at wait_cycles().. */ - framecnt = 0; - reset_decisions (); - return; - } - - { - static int cnt = 0; - if (cnt == 0) { - /* resolution_check_change (); */ - DISK_check_change (); - cnt = 5; - } - cnt--; - } - - /* Start a new set of copper records. */ - curr_cop_set ^= 1; - nr_cop_records[curr_cop_set] = 0; - - /* For now, let's only allow this to change at vsync time. It gets too - * hairy otherwise. */ - if ((beamcon0 & (0x20|0x80)) != (new_beamcon0 & (0x20|0x80)) || hack_vpos) - init_hz (); - - lof_changed = 0; - - eventtab[ev_copper].active = 0; - COPJMP (1); - - init_hardware_frame (); - - if (timehack_alive > 0) - timehack_alive--; - inputdevice_vsync (); -} - -#ifdef JIT - -#define N_LINES 8 - -static __inline__ int trigger_frh(int v) -{ - return (v & (N_LINES - 1)) == 0; -} - -extern int gonebad; - -static long int diff32(frame_time_t x, frame_time_t y) -{ - return (long int)(x-y); -} -static void frh_handler(void) -{ - if (currprefs.m68k_speed == -1) { - frame_time_t curr_time = read_processor_time (); - vsyncmintime += vsynctime * N_LINES / maxvpos; - /* @@@ Mathias? How do you think we should do this? */ - /* If we are too far behind, or we just did a reset, adjust the - * needed time. */ - if (rpt_did_reset) { - vsyncmintime = curr_time + vsynctime; - rpt_did_reset = 0; - } - /* Allow this to be one frame's worth of cycles out */ - while (diff32 (curr_time, vsyncmintime + vsynctime) > 0) { - vsyncmintime += vsynctime * N_LINES / maxvpos; - gonebad++; - if (turbo_emulation) - break; - } - } -} -#endif - -static void copper_check (int n) -{ - if (cop_state.state == COP_wait) { - int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); - if (vp < cop_state.vcmp) { - if (eventtab[ev_copper].active || copper_enabled_thisline) - write_log ("COPPER BUG %d: vp=%d vpos=%d vcmp=%d act=%d thisline=%d\n", n, vp, vpos, cop_state.vcmp, eventtab[ev_copper].active, copper_enabled_thisline); - } - } -} - -static void hsync_handler (void) -{ - static int ciahsync; - int hpos = current_hpos (); - - /* Using 0x8A makes sure that we don't accidentally trip over the - modified_regtypes check. */ - sync_copper_with_cpu (maxhpos, 0, 0x8A); - - //copper_check (1); - - finish_decisions (); - if (thisline_decision.plfleft != -1) { - if (currprefs.collision_level > 1) - do_sprite_collisions (); - if (currprefs.collision_level > 2) - do_playfield_collisions (); - } - hsync_record_line_state (next_lineno, nextline_how, thisline_changed); - - eventtab[ev_hsync].evtime += get_cycles () - eventtab[ev_hsync].oldcycles; - eventtab[ev_hsync].oldcycles = get_cycles (); - CIA_hsync_handler (); -#ifdef CD32 - AKIKO_hsync_handler (); -#endif - -#ifdef PICASSO96 - picasso_handle_hsync (); -#endif - - ciahsync++; - if (ciahsync >= (currprefs.ntscmode ? MAXVPOS_NTSC : MAXVPOS_PAL) * MAXHPOS_PAL / maxhpos) { /* not so perfect.. */ - CIA_vsync_handler (); - ciahsync = 0; - } - -#ifdef CPUEMU_6 - if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) { - decide_blitter (hpos); - memset (cycle_line, 0, MAXHPOS); -#if 1 -{ - cycle_line[maxhpos - 1] = CYCLE_REFRESH; - cycle_line[2] = CYCLE_REFRESH; - cycle_line[4] = CYCLE_REFRESH; - cycle_line[6] = CYCLE_REFRESH; -} -#else -{ - int i; - for (i = 12; i < 0x16; i += 2) - cycle_line[i] = CYCLE_NOCPU; - cycle_line[4] = CYCLE_REFRESH; - cycle_line[6] = CYCLE_REFRESH; - cycle_line[8] = CYCLE_REFRESH; - cycle_line[10] = CYCLE_REFRESH; -} -#endif - } -#endif - if ((currprefs.chipset_mask & CSMASK_AGA) || (!currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - last_custom_value = rand (); - else - last_custom_value = 0xffff; - - if (!currprefs.blitter_cycle_exact && bltstate != BLT_done && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) - blitter_slowdown (thisline_decision.plfleft, thisline_decision.plfright - (16 << fetchmode), - cycle_diagram_total_cycles[fmode][GET_RES (bplcon0)][GET_PLANES_LIMIT (bplcon0)], - cycle_diagram_free_cycles[fmode][GET_RES (bplcon0)][GET_PLANES_LIMIT (bplcon0)]); - - if (currprefs.produce_sound) - audio_hsync (1); - - hardware_line_completed (next_lineno); - - /* In theory only an equality test is needed here - but if a program - goes haywire with the VPOSW register, it can cause us to miss this, - with vpos going into the thousands (and all the nasty consequences - this has). */ - - if (++vpos >= (maxvpos + (lof == 0 ? 0 : 1))) { - vpos = 0; - vsync_handler (); - } - - DISK_hsync (maxhpos); - -#ifdef JIT - if (compiled_code) { - if (currprefs.m68k_speed == -1) { - static int count=0; - - count++; - if (trigger_frh(count)) { - frh_handler(); - } - is_lastline = trigger_frh(count+1) && ! rpt_did_reset; - } - else - is_lastline=0; - } else { -#endif - is_lastline = vpos + 1 == maxvpos + (lof == 0 ? 0 : 1) && currprefs.m68k_speed == -1 && ! rpt_did_reset; -#ifdef JIT - } -#endif - - if ((bplcon0 & 4) && currprefs.gfx_linedbl) - notice_interlace_seen (); - - if (!nodraw ()) { - int lineno = vpos; - nextline_how = nln_normal; - if (currprefs.gfx_linedbl) { - lineno *= 2; - nextline_how = currprefs.gfx_linedbl == 1 ? nln_doubled : nln_nblack; - if (bplcon0 & 4) { - if (!lof) { - lineno++; - nextline_how = nln_lower; - } else { - nextline_how = nln_upper; - } - } - } - next_lineno = lineno; - reset_decisions (); - } -#ifdef FILESYS - if (uae_int_requested) { - set_uae_int_flag (); - INTREQ (0x8000 | 0x0008); - } -#endif - /* See if there's a chance of a copper wait ending this line. */ - cop_state.hpos = 0; - cop_state.last_write = 0; - compute_spcflag_copper (); - inputdevice_hsync (); - serial_hsynchandler (); -#ifdef CUSTOM_SIMPLE - do_sprites (0); -#endif - //copper_check (2); -} - -static void init_regtypes (void) -{ - int i; - for (i = 0; i < 512; i += 2) { - regtypes[i] = REGTYPE_ALL; - if ((i >= 0x20 && i < 0x28) || i == 0x08 || i == 0x7E) - regtypes[i] = REGTYPE_DISK; - else if (i >= 0x68 && i < 0x70) - regtypes[i] = REGTYPE_NONE; - else if (i >= 0x40 && i < 0x78) - regtypes[i] = REGTYPE_BLITTER; - else if (i >= 0xA0 && i < 0xE0 && (i & 0xF) < 0xE) - regtypes[i] = REGTYPE_AUDIO; - else if (i >= 0xA0 && i < 0xE0) - regtypes[i] = REGTYPE_NONE; - else if (i >= 0xE0 && i < 0x100) - regtypes[i] = REGTYPE_PLANE; - else if (i >= 0x120 && i < 0x180) - regtypes[i] = REGTYPE_SPRITE; - else if (i >= 0x180 && i < 0x1C0) - regtypes[i] = REGTYPE_COLOR; - else switch (i) { - case 0x02: - /* DMACONR - setting this to REGTYPE_BLITTER will cause it to - conflict with DMACON (since that is REGTYPE_ALL), and the - blitter registers (for the BBUSY bit), but nothing else, - which is (I think) what we want. */ - regtypes[i] = REGTYPE_BLITTER; - break; - case 0x04: case 0x06: case 0x2A: case 0x2C: - regtypes[i] = REGTYPE_POS; - break; - case 0x0A: case 0x0C: - case 0x12: case 0x14: case 0x16: - case 0x36: - regtypes[i] = REGTYPE_JOYPORT; - break; - case 0x104: - case 0x102: - regtypes[i] = REGTYPE_PLANE; - break; - case 0x88: case 0x8A: - case 0x8E: case 0x90: case 0x92: case 0x94: - case 0x96: - case 0x100: - regtypes[i] |= REGTYPE_FORCE; - break; - } - } -} - -void init_eventtab (void) -{ - int i; - - nextevent = 0; - set_cycles (0); - for (i = 0; i < ev_max; i++) { - eventtab[i].active = 0; - eventtab[i].oldcycles = 0; - } - - eventtab[ev_cia].handler = CIA_handler; - eventtab[ev_hsync].handler = hsync_handler; - eventtab[ev_hsync].evtime = get_cycles () + HSYNCTIME; - eventtab[ev_hsync].active = 1; - - eventtab[ev_copper].handler = copper_handler; - eventtab[ev_copper].active = 0; - eventtab[ev_blitter].handler = blitter_handler; - eventtab[ev_blitter].active = 0; - eventtab[ev_disk].handler = DISK_handler; - eventtab[ev_disk].active = 0; - eventtab[ev_audio].handler = audio_evhandler; - eventtab[ev_audio].active = 0; - events_schedule (); -} - -void customreset (void) -{ - int i; - int zero = 0; - - write_log ("reset at %x\n", m68k_getpc ()); - if (! savestate_state) { - currprefs.chipset_mask = changed_prefs.chipset_mask; - if ((currprefs.chipset_mask & CSMASK_AGA) == 0) { - for (i = 0; i < 32; i++) { - current_colors.color_regs_ecs[i] = 0; - current_colors.acolors[i] = xcolors[0]; - } -#ifdef AGA - } else { - for (i = 0; i < 256; i++) { - current_colors.color_regs_aga[i] = 0; - current_colors.acolors[i] = CONVERT_RGB (zero); - } -#endif - } - - clxdat = 0; - - /* Clear the armed flags of all sprites. */ - memset (spr, 0, sizeof spr); - nr_armed = 0; - - dmacon = intena = 0; - - copcon = 0; - DSKLEN (0, 0); - - bplcon0 = 0; - bplcon4 = 0x11; /* Get AGA chipset into ECS compatibility mode */ - bplcon3 = 0xC00; - - FMODE (0); - CLXCON (0); - } - -#ifdef AUTOCONFIG - expamem_reset (); -#endif - a1000_reset (); - DISK_reset (); - CIA_reset (); -#ifdef JIT - compemu_reset (); -#endif - unset_special (~(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)); - - vpos = 0; - - inputdevice_reset (); - timehack_alive = 0; - - curr_sprite_entries = 0; - prev_sprite_entries = 0; - sprite_entries[0][0].first_pixel = 0; - sprite_entries[1][0].first_pixel = MAX_SPR_PIXELS; - sprite_entries[0][1].first_pixel = 0; - sprite_entries[1][1].first_pixel = MAX_SPR_PIXELS; - memset (spixels, 0, sizeof spixels); - memset (&spixstate, 0, sizeof spixstate); - - bltstate = BLT_done; - cop_state.state = COP_stop; - diwstate = DIW_waiting_start; - hdiwstate = DIW_waiting_start; - set_cycles (0); - - new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; - hack_vpos = 0; - init_hz (); - - audio_reset (); - if (savestate_state != STATE_RESTORE) { - /* must be called after audio_reset */ - adkcon = 0; - serial_uartbreak (0); - update_adkmasks (); - } - - init_sprites (); - - init_hardware_frame (); - drawing_init (); - - reset_decisions (); - - bogusframe = 1; - - init_regtypes (); - - sprite_buffer_res = currprefs.chipset_mask & CSMASK_AGA ? RES_HIRES : RES_LORES; - if (savestate_state == STATE_RESTORE) { - uae_u16 v; - uae_u32 vv; - - update_adkmasks (); - INTENA (0); - INTREQ (0); -#if 0 - DMACON (0, 0); -#endif - COPJMP (1); - v = bplcon0; - BPLCON0 (0, 0); - BPLCON0 (0, v); - FMODE (fmode); - if (!(currprefs.chipset_mask & CSMASK_AGA)) { - for(i = 0 ; i < 32 ; i++) { - vv = current_colors.color_regs_ecs[i]; - current_colors.color_regs_ecs[i] = -1; - record_color_change (0, i, vv); - remembered_color_entry = -1; - current_colors.color_regs_ecs[i] = vv; - current_colors.acolors[i] = xcolors[vv]; - } -#ifdef AGA - } else { - for(i = 0 ; i < 256 ; i++) { - vv = current_colors.color_regs_aga[i]; - current_colors.color_regs_aga[i] = -1; - record_color_change (0, i, vv); - remembered_color_entry = -1; - current_colors.color_regs_aga[i] = vv; - current_colors.acolors[i] = CONVERT_RGB(vv); - } -#endif - } - CLXCON (clxcon); - CLXCON2 (clxcon2); - calcdiw (); - write_log ("State restored\n"); - dumpcustom (); - for (i = 0; i < 8; i++) - nr_armed += spr[i].armed != 0; - } - expand_sprres (); - - #ifdef ACTION_REPLAY - /* Doing this here ensures we can use the 'reset' command from within AR */ - action_replay_reset (); - #endif - #if defined(ENFORCER) - enforcer_disable(); - #endif -} - -void dumpcustom (void) -{ - write_log ("DMACON: %x INTENA: %x INTREQ: %x VPOS: %x HPOS: %x\n", DMACONR(), - (unsigned int)intena, (unsigned int)intreq, (unsigned int)vpos, (unsigned int)current_hpos()); - write_log ("COP1LC: %08lx, COP2LC: %08lx COPPTR: %08lx\n", (unsigned long)cop1lc, (unsigned long)cop2lc, cop_state.ip); - write_log ("DIWSTRT: %04x DIWSTOP: %04x DDFSTRT: %04x DDFSTOP: %04x\n", - (unsigned int)diwstrt, (unsigned int)diwstop, (unsigned int)ddfstrt, (unsigned int)ddfstop); - write_log ("BPLCON 0: %04x 1: %04x 2: %04x 3: %04x 4: %04x\n", bplcon0, bplcon1, bplcon2, bplcon3, bplcon4); - if (timeframes) { - write_log ("Average frame time: %f ms [frames: %d time: %d]\n", - (double)frametime / timeframes, timeframes, frametime); - if (total_skipped) - write_log ("Skipped frames: %d\n", total_skipped); - } - /*for (i=0; i<256; i++) if (blitcount[i]) write_log ("minterm %x = %d\n",i,blitcount[i]); blitter debug */ -} - -static void gen_custom_tables (void) -{ - int i; - for (i = 0; i < 256; i++) { - sprtaba[i] = ((((i >> 7) & 1) << 0) - | (((i >> 6) & 1) << 2) - | (((i >> 5) & 1) << 4) - | (((i >> 4) & 1) << 6) - | (((i >> 3) & 1) << 8) - | (((i >> 2) & 1) << 10) - | (((i >> 1) & 1) << 12) - | (((i >> 0) & 1) << 14)); - sprtabb[i] = sprtaba[i] * 2; - sprite_ab_merge[i] = (((i & 15) ? 1 : 0) - | ((i & 240) ? 2 : 0)); - } - for (i = 0; i < 16; i++) { - clxmask[i] = (((i & 1) ? 0xF : 0x3) - | ((i & 2) ? 0xF0 : 0x30) - | ((i & 4) ? 0xF00 : 0x300) - | ((i & 8) ? 0xF000 : 0x3000)); - sprclx[i] = (((i & 0x3) == 0x3 ? 1 : 0) - | ((i & 0x5) == 0x5 ? 2 : 0) - | ((i & 0x9) == 0x9 ? 4 : 0) - | ((i & 0x6) == 0x6 ? 8 : 0) - | ((i & 0xA) == 0xA ? 16 : 0) - | ((i & 0xC) == 0xC ? 32 : 0)) << 9; - } -} - -void custom_init (void) -{ - -#ifdef OS_WITHOUT_MEMORY_MANAGEMENT - int num; - - for (num = 0; num < 2; num++) { - sprite_entries[num] = xmalloc (max_sprite_entry * sizeof (struct sprite_entry)); - color_changes[num] = xmalloc (max_color_change * sizeof (struct color_change)); - } -#endif - -#ifdef AUTOCONFIG - { - uaecptr pos; - pos = here (); - - org (RTAREA_BASE+0xFF70); - calltrap (deftrap (mousehack_helper)); - dw (RTS); - - org (RTAREA_BASE+0xFFA0); - calltrap (deftrap (timehack_helper)); - dw (RTS); - - org (pos); - } -#endif - - gen_custom_tables (); - build_blitfilltable (); - - drawing_init (); - - mousehack_set (mousehack_unknown); - if (needmousehack ()) - mousehack_set (mousehack_follow); - - create_cycle_diagram_table (); -} - -/* Custom chip memory bank */ - -static uae_u32 custom_lget (uaecptr) REGPARAM; -static uae_u32 custom_wget (uaecptr) REGPARAM; -static uae_u32 custom_bget (uaecptr) REGPARAM; -static void custom_lput (uaecptr, uae_u32) REGPARAM; -static void custom_wput (uaecptr, uae_u32) REGPARAM; -static void custom_bput (uaecptr, uae_u32) REGPARAM; - -addrbank custom_bank = { - custom_lget, custom_wget, custom_bget, - custom_lput, custom_wput, custom_bput, - default_xlate, default_check, NULL -}; - -STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (uaecptr addr, int noput) -{ - uae_u16 v; -#ifdef JIT - special_mem |= S_READ; -#endif - addr &= 0xfff; -#ifdef CUSTOM_DEBUG - write_log ("%d:%d:wget: %04.4X=%04.4X pc=%p\n", current_hpos(), vpos, addr, addr & 0x1fe, m68k_getpc ()); -#endif - switch (addr & 0x1fe) { - case 0x002: v = DMACONR (); break; - case 0x004: v = VPOSR (); break; - case 0x006: v = VHPOSR (); break; - - case 0x00A: v = JOY0DAT (); break; - case 0x00C: v = JOY1DAT (); break; - case 0x00E: v = CLXDAT (); break; - case 0x010: v = ADKCONR (); break; - - case 0x012: v = POT0DAT (); break; - case 0x014: v = POT1DAT (); break; - case 0x016: v = POTGOR (); break; - case 0x018: v = SERDATR (); break; - case 0x01A: v = DSKBYTR (current_hpos ()); break; - case 0x01C: v = INTENAR (); break; - case 0x01E: v = INTREQR (); break; - case 0x07C: v = DENISEID (); break; - - case 0x02E: v = 0xffff; break; /* temporary hack */ - -#ifdef AGA - case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: - case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: - case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2: - case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE: - case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA: - case 0x1BC: case 0x1BE: - v = COLOR_READ ((addr & 0x3E) / 2); - break; -#endif - - default: - /* reading write-only register causes write with last value in bus */ - v = last_custom_value; - if (!noput) { - int r; - int hpos = current_hpos (); - decide_line (hpos); - decide_fetch (hpos); - decide_blitter (hpos); - v = last_custom_value; - r = custom_wput_1 (hpos, addr, v, 1); - } - return v; - } - return v; -} - - STATIC_INLINE custom_wget2 (uaecptr addr) - { - uae_u32 v; - sync_copper_with_cpu (current_hpos (), 1, addr); - if (currprefs.cpu_level >= 2) { - if(addr >= 0xde0000 && addr <= 0xdeffff) { - return 0x7f7f; - } - if(addr >= 0xdd0000 && addr <= 0xddffff) { - return 0xffff; - } - } - v = custom_wget_1 (addr, 0); -#ifdef ACTION_REPLAY -#ifdef ACTION_REPLAY_COMMON - addr &= 0x1ff; - ar_custom[addr + 0] = (uae_u8)(v >> 8); - ar_custom[addr + 1] = (uae_u8)(v); -#endif -#endif - return v; -} - -uae_u32 REGPARAM2 custom_wget (uaecptr addr) -{ - uae_u32 v; - - if (addr & 1) { - /* think about move.w $dff005,d0.. (68020+ only) */ - addr &= ~1; - v = custom_wget2 (addr) << 8; - v |= custom_wget2 (addr + 2) >> 8; - return v; - } - return custom_wget2 (addr); - } - -uae_u32 REGPARAM2 custom_bget (uaecptr addr) -{ -#ifdef JIT - special_mem |= S_READ; -#endif - return custom_wget2 (addr & ~1) >> (addr & 1 ? 0 : 8); -} - -uae_u32 REGPARAM2 custom_lget (uaecptr addr) -{ -#ifdef JIT - special_mem |= S_READ; -#endif - return ((uae_u32)custom_wget (addr) << 16) | custom_wget (addr + 2); -} - -int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int noget) -{ - addr &= 0x1FE; - value &= 0xffff; -#ifdef ACTION_REPLAY -#ifdef ACTION_REPLAY_COMMON - ar_custom[addr+0]=(uae_u8)(value>>8); - ar_custom[addr+1]=(uae_u8)(value); -#endif -#endif - last_custom_value = value; - switch (addr) { - case 0x00E: CLXDAT (); break; - - case 0x020: DSKPTH (value); break; - case 0x022: DSKPTL (value); break; - case 0x024: DSKLEN (value, hpos); break; - case 0x026: DSKDAT (value); break; - - case 0x02A: VPOSW (value); break; - case 0x02E: COPCON (value); break; - case 0x030: SERDAT (value); break; - case 0x032: SERPER (value); break; - case 0x034: POTGO (value); break; - case 0x040: BLTCON0 (value); break; - case 0x042: BLTCON1 (value); break; - - case 0x044: BLTAFWM (value); break; - case 0x046: BLTALWM (value); break; - - case 0x050: BLTAPTH (value); break; - case 0x052: BLTAPTL (value); break; - case 0x04C: BLTBPTH (value); break; - case 0x04E: BLTBPTL (value); break; - case 0x048: BLTCPTH (value); break; - case 0x04A: BLTCPTL (value); break; - case 0x054: BLTDPTH (value); break; - case 0x056: BLTDPTL (value); break; - - case 0x058: BLTSIZE (value); break; - - case 0x064: BLTAMOD (value); break; - case 0x062: BLTBMOD (value); break; - case 0x060: BLTCMOD (value); break; - case 0x066: BLTDMOD (value); break; - - case 0x070: BLTCDAT (value); break; - case 0x072: BLTBDAT (value); break; - case 0x074: BLTADAT (value); break; - - case 0x07E: DSKSYNC (hpos, value); break; - - case 0x080: COP1LCH (value); break; - case 0x082: COP1LCL (value); break; - case 0x084: COP2LCH (value); break; - case 0x086: COP2LCL (value); break; - - case 0x088: COPJMP (1); break; - case 0x08A: COPJMP (2); break; - - case 0x08E: DIWSTRT (hpos, value); break; - case 0x090: DIWSTOP (hpos, value); break; - case 0x092: DDFSTRT (hpos, value); break; - case 0x094: DDFSTOP (hpos, value); break; - - case 0x096: DMACON (hpos, value); break; - case 0x098: CLXCON (value); break; - case 0x09A: INTENA (value); break; - case 0x09C: INTREQ (value); break; - case 0x09E: ADKCON (hpos, value); break; - - case 0x0A0: AUDxLCH (0, value); break; - case 0x0A2: AUDxLCL (0, value); break; - case 0x0A4: AUDxLEN (0, value); break; - case 0x0A6: AUDxPER (0, value); break; - case 0x0A8: AUDxVOL (0, value); break; - case 0x0AA: AUDxDAT (0, value); break; - - case 0x0B0: AUDxLCH (1, value); break; - case 0x0B2: AUDxLCL (1, value); break; - case 0x0B4: AUDxLEN (1, value); break; - case 0x0B6: AUDxPER (1, value); break; - case 0x0B8: AUDxVOL (1, value); break; - case 0x0BA: AUDxDAT (1, value); break; - - case 0x0C0: AUDxLCH (2, value); break; - case 0x0C2: AUDxLCL (2, value); break; - case 0x0C4: AUDxLEN (2, value); break; - case 0x0C6: AUDxPER (2, value); break; - case 0x0C8: AUDxVOL (2, value); break; - case 0x0CA: AUDxDAT (2, value); break; - - case 0x0D0: AUDxLCH (3, value); break; - case 0x0D2: AUDxLCL (3, value); break; - case 0x0D4: AUDxLEN (3, value); break; - case 0x0D6: AUDxPER (3, value); break; - case 0x0D8: AUDxVOL (3, value); break; - case 0x0DA: AUDxDAT (3, value); break; - - case 0x0E0: BPLxPTH (hpos, value, 0); break; - case 0x0E2: BPLxPTL (hpos, value, 0); break; - case 0x0E4: BPLxPTH (hpos, value, 1); break; - case 0x0E6: BPLxPTL (hpos, value, 1); break; - case 0x0E8: BPLxPTH (hpos, value, 2); break; - case 0x0EA: BPLxPTL (hpos, value, 2); break; - case 0x0EC: BPLxPTH (hpos, value, 3); break; - case 0x0EE: BPLxPTL (hpos, value, 3); break; - case 0x0F0: BPLxPTH (hpos, value, 4); break; - case 0x0F2: BPLxPTL (hpos, value, 4); break; - case 0x0F4: BPLxPTH (hpos, value, 5); break; - case 0x0F6: BPLxPTL (hpos, value, 5); break; - case 0x0F8: BPLxPTH (hpos, value, 6); break; - case 0x0FA: BPLxPTL (hpos, value, 6); break; - case 0x0FC: BPLxPTH (hpos, value, 7); break; - case 0x0FE: BPLxPTL (hpos, value, 7); break; - - case 0x100: BPLCON0 (hpos, value); break; - case 0x102: BPLCON1 (hpos, value); break; - case 0x104: BPLCON2 (hpos, value); break; -#ifdef AGA - case 0x106: BPLCON3 (hpos, value); break; -#endif - - case 0x108: BPL1MOD (hpos, value); break; - case 0x10A: BPL2MOD (hpos, value); break; -#ifdef AGA - case 0x10E: CLXCON2 (value); break; -#endif - - case 0x110: BPL1DAT (hpos, value); break; -#if 0 /* no point */ - case 0x112: BPL2DAT (value); break; - case 0x114: BPL3DAT (value); break; - case 0x116: BPL4DAT (value); break; - case 0x118: BPL5DAT (value); break; - case 0x11A: BPL6DAT (value); break; - case 0x11C: BPL7DAT (value); break; - case 0x11E: BPL8DAT (value); break; -#endif - - case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: - case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: - case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2: - case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE: - case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA: - case 0x1BC: case 0x1BE: - COLOR_WRITE (hpos, value & 0xFFF, (addr & 0x3E) / 2); - break; - case 0x120: case 0x124: case 0x128: case 0x12C: - case 0x130: case 0x134: case 0x138: case 0x13C: - SPRxPTH (hpos, value, (addr - 0x120) / 4); - break; - case 0x122: case 0x126: case 0x12A: case 0x12E: - case 0x132: case 0x136: case 0x13A: case 0x13E: - SPRxPTL (hpos, value, (addr - 0x122) / 4); - break; - case 0x140: case 0x148: case 0x150: case 0x158: - case 0x160: case 0x168: case 0x170: case 0x178: - SPRxPOS (hpos, value, (addr - 0x140) / 8); - break; - case 0x142: case 0x14A: case 0x152: case 0x15A: - case 0x162: case 0x16A: case 0x172: case 0x17A: - SPRxCTL (hpos, value, (addr - 0x142) / 8); - break; - case 0x144: case 0x14C: case 0x154: case 0x15C: - case 0x164: case 0x16C: case 0x174: case 0x17C: - SPRxDATA (hpos, value, (addr - 0x144) / 8); - break; - case 0x146: case 0x14E: case 0x156: case 0x15E: - case 0x166: case 0x16E: case 0x176: case 0x17E: - SPRxDATB (hpos, value, (addr - 0x146) / 8); - break; - - case 0x36: JOYTEST (value); break; - case 0x5A: BLTCON0L (value); break; - case 0x5C: BLTSIZV (value); break; - case 0x5E: BLTSIZH (value); break; - case 0x1E4: DIWHIGH (hpos, value); break; -#ifdef AGA - case 0x10C: BPLCON4 (hpos, value); break; -#endif - -#ifndef CUSTOM_SIMPLE - case 0x1DC: BEAMCON0 (value); break; - case 0x1C0: if (htotal != value) { htotal = value; varsync (); } break; - case 0x1C2: if (hsstop != value) { hsstop = value; varsync (); } break; - case 0x1C4: if (hbstrt != value) { hbstrt = value; varsync (); } break; - case 0x1C6: if (hbstop != value) { hbstop = value; varsync (); } break; - case 0x1C8: if (vtotal != value) { vtotal = value; varsync (); } break; - case 0x1CA: if (vsstop != value) { vsstop = value; varsync (); } break; - case 0x1CC: if (vbstrt != value) { vbstrt = value; varsync (); } break; - case 0x1CE: if (vbstop != value) { vbstop = value; varsync (); } break; - case 0x1DE: if (hsstrt != value) { hsstrt = value; varsync (); } break; - case 0x1E0: if (vsstrt != value) { vsstrt = value; varsync (); } break; - case 0x1E2: if (hcenter != value) { hcenter = value; varsync (); } break; -#endif - -#ifdef AGA - case 0x1FC: FMODE (value); break; -#endif - - /* writing to read-only register causes read access */ - default: - if (!noget) - custom_wget_1 (addr, 1); - if (!(currprefs.chipset_mask & CSMASK_AGA) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - last_custom_value = 0xffff; - return 1; - } - return 0; -} - -void REGPARAM2 custom_wput (uaecptr addr, uae_u32 value) -{ - int hpos = current_hpos (); -#ifdef JIT - special_mem |= S_WRITE; -#endif -#ifdef CUSTOM_DEBUG - write_log ("%d:%d:wput: %04.4X %04.4X pc=%p\n", hpos, vpos, addr & 0x01fe, value & 0xffff, m68k_getpc ()); -#endif - sync_copper_with_cpu (hpos, 1, addr); - custom_wput_1 (hpos, addr, value, 0); -} - -void REGPARAM2 custom_bput (uaecptr addr, uae_u32 value) -{ - static int warned; - /* Is this correct now? (There are people who bput things to the upper byte of AUDxVOL). */ - uae_u16 rval = (value << 8) | (value & 0xFF); -#ifdef JIT - special_mem |= S_WRITE; -#endif - custom_wput (addr & ~1, rval); - if (warned < 10) { - write_log ("Byte put to custom register %04.4X PC=%08.8X\n", addr, m68k_getpc ()); - warned++; - } -} - -void REGPARAM2 custom_lput(uaecptr addr, uae_u32 value) -{ -#ifdef JIT - special_mem |= S_WRITE; -#endif - custom_wput (addr & 0xfffe, value >> 16); - custom_wput ((addr + 2) & 0xfffe, (uae_u16)value); -} - -void custom_prepare_savestate (void) -{ -} - -#define RB restore_u8 () -#define RW restore_u16 () -#define RL restore_u32 () - -uae_u8 *restore_custom (uae_u8 *src) -{ - uae_u16 dsklen, dskbytr; - int dskpt; - int i; - - audio_reset (); - - changed_prefs.chipset_mask = currprefs.chipset_mask = RL; - RW; /* 000 ? */ - RW; /* 002 DMACONR */ - RW; /* 004 VPOSR */ - RW; /* 006 VHPOSR */ - RW; /* 008 DSKDATR (dummy register) */ - RW; /* 00A JOY0DAT */ - RW; /* 00C JOY1DAT */ - clxdat = RW; /* 00E CLXDAT */ - RW; /* 010 ADKCONR */ - RW; /* 012 POT0DAT* */ - RW; /* 014 POT1DAT* */ - RW; /* 016 POTINP* */ - RW; /* 018 SERDATR* */ - dskbytr = RW; /* 01A DSKBYTR */ - RW; /* 01C INTENAR */ - RW; /* 01E INTREQR */ - dskpt = RL; /* 020-022 DSKPT */ - dsklen = RW; /* 024 DSKLEN */ - RW; /* 026 DSKDAT */ - RW; /* 028 REFPTR */ - lof = RW; /* 02A VPOSW */ - RW; /* 02C VHPOSW */ - COPCON(RW); /* 02E COPCON */ - RW; /* 030 SERDAT* */ - RW; /* 032 SERPER* */ - POTGO(RW); /* 034 POTGO */ - RW; /* 036 JOYTEST* */ - RW; /* 038 STREQU */ - RW; /* 03A STRVHBL */ - RW; /* 03C STRHOR */ - RW; /* 03E STRLONG */ - BLTCON0(RW); /* 040 BLTCON0 */ - BLTCON1(RW); /* 042 BLTCON1 */ - BLTAFWM(RW); /* 044 BLTAFWM */ - BLTALWM(RW); /* 046 BLTALWM */ - BLTCPTH(RL); /* 048-04B BLTCPT */ - BLTBPTH(RL); /* 04C-04F BLTBPT */ - BLTAPTH(RL); /* 050-053 BLTAPT */ - BLTDPTH(RL); /* 054-057 BLTDPT */ - RW; /* 058 BLTSIZE */ - RW; /* 05A BLTCON0L */ - blt_info.vblitsize = RW; /* 05C BLTSIZV */ - blt_info.hblitsize = RW; /* 05E BLTSIZH */ - BLTCMOD(RW); /* 060 BLTCMOD */ - BLTBMOD(RW); /* 062 BLTBMOD */ - BLTAMOD(RW); /* 064 BLTAMOD */ - BLTDMOD(RW); /* 066 BLTDMOD */ - RW; /* 068 ? */ - RW; /* 06A ? */ - RW; /* 06C ? */ - RW; /* 06E ? */ - BLTCDAT(RW); /* 070 BLTCDAT */ - BLTBDAT(RW); /* 072 BLTBDAT */ - BLTADAT(RW); /* 074 BLTADAT */ - RW; /* 076 ? */ - RW; /* 078 ? */ - RW; /* 07A ? */ - RW; /* 07C LISAID */ - DSKSYNC(-1, RW); /* 07E DSKSYNC */ - cop1lc = RL; /* 080/082 COP1LC */ - cop2lc = RL; /* 084/086 COP2LC */ - RW; /* 088 ? */ - RW; /* 08A ? */ - RW; /* 08C ? */ - diwstrt = RW; /* 08E DIWSTRT */ - diwstop = RW; /* 090 DIWSTOP */ - ddfstrt = RW; /* 092 DDFSTRT */ - ddfstop = RW; /* 094 DDFSTOP */ - dmacon = RW & ~(0x2000|0x4000); /* 096 DMACON */ - CLXCON(RW); /* 098 CLXCON */ - intena = RW; /* 09A INTENA */ - intreq = RW; /* 09C INTREQ */ - adkcon = RW; /* 09E ADKCON */ - for (i = 0; i < 8; i++) - bplpt[i] = RL; - bplcon0 = RW; /* 100 BPLCON0 */ - bplcon1 = RW; /* 102 BPLCON1 */ - bplcon2 = RW; /* 104 BPLCON2 */ - bplcon3 = RW; /* 106 BPLCON3 */ - bpl1mod = RW; /* 108 BPL1MOD */ - bpl2mod = RW; /* 10A BPL2MOD */ - bplcon4 = RW; /* 10C BPLCON4 */ - clxcon2 = RW; /* 10E CLXCON2* */ - for(i = 0; i < 8; i++) - RW; /* BPLXDAT */ - for(i = 0; i < 32; i++) - current_colors.color_regs_ecs[i] = RW; /* 180 COLORxx */ - htotal = RW; /* 1C0 HTOTAL */ - RW; /* 1C2 ? */ - RW; /* 1C4 ? */ - RW; /* 1C6 ? */ - vtotal = RW; /* 1C8 VTOTAL */ - RW; /* 1CA ? */ - RW; /* 1CC ? */ - RW; /* 1CE ? */ - RW; /* 1D0 ? */ - RW; /* 1D2 ? */ - RW; /* 1D4 ? */ - RW; /* 1D6 ? */ - RW; /* 1D8 ? */ - RW; /* 1DA ? */ - new_beamcon0 = RW; /* 1DC BEAMCON0 */ - RW; /* 1DE ? */ - RW; /* 1E0 ? */ - RW; /* 1E2 ? */ - diwhigh = RW; /* 1E4 ? */ - if (diwhigh & 0x8000) - diwhigh_written = 1; - diwhigh &= 0x7fff; - RW; /* 1E6 ? */ - RW; /* 1E8 ? */ - RW; /* 1EA ? */ - RW; /* 1EC ? */ - RW; /* 1EE ? */ - RW; /* 1F0 ? */ - RW; /* 1F2 ? */ - RW; /* 1F4 ? */ - RW; /* 1F6 ? */ - RW; /* 1F8 ? */ - RW; /* 1FA ? */ - fmode = RW; /* 1FC FMODE */ - last_custom_value = RW; /* 1FE ? */ - - DISK_restore_custom (dskpt, dsklen, dskbytr); - - return src; -} - - -#define SB save_u8 -#define SW save_u16 -#define SL save_u32 - -extern uae_u16 serper; - -uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full) -{ - uae_u8 *dstbak, *dst; - int i; - uae_u32 dskpt; - uae_u16 dsklen, dsksync, dskbytr; - - DISK_save_custom (&dskpt, &dsklen, &dsksync, &dskbytr); - - if (dstptr) - dstbak = dst = dstptr; - else - dstbak = dst = malloc (8+256*2); - - SL (currprefs.chipset_mask); - SW (0); /* 000 ? */ - SW (dmacon); /* 002 DMACONR */ - SW (VPOSR()); /* 004 VPOSR */ - SW (VHPOSR()); /* 006 VHPOSR */ - SW (0); /* 008 DSKDATR */ - SW (JOY0DAT()); /* 00A JOY0DAT */ - SW (JOY1DAT()); /* 00C JOY1DAT */ - SW (clxdat); /* 00E CLXDAT */ - SW (ADKCONR()); /* 010 ADKCONR */ - SW (POT0DAT()); /* 012 POT0DAT */ - SW (POT0DAT()); /* 014 POT1DAT */ - SW (0) ; /* 016 POTINP * */ - SW (0); /* 018 SERDATR * */ - SW (dskbytr); /* 01A DSKBYTR */ - SW (INTENAR()); /* 01C INTENAR */ - SW (INTREQR()); /* 01E INTREQR */ - SL (dskpt); /* 020-023 DSKPT */ - SW (dsklen); /* 024 DSKLEN */ - SW (0); /* 026 DSKDAT */ - SW (0); /* 028 REFPTR */ - SW (lof); /* 02A VPOSW */ - SW (0); /* 02C VHPOSW */ - SW (copcon); /* 02E COPCON */ - SW (serper); /* 030 SERDAT * */ - SW (serdat); /* 032 SERPER * */ - SW (potgo_value); /* 034 POTGO */ - SW (0); /* 036 JOYTEST * */ - SW (0); /* 038 STREQU */ - SW (0); /* 03A STRVBL */ - SW (0); /* 03C STRHOR */ - SW (0); /* 03E STRLONG */ - SW (bltcon0); /* 040 BLTCON0 */ - SW (bltcon1); /* 042 BLTCON1 */ - SW (blt_info.bltafwm); /* 044 BLTAFWM */ - SW (blt_info.bltalwm); /* 046 BLTALWM */ - SL (bltcpt); /* 048-04B BLTCPT */ - SL (bltbpt); /* 04C-04F BLTCPT */ - SL (bltapt); /* 050-053 BLTCPT */ - SL (bltdpt); /* 054-057 BLTCPT */ - SW (0); /* 058 BLTSIZE */ - SW (0); /* 05A BLTCON0L (use BLTCON0 instead) */ - SW (blt_info.vblitsize); /* 05C BLTSIZV */ - SW (blt_info.hblitsize); /* 05E BLTSIZH */ - SW (blt_info.bltcmod); /* 060 BLTCMOD */ - SW (blt_info.bltbmod); /* 062 BLTBMOD */ - SW (blt_info.bltamod); /* 064 BLTAMOD */ - SW (blt_info.bltdmod); /* 066 BLTDMOD */ - SW (0); /* 068 ? */ - SW (0); /* 06A ? */ - SW (0); /* 06C ? */ - SW (0); /* 06E ? */ - SW (blt_info.bltcdat); /* 070 BLTCDAT */ - SW (blt_info.bltbdat); /* 072 BLTBDAT */ - SW (blt_info.bltadat); /* 074 BLTADAT */ - SW (0); /* 076 ? */ - SW (0); /* 078 ? */ - SW (0); /* 07A ? */ - SW (DENISEID()); /* 07C DENISEID/LISAID */ - SW (dsksync); /* 07E DSKSYNC */ - SL (cop1lc); /* 080-083 COP1LC */ - SL (cop2lc); /* 084-087 COP2LC */ - SW (0); /* 088 ? */ - SW (0); /* 08A ? */ - SW (0); /* 08C ? */ - SW (diwstrt); /* 08E DIWSTRT */ - SW (diwstop); /* 090 DIWSTOP */ - SW (ddfstrt); /* 092 DDFSTRT */ - SW (ddfstop); /* 094 DDFSTOP */ - SW (dmacon); /* 096 DMACON */ - SW (clxcon); /* 098 CLXCON */ - SW (intena); /* 09A INTENA */ - SW (intreq); /* 09C INTREQ */ - SW (adkcon); /* 09E ADKCON */ - for (i = 0; full && i < 32; i++) - SW (0); - for (i = 0; i < 8; i++) - SL (bplpt[i]); /* 0E0-0FE BPLxPT */ - SW (bplcon0); /* 100 BPLCON0 */ - SW (bplcon1); /* 102 BPLCON1 */ - SW (bplcon2); /* 104 BPLCON2 */ - SW (bplcon3); /* 106 BPLCON3 */ - SW (bpl1mod); /* 108 BPL1MOD */ - SW (bpl2mod); /* 10A BPL2MOD */ - SW (bplcon4); /* 10C BPLCON4 */ - SW (clxcon2); /* 10E CLXCON2 */ - for (i = 0;i < 8; i++) - SW (0); /* 110 BPLxDAT */ - if (full) { - for (i = 0; i < 8; i++) { - SL (spr[i].pt); /* 120-13E SPRxPT */ - SW (sprpos[i]); /* 1x0 SPRxPOS */ - SW (sprctl[i]); /* 1x2 SPRxPOS */ - SW (sprdata[i][0]); /* 1x4 SPRxDATA */ - SW (sprdatb[i][0]); /* 1x6 SPRxDATB */ - } - } - for ( i = 0; i < 32; i++) - SW (current_colors.color_regs_ecs[i]); /* 180-1BE COLORxx */ - SW (htotal); /* 1C0 HTOTAL */ - SW (0); /* 1C2 */ - SW (0); /* 1C4 */ - SW (0); /* 1C6 */ - SW (vtotal); /* 1C8 VTOTAL */ - SW (0); /* 1CA */ - SW (0); /* 1CC */ - SW (0); /* 1CE */ - SW (0); /* 1D0 */ - SW (0); /* 1D2 */ - SW (0); /* 1D4 */ - SW (0); /* 1D6 */ - SW (0); /* 1D8 */ - SW (0); /* 1DA */ - SW (beamcon0); /* 1DC BEAMCON0 */ - SW (0); /* 1DE */ - SW (0); /* 1E0 */ - SW (0); /* 1E2 */ - SW (diwhigh | (diwhigh_written ? 0x8000 : 0)); /* 1E4 */ - SW (0); /* 1E6 */ - SW (0); /* 1E8 */ - SW (0); /* 1EA */ - SW (0); /* 1EC */ - SW (0); /* 1EE */ - SW (0); /* 1F0 */ - SW (0); /* 1F2 */ - SW (0); /* 1F4 */ - SW (0); /* 1F6 */ - SW (0); /* 1F8 */ - SW (0); /* 1FA */ - SW (fmode); /* 1FC FMODE */ - SW (last_custom_value); /* 1FE */ - - *len = dst - dstbak; - return dstbak; -} - -uae_u8 *restore_custom_agacolors (uae_u8 *src) -{ - int i; - - for (i = 0; i < 256; i++) -#ifdef AGA - current_colors.color_regs_aga[i] = RL; -#else - RL; -#endif - return src; -} - -uae_u8 *save_custom_agacolors (int *len, uae_u8 *dstptr) -{ - uae_u8 *dstbak, *dst; - int i; - - if (dstptr) - dstbak = dst = dstptr; - else - dstbak = dst = malloc (256*4); - for (i = 0; i < 256; i++) -#ifdef AGA - SL (current_colors.color_regs_aga[i]); -#else - SL (0); -#endif - *len = dst - dstbak; - return dstbak; -} - -uae_u8 *restore_custom_sprite (int num, uae_u8 *src) -{ - spr[num].pt = RL; /* 120-13E SPRxPT */ - sprpos[num] = RW; /* 1x0 SPRxPOS */ - sprctl[num] = RW; /* 1x2 SPRxPOS */ - sprdata[num][0] = RW; /* 1x4 SPRxDATA */ - sprdatb[num][0] = RW; /* 1x6 SPRxDATB */ - sprdata[num][1] = RW; - sprdatb[num][1] = RW; - sprdata[num][2] = RW; - sprdatb[num][2] = RW; - sprdata[num][3] = RW; - sprdatb[num][3] = RW; - spr[num].armed = RB; - return src; -} - -uae_u8 *save_custom_sprite(int num, int *len, uae_u8 *dstptr) -{ - uae_u8 *dstbak, *dst; - - if (dstptr) - dstbak = dst = dstptr; - else - dstbak = dst = malloc (25); - SL (spr[num].pt); /* 120-13E SPRxPT */ - SW (sprpos[num]); /* 1x0 SPRxPOS */ - SW (sprctl[num]); /* 1x2 SPRxPOS */ - SW (sprdata[num][0]); /* 1x4 SPRxDATA */ - SW (sprdatb[num][0]); /* 1x6 SPRxDATB */ - SW (sprdata[num][1]); - SW (sprdatb[num][1]); - SW (sprdata[num][2]); - SW (sprdatb[num][2]); - SW (sprdata[num][3]); - SW (sprdatb[num][3]); - SB (spr[num].armed ? 1 : 0); - *len = dst - dstbak; - return dstbak; -} - -void check_prefs_changed_custom (void) -{ - currprefs.gfx_framerate = changed_prefs.gfx_framerate; - if (inputdevice_config_change_test ()) { - inputdevice_copyconfig (&changed_prefs, &currprefs); - inputdevice_updateconfig (&currprefs); - } - currprefs.immediate_blits = changed_prefs.immediate_blits; - currprefs.collision_level = changed_prefs.collision_level; - currprefs.fast_copper = changed_prefs.fast_copper; - - if (currprefs.chipset_mask != changed_prefs.chipset_mask || - currprefs.gfx_vsync != changed_prefs.gfx_vsync || - currprefs.ntscmode != changed_prefs.ntscmode) { - currprefs.gfx_vsync = changed_prefs.gfx_vsync; - currprefs.chipset_mask = changed_prefs.chipset_mask; - if (currprefs.ntscmode != changed_prefs.ntscmode) { - currprefs.ntscmode = changed_prefs.ntscmode; - new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; - } - init_custom (); - } - currprefs.gfx_filter_horiz_zoom = changed_prefs.gfx_filter_horiz_zoom; - currprefs.gfx_filter_vert_zoom = changed_prefs.gfx_filter_vert_zoom; - currprefs.gfx_filter_horiz_offset = changed_prefs.gfx_filter_horiz_offset; - currprefs.gfx_filter_vert_offset = changed_prefs.gfx_filter_vert_offset; - currprefs.gfx_filter_scanlines = changed_prefs.gfx_filter_scanlines; - currprefs.gfx_filter_filtermode = changed_prefs.gfx_filter_filtermode; -} - -#ifdef CPUEMU_6 - -STATIC_INLINE void sync_copper (int hpos) -{ - if (eventtab[ev_copper].active) { - eventtab[ev_copper].active = 0; - update_copper (hpos); - return; - } - if (copper_enabled_thisline) - update_copper (hpos); -} - -STATIC_INLINE decide_fetch_ce (int hpos) -{ - if (ddf_change == vpos && vpos < maxvpos) - decide_fetch (hpos); -} - -STATIC_INLINE int dma_cycle(void) -{ - int hpos, cycles = 0, bnasty = 0; - - for (;;) { - int bpldma; - int blitpri = dmaen (DMA_BLITPRI); - do_cycles (1 * CYCLE_UNIT); - cycles += CYCLE_UNIT; - hpos = current_hpos (); - sync_copper (hpos); - decide_line (hpos); - decide_fetch_ce (hpos); - bpldma = is_bitplane_dma (hpos); - if (cycle_line[hpos] == 0 && !bpldma) { - if (bltstate == BLT_done || bnasty >= 3) - break; - decide_blitter (hpos); - if (cycle_line[hpos] == 0) - break; - if (!blitpri || blit_singlechannel) - bnasty++; - } else if (bpldma && (blit_singlechannel || !blitpri)) { - bnasty++; - } - /* bus was allocated to dma channel, wait for next cycle.. */ - } - cycle_line[hpos] |= CYCLE_CPU; - return cycles; -} - -uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode) -{ - uae_u32 v = 0; - dma_cycle (); - if (mode > 0) - v = get_word (addr); - else if (mode == 0) - v = get_byte (addr); - do_cycles (1 * CYCLE_UNIT); - return v; -} - -uae_u32 wait_cpu_cycle_read_cycles (uaecptr addr, int mode, int *cycles) -{ - uae_u32 v = 0; - *cycles = dma_cycle () + CYCLE_UNIT; - if (mode > 0) - v = get_word (addr); - else if (mode == 0) - v = get_byte (addr); - do_cycles (1 * CYCLE_UNIT); - return v; -} - -void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v) -{ - dma_cycle (); - if (mode > 0) - put_word (addr, v); - else if (mode == 0) - put_byte (addr, v); - do_cycles (1 * CYCLE_UNIT); -} - -void do_cycles_ce (long cycles) -{ - int hpos, bpldma; - while (cycles > 0) { - do_cycles (1 * CYCLE_UNIT); - cycles -= CYCLE_UNIT; - hpos = current_hpos (); - sync_copper (hpos); - decide_line (hpos); - decide_fetch_ce (hpos); - bpldma = is_bitplane_dma (hpos); - if (cycle_line[hpos] == 0 && !bpldma) - decide_blitter (hpos); - } -} - -#endif diff --git a/debug.c b/debug.c index b063694b..34b44be2 100755 --- a/debug.c +++ b/debug.c @@ -606,7 +606,7 @@ static void dump_custom_regs (int aga) addr2 = custd[j].adr & 0x1ff; v1 = (p1[addr1 + 0] << 8) | p1[addr1 + 1]; v2 = (p1[addr2 + 0] << 8) | p1[addr2 + 1]; - console_out_f ("%03.3X %s\t%04.4X\t%03.3X %s\t%04.4X\n", + console_out_f ("%03X %s\t%04X\t%03X %s\t%04X\n", addr1, custd[i].name, v1, addr2, custd[j].name, v2); } @@ -818,7 +818,7 @@ static int copper_debugger (char **c) debug_copper = 1|4; if (more_params(c)) { debug_copper_pc = readhex(c); - console_out_f ("Copper breakpoint @0x%08.8x\n", debug_copper_pc); + console_out_f ("Copper breakpoint @0x%08x\n", debug_copper_pc); } else { debug_copper &= ~4; } @@ -1242,17 +1242,17 @@ static void illg_debug_do (uaecptr addr, int rwi, int size, uae_u32 val) illg_debug_check (ad, rwi, size, val); } else if ((mask & 3) == 0) { if (rwi & 2) - console_out_f ("W: %08.8X=%02.2X PC=%08.8X\n", ad, v, pc); + console_out_f ("W: %08X=%02X PC=%08X\n", ad, v, pc); else if (rwi & 1) - console_out_f ("R: %08.8X PC=%08.8X\n", ad, pc); + console_out_f ("R: %08X PC=%08X\n", ad, pc); if (illgdebug_break) activate_debugger (); } else if (!(mask & 1) && (rwi & 1)) { - console_out_f ("RO: %08.8X=%02.2X PC=%08.8X\n", ad, v, pc); + console_out_f ("RO: %08X=%02X PC=%08X\n", ad, v, pc); if (illgdebug_break) activate_debugger (); } else if (!(mask & 2) && (rwi & 2)) { - console_out_f ("WO: %08.8X PC=%08.8X\n", ad, pc); + console_out_f ("WO: %08X PC=%08X\n", ad, pc); if (illgdebug_break) activate_debugger (); } @@ -1346,7 +1346,7 @@ static void smc_detector (uaecptr addr, int rwi, int size, uae_u32 *valp) } if (hitcnt < 100) { smc_table[hitaddr].cnt++; - console_out_f ("SMC at %08.8X - %08.8X (%d) from %08.8X\n", + console_out_f ("SMC at %08X - %08X (%d) from %08X\n", hitaddr, hitaddr + hitcnt, hitcnt, hitpc); if (smc_mode) activate_debugger (); @@ -1684,7 +1684,7 @@ void memwatch_dump2 (char *buf, int bufsize, int num) mwn = &mwnodes[i]; if (mwn->size == 0) continue; - buf = buf_out (buf, &bufsize, "%d: %08.8X - %08.8X (%d) %c%c%c", + buf = buf_out (buf, &bufsize, "%d: %08X - %08X (%d) %c%c%c", i, mwn->addr, mwn->addr + (mwn->size - 1), mwn->size, (mwn->rwi & 1) ? 'R' : ' ', (mwn->rwi & 2) ? 'W' : ' ', (mwn->rwi & 4) ? 'I' : ' '); if (mwn->frozen) @@ -1741,7 +1741,7 @@ static void memwatch (char **c) uae_u32 len = 1; if (more_params (c)) len = readhex (c); - console_out_f ("cleared logging addresses %08.8X - %08.8X\n", addr, addr + len); + console_out_f ("cleared logging addresses %08X - %08X\n", addr, addr + len); while (len > 0) { addr &= 0xffffff; illgdebug[addr] = 7; @@ -1900,7 +1900,7 @@ static void memory_map_dump_2 (int log) size_out /= 1024; size_ext = 'M'; } - sprintf (txt, "%08.8X %7d%c/%d = %7d%c %s", j << 16, size_out, size_ext, + sprintf (txt, "%08X %7d%c/%d = %7d%c %s", j << 16, size_out, size_ext, mirrored, mirrored ? size_out / mirrored : size_out, size_ext, name); tmp[0] = 0; @@ -1908,7 +1908,7 @@ static void memory_map_dump_2 (int log) char *p = txt + strlen (txt); uae_u32 crc = get_crc32 (a1->xlateaddr(j << 16), (size * 1024) / mirrored); struct romdata *rd = getromdatabycrc (crc); - sprintf(p, " (%08.8X)", crc); + sprintf(p, " (%08X)", crc); if (rd) { tmp[0] = '='; getromname (rd, tmp + 1); @@ -2639,7 +2639,7 @@ static void debug_1 (void) next_char (&inptr); if (more_params (&inptr)) debug_sprite_mask = readhex (&inptr); - console_out_f ("sprite mask: %02.2X\n", debug_sprite_mask); + console_out_f ("sprite mask: %02X\n", debug_sprite_mask); } } else { searchmem (&inptr); @@ -2834,8 +2834,11 @@ static void debug_1 (void) case 'a': if (more_params (&inptr)) { char nc = next_char (&inptr); - if (nc == 'm') - audio_channel_mask = readint (&inptr); + if (nc == 'm') { + if (more_params (&inptr)) + audio_channel_mask = readint (&inptr); + console_out_f ("Audio mask = %02X\n", audio_channel_mask); + } } break; case 'h': @@ -2849,7 +2852,7 @@ static void debug_1 (void) } } -static void addhistory(void) +static void addhistory (void) { uae_u32 pc = m68k_getpc (®s); // if (!notinrom()) @@ -2903,7 +2906,7 @@ void debug (void) continue; if (bpnodes[i].addr == pc) { bp = 1; - console_out_f ("Breakpoint at %08.8X\n", pc); + console_out_f ("Breakpoint at %08X\n", pc); break; } } @@ -2968,7 +2971,7 @@ void debug (void) } } } else { - console_out_f ("Memwatch %d: break at %08X.%c %c%c%c %08.8X PC=%08X\n", memwatch_triggered - 1, mwhit.addr, + console_out_f ("Memwatch %d: break at %08X.%c %c%c%c %08X PC=%08X\n", memwatch_triggered - 1, mwhit.addr, mwhit.size == 1 ? 'B' : (mwhit.size == 2 ? 'W' : 'L'), (mwhit.rwi & 1) ? 'R' : ' ', (mwhit.rwi & 2) ? 'W' : ' ', (mwhit.rwi & 4) ? 'I' : ' ', mwhit.val, mwhit.pc); @@ -3033,8 +3036,8 @@ const char *debuginfo (int mode) { static char txt[100]; uae_u32 pc = M68K_GETPC; - sprintf (txt, "PC=%08.8X INS=%04.4X %04.4X %04.4X", - pc, get_word (pc), get_word (pc+2), get_word (pc+4)); + sprintf (txt, "PC=%08X INS=%04X %04X %04X", + pc, get_word (pc), get_word (pc + 2), get_word (pc + 4)); return txt; } @@ -3139,7 +3142,7 @@ static void mmu_do_hit_pre (struct mmudata *md, uaecptr addr, int size, int rwi, mmur = regs; pc = m68k_getpc (®s); if (mmu_logging) - console_out_f ("MMU: hit %08.8X SZ=%d RW=%d V=%08.8X PC=%08.8X\n", addr, size, rwi, v, pc); + console_out_f ("MMU: hit %08X SZ=%d RW=%d V=%08X PC=%08X\n", addr, size, rwi, v, pc); p = mmu_regs; put_long (p, 0); p += 4; @@ -3202,7 +3205,7 @@ static int mmu_hit (uaecptr addr, int size, int rwi, uae_u32 *v) if (maddr == addr) /* infinite mmu hit loop? no thanks.. */ return 1; if (mmu_logging) - console_out_f ("MMU: remap %08.8X -> %08.8X SZ=%d RW=%d\n", addr, maddr, size, rwi); + console_out_f ("MMU: remap %08X -> %08X SZ=%d RW=%d\n", addr, maddr, size, rwi); if ((rwi & 2)) { switch (size) { @@ -3262,8 +3265,8 @@ static void mmu_free_node(struct mmunode *mn) { if (!mn) return; - mmu_free_node(mn->next); - xfree(mn); + mmu_free_node (mn->next); + xfree (mn); } static void mmu_free(void) @@ -3273,9 +3276,9 @@ static void mmu_free(void) for (i = 0; i < mmu_slots; i++) { mn = mmunl[i]; - mmu_free_node(mn); + mmu_free_node (mn); } - xfree(mmunl); + xfree (mmunl); mmunl = NULL; xfree (mmubanks); mmubanks = NULL; @@ -3305,13 +3308,13 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) wasjit = currprefs.cachesize; changed_prefs.cachesize = 0; console_out ("MMU: JIT disabled\n"); - check_prefs_changed_comp(); + check_prefs_changed_comp (); } if (mode == 0) { if (mmu_enabled) { - mmu_free(); - deinitialize_memwatch(); + mmu_free (); + deinitialize_memwatch (); console_out ("MMU: disabled\n"); changed_prefs.cachesize = wasjit; } @@ -3350,7 +3353,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) if (mn->mmubank->p_addr == parm2) { getmmubank(mn->mmubank, parm2); if (mmu_logging) - console_out_f ("MMU: bank update %08.8X: %08.8X - %08.8X %08.8X\n", + console_out_f ("MMU: bank update %08X: %08X - %08X %08X\n", mn->mmubank->flags, mn->mmubank->addr, mn->mmubank->len + mn->mmubank->addr, mn->mmubank->remap); } @@ -3360,7 +3363,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) } mmu_slots = 1 << ((currprefs.address_space_24 ? 24 : 32) - MMU_PAGE_SHIFT); - mmunl = (struct mmunode**)xcalloc (sizeof (struct mmunode*) * mmu_slots, 1); + mmunl = xcalloc (sizeof (struct mmunode*) * mmu_slots, 1); size = 1; p2 = get_long (p); while (get_long (p2) != 0xffffffff) { @@ -3368,7 +3371,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) size++; } p = banks = get_long (p); - snptr = mmubanks = (struct mmudata*)xmalloc (sizeof (struct mmudata) * size); + snptr = mmubanks = xmalloc (sizeof (struct mmudata) * size); for (;;) { int off; if (getmmubank(snptr, p)) @@ -3376,19 +3379,19 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) p += 16; off = snptr->addr >> MMU_PAGE_SHIFT; if (mmunl[off] == NULL) { - mn = mmunl[off] = (struct mmunode*)xcalloc (sizeof (struct mmunode), 1); + mn = mmunl[off] = xcalloc (sizeof (struct mmunode), 1); } else { mn = mmunl[off]; while (mn->next) mn = mn->next; - mn = mn->next = (struct mmunode*)xcalloc (sizeof (struct mmunode), 1); + mn = mn->next = xcalloc (sizeof (struct mmunode), 1); } mn->mmubank = snptr; snptr++; } - initialize_memwatch(1); - console_out_f ("MMU: enabled, %d banks, CB=%08.8X S=%08.8X BNK=%08.8X SF=%08.8X, %d*%d\n", + initialize_memwatch (1); + console_out_f ("MMU: enabled, %d banks, CB=%08X S=%08X BNK=%08X SF=%08X, %d*%d\n", size - 1, mmu_callback, parm, banks, mmu_regs, mmu_slots, 1 << MMU_PAGE_SHIFT); set_special (®s, SPCFLAG_BRK); return 1; diff --git a/disk.c b/disk.c index 9423c847..ac5738e2 100755 --- a/disk.c +++ b/disk.c @@ -1689,7 +1689,7 @@ static int drive_write_pcdos (drive *drv) continue; } if (mark != 0xfb) { - write_log ("PCDOS: track %d: unknown address mark %02.2X\n", drv->cyl * 2 + side, mark); + write_log ("PCDOS: track %d: unknown address mark %02X\n", drv->cyl * 2 + side, mark); continue; } if (sector < 0) @@ -2154,7 +2154,7 @@ void DISK_select (uae_u8 data) step_pulse = data & 1; if (disk_debug_logging > 1) - write_log ("%08.8X %02.2X %s drvmask=%x", M68K_GETPC, data, tobin(data), selected ^ 15); + write_log ("%08X %02X %s drvmask=%x", M68K_GETPC, data, tobin(data), selected ^ 15); #ifdef AMAX if (currprefs.amaxromfile[0]) @@ -2217,7 +2217,7 @@ void DISK_select (uae_u8 data) if (!currprefs.cs_df0idhw && dr == 0) drv->idbit = 0; #ifdef DEBUG_DRIVE_ID - write_log ("DISK_status: sel %d id %s (%08.8X) [0x%08lx, bit #%02d: %d]\n", + write_log ("DISK_status: sel %d id %s (%08X) [0x%08lx, bit #%02d: %d]\n", dr, drive_id_name(drv), drv->drive_id, drv->drive_id << drv->drive_id_scnt, 31 - drv->drive_id_scnt, drv->idbit); #endif } @@ -2316,7 +2316,7 @@ void dumpdisk (void) drive_writeprotected(drv) ? "ro" : "rw", drv->mfmpos, drv->tracklen); w = word; for (j = 0; j < 15; j++) { - console_out_f ("%04.4X ", w); + console_out_f ("%04X ", w); for (k = 0; k < 16; k++) { w <<= 1; w |= getonebit (drv->bigmfmbuf, drv->mfmpos + j * 16 + k); @@ -2325,7 +2325,7 @@ void dumpdisk (void) console_out ("\n"); } } - console_out_f ("side %d, dma %d, bitoffset %d, word %04.4X, dskbytr %04.4X adkcon %04.4X dsksync %04.4X\n", side, dskdmaen, bitoffset, word, dskbytr_val, adkcon, dsksync); + console_out_f ("side %d, dma %d, bitoffset %d, word %04X, dskbytr %04X adkcon %04X dsksync %04X\n", side, dskdmaen, bitoffset, word, dskbytr_val, adkcon, dsksync); } static void disk_dmafinished (void) @@ -2335,7 +2335,7 @@ static void disk_dmafinished (void) dskdmaen = 0; if (disk_debug_logging > 0) { int dr, mfmpos = -1; - write_log ("disk dma finished %08.8X MFMpos=", dskpt); + write_log ("disk dma finished %08X MFMpos=", dskpt); for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) write_log ("%d%s", floppy[dr].mfmpos, dr < MAX_FLOPPY_DRIVES - 1 ? "," : ""); write_log ("\n"); @@ -2585,7 +2585,7 @@ static void disk_doupdate_read (drive * drv, int floppybits) else word |= getonebit (drv->bigmfmbuf, drv->mfmpos); } - //write_log ("%08.8X bo=%d so=%d mfmpos=%d dma=%d\n", (word & 0xffffff), bitoffset, syncoffset, drv->mfmpos,dma_enable); + //write_log ("%08X bo=%d so=%d mfmpos=%d dma=%d\n", (word & 0xffffff), bitoffset, syncoffset, drv->mfmpos,dma_enable); drv->mfmpos++; drv->mfmpos %= drv->tracklen; if (drv->mfmpos == drv->indexoffset) { @@ -2641,7 +2641,7 @@ static void disk_doupdate_read (drive * drv, int floppybits) static void disk_dma_debugmsg (void) { - write_log ("LEN=%04.4X (%d) SYNC=%04.4X PT=%08.8X ADKCON=%04.4X PC=%08.8X\n", + write_log ("LEN=%04X (%d) SYNC=%04X PT=%08X ADKCON=%04X PC=%08X\n", dsklength, dsklength, (adkcon & 0x400) ? dsksync : 0xffff, dskpt, adkcon, M68K_GETPC); } @@ -2679,7 +2679,7 @@ uae_u16 DSKBYTR (int hpos) if (dsklen & 0x4000) v |= 0x2000; if (disk_debug_logging > 1) - write_log ("DSKBYTR=%04.4X hpos=%d\n", v, hpos); + write_log ("DSKBYTR=%04X hpos=%d\n", v, hpos); if (disk_debug_mode & DISK_DEBUG_PIO) { int dr; for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { @@ -2689,7 +2689,7 @@ uae_u16 DSKBYTR (int hpos) if (!(selected & (1 << dr))) { if (disk_debug_track < 0 || disk_debug_track == 2 * drv->cyl + side) { disk_dma_debugmsg (); - write_log ("DSKBYTR=%04.4X\n", v); + write_log ("DSKBYTR=%04X\n", v); activate_debugger (); break; } @@ -3004,7 +3004,7 @@ void DSKDAT (uae_u16 v) #endif if (count < 5) { count++; - write_log ("%04.4X written to DSKDAT. Not good. PC=%08.8X", v, M68K_GETPC); + write_log ("%04X written to DSKDAT. Not good. PC=%08X", v, M68K_GETPC); if (count == 5) write_log ("(further messages suppressed)"); diff --git a/expansion.c b/expansion.c index ddc7a820..366c41ec 100755 --- a/expansion.c +++ b/expansion.c @@ -230,7 +230,7 @@ static uae_u32 REGPARAM2 expamem_bget (uaecptr addr) #endif addr &= 0xFFFF; b = expamem[addr]; - //write_log ("%08x=%02.2X\n", addr, b); + //write_log ("%08x=%02X\n", addr, b); return b; } @@ -499,7 +499,7 @@ static uae_u32 REGPARAM2 catweasel_lget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif - write_log ("catweasel_lget @%08.8X!\n",addr); + write_log ("catweasel_lget @%08X!\n",addr); return 0; } @@ -508,7 +508,7 @@ static uae_u32 REGPARAM2 catweasel_wget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif - write_log ("catweasel_wget @%08.8X!\n",addr); + write_log ("catweasel_wget @%08X!\n",addr); return 0; } @@ -527,7 +527,7 @@ static void REGPARAM2 catweasel_lput (uaecptr addr, uae_u32 l) #ifdef JIT special_mem |= S_WRITE; #endif - write_log ("catweasel_lput @%08.8X=%08.8X!\n",addr,l); + write_log ("catweasel_lput @%08X=%08X!\n",addr,l); } static void REGPARAM2 catweasel_wput (uaecptr addr, uae_u32 w) @@ -535,7 +535,7 @@ static void REGPARAM2 catweasel_wput (uaecptr addr, uae_u32 w) #ifdef JIT special_mem |= S_WRITE; #endif - write_log ("catweasel_wput @%08.8X=%04.4X!\n",addr,w); + write_log ("catweasel_wput @%08X=%04X!\n",addr,w); } static void REGPARAM2 catweasel_bput (uaecptr addr, uae_u32 b) @@ -555,7 +555,7 @@ static int REGPARAM2 catweasel_check (uaecptr addr, uae_u32 size) static uae_u8 *REGPARAM2 catweasel_xlate (uaecptr addr) { - write_log ("catweasel_xlate @%08.8X size %08.8X\n", addr); + write_log ("catweasel_xlate @%08X size %08X\n", addr); return 0; } diff --git a/fdi2raw.c b/fdi2raw.c index 87ab7a9c..f7b28570 100755 --- a/fdi2raw.c +++ b/fdi2raw.c @@ -59,7 +59,7 @@ static char *datalog (uae_u8 *src, int len) offset2 = offset; buf[offset++]='\''; while (len--) { - sprintf (buf + offset, "%02.2X", src[i]); + sprintf (buf + offset, "%02X", src[i]); offset += 2; i++; if (i > 10) break; @@ -329,13 +329,13 @@ static int decode_raw_track (FDI *fdi) /* unknown track */ static void zxx (FDI *fdi) { - outlog ("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type); + outlog ("track %d: unknown track type 0x%02X\n", fdi->current_track, fdi->track_type); // return -1; } /* unsupported track */ static void zyy (FDI *fdi) { - outlog ("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type); + outlog ("track %d: unsupported track type 0x%02X\n", fdi->current_track, fdi->track_type); // return -1; } /* empty track */ @@ -347,13 +347,13 @@ static void track_empty (FDI *fdi) /* unknown sector described type */ static void dxx (FDI *fdi) { - outlog ("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type); + outlog ("\ntrack %d: unknown sector described type 0x%02X\n", fdi->current_track, fdi->track_type); fdi->err = 1; } /* unsupported sector described type */ static void dyy (FDI *fdi) { - outlog ("\ntrack %d: unsupported sector described 0x%02.2X\n", fdi->current_track, fdi->track_type); + outlog ("\ntrack %d: unsupported sector described 0x%02X\n", fdi->current_track, fdi->track_type); fdi->err = 1; } /* add position of mfm sync bit */ @@ -476,7 +476,7 @@ static void s08(FDI *fdi) int bytes = *fdi->track_src++; uae_u8 byte = *fdi->track_src++; if (bytes == 0) bytes = 256; - debuglog ("s08:len=%d,data=%02.2X",bytes,byte); + debuglog ("s08:len=%d,data=%02X",bytes,byte); while(bytes--) byte_add (fdi, byte); } /* RLE MFM-decoded data */ @@ -486,7 +486,7 @@ static void s09(FDI *fdi) uae_u8 byte = *fdi->track_src++; if (bytes == 0) bytes = 256; bit_drop_next (fdi); - debuglog ("s09:len=%d,data=%02.2X",bytes,byte); + debuglog ("s09:len=%d,data=%02X",bytes,byte); while(bytes--) byte_mfm_add (fdi, byte); } /* MFM-encoded data */ @@ -694,7 +694,7 @@ static int amiga_check_track (FDI *fdi) continue; } if ((id >> 24) != 0xff) { - outlog ("sector %d format type %02.2X?\n", trackoffs, id >> 24); + outlog ("sector %d format type %02X?\n", trackoffs, id >> 24); ok = 0; } chksum = odd ^ even; @@ -1320,7 +1320,7 @@ static int handle_sectors_described_track (FDI *fdi) do { fdi->track_type = *fdi->track_src++; - outlog ("%06.6X %06.6X %02.2X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type); + outlog ("%06X %06X %02X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type); oldout = fdi->out; decode_sectors_described_track[fdi->track_type](fdi); outlog (" %d\n", fdi->out - oldout); @@ -1330,7 +1330,7 @@ static int handle_sectors_described_track (FDI *fdi) return -1; } if (fdi->track_src - fdi->track_src_buffer >= fdi->track_src_len) { - outlog ("source buffer overrun, previous type: %02.2X\n", fdi->track_type); + outlog ("source buffer overrun, previous type: %02X\n", fdi->track_type); return -1; } } while (fdi->track_type != 0xff); @@ -2151,7 +2151,7 @@ int fdi2raw_loadtrack (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int trac else fdi->bit_rate = 250; - debuglog ("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n", + debuglog ("track %d: srclen: %d track_type: %02X, bitrate: %d\n", fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate); if ((fdi->track_type & 0xc0) == 0x80) { diff --git a/filesys.c b/filesys.c index ed51619a..5f577b40 100755 --- a/filesys.c +++ b/filesys.c @@ -2161,26 +2161,21 @@ static void free_key (Unit *unit, Key *k) static Key *lookup_key (Unit *unit, uae_u32 uniq) { Key *k; + unsigned int total = 0; /* It's hardly worthwhile to optimize this - most of the time there are * only one or zero keys. */ for (k = unit->keys; k; k = k->next) { + total++; if (uniq == k->uniq) return k; } - write_log ("Error: couldn't find key!\n"); -#if 0 - exit(1); - /* NOTREACHED */ -#endif - /* There isn't much hope we will recover. Unix would kill the process, - * AmigaOS gets killed by it. */ - write_log ("Better reset that Amiga - the system is messed up.\n"); + write_log ("Error: couldn't find key %u / %u!\n", uniq, total); return 0; } static Key *new_key (Unit *unit) { - Key *k = (Key *) xmalloc (sizeof(Key)); + Key *k = xmalloc (sizeof(Key)); k->uniq = ++key_uniq; k->fd = NULL; k->file_pos = 0; diff --git a/fpp.c b/fpp.c index 4aebb38c..72c4a98c 100755 --- a/fpp.c +++ b/fpp.c @@ -120,7 +120,7 @@ static uae_u16 x87_cw_tab[] = { static __inline__ void native_set_fpucw (uae_u32 m68k_cw) { #if USE_X86_FPUCW - uae_u16 x87_cw = x87_cw_tab[(m68k_cw>>4)&0xf]; + uae_u16 x87_cw = x87_cw_tab[(m68k_cw >> 4) & 0xf]; #if defined(X86_MSVC_ASSEMBLY) __asm { @@ -172,7 +172,7 @@ static void fpu_op_illg (uae_u32 opcode, struct regstruct *regs, int pcoffset) op_illg (opcode, regs); } -STATIC_INLINE int fault_if_no_fpu(uae_u32 opcode, struct regstruct *regs, int pcoffset) +STATIC_INLINE int fault_if_no_fpu (uae_u32 opcode, struct regstruct *regs, int pcoffset) { if ((regs->pcr & 2) || currprefs.fpu_model <= 0) { fpu_op_illg (opcode, regs, pcoffset); @@ -181,7 +181,7 @@ STATIC_INLINE int fault_if_no_fpu(uae_u32 opcode, struct regstruct *regs, int pc return 0; } -static int get_fpu_version(void) +static int get_fpu_version (void) { int v = 0; @@ -513,7 +513,7 @@ STATIC_INLINE int put_fp_value (struct regstruct *regs, fptype value, uae_u32 op #if DEBUG_FPP if (!isinrom ()) - write_log ("PUTFP: %f %04.4X %04.4X\n", value, opcode, extra); + write_log ("PUTFP: %f %04X %04X\n", value, opcode, extra); #endif if (!(extra & 0x4000)) { regs->fp[(extra >> 10) & 7] = value; @@ -1156,7 +1156,7 @@ void fpuop_arithmetic (uae_u32 opcode, struct regstruct *regs, uae_u16 extra) } if (extra & 0x1000) { regs->fpcr = get_long (ad); - native_set_fpucw(regs->fpcr); + native_set_fpucw (regs->fpcr); ad += 4; } if (extra & 0x0800) { @@ -1635,6 +1635,7 @@ uae_u8 *restore_fpu (uae_u8 *src) regs.fp[i] = to_exten (w1, w2, w3); } regs.fpcr = restore_u32 (); + native_set_fpucw (regs.fpcr); regs.fpsr = restore_u32 (); regs.fpiar = restore_u32 (); if (flags & 0x80000000) { diff --git a/gencpu.c b/gencpu.c index f351d413..81414ab0 100755 --- a/gencpu.c +++ b/gencpu.c @@ -1718,7 +1718,7 @@ static void gen_opcode (unsigned long int opcode) pop_braces (old_brace_level); printf ("\tregs->sr = newsr; MakeFromSR (regs);\n"); printf ("\tif (newpc & 1)\n"); - printf ("\t\texception3 (0x%04.4X, m68k_getpc (regs), newpc);\n", opcode); + printf ("\t\texception3 (0x%04X, m68k_getpc (regs), newpc);\n", opcode); printf ("\telse\n"); printf ("\t\tm68k_setpc (regs, newpc);\n"); need_endlabel = 1; @@ -1732,7 +1732,7 @@ static void gen_opcode (unsigned long int opcode) genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0); printf ("\tm68k_areg (regs, 7) += offs;\n"); printf ("\tif (pc & 1)\n"); - printf ("\t\texception3 (0x%04.4X, m68k_getpc (regs), pc);\n", opcode); + printf ("\t\texception3 (0x%04X, m68k_getpc (regs), pc);\n", opcode); printf ("\telse\n"); printf ("\t\tm68k_setpc (regs, pc);\n"); /* PC is set and prefetch filled. */ diff --git a/hardfile.c b/hardfile.c index af10548f..5161e4c1 100755 --- a/hardfile.c +++ b/hardfile.c @@ -126,7 +126,7 @@ static void getchs2 (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head, static void getchs (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head, int *tracksec) { getchs2 (hfd, cyl, cylsec, head, tracksec); - hf_log ("CHS: %08.8X-%08.8X %d %d %d %d %d\n", + hf_log ("CHS: %08X-%08X %d %d %d %d %d\n", (uae_u32)(hfd->size >> 32),(uae_u32)hfd->size, *cyl, *cylsec, *head, *tracksec); } @@ -329,7 +329,7 @@ int hdf_hd_open (struct hd_hardfiledata *hfd, const char *path, int blocksize, i static uae_u64 cmd_readx (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len) { gui_hd_led (hfd->unitnum, 1); - hf_log3 ("cmd_read: %p %04.4x-%08.8x (%d) %08.8x (%d)\n", + hf_log3 ("cmd_read: %p %04x-%08x (%d) %08x (%d)\n", dataptr, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->blocksize), (uae_u32)len, (uae_u32)(len / hfd->blocksize)); return hdf_read (hfd, dataptr, offset, len); } @@ -343,7 +343,7 @@ static uae_u64 cmd_read (struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offs static uae_u64 cmd_writex (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len) { gui_hd_led (hfd->unitnum, 2); - hf_log3 ("cmd_write: %p %04.4x-%08.8x (%d) %08.8x (%d)\n", + hf_log3 ("cmd_write: %p %04x-%08x (%d) %08x (%d)\n", dataptr, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->blocksize), (uae_u32)len, (uae_u32)(len / hfd->blocksize)); return hdf_write (hfd, dataptr, offset, len); } @@ -618,7 +618,7 @@ nodisk: default: err: lr = -1; - write_log ("UAEHF: unsupported scsi command 0x%02.2X\n", cmdbuf[0]); + write_log ("UAEHF: unsupported scsi command 0x%02X\n", cmdbuf[0]); status = 2; /* CHECK CONDITION */ s[0] = 0x70; s[2] = 5; /* ILLEGAL REQUEST */ @@ -658,11 +658,11 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd) status = 0; memset (reply, 0, sizeof reply); reply_len = 0; sense_len = 0; - scsi_log ("hdf scsiemu: cmd=%02.2X,%d flags=%02.2X sense=%p,%d data=%p,%d\n", + scsi_log ("hdf scsiemu: cmd=%02X,%d flags=%02X sense=%p,%d data=%p,%d\n", cmd, scsi_cmd_len, scsi_flags, scsi_sense, scsi_sense_len, scsi_data, scsi_len); for (i = 0; i < scsi_cmd_len; i++) { cmdbuf[i] = get_byte (scsi_cmd + i); - scsi_log ("%02.2X%c", get_byte (scsi_cmd + i), i < scsi_cmd_len - 1 ? '.' : ' '); + scsi_log ("%02X%c", get_byte (scsi_cmd + i), i < scsi_cmd_len - 1 ? '.' : ' '); } scsi_log ("\n"); @@ -675,7 +675,7 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd) i = 0; while (i < reply_len) { if (i < 24) - scsi_log ("%02.2X%c", reply[i], i < reply_len - 1 ? '.' : ' '); + scsi_log ("%02X%c", reply[i], i < reply_len - 1 ? '.' : ' '); put_byte (scsi_data + i, reply[i]); i++; } @@ -794,7 +794,7 @@ static void abort_async (struct hardfileprivdata *hfpd, uaecptr request, int err } i = release_async_request (hfpd, request); if (i >= 0) - hf_log ("asyncronous request=%08.8X aborted, error=%d\n", request, errcode); + hf_log ("asyncronous request=%08X aborted, error=%d\n", request, errcode); } static void *hardfile_thread (void *devs); @@ -878,13 +878,13 @@ static uae_u32 REGPARAM2 hardfile_expunge (TrapContext *context) static void outofbounds (int cmd, uae_u64 offset, uae_u64 len, uae_u64 max) { - write_log ("UAEHF: cmd %d: out of bounds, %08.8X-%08.8X + %08.8X-%08.8X > %08.8X-%08.8X\n", cmd, + write_log ("UAEHF: cmd %d: out of bounds, %08X-%08X + %08X-%08X > %08X-%08X\n", cmd, (uae_u32)(offset >> 32),(uae_u32)offset,(uae_u32)(len >> 32),(uae_u32)len, (uae_u32)(max >> 32),(uae_u32)max); } static void unaligned (int cmd, uae_u64 offset, uae_u64 len, int blocksize) { - write_log ("UAEHF: cmd %d: unaligned access, %08.8X-%08.8X, %08.8X-%08.8X, %08.8X\n", cmd, + write_log ("UAEHF: cmd %d: unaligned access, %08X-%08X, %08X-%08X, %08X\n", cmd, (uae_u32)(offset >> 32),(uae_u32)offset,(uae_u32)(len >> 32),(uae_u32)len, blocksize); } @@ -1101,7 +1101,7 @@ static uae_u32 REGPARAM2 hardfile_abortio (TrapContext *context) return get_byte (request + 31); } put_byte (request + 31, -2); - hf_log2 ("unit=%d, request=%08.8X\n", unit, request); + hf_log2 ("unit=%d, request=%08X\n", unit, request); abort_async (hfpd, request, -2, 0); return 0; } @@ -1181,7 +1181,7 @@ static void *hardfile_thread (void *devs) release_async_request (hfpd, request); uae_ReplyMsg (request); } else { - hf_log2 ("async request %08.8X\n", request); + hf_log2 ("async request %08X\n", request); } uae_sem_post (&change_sem); } diff --git a/include/gfxfilter.h b/include/gfxfilter.h index ce1bfd79..5dd78237 100755 --- a/include/gfxfilter.h +++ b/include/gfxfilter.h @@ -23,9 +23,12 @@ typedef int bool; extern void S2X_configure (int rb, int gb, int bb, int rs, int gs, int bs); extern int Init_2xSaI(int rb, int gb, int bb, int rs, int gs, int bs); -extern void Super2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); -extern void SuperEagle(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); -extern void _2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); +extern void Super2xSaI_16(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); +extern void Super2xSaI_32(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); +extern void SuperEagle_16(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); +extern void SuperEagle_32(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); +extern void _2xSaI_16(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); +extern void _2xSaI_32(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); extern void AdMame2x(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ u8 *dstPtr, u32 dstPitch, int width, int height); extern void AdMame2x32(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ diff --git a/include/options.h b/include/options.h index 50c22010..4cbd08b1 100755 --- a/include/options.h +++ b/include/options.h @@ -115,7 +115,6 @@ struct uae_prefs { int sound_stereo; int sound_stereo_separation; int sound_mixed_stereo_delay; - int sound_bits; int sound_freq; int sound_maxbsiz; int sound_latency; diff --git a/inputdevice.c b/inputdevice.c index 7efcb55c..c18aecf4 100755 --- a/inputdevice.c +++ b/inputdevice.c @@ -224,7 +224,7 @@ void inprec_rstr(const char *s) } void inprec_rstart(uae_u8 type) { - write_log ("INPREC: %08.8X: %d\n", hsync_counter, type); + write_log ("INPREC: %08X: %d\n", hsync_counter, type); inprec_ru32(hsync_counter); inprec_ru8(0); inprec_plast = inprec_p; @@ -259,14 +259,14 @@ int inprec_pstart(uae_u8 type) for (;;) { uae_u32 hc2 = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; if (p > lastp) { - write_log ("INPREC: Next %08.8x (%08.8x=%d): %d (%d)\n", hc2, hc, hc2 - hc, p[5 + 1], p[5]); + write_log ("INPREC: Next %08x (%08x=%d): %d (%d)\n", hc2, hc, hc2 - hc, p[5 + 1], p[5]); lastp = p; } hc2_orig = hc2; hc2 /= inprec_div; hc2 *= inprec_div; if (hc > hc2) { - write_log ("INPREC: %08.8x > %08.8x: %d (%d) missed!\n", hc, hc2, p[5 + 1], p[5]); + write_log ("INPREC: %08x > %08x: %d (%d) missed!\n", hc, hc2, p[5 + 1], p[5]); inprec_close(); return 0; } @@ -275,7 +275,7 @@ int inprec_pstart(uae_u8 type) break; } if (p[5 + 1] == type) { - write_log ("INPREC: %08.8x: %d (%d) (%+d)\n", hc, type, p[5], hc_orig - hc2_orig); + write_log ("INPREC: %08x: %d (%d) (%+d)\n", hc, type, p[5], hc_orig - hc2_orig); inprec_plast = p; inprec_plastptr = p + 5 + 2; return 1; @@ -1155,7 +1155,7 @@ int getjoystate (int joy) } #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("JOY%dDAT %04.4X %s\n", joy, v, debuginfo (0)); + write_log ("JOY%dDAT %04X %s\n", joy, v, debuginfo (0)); #endif if (input_recording > 0 && oldjoy[joy] != v) { oldjoy[joy] = v; @@ -1197,7 +1197,7 @@ void JOYTEST (uae_u16 v) mouse_frame_x[1] = mouse_x[1]; mouse_frame_y[1] = mouse_y[1]; if (inputdevice_logging & 2) - write_log ("JOYTEST: %04.4X PC=%x\n", v , M68K_GETPC); + write_log ("JOYTEST: %04X PC=%x\n", v , M68K_GETPC); } static uae_u8 parconvert (uae_u8 v, int jd, int shift) @@ -1259,7 +1259,7 @@ uae_u8 handle_joystick_buttons (uae_u8 dra) } } if (inputdevice_logging & 4) - write_log ("BFE001: %02.2X:%02.2X %x\n", dra, but, M68K_GETPC); + write_log ("BFE001: %02X:%02X %x\n", dra, but, M68K_GETPC); return but; } @@ -1417,10 +1417,10 @@ void POTGO (uae_u16 v) int i; if (inputdevice_logging & 16) - write_log ("POTGO_W: %04.4X %p\n", v, M68K_GETPC); + write_log ("POTGO_W: %04X %p\n", v, M68K_GETPC); #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("POTGO %04.4X %s\n", v, debuginfo(0)); + write_log ("POTGO %04X %s\n", v, debuginfo(0)); #endif potgo_value = potgo_value & 0x5500; /* keep state of data bits */ potgo_value |= v & 0xaa00; /* get new direction bits */ @@ -1451,10 +1451,10 @@ uae_u16 POTGOR (void) uae_u16 v = handle_joystick_potgor (potgo_value) & 0x5500; #ifdef DONGLE_DEBUG if (notinrom ()) - write_log ("POTGOR %04.4X %s\n", v, debuginfo(0)); + write_log ("POTGOR %04X %s\n", v, debuginfo(0)); #endif if (inputdevice_logging & 16) - write_log ("POTGO_R: %04.4X %d %p\n", v, cd32_shifter[1], M68K_GETPC); + write_log ("POTGO_R: %04X %d %p\n", v, cd32_shifter[1], M68K_GETPC); return v; } @@ -1539,7 +1539,7 @@ void inputdevice_do_keyboard (int code, int state) } record_key ((uae_u8)((key << 1) | (key >> 7))); if (inputdevice_logging & 1) - write_log ("Amiga key %02.2X %d\n", key & 0x7f, key >> 7); + write_log ("Amiga key %02X %d\n", key & 0x7f, key >> 7); return; } inputdevice_add_inputcode (code, state); @@ -2844,7 +2844,7 @@ static void get_ename (const struct inputevent *ie, char *out) if (!out) return; if (ie->allow_mask == AM_K) - sprintf (out, "%s (0x%02.2X)", ie->name, ie->data); + sprintf (out, "%s (0x%02X)", ie->name, ie->data); else strcpy (out, ie->name); } diff --git a/keybuf.c b/keybuf.c index 12e6ed07..223fa9e6 100755 --- a/keybuf.c +++ b/keybuf.c @@ -73,7 +73,7 @@ void record_key_direct (int kc) int k = kc >> 1; int b = !(kc & 1); - //write_log ("got kc %02.2X\n", ((kc << 7) | (kc >> 1)) & 0xff); + //write_log ("got kc %02X\n", ((kc << 7) | (kc >> 1)) & 0xff); if (kpb_next == 256) kpb_next = 0; if (kpb_next == kpb_last) { diff --git a/memory.c b/memory.c index 8efd88a4..8f27c0b2 100755 --- a/memory.c +++ b/memory.c @@ -2074,7 +2074,7 @@ uae_u8 *REGPARAM2 default_xlate (uaecptr a) int i, j; uaecptr a2 = a - 32; uaecptr a3 = m68k_getpc (®s) - 32; - write_log ("Your Amiga program just did something terribly stupid %08X PC=%08.8X\n", a, M68K_GETPC); + write_log ("Your Amiga program just did something terribly stupid %08X PC=%08X\n", a, M68K_GETPC); m68k_dumpstate (0, 0); for (i = 0; i < 10; i++) { write_log ("%08X ", i >= 5 ? a3 : a2); @@ -2736,7 +2736,7 @@ static int patch_shapeshifter (uae_u8 *kickmemory) !memcmp (kickmemory + i, kickshift2, sizeof (kickshift2)) || !memcmp (kickmemory + i, kickshift3, sizeof (kickshift3))) { kickmemory[i + 2] = 0x30; - write_log ("Kickstart KickShifted @%04.4X\n", i); + write_log ("Kickstart KickShifted @%04X\n", i); patched++; } } @@ -2764,7 +2764,7 @@ static int patch_residents (uae_u8 *kickmemory, int size) j = 0; while (residents[j]) { if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) { - write_log ("KSPatcher: '%s' at %08.8X disabled\n", residents[j], i + base); + write_log ("KSPatcher: '%s' at %08X disabled\n", residents[j], i + base); kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */ patched++; break; @@ -3565,7 +3565,7 @@ void memory_reset (void) #ifdef ARCADIA if (!arcadia_bios) { #endif - action_replay_memory_reset(); + action_replay_memory_reset (); #ifdef ARCADIA } #endif diff --git a/ncr_scsi.c b/ncr_scsi.c index 82e09d39..d570bf4e 100755 --- a/ncr_scsi.c +++ b/ncr_scsi.c @@ -259,7 +259,7 @@ static void INT2(void) static uae_u8 read_rombyte (uaecptr addr) { uae_u8 v = rom[addr]; - //write_log ("%08.8X = %02.2X PC=%08X\n", addr, v, M68K_GETPC); + //write_log ("%08X = %02X PC=%08X\n", addr, v, M68K_GETPC); return v; } @@ -278,7 +278,7 @@ void ncr_bput2 (uaecptr addr, uae_u32 val) INT2(); break; } - write_log ("%s write %04.4X (%s) = %02.2X PC=%08.8X\n", NCRNAME, addr, regname(addr), v & 0xff, M68K_GETPC); + write_log ("%s write %04X (%s) = %02X PC=%08X\n", NCRNAME, addr, regname(addr), v & 0xff, M68K_GETPC); ncrregs[addr] = val; } @@ -305,7 +305,7 @@ uae_u32 ncr_bget2 (uaecptr addr) v &= 0x0f; // revision 0 break; } - write_log ("%s read %04.4X (%s) = %02.2X PC=%08.8X\n", NCRNAME, addr, regname(addr), v, M68K_GETPC); + write_log ("%s read %04X (%s) = %02X PC=%08X\n", NCRNAME, addr, regname(addr), v, M68K_GETPC); if (v2 != v) ncrregs[addr] = v2; return v; @@ -324,7 +324,7 @@ static uae_u32 REGPARAM2 ncr_lget (uaecptr addr) (ncr_bget2 (addr + 2) << 8) | (ncr_bget2 (addr + 3)); #if NCR_DEBUG > 0 if (addr < ROM_VECTOR) - write_log ("ncr_lget %08.8X=%08.8X PC=%08.8X\n", addr, v, M68K_GETPC); + write_log ("ncr_lget %08X=%08X PC=%08X\n", addr, v, M68K_GETPC); #endif return v; } @@ -339,7 +339,7 @@ static uae_u32 REGPARAM2 ncr_wget (uaecptr addr) v = (ncr_bget2 (addr) << 8) | ncr_bget2 (addr + 1); #if NCR_DEBUG > 0 if (addr < ROM_VECTOR) - write_log ("ncr_wget %08.8X=%04.4X PC=%08.8X\n", addr, v, M68K_GETPC); + write_log ("ncr_wget %08X=%04X PC=%08X\n", addr, v, M68K_GETPC); #endif return v; } @@ -368,7 +368,7 @@ static void REGPARAM2 ncr_lput (uaecptr addr, uae_u32 l) addr &= board_mask; #if NCR_DEBUG > 0 if (addr < ROM_VECTOR) - write_log ("ncr_lput %08.8X=%08.8X PC=%08.8X\n", addr, l, M68K_GETPC); + write_log ("ncr_lput %08X=%08X PC=%08X\n", addr, l, M68K_GETPC); #endif ncr_bput2 (addr, l >> 24); ncr_bput2 (addr + 1, l >> 16); @@ -385,7 +385,7 @@ static void REGPARAM2 ncr_wput (uaecptr addr, uae_u32 w) addr &= board_mask; #if NCR_DEBUG > 0 if (addr < ROM_VECTOR) - write_log ("ncr_wput %04.4X=%04.4X PC=%08.8X\n", addr, w & 65535, M68K_GETPC); + write_log ("ncr_wput %04X=%04X PC=%08X\n", addr, w & 65535, M68K_GETPC); #endif if (addr == 0x44 && !configured) { uae_u32 value = (p96ram_start + ((currprefs.gfxmem_size + 0xffffff) & ~0xffffff)) >> 16; diff --git a/newcpu.c b/newcpu.c index c85f821f..48a6ab21 100755 --- a/newcpu.c +++ b/newcpu.c @@ -879,7 +879,7 @@ static void exception_debug (int nr) #ifdef DEBUGGER if (!exception_debugging) return; - console_out_f ("Exception %d, PC=%08.8X\n", nr, m68k_getpc (®s)); + console_out_f ("Exception %d, PC=%08X\n", nr, m68k_getpc (®s)); #endif } @@ -1118,7 +1118,7 @@ void REGPARAM2 Exception (int nr, struct regstruct *regs, uaecptr oldpc) { #if 0 if (1 || nr < 24) - write_log ("exception %d %08.8X %08.8X (%04.4X %04.4X)\n", + write_log ("exception %d %08X %08X (%04X %04X)\n", nr, oldpc, m68k_getpc (regs), intena, intreq); #endif #ifdef CPUEMU_12 @@ -1135,7 +1135,7 @@ STATIC_INLINE void do_interrupt (int nr, struct regstruct *regs) #if 0 if (nr == 2) write_log ("."); - //write_log ("irq %d at %x (%04.4X) ", nr, m68k_getpc (regs), intena & intreq); + //write_log ("irq %d at %x (%04X) ", nr, m68k_getpc (regs), intena & intreq); #endif regs->stopped = 0; unset_special (regs, SPCFLAG_STOP); @@ -1198,7 +1198,7 @@ int movec_illg (int regno) int m68k_move2c (int regno, uae_u32 *regp) { #if MOVEC_DEBUG > 0 - write_log ("move2c %04.4X <- %08.8X PC=%x\n", regno, *regp, M68K_GETPC); + write_log ("move2c %04X <- %08X PC=%x\n", regno, *regp, M68K_GETPC); #endif if (movec_illg (regno)) { op_illg (0x4E7B, ®s); @@ -1268,7 +1268,7 @@ int m68k_move2c (int regno, uae_u32 *regp) int m68k_movec2 (int regno, uae_u32 *regp) { #if MOVEC_DEBUG > 0 - write_log ("movec2 %04.4X PC=%x\n", regno, M68K_GETPC); + write_log ("movec2 %04X PC=%x\n", regno, M68K_GETPC); #endif if (movec_illg (regno)) { op_illg (0x4E7A, ®s); @@ -1315,7 +1315,7 @@ int m68k_movec2 (int regno, uae_u32 *regp) } } #if MOVEC_DEBUG > 0 - write_log ("-> %08.8X\n", *regp); + write_log ("-> %08X\n", *regp); #endif return 1; } @@ -2129,7 +2129,7 @@ static void out_cd32io (uae_u32 pc) write_log ("old request still not returned!\n"); cd32request = request; cd32nextpc = get_long (m68k_areg (®s, 7)); - write_log ("%s A1=%08.8X\n", out, request); + write_log ("%s A1=%08X\n", out, request); if (ioreq) { static int cnt = 0; int cmd = get_word (request + 28); @@ -2140,7 +2140,7 @@ static void out_cd32io (uae_u32 pc) activate_debugger (); } #endif - write_log ("CMD=%d DATA=%08.8X LEN=%d %OFF=%d PC=%x\n", + write_log ("CMD=%d DATA=%08X LEN=%d %OFF=%d PC=%x\n", cmd, get_long (request + 40), get_long (request + 36), get_long (request + 44), M68K_GETPC); } @@ -2182,7 +2182,7 @@ static void m68k_run_1 (void) if (pc != pcs[0] && (pc < 0xd00000 || pc > 0x1000000)) { memmove (pcs + 1, pcs, 998 * 4); pcs[0] = pc; - //write_log ("%08.8X-%04.4X ", pc, opcode); + //write_log ("%08X-%04X ", pc, opcode); } #endif do_cycles (cpu_cycles); @@ -2920,14 +2920,14 @@ void m68k_dumpstate (void *f, uaecptr *nextpc) if (regs.s && regs.m) regs.msp = m68k_areg (®s, 7); if (regs.s && regs.m == 0) regs.isp = m68k_areg (®s, 7); j = 2; - f_out (f, "USP %08.8X ISP %08.8X ", regs.usp, regs.isp); + f_out (f, "USP %08X ISP %08X ", regs.usp, regs.isp); for (i = 0; m2cregs[i].regno>= 0; i++) { if (!movec_illg (m2cregs[i].regno)) { if (!strcmp (m2cregs[i].regname, "USP") || !strcmp (m2cregs[i].regname, "ISP")) continue; if (j > 0 && (j % 4) == 0) f_out (f, "\n"); - f_out (f, "%-4s %08.8X ", m2cregs[i].regname, val_move2c (m2cregs[i].regno)); + f_out (f, "%-4s %08X ", m2cregs[i].regname, val_move2c (m2cregs[i].regno)); j++; } } @@ -3045,7 +3045,7 @@ uae_u8 *restore_cpu (uae_u8 *src) if (khz > 0 && khz < 800000) currprefs.m68k_speed = changed_prefs.m68k_speed = 0; } - write_log ("CPU %d%s%03d, PC=%08.8X\n", + write_log ("CPU %d%s%03d, PC=%08X\n", model / 1000, flags & 1 ? "EC" : "", model % 1000, regs.pc); return src; diff --git a/od-win32/ahidsound.c b/od-win32/ahidsound.c index e6917f47..03998f70 100755 --- a/od-win32/ahidsound.c +++ b/od-win32/ahidsound.c @@ -262,8 +262,6 @@ void ahi_finish_sound_buffer (void) ahi_updatesound(2); } -extern GUID sound_device_guid[]; - static WAVEFORMATEX wavfmt; static int ahi_init_record_win32 (void) @@ -320,7 +318,7 @@ static int ahi_init_sound_win32 (void) if (lpDS2) return 0; - enumerate_sound_devices (0); + enumerate_sound_devices (); wavfmt.wFormatTag = WAVE_FORMAT_PCM; wavfmt.nChannels = sound_channels_ahi; wavfmt.nSamplesPerSec = sound_freq_ahi; @@ -339,7 +337,7 @@ static int ahi_init_sound_win32 (void) ahisndbuffer = malloc (ahisndbufsize + 32); if (!ahisndbuffer) return 0; - hr = DirectSoundCreate (&sound_device_guid[currprefs.win32_soundcard], &lpDS2, NULL); + hr = DirectSoundCreate (&sound_devices[currprefs.win32_soundcard].guid, &lpDS2, NULL); if (FAILED (hr)) { write_log ("AHI: DirectSoundCreate() failure: %s\n", DXError (hr)); return 0; @@ -450,6 +448,7 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) // d0=200 ahitweak d1=offset for dsound position pointer int opcode = m68k_dreg (&context->regs, 0); + switch (opcode) { uae_u32 src, num_vars; @@ -638,30 +637,36 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) dllname = (char *)get_real_address (dllptr); dpath[0] = 0; GetFullPathName (dllname, sizeof dpath, dpath, &filepart); - if (strlen (dpath) > strlen (start_path_data) && !strnicmp (dpath, start_path_data, strlen (dpath))) { + if (strlen (dpath) > strlen (start_path_data) && !strnicmp (dpath, start_path_data, strlen (start_path_data))) { /* path really is relative to winuae directory */ ok = 1; - strcpy (newdllpath, dpath + strlen (start_path_data) + 1); + strcpy (newdllpath, dpath + strlen (start_path_data)); if (!strnicmp (newdllpath, dlldir, strlen (dlldir))) /* remove "winuae_dll" */ strcpy (newdllpath, dpath + strlen (start_path_data) + 1 + strlen (dlldir)); sprintf (dpath, "%s%s%s", start_path_data, WIN32_PLUGINDIR, newdllpath); h = LoadLibrary (dpath); - write_log ("native open: '%s' = %p\n", dpath, h); + if (h == NULL) + write_log ("native open: '%s' = %d\n", dpath, GetLastError ()); if (h == NULL) { sprintf (dpath, "%s%s\\%s", start_path_data, dlldir, newdllpath); h = LoadLibrary (dllname); - write_log ("fallback native open: '%s' = %p\n", dpath, h); + if (h == NULL) + write_log ("fallback native open: '%s' = %d\n", dpath, GetLastError ()); } + } else { + write_log ("native open outside of installation dir '%s'!\n", dpath); } +#if 0 if (h == NULL) { h = LoadLibrary (filepart); - write_log ("native file open: '%s' = %p\n", dllname, h); + write_log ("native file open: '%s' = %p\n", filepart, h); if (h == NULL) { sprintf (dpath, "%s%s%s", start_path_data, WIN32_PLUGINDIR, filepart); h = LoadLibrary (dpath); write_log ("native path open: '%s' = %p\n", dpath, h); } } +#endif syncdivisor = (3580000.0 * CYCLE_UNIT) / (double)syncbase; return (uae_u32)h; } diff --git a/od-win32/ahidsound_new.c b/od-win32/ahidsound_new.c index a32b6a9c..3f156791 100755 --- a/od-win32/ahidsound_new.c +++ b/od-win32/ahidsound_new.c @@ -1,7 +1,7 @@ /* * UAE - The Un*x Amiga Emulator * - * DirectSound AHI wrapper + * DirectSound AHI 7.1 wrapper * * Copyright 2008 Toni Wilen */ @@ -42,11 +42,13 @@ #include #include +#define AHI_STRUCT_VERSION 1 static int ahi_debug = 1; #define UAE_MAXCHANNELS 24 #define UAE_MAXSOUNDS 256 +#define RECORDSAMPLES 2048 #define ub_Flags 34 #define ub_Pad1 (ub_Flags + 1) @@ -56,7 +58,9 @@ static int ahi_debug = 1; #define ub_DOSBase (ub_SegList + 4) #define ub_AHIFunc (ub_DOSBase + 4) -#define pub_Index 0 +#define pub_SizeOf 0 +#define pub_Version (pub_SizeOf + 4) +#define pub_Index (pub_Version + 4) #define pub_Base (pub_Index + 4) #define pub_audioctrl (pub_Base + 4) #define pub_FuncTask (pub_audioctrl + 4) @@ -65,6 +69,18 @@ static int ahi_debug = 1; #define pub_FuncMode (pub_WaitSigBit +4) #define pub_TaskMode (pub_FuncMode + 2) #define pub_ChannelSignal (pub_TaskMode + 2) +#define pub_ChannelSignalAck (pub_ChannelSignal + 4) +#define pub_ahism_Channel (pub_ChannelSignalAck + 4) +#define pub_RecordHookDone (pub_ahism_Channel + 2) +#define pub_RecordSampleType (pub_RecordHookDone + 2) +#define pub_RecordBufferSize (pub_RecordSampleType + 4) +#define pub_RecordBufferSizeBytes (pub_RecordBufferSize + 4) +#define pub_RecordBuffer (pub_RecordBufferSizeBytes + 4) +#define pub_End (pub_RecordBuffer + 4 + 4 + 4 + 4) + +#define FUNCMODE_PLAY 1 +#define FUNCMODE_RECORD 2 +#define FUNCMODE_RECORDALLOC 4 #define ahiac_AudioCtrl 0 #define ahiac_Flags ahiac_AudioCtrl + 4 @@ -349,55 +365,70 @@ struct AHIAudioCtrlDrv struct dssample { int num; - LPDIRECTSOUNDBUFFER8 dsb; - LPDIRECTSOUNDBUFFER8 dsbback; - LPDIRECTSOUNDNOTIFY dsnotify; - HANDLE notifyevent; - int ch, chout; + int ch; int bitspersample; - int bitspersampleout; int bytespersample; - int bytespersampleout; - int frequency; - int volume; - int panning; uae_u32 addr; uae_u32 len; uae_u32 type; - int streaming; - int ready; // 1 = playing, -1 = set + uae_u32 sampletype; + uae_u32 offset; int channel; }; struct dschannel { + int num; int frequency; int volume; int panning; + int backwards; struct dssample *ds; + LPDIRECTSOUNDBUFFER8 dsb; + + uae_u8 *buffer; + int buffercursor; + int hsync; + int channelsignal; + + int playing, dsplaying; + int dscursor; + + int srcoffset; + int prevsrcoffset; + int srcplayoffset; + int srcplaylen; }; struct DSAHI { uae_u32 audioctrl; - uae_u32 audioid; - int mixfreq; + int chout; + int bits24; + int bitspersampleout; + int bytespersampleout; + int channellength; + int mixlength; + int input; + int output; int channels; int sounds; - uae_u32 soundfunc; - uae_u32 playerfunc; int playerfreq; - int minplayerfreq; - int maxplayerfreq; - uae_u32 recordfunc; - uae_u32 userdata; - int anticlicksamples; int enabledisable; struct dssample *sample; struct dschannel *channel; int playing, recording; - int cansurround; evt evttime; - volatile int thread; - HANDLE threadevent; + uae_u32 signalchannelmask; + LPDIRECTSOUND8 DS; + + LPDIRECTSOUNDCAPTURE DSC; + LPDIRECTSOUNDCAPTUREBUFFER dscb; + int dsrecording; + int recordingcursor; + int record_ch; + int record_bytespersample; + int channellength_record; + int mixlength_record; + int record_wait; }; static struct DSAHI dsahi[1]; @@ -407,7 +438,12 @@ static struct DSAHI dsahi[1]; #define GETCHANNEL (dsahip && channel >= 0 && channel < UAE_MAXCHANNELS ? &dsahip->channel[channel] : NULL) static int default_freq = 44100; -static uae_u32 xahi_author, xahi_copyright, xahi_version, xahi_output; +static int cansurround; +static uae_u32 xahi_author, xahi_copyright, xahi_version; +static uae_u32 xahi_output[MAX_SOUND_DEVICES], xahi_output_num; +static uae_u32 xahi_input[MAX_SOUND_DEVICES], xahi_input_num; +static int ahi_paused; +static int ahi_active; #define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */ #define TAG_IGNORE (1L) /* ignore this item, not end of array */ @@ -450,15 +486,19 @@ static int sendsignal (struct DSAHI *dsahip) uae_u32 puaebase = get_long (audioctrl + ahiac_DriverData); uae_u32 task, signalmask; uae_s16 taskmode = get_word (puaebase + pub_TaskMode); + uae_s16 funcmode = get_word (puaebase + pub_FuncMode); task = get_long (puaebase + pub_FuncTask); signalmask = get_long (puaebase + pub_WaitMask); - if (!dsahip->playing) + if ((!dsahip->playing && !dsahip->recording) || ahi_paused) return 0; if (taskmode <= 0) return 0; - if (dsahip->enabledisable) - return 0; + if (dsahip->enabledisable) { + // allocate Amiga-side recordingbuffer + funcmode &= FUNCMODE_RECORDALLOC; + put_word (puaebase + pub_FuncMode, funcmode); + } uae_Signal (task, signalmask); return 1; } @@ -468,21 +508,31 @@ static void setchannelevent (struct DSAHI *dsahip, struct dschannel *dc) uae_u32 audioctrl = dsahip->audioctrl; uae_u32 puaebase = get_long (audioctrl + ahiac_DriverData); int ch = dc - &dsahip->channel[0]; + uae_u32 mask; - //write_log ("AHI: channel signal %d\n", ch); - put_long (puaebase + pub_ChannelSignal, get_long (puaebase + pub_ChannelSignal) | (1 << ch)); + if (!dsahip->playing || ahi_paused || dc->dsb == NULL) + return; + mask = get_long (puaebase + pub_ChannelSignal); + if (mask & (1 << ch)) + return; + dc->channelsignal = 1; + put_long (puaebase + pub_ChannelSignal, mask | (1 << ch)); sendsignal (dsahip); } static void evtfunc (uae_u32 v) { - struct DSAHI *dsahip = &dsahi[v]; - uae_u32 audioctrl = dsahip->audioctrl; - uae_u32 puaebase = get_long (audioctrl + ahiac_DriverData); - - put_word (puaebase + pub_FuncMode, get_word (puaebase + pub_FuncMode) | 1); - if (sendsignal (dsahip)) - event2_newevent2 (dsahip->evttime, v, evtfunc); + if (ahi_active) { + struct DSAHI *dsahip = &dsahi[v]; + uae_u32 audioctrl = dsahip->audioctrl; + uae_u32 puaebase = get_long (audioctrl + ahiac_DriverData); + + put_word (puaebase + pub_FuncMode, get_word (puaebase + pub_FuncMode) | FUNCMODE_PLAY); + if (sendsignal (dsahip)) + event2_newevent2 (dsahip->evttime, v, evtfunc); + else + dsahip->evttime = 0; + } } static void setevent (struct DSAHI *dsahip) @@ -494,129 +544,160 @@ static void setevent (struct DSAHI *dsahip) evt t; f = ((double)(freq >> 16)) + ((double)(freq & 0xffff)) / 65536.0; - write_log ("AHI: playerfunc freq = %.2fHz\n", f); + if (f < 1) + return; cycles = maxhpos * maxvpos * vblank_hz; t = (evt)(cycles / f); + if (dsahip->evttime == t) + return; + write_log ("AHI: playerfunc freq = %.2fHz\n", f); dsahip->evttime = t; + if (t < 10) + return; event2_newevent2 (t, dsahip - &dsahi[0], evtfunc); } -static LPDIRECTSOUND8 lpDS; -extern GUID sound_device_guid[]; const static GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010, {0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}; #define KSAUDIO_SPEAKER_QUAD_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) - -static void ds_freebuffer (struct DSAHI *ahidsp, struct dssample *ds) +static void ds_freechannel (struct DSAHI *ahidsp, struct dschannel *dc) { - if (!ds) + if (!dc) return; - if (ds->dsb) - IDirectSoundBuffer8_Release (ds->dsb); - if (ds->dsbback) - IDirectSoundBuffer8_Release (ds->dsbback); - if (ds->dsnotify) - IDirectSoundNotify_Release (ds->dsnotify); - if (ds->notifyevent) - CloseHandle (ds->notifyevent); - memset (ds, 0, sizeof (struct dssample)); - ds->channel = -1; + if (dc->dsb) + IDirectSoundBuffer8_Release (dc->dsb); + xfree (dc->buffer); + memset (dc, 0, sizeof (struct dschannel)); + dc->ds = NULL; } static void ds_free (struct DSAHI *dsahip) { int i; - for (i = 0; i < dsahip->sounds; i++) { - struct dssample *ds = &dsahip->sample[i]; - ds_freebuffer (dsahip, ds); - } - if (lpDS) - IDirectSound_Release (lpDS); - lpDS = NULL; - if (dsahip->thread) { - dsahip->thread = -1; - SetEvent (dsahip->threadevent); - while (dsahip->thread) - Sleep (2); + for (i = 0; i < dsahip->channels; i++) { + struct dschannel *dc = &dsahip->channel[i]; + ds_freechannel (dsahip, dc); } + if (dsahip->DS) + IDirectSound_Release (dsahip->DS); + dsahip->DS = NULL; + if (ahi_debug && ahi_active) + write_log ("AHI: DSOUND freed\n"); + ahi_active = 0; +} + +DWORD fillsupportedmodes (LPDIRECTSOUND8 lpDS, int freq, struct dsaudiomodes *dsam); +static struct dsaudiomodes supportedmodes[16]; + +static void ds_free_record (struct DSAHI *dsahip) +{ + if (dsahip->dscb) + IDirectSoundCaptureBuffer_Release (dsahip->dscb); + if (dsahip->DSC) + IDirectSoundCapture_Release (dsahip->DSC); + dsahip->dscb = NULL; + dsahip->DSC = NULL; } -static unsigned __stdcall waitthread (void *f) +static int ds_init_record (struct DSAHI *dsahip) { - struct DSAHI *dsahip = f; - - dsahip->thread = 1; - while (dsahip->thread > 0) { - HANDLE handles[UAE_MAXCHANNELS + 1]; - int channelindex[UAE_MAXCHANNELS + 1]; - DWORD ob; - int maxnum = UAE_MAXCHANNELS + 1; - int num = 0; - int i; - - handles[num++] = dsahip->threadevent; - if (dsahip->playing) { - for (i = 0; i < UAE_MAXSOUNDS && num < maxnum; i++) { - struct dssample *ds = &dsahip->sample[i]; - if (ds->channel >= 0 && ds->notifyevent) { - handles[num] = ds->notifyevent; - channelindex[num] = ds->channel; - num++; - } - } - } - //write_log ("AHI: WFMO %d\n", num); - ob = WaitForMultipleObjects (num, handles, FALSE, INFINITE); - if (ob == WAIT_OBJECT_0) - continue; - if (ob >= WAIT_OBJECT_0 + 1 && ob < WAIT_OBJECT_0 + num) { - int ch; - ob -= WAIT_OBJECT_0; - ch = channelindex[ob]; - setchannelevent (dsahip, &dsahip->channel[ch]); - } + HRESULT hr; + WAVEFORMATEXTENSIBLE wavfmt; + DSCBUFFERDESC dbd; + uae_u32 pbase = get_long (dsahip->audioctrl + ahiac_DriverData); + int freq = get_long (dsahip->audioctrl + ahiac_MixFreq); + + if (dsahip->DSC) + return 1; + if (!freq) + return 0; + dsahip->mixlength_record = RECORDSAMPLES; // in sample units, not bytes + dsahip->record_ch = 2; + dsahip->record_bytespersample = 2; + dsahip->channellength_record = freq * dsahip->record_bytespersample * dsahip->record_ch * 10; + put_long (pbase + pub_RecordBufferSize, dsahip->mixlength_record); + put_long (pbase + pub_RecordBufferSizeBytes, dsahip->mixlength_record * dsahip->record_ch * dsahip->record_bytespersample); + put_long (pbase + pub_RecordSampleType, AHIST_S16S); + put_word (pbase + pub_RecordHookDone, 0); + + hr = DirectSoundCaptureCreate (&record_devices[dsahip->input].guid, &dsahip->DSC, NULL); + if (FAILED (hr)) { + write_log ("AHI: DirectSoundCaptureCreate() failure %dHz: %s\n", freq, DXError (hr)); + goto end; } - dsahip->thread = 0; + memset (&dbd, 0, sizeof dbd); + dbd.dwSize = sizeof dbd; + dbd.dwBufferBytes = dsahip->channellength_record; + dbd.lpwfxFormat = &wavfmt.Format; + dbd.dwFlags = 0 ; + memset (&wavfmt, 0, sizeof wavfmt); + wavfmt.Format.nChannels = dsahip->record_ch; + wavfmt.Format.nSamplesPerSec = freq; + wavfmt.Format.wBitsPerSample = dsahip->record_bytespersample * 8; + wavfmt.Format.wFormatTag = WAVE_FORMAT_PCM; + wavfmt.Format.nBlockAlign = wavfmt.Format.wBitsPerSample / 8 * wavfmt.Format.nChannels; + wavfmt.Format.nAvgBytesPerSec = wavfmt.Format.nBlockAlign * wavfmt.Format.nSamplesPerSec; + hr = IDirectSoundCapture_CreateCaptureBuffer (dsahip->DSC, &dbd, &dsahip->dscb, NULL); + if (FAILED (hr)) { + write_log ("AHI: CreateCaptureSoundBuffer() failure: %s\n", DXError(hr)); + goto end; + } + if (ahi_debug) + write_log ("AHI: DSOUND Recording initialized. %dHz, %s\n", freq, record_devices[dsahip->input].name); + + put_word (pbase + pub_FuncMode, get_word (pbase + pub_FuncMode) | FUNCMODE_RECORDALLOC); + sendsignal (dsahip); + return 1; +end: + ds_free_record (dsahip); return 0; } -DWORD fillsupportedmodes (LPDIRECTSOUND8 lpDS, int freq, struct dsaudiomodes *dsam); -static struct dsaudiomodes supportedmodes[16]; - static int ds_init (struct DSAHI *dsahip) { - unsigned int ta; - int freq = 48000; + int freq = 44100; DSCAPS DSCaps; HRESULT hr; DWORD speakerconfig; - hr = DirectSoundCreate8 (&sound_device_guid[currprefs.win32_soundcard], &lpDS, NULL); + hr = DirectSoundCreate8 (&sound_devices[dsahip->output].guid, &dsahip->DS, NULL); if (FAILED (hr)) { write_log ("AHI: DirectSoundCreate8() failure: %s\n", DXError (hr)); return 0; } - hr = IDirectSound_SetCooperativeLevel (lpDS, hMainWnd, DSSCL_PRIORITY); + hr = IDirectSound_SetCooperativeLevel (dsahip->DS, hMainWnd, DSSCL_PRIORITY); if (FAILED (hr)) { write_log ("AHI: Can't set cooperativelevel: %s\n", DXError (hr)); goto error; } - fillsupportedmodes (lpDS, default_freq, supportedmodes); - if (SUCCEEDED (IDirectSound8_GetSpeakerConfig (lpDS, &speakerconfig))) { - if (speakerconfig > DSSPEAKER_STEREO) - dsahip->cansurround = 1; + fillsupportedmodes (dsahip->DS, default_freq, supportedmodes); + dsahip->chout = 2; + if (SUCCEEDED (IDirectSound8_GetSpeakerConfig (dsahip->DS, &speakerconfig))) { + if (speakerconfig >= DSSPEAKER_5POINT1) { + cansurround = 1; + dsahip->chout = 6; + if (speakerconfig >= DSSPEAKER_7POINT1) + dsahip->chout = 8; + } } + dsahip->bitspersampleout = dsahip->bits24 ? 24 : 16; + dsahip->bytespersampleout = dsahip->bitspersampleout / 8; + dsahip->channellength = 65536 * dsahip->chout * dsahip->bytespersampleout; + dsahip->mixlength = 48000 * dsahip->chout * dsahip->bytespersampleout / 20; + if (ahi_debug) + write_log("AHI: CH=%d BLEN=%d MLEN=%d\n", dsahip->chout, dsahip->channellength, dsahip->mixlength); + memset (&DSCaps, 0, sizeof (DSCaps)); DSCaps.dwSize = sizeof (DSCaps); - hr = IDirectSound_GetCaps (lpDS, &DSCaps); + hr = IDirectSound_GetCaps (dsahip->DS, &DSCaps); if (FAILED(hr)) { write_log ("AHI: Error getting DirectSound capabilities: %s\n", DXError (hr)); goto error; @@ -636,12 +717,9 @@ static int ds_init (struct DSAHI *dsahip) write_log ("AHI: maximum supported frequency: %d\n", maxfreq); } } - if (ahi_debug) - write_log ("AHI: DSOUND initialized\n"); - dsahip->thread = -1; - dsahip->threadevent = CreateEvent (NULL, FALSE, FALSE, NULL); - _beginthreadex (NULL, 0, waitthread, dsahip, 0, &ta); + if (ahi_debug) + write_log ("AHI: DSOUND initialized: %s\n", sound_devices[dsahip->output].name); return 1; error: @@ -651,479 +729,655 @@ error: return 0; } -static void ds_play (struct DSAHI *dsahip, struct dssample *ds) +static int ds_reinit (struct DSAHI *dsahip) { - HRESULT hr; - DWORD status; - - if (ahi_debug) - write_log ("AHI: ds_play(%d)\n", ds->num); - hr = IDirectSoundBuffer8_GetStatus (ds->dsb, &status); - if (FAILED (hr)) { - write_log ("AHI: IDirectSoundBuffer8_GetStatus() failed, %s\n", DXError (hr)); - } else { - if (!(status & DSBSTATUS_PLAYING)) - setchannelevent (dsahip, &dsahip->channel[ds->channel]); - } - hr = IDirectSoundBuffer8_Play (ds->dsb, 0, 0, DSBPLAY_LOOPING); - if (FAILED (hr)) - write_log ("AHI: IDirectSoundBuffer8_Play() failed, %s\n", DXError (hr)); - if (ds->dsbback) { - hr = IDirectSoundBuffer8_Play (ds->dsbback, 0, 0, DSBPLAY_LOOPING); - if (FAILED (hr)) - write_log ("AHI: IDirectSoundBuffer8_PlayBack() failed, %s\n", DXError (hr)); - } - ds->ready = -1; + ds_free (dsahip); + return ds_init (dsahip); } -static void ds_setvolume (struct dssample *ds, int volume, int panning) + +static void ds_setvolume (struct DSAHI *dsahip, struct dschannel *dc, int volume, int panning) { HRESULT hr; LONG vol, pan; - // weird AHI features: - // negative pan = output from surround speakers! - // negative volume = invert sample data!! (not yet emulated) - vol = (LONG)((DSBVOLUME_MIN / 2) + (-DSBVOLUME_MIN / 2) * log (1 + (2.718281828 - 1) * (abs (volume) / 65536.0))); - pan = (abs (panning) - 0x8000) * DSBPAN_RIGHT / 32768; - if (panning >= 0 || ds->chout <= 2) { - hr = IDirectSoundBuffer_SetPan (ds->dsb, pan); - if (FAILED (hr)) - write_log ("AHI: SetPan(%d,%d) failed: %s\n", ds->num, pan, DXError (hr)); - hr = IDirectSoundBuffer_SetVolume (ds->dsb, vol); - if (FAILED (hr)) - write_log ("AHI: SetVolume(%d,%d) failed: %s\n", ds->num, vol, DXError (hr)); - if (ds->dsbback) { - hr = IDirectSoundBuffer_SetVolume (ds->dsbback, DSBVOLUME_MIN); + if (dc->dsb) { + if (abs (dc->volume) != abs (volume)) { + vol = (LONG)((DSBVOLUME_MIN / 2) + (-DSBVOLUME_MIN / 2) * log (1 + (2.718281828 - 1) * (abs (volume) / 65536.0))); + hr = IDirectSoundBuffer_SetVolume (dc->dsb, vol); if (FAILED (hr)) - write_log ("AHI: muteback %d: %s\n", ds->num, DXError (hr)); + write_log ("AHI: SetVolume(%d,%d) failed: %s\n", dc->num, vol, DXError (hr)); } - } else { - hr = IDirectSoundBuffer_SetVolume (ds->dsb, DSBVOLUME_MIN); - if (FAILED (hr)) - write_log ("AHI: mutefront %d: %s\n", ds->num, DXError (hr)); - if (ds->dsbback) { - hr = IDirectSoundBuffer_SetPan (ds->dsbback, pan); - if (FAILED (hr)) - write_log ("AHI: SetPanBack(%d,%d) failed: %s\n", ds->num, pan, DXError (hr)); - hr = IDirectSoundBuffer_SetVolume (ds->dsbback, vol); + if (abs (dc->panning) != abs (panning)) { + pan = (abs (panning) - 0x8000) * DSBPAN_RIGHT / 32768; + hr = IDirectSoundBuffer_SetPan (dc->dsb, pan); if (FAILED (hr)) - write_log ("AHI: SetVolumeBack(%d,%d) failed: %s\n", ds->num, vol, DXError (hr)); + write_log ("AHI: SetPan(%d,%d) failed: %s\n", dc->num, pan, DXError (hr)); } } - ds->volume = volume; - ds->panning = panning; + dc->volume = volume; + dc->panning = panning; } -static void ds_setfreq (struct DSAHI *dsahip, struct dssample *ds, int frequency) +static void ds_setfreq (struct DSAHI *dsahip, struct dschannel *dc, int frequency) { HRESULT hr; - if (frequency == 0) { - hr = IDirectSoundBuffer8_Stop (ds->dsb); - if (ds->dsbback) - hr = IDirectSoundBuffer8_Stop (ds->dsbback); - } else { - hr = IDirectSoundBuffer8_SetFrequency (ds->dsb, frequency); + if (dc->frequency != frequency && frequency > 0 && dc->dsb) { + hr = IDirectSoundBuffer8_SetFrequency (dc->dsb, frequency); if (FAILED (hr)) - write_log ("AHI: SetFrequency(%d,%d) failed: %s\n", ds->num, frequency, DXError (hr)); - if (ds->dsbback) { - hr = IDirectSoundBuffer8_SetFrequency (ds->dsbback, frequency); - if (FAILED (hr)) - write_log ("AHI: SetFrequencyBack(%d,%d) failed: %s\n", ds->num, frequency, DXError (hr)); + write_log ("AHI: SetFrequency(%d,%d) failed: %s\n", dc->num, frequency, DXError (hr)); + } + dc->frequency = frequency; +} + +static int ds_allocchannel (struct DSAHI *dsahip, struct dschannel *dc) +{ + HRESULT hr; + DSBUFFERDESC dd; + WAVEFORMATEXTENSIBLE wavfmt; + LPDIRECTSOUNDBUFFER pdsb; + LPDIRECTSOUNDBUFFER8 pdsb8; + int round, vol, freq, pan; + + if (dc->dsb) + return 1; + pdsb = NULL; + for (round = 0; supportedmodes[round].ch; round++) { + DWORD ksmode = 0; + + pdsb = NULL; + if (supportedmodes[round].ch != dsahip->chout) + continue; + + memset (&wavfmt, 0, sizeof (WAVEFORMATEXTENSIBLE)); + wavfmt.Format.nChannels = dsahip->chout; + wavfmt.Format.nSamplesPerSec = default_freq; + wavfmt.Format.wBitsPerSample = dsahip->bitspersampleout; + if (dsahip->chout <= 2) { + wavfmt.Format.wFormatTag = WAVE_FORMAT_PCM; + } else { + DWORD ksmode = 0; + wavfmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + wavfmt.Format.cbSize = sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX); + wavfmt.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + wavfmt.Samples.wValidBitsPerSample = dsahip->bitspersampleout; + wavfmt.dwChannelMask = supportedmodes[round].ksmode; } - if (ds->frequency == 0) - ds_play (dsahip, ds); + wavfmt.Format.nBlockAlign = dsahip->bytespersampleout * wavfmt.Format.nChannels; + wavfmt.Format.nAvgBytesPerSec = wavfmt.Format.nBlockAlign * wavfmt.Format.nSamplesPerSec; + + memset (&dd, 0, sizeof dd); + dd.dwSize = sizeof dd; + dd.dwBufferBytes = dsahip->channellength; + dd.lpwfxFormat = &wavfmt.Format; + dd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY; + dd.dwFlags |= DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; + dd.dwFlags |= dsahip->chout >= 4 ? DSBCAPS_LOCHARDWARE : DSBCAPS_LOCSOFTWARE; + dd.guid3DAlgorithm = GUID_NULL; + + hr = IDirectSound_CreateSoundBuffer (dsahip->DS, &dd, &pdsb, NULL); + if (SUCCEEDED (hr)) + break; + if (dd.dwFlags & DSBCAPS_LOCHARDWARE) { + HRESULT hr2 = hr; + dd.dwFlags &= ~DSBCAPS_LOCHARDWARE; + dd.dwFlags |= DSBCAPS_LOCSOFTWARE; + hr = IDirectSound_CreateSoundBuffer (dsahip->DS, &dd, &pdsb, NULL); + if (SUCCEEDED (hr)) + break; + } + write_log ("AHI: DS sound buffer failed (ch=%d,bps=%d): %s\n", + dsahip->chout, dsahip->bitspersampleout, DXError (hr)); + } + if (pdsb == NULL) + goto error; + + hr = IDirectSound_QueryInterface (pdsb, &IID_IDirectSoundBuffer8, (LPVOID*)&pdsb8); + if (FAILED (hr)) { + write_log ("AHI: Secondary QueryInterface(IID_IDirectSoundBuffer8) failure: %s\n", DXError (hr)); + goto error; } - ds->frequency = frequency; + IDirectSound_Release (pdsb); + dc->dsb = pdsb8; + + freq = dc->frequency; + vol = dc->volume; + pan = dc->panning; + dc->frequency = -1; + dc->volume = -1; + dc->panning = -1; + ds_setvolume (dsahip, dc, vol, pan); + ds_setfreq (dsahip, dc, freq); + dc->buffer = xcalloc (dsahip->mixlength, 1); + dc->buffercursor = 0; + return 1; +error: + ds_freechannel (dsahip, dc); + return 0; } -#define US(x) ((x)) +#define MAKEXCH makexch (dsahip, dc, dst, i, och2, l, r) + +STATIC_INLINE void makexch (struct DSAHI *dsahip, struct dschannel *dc, uae_u8 *dst, int idx, int och2, uae_s16 l, uae_s16 r) +{ + if (dsahip->bits24) { + } else { + uae_s16 *dst2 = (uae_u16*)(&dst[idx * och2]); + l >>= 8; + r >>= 8; + if (dc->volume < 0) { + l = -l; + r = -r; + } + dst2[0] = l; + dst2[1] = r; + if (dsahip->chout <= 2) + return; + dst2[4] = dst2[0]; + dst2[5] = dst2[1]; + if (dc->panning < 0) { + // surround only + dst2[2] = 0; // center + dst2[3] = (dst2[0] + dst2[1]) / 4; // lfe + dst2[0] = dst2[1] = 0; + return; + } + dst2[2] = dst2[3] = (dst2[0] + dst2[1]) / 4; + if (dsahip->chout <= 6) + return; + dst2[6] = dst2[4]; + dst2[7] = dst2[5]; + } +} -static void copysampledata (struct dssample *ds, void *srcp, void *dstp, int dstsize, int offset, int srcsize) +static void copysampledata (struct DSAHI *dsahip, struct dschannel *dc, struct dssample *ds, uae_u8 **psrcp, uae_u8 *srce, uae_u8 *srcp, void *dstp, int dstlen) { - int i, j; - uae_u8 *src = (uae_u8*)srcp; + int i; + uae_u8 *src = *psrcp; uae_u8 *dst = (uae_u8*)dstp; - int och = ds->chout; + int och = dsahip->chout; + int och2 = och * 2; int ich = ds->ch; + int len; - src += offset * ds->ch * ds->bytespersample; - if (dstsize < srcsize) - srcsize = dstsize; - - switch (ds->type) + len = dstlen; + switch (ds->sampletype) { case AHIST_M8S: - for (i = 0; i < srcsize; i++) { - dst[i * 4 + 0] = US (src[i]); - dst[i * 4 + 1] = US (src[i]); - dst[i * 4 + 2] = US (src[i]); - dst[i * 4 + 3] = US (src[i]); + for (i = 0; i < len; i++) { + uae_u32 l = (src[0] << 16) | (src[0] << 8) | src[0] ; + uae_u32 r = (src[0] << 16) | (src[0] << 8) | src[0]; + src += 1; + if (src >= srce) + src = srcp; + MAKEXCH; } break; case AHIST_S8S: - for (i = 0; i < srcsize; i++) { - dst[i * 4 + 0] = src[i * 2 + 0]; - dst[i * 4 + 1] = src[i * 2 + 0]; - dst[i * 4 + 2] = src[i * 2 + 1]; - dst[i * 4 + 3] = src[i * 2 + 1]; + for (i = 0; i < len; i++) { + uae_u32 l = (src[0] << 16) | (src[0] << 8) | src[0] ; + uae_u32 r = (src[1] << 16) | (src[1] << 8) | src[1]; + src += 2; + if (src >= srce) + src = srcp; + MAKEXCH; } break; case AHIST_M16S: - for (i = 0; i < srcsize; i++) { - dst[i * 4 + 0] = src[i * 2 + 1]; - dst[i * 4 + 1] = src[i * 2 + 0]; - dst[i * 4 + 2] = src[i * 2 + 1]; - dst[i * 4 + 3] = src[i * 2 + 0]; + for (i = 0; i < len; i++) { + uae_u32 l = (src[0] << 16) | (src[1] << 8) | src[1]; + uae_u32 r = (src[0] << 16) | (src[1] << 8) | src[1]; + src += 2; + if (src >= srce) + src = srcp; + MAKEXCH; } break; case AHIST_S16S: - for (i = 0; i < srcsize; i++) { - dst[i * 4 + 0] = src[i * 4 + 1]; - dst[i * 4 + 1] = src[i * 4 + 0]; - dst[i * 4 + 2] = src[i * 4 + 3]; - dst[i * 4 + 3] = src[i * 4 + 2]; + for (i = 0; i < len; i++) { + uae_u32 l = (src[0] << 16) | (src[1] << 8) | src[1]; + uae_u32 r = (src[2] << 16) | (src[3] << 8) | src[3]; + src += 4; + if (src >= srce) + src = srcp; + MAKEXCH; } break; case AHIST_M32S: - for (i = 0; i < srcsize; i++) { - dst[i * 4 + 0] = src[i * 4 + 3]; - dst[i * 4 + 1] = src[i * 4 + 2]; - dst[i * 4 + 2] = src[i * 4 + 3]; - dst[i * 4 + 3] = src[i * 4 + 2]; + for (i = 0; i < len; i++) { + uae_u32 l = (src[3] << 16) | (src[2] << 8) | src[1]; + uae_u32 r = (src[3] << 16) | (src[2] << 8) | src[1]; + src += 4; + if (src >= srce) + src = srcp; + MAKEXCH; } break; case AHIST_S32S: - for (i = 0; i < srcsize; i++) { - dst[i * 4 + 0] = src[i * 8 + 3]; - dst[i * 4 + 1] = src[i * 8 + 2]; - dst[i * 4 + 2] = src[i * 8 + 7]; - dst[i * 4 + 3] = src[i * 8 + 6]; + for (i = 0; i < len; i++) { + uae_u32 l = (src[3] << 16) | (src[2] << 8) | src[1]; + uae_u32 r = (src[7] << 16) | (src[6] << 8) | src[5]; + src += 8; + if (src >= srce) + src = srcp; + MAKEXCH; } break; case AHIST_L7_1: - if (ds->chout == 8) { - for (i = 0; i < srcsize; i++) { - for (j = 0; j < 8; j++) { - dst[j * 4 + 0] = src[j * 4 + 2]; - dst[j * 4 + 1] = src[j * 4 + 1]; - dst[j * 4 + 2] = src[j * 4 + 0]; - dst[j * 4 + 3] = 0; + if (och == 8) { + for (i = 0; i < len; i++) { + if (dsahip->bits24) { + uae_u32 fl = (src[0 * 4 + 3] << 16) | (src[0 * 4 + 2] << 8) | src[0 * 4 + 1]; + uae_u32 fr = (src[1 * 4 + 3] << 16) | (src[1 * 4 + 2] << 8) | src[1 * 4 + 1]; + uae_u32 cc = (src[6 * 4 + 3] << 16) | (src[6 * 4 + 2] << 8) | src[6 * 4 + 1]; + uae_u32 lf = (src[7 * 4 + 3] << 16) | (src[7 * 4 + 2] << 8) | src[7 * 4 + 1]; + uae_u32 bl = (src[2 * 4 + 3] << 16) | (src[2 * 4 + 2] << 8) | src[2 * 4 + 1]; + uae_u32 br = (src[3 * 4 + 3] << 16) | (src[3 * 4 + 2] << 8) | src[3 * 4 + 1]; + uae_u32 sl = (src[4 * 4 + 3] << 16) | (src[4 * 4 + 2] << 8) | src[4 * 4 + 1]; + uae_u32 sr = (src[5 * 4 + 3] << 16) | (src[5 * 4 + 2] << 8) | src[5 * 4 + 1]; + uae_s32 *dst2 = (uae_s32*)(&dst[i * och2]); + dst2[0] = fl; + dst2[1] = fr; + dst2[2] = cc; + dst2[3] = lf; + dst2[4] = bl; + dst2[5] = br; + dst2[6] = sl; + dst2[7] = sr; + } else { + uae_u16 fl = (src[0 * 4 + 3] << 8) | src[0 * 4 + 2]; + uae_u16 fr = (src[1 * 4 + 3] << 8) | src[1 * 4 + 2]; + uae_u16 cc = (src[6 * 4 + 3] << 8) | src[6 * 4 + 2]; + uae_u16 lf = (src[7 * 4 + 3] << 8) | src[7 * 4 + 2]; + uae_u16 bl = (src[2 * 4 + 3] << 8) | src[2 * 4 + 2]; + uae_u16 br = (src[3 * 4 + 3] << 8) | src[3 * 4 + 2]; + uae_u16 sl = (src[4 * 4 + 3] << 8) | src[4 * 4 + 2]; + uae_u16 sr = (src[5 * 4 + 3] << 8) | src[5 * 4 + 2]; + uae_s16 *dst2 = (uae_s16*)(&dst[i * och2]); + dst2[0] = fl; + dst2[1] = fr; + dst2[2] = cc; + dst2[3] = lf; + dst2[4] = bl; + dst2[5] = br; + dst2[6] = sl; + dst2[7] = sr; } - dst += 4 * 8; - src += 4 * 8; + dst += och2; + src += 8 * 4; + if (src >= srce) + src = srcp; } - } else { /* 7.1 -> 5.1 */ - for (i = 0; i < srcsize; i++) { - for (j = 0; j < 6; j++) { - dst[j * 4 + 0] = src[j * 4 + 2]; - dst[j * 4 + 1] = src[j * 4 + 1]; - dst[j * 4 + 2] = src[j * 4 + 0]; - dst[j * 4 + 3] = 0; + } else if (och == 6) { /* 7.1 -> 5.1 */ + for (i = 0; i < len; i++) { + if (dsahip->bits24) { + uae_s32 *dst2 = (uae_s32*)(&dst[i * och2]); + uae_u32 fl = (src[0 * 4 + 3] << 16) | (src[0 * 4 + 2] << 8) | src[0 * 4 + 1]; + uae_u32 fr = (src[1 * 4 + 3] << 16) | (src[1 * 4 + 2] << 8) | src[1 * 4 + 1]; + uae_u32 cc = (src[6 * 4 + 3] << 16) | (src[6 * 4 + 2] << 8) | src[6 * 4 + 1]; + uae_u32 lf = (src[7 * 4 + 3] << 16) | (src[7 * 4 + 2] << 8) | src[7 * 4 + 1]; + uae_u32 bl = (src[2 * 4 + 3] << 16) | (src[2 * 4 + 2] << 8) | src[2 * 4 + 1]; + uae_u32 br = (src[3 * 4 + 3] << 16) | (src[3 * 4 + 2] << 8) | src[3 * 4 + 1]; + uae_u32 sl = (src[4 * 4 + 3] << 16) | (src[4 * 4 + 2] << 8) | src[4 * 4 + 1]; + uae_u32 sr = (src[5 * 4 + 3] << 16) | (src[5 * 4 + 2] << 8) | src[5 * 4 + 1]; + } else { + uae_s16 *dst2 = (uae_s16*)(&dst[i * och2]); + uae_u16 fl = (src[0 * 4 + 3] << 8) | src[0 * 4 + 2]; + uae_u16 fr = (src[1 * 4 + 3] << 8) | src[1 * 4 + 2]; + uae_u16 cc = (src[6 * 4 + 3] << 8) | src[6 * 4 + 2]; + uae_u16 lf = (src[7 * 4 + 3] << 8) | src[7 * 4 + 2]; + uae_u16 bl = (src[2 * 4 + 3] << 8) | src[2 * 4 + 2]; + uae_u16 br = (src[3 * 4 + 3] << 8) | src[3 * 4 + 2]; + uae_u16 sl = (src[4 * 4 + 3] << 8) | src[4 * 4 + 2]; + uae_u16 sr = (src[5 * 4 + 3] << 8) | src[5 * 4 + 2]; + dst2[0] = fl; + dst2[1] = fr; + dst2[2] = cc; + dst2[3] = lf; + dst2[4] = (bl + sl) / 2; + dst2[5] = (br + sr) / 2; } - dst += 4 * 8; - src += 4 * 8; + dst += och2; + src += 8 * 4; + if (src >= srce) + src = srcp; } } break; } + *psrcp = src; } -static void clearsample (struct dssample *ds, LPDIRECTSOUNDBUFFER8 dsb, int dstlength) +static void dorecord (struct DSAHI *dsahip) { + uae_u32 pbase = get_long (dsahip->audioctrl + ahiac_DriverData); HRESULT hr; - void *buffer1; - DWORD size1, outlen; + DWORD cpos, rpos, diff; + void *buf1, *buf2; + DWORD size1, size2; + uae_u32 recordbuf; + int mixlength_bytes; - if (!dsb) + if (dsahip->dscb == NULL) + return; + if (dsahip->record_wait && !get_word (pbase + pub_RecordHookDone)) + return; + dsahip->record_wait = 0; + mixlength_bytes = dsahip->mixlength_record * dsahip->record_ch * dsahip->record_bytespersample; + recordbuf = get_long (pbase + pub_RecordBuffer); + if (recordbuf == 0 || !valid_address (recordbuf, mixlength_bytes)) + return; + hr = IDirectSoundCaptureBuffer_GetCurrentPosition (dsahip->dscb, &cpos, &rpos); + if (FAILED (hr)) { + write_log ("AHI: IDirectSoundCaptureBuffer_GetCurrentPosition() failed %s\n", DXError (hr)); return; - outlen = dstlength * ds->bytespersampleout * ds->chout; - hr = IDirectSoundBuffer8_Lock (dsb, 0, outlen, &buffer1, &size1, NULL, NULL, 0); - if (hr == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore (dsb); - hr = IDirectSoundBuffer8_Lock (dsb, 0, outlen, &buffer1, &size1, NULL, NULL, 0); } - if (FAILED (hr)) + if (rpos < dsahip->recordingcursor) + rpos += dsahip->channellength_record; + diff = rpos - dsahip->recordingcursor; + if (diff < mixlength_bytes) return; - memset (buffer1, 0, size1); - IDirectSoundBuffer8_Unlock (dsb, buffer1, size1, NULL, 0); + hr = IDirectSoundCaptureBuffer_Lock (dsahip->dscb, dsahip->recordingcursor, mixlength_bytes, &buf1, &size1, &buf2, &size2, 0); + if (SUCCEEDED (hr)) { + uae_u8 *addr = get_real_address (recordbuf); + uae_u8 *b = (uae_u8*)buf1; + int s; + b = (uae_u8*)buf1; + s = size1; + while (s > 0) { + addr[0] = b[1]; + addr[1] = b[0]; + addr += 2; + b += 2; + s -= 2; + } + b = (uae_u8*)buf2; + s = size2; + while (s > 0) { + addr[0] = b[1]; + addr[1] = b[0]; + addr += 2; + b += 2; + s -= 2; + } + IDirectSoundCaptureBuffer_Unlock (dsahip->dscb, buf1, size1, buf2, size2); + put_word (pbase + pub_RecordHookDone, 0); + dsahip->record_wait = 1; + put_word (pbase + pub_FuncMode, get_word (pbase + pub_FuncMode) | FUNCMODE_RECORD); + sendsignal (dsahip); + } + dsahip->recordingcursor += mixlength_bytes; + if (dsahip->recordingcursor >= dsahip->channellength_record) + dsahip->recordingcursor -= dsahip->channellength_record; } -static void copysample (struct dssample *ds, LPDIRECTSOUNDBUFFER8 dsb, int dstoffset, int dstlength, uae_u32 srcoffset, uae_u32 srclength) +static int ds_copysample (struct DSAHI *dsahip, struct dschannel *dc) { HRESULT hr; - void *buffer1, *buffer2; - DWORD size1, size2, outoffset, outlen; - uae_u32 addr; + DWORD playc, writec; + DWORD size1, size2; + DWORD diff; + void *buf1, *buf2; - if (!dsb) - return; - outlen = dstlength * ds->bytespersampleout * ds->chout; - outoffset = dstoffset * ds->bytespersampleout * ds->chout; - hr = IDirectSoundBuffer8_Lock (dsb, outoffset, outlen, &buffer1, &size1, &buffer2, &size2, 0); - if (hr == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore (dsb); - hr = IDirectSoundBuffer8_Lock (dsb, outoffset, outlen, &buffer1, &size1, &buffer2, &size2, 0); + hr = IDirectSoundBuffer8_GetCurrentPosition (dc->dsb, &playc, &writec); + if (FAILED (hr)) { + write_log ("AHI: GetCurrentPosition(%d) failed, %s\n", dc->num, DXError (hr)); + return 0; } - if (FAILED (hr)) - return; - if (ds->addr == 0 && ds->len == 0xffffffff) - addr = srcoffset; + + if (dc->dscursor >= writec) + diff = dc->dscursor - writec; else - addr = ds->addr; - if (valid_address (addr + srcoffset * ds->ch * ds->bytespersample, srclength * ds->ch * ds->bytespersample)) { - uae_u8 *naddr = get_real_address (addr); - int part1 = size1 / (ds->bytespersampleout * ds->chout); - int part2 = size2 / (ds->bytespersampleout * ds->chout); - copysampledata (ds, naddr, buffer1, part1, srcoffset, srclength); - srcoffset += part1; - srclength -= part1; - if (srclength != 0) - copysampledata (ds, naddr, buffer2, part2, srcoffset, srclength); + diff = dsahip->channellength - writec + dc->dscursor; + + if (diff > dsahip->mixlength) + return 0; + + hr = IDirectSoundBuffer8_Lock (dc->dsb, dc->dscursor, dsahip->mixlength, &buf1, &size1, &buf2, &size2, 0); + if (hr == DSERR_BUFFERLOST) { + IDirectSoundBuffer8_Restore (dc->dsb); + hr = IDirectSoundBuffer8_Lock (dc->dsb, dc->dscursor, dsahip->mixlength, &buf1, &size1, &buf2, &size2, 0); + } + if (SUCCEEDED (hr)) { + memcpy (buf1, dc->buffer, size1); + if (buf2) + memcpy (buf2, dc->buffer + size1, size2); + IDirectSoundBuffer8_Unlock (dc->dsb, buf1, size1, buf2, size2); + } + + if (ahi_debug > 1) + write_log ("%d playc=%08d writec=%08d dscursor=%08d\n", + diff / (dsahip->chout * dsahip->bytespersampleout), + playc, writec, dc->dscursor); + + dc->dscursor += dsahip->mixlength; + if (dc->dscursor >= dsahip->channellength) + dc->dscursor -= dsahip->channellength; + + return 1; +} + +static void copysample (struct DSAHI *dsahip, struct dschannel *dc) +{ + int dstlen, dstlenbytes; + struct dssample *ds; + int srclen, srclendstbytes; + int chbytesout; + uae_u8 *dstbuf; + int ok; + + assert (dc->buffercursor < dsahip->mixlength); + + ds = dc->ds; + + chbytesout = dsahip->chout * dsahip->bytespersampleout; + dstbuf = dc->buffer + dc->buffercursor; + dstlenbytes = dsahip->mixlength - dc->buffercursor; + dstlen = dstlenbytes / chbytesout; + + ok = 0; + if (ds && dc->playing > 0) { + uae_u32 addr, addre, addrs; + int chbytesin = ds->ch * ds->bytespersample; + + if (ds->addr == 0 && ds->len == 0xffffffff) { + addrs = addr = ds->offset; + } else { + addr = ds->addr; + addr += dc->srcplayoffset * chbytesin; + addrs = addr; + } + addre = addr + dc->srcplaylen * chbytesin; + addr += dc->srcoffset * chbytesin; + + srclen = dc->srcplaylen - dc->srcoffset; + assert (srclen > 0); + srclendstbytes = srclen * chbytesout; + + if (srclendstbytes > dstlenbytes) { + srclendstbytes = dstlenbytes; + srclen = srclendstbytes / chbytesout; + } + if (dstlenbytes > srclendstbytes) { + dstlenbytes = srclendstbytes; + dstlen = dstlenbytes / chbytesout; + } + + assert (dstlen > 0); + + if (valid_address (addrs, addre - addrs)) { + uae_u8 *naddr = get_real_address (addr); + uae_u8 *naddre = get_real_address (addre); + uae_u8 *naddrs = get_real_address (addrs); + copysampledata (dsahip, dc, ds, &naddr, naddre, naddrs, dstbuf, dstlen); + dc->srcoffset = (naddr - naddrs) / chbytesin; + if (dc->srcoffset == dc->srcplayoffset) { + setchannelevent (dsahip, dc); + } + ok = 1; + } + } + if (!ok) { + memset (dstbuf, 0, dstlenbytes); + if (dc->playing < 0) + setchannelevent (dsahip, dc); + dc->playing = 0; } - IDirectSoundBuffer8_Unlock (dsb, buffer1, size1, buffer2, size2); + dc->hsync += 10; + dc->buffercursor += dstlenbytes; + //write_log ("%d ", dstlen / (dsahip->chout * dsahip->bytespersampleout)); } -void ahi_vsync (void) +void ahi_hsync (void) { struct DSAHI *dsahip = &dsahi[0]; - int i; + static int cnt; + uae_u32 pbase = get_long (dsahip->audioctrl + ahiac_DriverData); + int i, flags; + if (ahi_paused || dsahip->enabledisable) + return; + cnt--; + if (cnt < 0) { + if (dsahip->dsrecording) + dorecord (dsahip); + cnt = 100; + } if (!dsahip->playing) return; + flags = get_long (pbase + pub_ChannelSignalAck); for (i = 0; i < UAE_MAXCHANNELS; i++) { - HRESULT hr; - DWORD playc, writec; - struct dssample *ds = dsahip->channel[i].ds; - - if (ds == NULL) - continue; - if (ds->type != AHIST_DYNAMICSAMPLE) + struct dschannel *dc = &dsahip->channel[i]; + if (dc->buffer == NULL) continue; - hr = IDirectSoundBuffer8_GetCurrentPosition (ds->dsb, &playc, &writec); - if (FAILED (hr)) { - write_log ("AHI: GetCurrentPosition(%d) failed, %s\n", ds->channel, DXError (hr)); + if (dc->hsync > 0) { + dc->hsync--; continue; } - write_log ("AHI: ch=%d writec=%d\n", ds->channel, writec / (ds->bytespersampleout * ds->chout)); - copysample (ds, ds->dsb, - writec / (ds->bytespersampleout * ds->chout), - ds->len - 1000, - writec / (ds->bytespersampleout * ds->chout), - ds->len - 1000); + if (dc->channelsignal) { + if (!(flags & (1 << dc->num))) + continue; + dc->channelsignal = 0; + flags &= ~(1 << dc->num); + } + if (dc->buffercursor < dsahip->mixlength) + copysample (dsahip, dc); + assert (dc->buffercursor <= dsahip->mixlength); + if (dc->buffercursor == dsahip->mixlength) { + if (ds_copysample (dsahip, dc)) { + dc->buffercursor = 0; + } else { + dc->hsync = 10; + } + } } + put_long (pbase + pub_ChannelSignalAck, flags); } -static void ds_stop (struct dssample *ds) +static void ds_record (struct DSAHI *dsahip, int start) { HRESULT hr; - if (!ds->ready) + if (dsahip->dscb == NULL) return; - if (ahi_debug) - write_log ("AHI: ds_stop(%d)\n", ds->num); - hr = IDirectSoundBuffer8_Stop (ds->dsb); - if (FAILED (hr)) - write_log ("AHI: IDirectSoundBuffer8_Stop() failed, %s\n", DXError (hr)); - if (ds->dsbback) { - hr = IDirectSoundBuffer8_Stop (ds->dsbback); - if (FAILED (hr)) - write_log ("AHI: IDirectSoundBuffer8_StopBack() failed, %s\n", DXError (hr)); + if (dsahip->dsrecording && start) + return; + dsahip->dsrecording = 0; + if (start) { + hr = IDirectSoundCaptureBuffer_Start (dsahip->dscb, DSCBSTART_LOOPING); + if (FAILED (hr)) { + write_log ("AHI: DirectSoundCaptureBuffer_Start failed: %s\n", DXError (hr)); + return; + } + dsahip->dsrecording = 1; + } else { + hr = IDirectSoundCaptureBuffer_Stop (dsahip->dscb); + if (FAILED (hr)) { + write_log ("AHI: DirectSoundCaptureBuffer_Stop failed: %s\n", DXError (hr)); + return; + } } - ds->ready = 1; } -static void ds_setsound (struct DSAHI *dsahip, struct dssample *ds, int offset, int length) +static void ds_stop (struct DSAHI *dsahip, struct dschannel *dc) { HRESULT hr; - clearsample (ds, ds->dsb, ds->len); - clearsample (ds, ds->dsbback, ds->len); - copysample (ds, ds->dsb, 0, ds->len, offset, length); - copysample (ds, ds->dsbback, 0, ds->len, offset, length); - hr = IDirectSoundBuffer8_SetCurrentPosition (ds->dsb, 0); + dc->dsplaying = 0; + if (dc->dsb == NULL) + return; + if (ahi_debug) + write_log ("AHI: ds_stop(%d)\n", dc->num); + hr = IDirectSoundBuffer8_Stop (dc->dsb); if (FAILED (hr)) - write_log ("AHI: IDirectSoundBuffer8_SetCurrentPosition() failed, %s\n", DXError (hr)); - if (ds->dsbback) { - hr = IDirectSoundBuffer8_SetCurrentPosition (ds->dsbback, 0); - if (FAILED (hr)) - write_log ("AHI: IDirectSoundBuffer8_SetCurrentPositionBack() failed, %s\n", DXError (hr)); - } + write_log ("AHI: IDirectSoundBuffer8_Stop() failed, %s\n", DXError (hr)); } -static int ds_allocbuffer (struct DSAHI *ahidsp, struct dssample *ds, int type, uae_u32 len) +static void ds_play (struct DSAHI *dsahip, struct dschannel *dc) { HRESULT hr; - DSBUFFERDESC dd; - WAVEFORMATEXTENSIBLE wavfmt; - LPDIRECTSOUNDBUFFER pdsb; - LPDIRECTSOUNDBUFFER8 pdsb8; - int round, chround; - int channels[] = { 2, 4, 6, 8 }; - int ch, chout, bps, bpsout; - DSBPOSITIONNOTIFY pn[1]; + DWORD status, playc, writec; - if (!ds) - return 0; - switch (type) - { - case AHIST_M8S: - case AHIST_S8S: - ch = 1; - break; - case AHIST_M16S: - case AHIST_S16S: - case AHIST_M32S: - case AHIST_S32S: - ch = 2; - break; - case AHIST_L7_1: - ch = 8; - channels[0] = 6; - channels[1] = 8; - channels[2] = 0; - break; - default: - return 0; - } - switch (type) - { - case AHIST_M8S: - case AHIST_S8S: - bps = 8; - break; - case AHIST_M16S: - case AHIST_S16S: - bps = 16; - break; - case AHIST_M32S: - case AHIST_S32S: - case AHIST_L7_1: - bps = 24; - break; - default: - return 0; - } + if (dc->dsb == NULL) + return; + if (dc->dsplaying) + return; + if (dc->frequency == 0) + return; + dc->dsplaying = 1; if (ahi_debug) - write_log ("AHI: AllocBuffer ch=%d,bps=%d\n", ch, bps); - - pdsb = NULL; - bpsout = 16; - for (chround = 0; channels[chround]; chround++) { - chout = channels[chround]; - for (round = 0; supportedmodes[round].ch; round++) { - DWORD ksmode = 0; - - pdsb = NULL; - if (supportedmodes[round].ch != chout) - continue; - - memset (&wavfmt, 0, sizeof (WAVEFORMATEXTENSIBLE)); - wavfmt.Format.nChannels = chout; - wavfmt.Format.nSamplesPerSec = default_freq; - wavfmt.Format.wBitsPerSample = bpsout; - if (chout <= 2) { - wavfmt.Format.wFormatTag = WAVE_FORMAT_PCM; - } else { - DWORD ksmode = 0; - wavfmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; - wavfmt.Format.cbSize = sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX); - wavfmt.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - wavfmt.Samples.wValidBitsPerSample = bpsout; - wavfmt.dwChannelMask = supportedmodes[round].ksmode; - } - wavfmt.Format.nBlockAlign = bpsout / 8 * wavfmt.Format.nChannels; - wavfmt.Format.nAvgBytesPerSec = wavfmt.Format.nBlockAlign * wavfmt.Format.nSamplesPerSec; - - memset (&dd, 0, sizeof dd); - dd.dwSize = sizeof dd; - dd.dwBufferBytes = len * bpsout / 8 * chout; - dd.lpwfxFormat = &wavfmt.Format; - dd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY; - dd.dwFlags |= DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; - dd.dwFlags |= chout >= 4 ? DSBCAPS_LOCHARDWARE : DSBCAPS_LOCSOFTWARE; - dd.guid3DAlgorithm = GUID_NULL; - - hr = IDirectSound_CreateSoundBuffer (lpDS, &dd, &pdsb, NULL); - if (SUCCEEDED (hr)) - break; - if (dd.dwFlags & DSBCAPS_LOCHARDWARE) { - HRESULT hr2 = hr; - dd.dwFlags &= ~DSBCAPS_LOCHARDWARE; - dd.dwFlags |= DSBCAPS_LOCSOFTWARE; - hr = IDirectSound_CreateSoundBuffer (lpDS, &dd, &pdsb, NULL); - if (SUCCEEDED (hr)) { - write_log ("AHI: Couldn't use hardware buffer (switched to software): %s\n", DXError (hr2)); - break; - } - } - write_log ("AHI: DS sound buffer failed (ch=%d,bps=%d): %s\n", - chout, bpsout, DXError (hr)); - } - if (pdsb) - break; - } - if (pdsb == NULL) - goto error; - - hr = IDirectSound_QueryInterface (pdsb, &IID_IDirectSoundBuffer8, (LPVOID*)&pdsb8); - if (FAILED (hr)) { - write_log ("AHI: Secondary QueryInterface(IID_IDirectSoundBuffer8) failure: %s\n", DXError (hr)); - goto error; - } - - IDirectSound_Release (pdsb); - ds->dsb = pdsb8; - - hr = IDirectSoundBuffer8_QueryInterface (pdsb, &IID_IDirectSoundNotify8, (void**)&ds->dsnotify); - if (FAILED (hr)) { - write_log ("AHI: Secondary QueryInterface(IID_IDirectSoundNotify8) failure: %s\n", DXError (hr)); - goto error; - } - ds->notifyevent = CreateEvent (NULL, FALSE, FALSE, NULL); - pn[0].dwOffset = 0; - pn[0].hEventNotify = ds->notifyevent; - hr = IDirectSoundNotify_SetNotificationPositions (ds->dsnotify, 1, pn); - if (FAILED (hr)) { - write_log ("AHI: Secondary SetNotificationPositions() failure: %s\n", DXError (hr)); - goto error; - } + write_log ("AHI: ds_play(%d)\n", dc->num); + hr = IDirectSoundBuffer8_GetStatus (dc->dsb, &status); + if (FAILED (hr)) + write_log ("AHI: ds_play() IDirectSoundBuffer8_GetStatus() failed, %s\n", DXError (hr)); + hr = IDirectSoundBuffer8_Play (dc->dsb, 0, 0, DSBPLAY_LOOPING); + if (FAILED (hr)) + write_log ("AHI: ds_play() IDirectSoundBuffer8_Play() failed, %s\n", DXError (hr)); + hr = IDirectSoundBuffer8_GetCurrentPosition (dc->dsb, &playc, &writec); + if (FAILED (hr)) + write_log ("AHI: ds_play() IDirectSoundBuffer8_GetCurrentPosition() failed, %s\n", DXError (hr)); + dc->dscursor = writec + dsahip->mixlength; + if (dc->dscursor >= dsahip->channellength) + dc->dscursor -= dsahip->channellength; + if (ahi_debug) + write_log("AHI: ds_play(%d) Start=%d->%d\n", dc->num, writec, dc->dscursor); +} +void ahi2_pause_sound (int paused) +{ + int i; + struct DSAHI *dsahip = &dsahi[0]; - if (chout > 2) { - // create "surround" sound buffer - hr = IDirectSound_CreateSoundBuffer (lpDS, &dd, &pdsb, NULL); - if (SUCCEEDED (hr)) { - hr = IDirectSound_QueryInterface (pdsb, &IID_IDirectSoundBuffer8, (LPVOID*)&pdsb8); - if (SUCCEEDED (hr)) - ds->dsbback = pdsb8; - IDirectSound_Release (pdsb); + ahi_paused = paused; + if (!dsahip->playing && !dsahip->recording) + return; + for (i = 0; i < UAE_MAXCHANNELS; i++) { + struct dschannel *dc = &dsahip->channel[i]; + if (dc->dsb == NULL) + continue; + if (paused) { + ds_stop (dsahip, dc); + } else { + ds_play (dsahip, dc); } } - - ds_setvolume (ds, 0, 0); - ds->bitspersample = bps; - ds->bitspersampleout = bpsout; - ds->ch = ch; - ds->chout = chout; - ds->bytespersample = bps / 8; - ds->bytespersampleout = bpsout / 8; - - SetEvent (ahidsp->threadevent); - - return 1; - -error: - return 0; } static uae_u32 init (TrapContext *ctx) { + int i; + + enumerate_sound_devices (); xahi_author = ds ("Toni Wilen"); xahi_copyright = ds ("GPL"); xahi_version = ds ("uae2 0.1 (xx.xx.2008)\r\n"); - xahi_output = ds ("Default Output"); + for (i = 0; sound_devices[i].name; i++) + xahi_output[i] = ds (sound_devices[i].name); + xahi_output_num = i; + for (i = 0; record_devices[i].name; i++) + xahi_input[i] = ds (record_devices[i].name); + xahi_input_num = i; return 1; } @@ -1133,13 +1387,30 @@ static uae_u32 AHIsub_AllocAudio (TrapContext *ctx) uae_u32 tags = m68k_areg (&ctx->regs, 1); uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); uae_u32 pbase = get_long (audioctrl + ahiac_DriverData); - uae_u32 tag, data; + uae_u32 tag, data, v, ver, size; uae_u32 ret = AHISF_KNOWSTEREO | AHISF_KNOWHIFI; struct DSAHI *dsahip = &dsahi[0]; if (ahi_debug) write_log ("AHI: AllocAudio(%08x,%08x)\n", tags, audioctrl); + ver = get_long (pbase + pub_Version); + size = get_long (pbase + pub_SizeOf); + if (ver != AHI_STRUCT_VERSION) { + gui_message ("AHI: Incompatible DEVS:AHI/uae2.audio\nVersion mismatch %d<>%d.", ver, AHI_STRUCT_VERSION); + return AHISF_ERROR; + } + if (size < pub_End) { + gui_message ("AHI: Incompatible DEVS:AHI/uae2.audio.\nInternal structure size %d<%d.", size, pub_End); + return AHISF_ERROR; + } + + + v = get_long (pbase + pub_Index); + if (v != -1) { + write_log ("AHI: corrupted memory\n"); + return AHISF_ERROR; + } put_long (pbase + pub_Index, dsahip - dsahi); dsahip->audioctrl = audioctrl; @@ -1148,12 +1419,15 @@ static uae_u32 AHIsub_AllocAudio (TrapContext *ctx) dsahip->sounds = UAE_MAXSOUNDS; dsahip->channels = UAE_MAXCHANNELS; - if (dsahip->cansurround) + if (xahi_input_num) + ret |= AHISF_CANRECORD; + if (cansurround) ret |= AHISF_KNOWMULTICHANNEL; while ((tag = gettag (&tags, &data))) { if (ahi_debug) write_log ("- TAG %08x=%d: %08x=%u\n", tag, tag & 0x7fff, data, data); +#if 0 switch (tag) { case AHIA_Sounds: @@ -1175,21 +1449,25 @@ static uae_u32 AHIsub_AllocAudio (TrapContext *ctx) dsahip->maxplayerfreq = data; break; } +#endif } if (dsahip->sounds < 0 || dsahip->sounds > 1000) { ds_free (dsahip); + ds_free_record (dsahip); return AHISF_ERROR; } dsahip->sample = xcalloc (sizeof (struct dssample), dsahip->sounds); dsahip->channel = xcalloc (sizeof (struct dschannel), dsahip->channels); for (i = 0; i < dsahip->channels; i++) { struct dschannel *dc = &dsahip->channel[i]; + dc->num = i; } for (i = 0; i < dsahip->sounds; i++) { struct dssample *ds = &dsahip->sample[i]; ds->channel = -1; ds->num = -1; } + ahi_active = 1; return ret; } @@ -1220,8 +1498,13 @@ static void AHIsub_FreeAudio (TrapContext *ctx) struct DSAHI *dsahip = GETAHI; if (ahi_debug) write_log ("AHI: FreeAudio(%08x)\n", audioctrl); + if (ahi_active == 0) + return; + ahi_active = 0; put_long (pbase + pub_Index, -1); if (dsahip) { + ds_free (dsahip); + ds_free_record (dsahip); xfree (dsahip->channel); xfree (dsahip->sample); memset (dsahip, 0, sizeof (struct DSAHI)); @@ -1231,7 +1514,7 @@ static void AHIsub_FreeAudio (TrapContext *ctx) static uae_u32 frequencies[] = { 48000, 44100 }; #define MAX_FREQUENCIES (sizeof (frequencies) / sizeof (uae_u32)) -static uae_u32 getattr2 (struct DSAHI *dsahip, uae_u32 attribute, uae_u32 argument, uae_u32 def) +static uae_u32 getattr2 (uae_u32 attribute, uae_u32 argument, uae_u32 def) { int i; @@ -1266,29 +1549,39 @@ static uae_u32 getattr2 (struct DSAHI *dsahip, uae_u32 attribute, uae_u32 argume case AHIDB_Version: return xahi_version; case AHIDB_Record: - return TRUE; + return -1; case AHIDB_Realtime: - return TRUE; - case AHIDB_Outputs: - return 1; + return -1; case AHIDB_MinOutputVolume: return 0x00000; case AHIDB_MaxOutputVolume: return 0x10000; + case AHIDB_Outputs: + return xahi_output_num; case AHIDB_Output: - return xahi_output; + if (argument >= 0 && argument < xahi_output_num) + return xahi_output[argument]; + return 0; + case AHIDB_Inputs: + return xahi_input_num; + case AHIDB_Input: + if (argument >= 0 && argument < xahi_input_num) + return xahi_input[argument]; + return 0; case AHIDB_Volume: - return 1; + return -1; case AHIDB_Panning: - return 1; + return -1; case AHIDB_HiFi: - return 1; + return -1; case AHIDB_MultiChannel: - return dsahip->cansurround; + return cansurround ? -1 : 0; case AHIDB_MaxChannels: return UAE_MAXCHANNELS; case AHIDB_FullDuplex: - return 1; + return -1; + case AHIDB_MaxRecordSamples: + return RECORDSAMPLES; default: return def; } @@ -1301,12 +1594,11 @@ static uae_u32 AHIsub_GetAttr (TrapContext *ctx) uae_u32 def = m68k_dreg (&ctx->regs, 2); uae_u32 taglist = m68k_areg (&ctx->regs, 1); uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); - struct DSAHI *dsahip = GETAHI; uae_u32 v; - v = getattr2 (dsahip, attribute, argument, def); + v = getattr2 (attribute, argument, def); if (ahi_debug) - write_log ("AHI: GetAttr(%08x=%d,%08x,%08x)=%08x\n", attribute, (attribute & 0x7fff), argument, def, v); + write_log ("AHI: GetAttr(%08x=%d,%08x,%08x)=%08x\n", attribute, attribute & 0x7fff, argument, def, v); return v; } @@ -1318,7 +1610,32 @@ static uae_u32 AHIsub_HardwareControl (TrapContext *ctx) uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); struct DSAHI *dsahip = GETAHI; if (ahi_debug) - write_log ("AHI: HardwareControl(%08x,%08x,%08x)\n", attribute, argument, audioctrl); + write_log ("AHI: HardwareControl(%08x=%d,%08x,%08x)\n", attribute, attribute & 0x7fff, argument, audioctrl); + switch (attribute) + { + case AHIC_Input: + if (dsahip->input != argument) { + dsahip->input = argument; + if (dsahip->dscb) { + ds_free_record (dsahip); + ds_init_record (dsahip); + if (dsahip->recording) + ds_record (dsahip, 1); + } + } + break; + case AHIC_Input_Query: + return dsahip->input; + case AHIC_Output: + if (dsahip->output != argument) { + dsahip->output = argument; + if (dsahip->DS) + ds_reinit (dsahip); + } + break; + case AHIC_Output_Query: + return dsahip->output; + } return 0; } @@ -1338,16 +1655,16 @@ static uae_u32 AHIsub_Start (TrapContext *ctx) dsahip->recording = 1; if (dsahip->playing) { setevent (dsahip); - for (i = 0; i < dsahip->sounds; i++) { - struct dssample *ds = &dsahip->sample[i]; - if (ds->ready > 0 && ds->channel >= 0) { - struct dschannel *dc = &dsahip->channel[ds->channel]; - ds_setvolume (ds, dc->volume, dc->panning); - ds->frequency = 0; - ds_setfreq (dsahip, ds, dc->frequency); // this also starts playback - } + for (i = 0; i < dsahip->channels; i++) { + struct dschannel *dc = &dsahip->channel[i]; + dc->playing = 1; + ds_play (dsahip, dc); } } + if (dsahip->recording) { + ds_init_record (dsahip); + ds_record (dsahip, 1); + } return 0; } @@ -1366,12 +1683,16 @@ static uae_u32 AHIsub_Stop (TrapContext *ctx) if (flags & AHISF_RECORD) dsahip->recording = 0; if (!dsahip->playing) { - for (i = 0; i < dsahip->sounds; i++) { - struct dssample *ds = &dsahip->sample[i]; - if (ds->ready) - ds_stop (ds); + for (i = 0; i < dsahip->channels; i++) { + struct dschannel *dc = &dsahip->channel[i]; + dc->playing = 0; + ds_stop (dsahip, dc); } } + if (!dsahip->recording) { + ds_record (dsahip, 0); + ds_free_record (dsahip); + } return 0; } @@ -1388,7 +1709,6 @@ static uae_u32 AHIsub_Update (TrapContext *ctx) static uae_u32 AHIsub_SetVol (TrapContext *ctx) { - int i; uae_u16 channel = m68k_dreg (&ctx->regs, 0); uae_u32 volume = m68k_dreg (&ctx->regs, 1); uae_u32 pan = m68k_dreg (&ctx->regs, 2); @@ -1398,23 +1718,15 @@ static uae_u32 AHIsub_SetVol (TrapContext *ctx) struct dschannel *dc = GETCHANNEL; if (ahi_debug) - write_log ("AHI: SetVol(%d,%d,%08x,%08x)\n", - channel, pan, audioctrl, flags); - if (dc) { - dc->volume = volume; - dc->panning = pan; - for (i = 0; i < dsahip->sounds; i++) { - struct dssample *ds = &dsahip->sample[i]; - if (ds->channel == channel) - ds_setvolume (ds, volume, pan); - } - } + write_log ("AHI: SetVol(%d,%d,%d,%08x,%08x)\n", + channel, volume, pan, audioctrl, flags); + if (dc) + ds_setvolume (dsahip, dc, volume, pan); return 0; } static uae_u32 AHIsub_SetFreq (TrapContext *ctx) { - int i; uae_u16 channel = m68k_dreg (&ctx->regs, 0); uae_u32 frequency = m68k_dreg (&ctx->regs, 1); uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); @@ -1426,19 +1738,14 @@ static uae_u32 AHIsub_SetFreq (TrapContext *ctx) write_log ("AHI: SetFreq(%d,%d,%08x,%08x)\n", channel, frequency, audioctrl, flags); if (dc) { - dc->frequency = frequency; - for (i = 0; i < dsahip->sounds; i++) { - struct dssample *ds = &dsahip->sample[i]; - if (ds->channel == channel) - ds_setfreq (dsahip, ds, frequency); - } + ds_setfreq (dsahip, dc, frequency); + ds_play (dsahip, dc); } - return 0; + return 0; } static uae_u32 AHIsub_SetSound (TrapContext *ctx) { - int i; uae_u16 channel = m68k_dreg (&ctx->regs, 0); uae_u16 sound = m68k_dreg (&ctx->regs, 1); uae_u32 offset = m68k_dreg (&ctx->regs, 2); @@ -1452,33 +1759,28 @@ static uae_u32 AHIsub_SetSound (TrapContext *ctx) if (ahi_debug) write_log ("AHI: SetSound(%d,%d,%08x,%d,%08x,%08x)\n", channel, sound, offset, length, audioctrl, flags); - dc->ds = NULL; + if (dc == NULL) + return 0; if (sound == 0xffff) { - for (i = 0; i < dsahip->sounds; i++) { - struct dssample *ds2 = &dsahip->sample[i]; - if (ds2->channel == channel) { - ds_stop (ds2); - ds2->channel = -1; - - } - } + if (dc->playing) + dc->playing = -1; } else if (ds) { + int wasplaying; + ds_allocchannel (dsahip, dc); + dc->backwards = length < 0; length = abs (length); if (length == 0) length = ds->len; - ds->ready = 1; ds->channel = channel; dc->ds = ds; - for (i = 0; i < dsahip->sounds; i++) { - struct dssample *ds2 = &dsahip->sample[i]; - if (ds2 != ds && ds2->channel == channel) { - ds_stop (ds2); - ds2->channel = -1; - } - } - ds_setsound (dsahip, ds, offset, length); - if (dsahip->playing) - ds_play (dsahip, ds); + dc->srcplaylen = length; + dc->srcplayoffset = offset; + dc->srcoffset = 0; + ds_setvolume (dsahip, dc, dc->volume, dc->panning); + ds_setfreq (dsahip, dc, dc->frequency); + wasplaying = dc->dsplaying; + dc->playing = 1; + ds_play (dsahip, dc); } return 0; } @@ -1506,27 +1808,72 @@ static uae_u32 AHIsub_LoadSound (TrapContext *ctx) uae_u32 addr = get_long (info + ahisi_Address); uae_u32 len = get_long (info + ahisi_Length); struct dssample *ds = GETSAMPLE; + int ch; + int bps; if (ahi_debug) write_log ("AHI: LoadSound(%d,%d,%08x,%08x,SMP=%d,ADDR=%08x,LEN=%d)\n", sound, type, info, audioctrl, sampletype, addr, len); - if (ds) { - ds->num = sound; - if (!dsahip->cansurround && type == AHIST_L7_1) - return AHIE_BADSOUNDTYPE; - ds->addr = addr; - ds->type = type; - ds->len = len; - ds->frequency = 0; - if (ds_allocbuffer (dsahip, ds, type, len)) - ret = AHIE_OK; + if (!ds) + return AHIE_BADSOUNDTYPE; + + ds->num = sound; + if (!cansurround && sampletype == AHIST_L7_1) + return AHIE_BADSOUNDTYPE; + ds->addr = addr; + ds->sampletype = sampletype; + ds->type = type; + ds->len = len; + + switch (sampletype) + { + case AHIST_M8S: + case AHIST_M16S: + case AHIST_M32S: + ch = 1; + break; + case AHIST_S8S: + case AHIST_S16S: + case AHIST_S32S: + ch = 2; + break; + case AHIST_L7_1: + ch = 8; + break; + default: + return 0; } - return ret; + switch (sampletype) + { + case AHIST_M8S: + case AHIST_S8S: + bps = 8; + break; + case AHIST_M16S: + case AHIST_S16S: + bps = 16; + break; + case AHIST_M32S: + case AHIST_S32S: + case AHIST_L7_1: + bps = 24; + break; + default: + return 0; + } + if (ahi_debug) + write_log ("AHI: AllocBuffer ch=%d,bps=%d\n", ch, bps); + + ds->bitspersample = bps; + ds->ch = ch; + ds->bytespersample = bps / 8; + return AHIE_OK; } static uae_u32 AHIsub_UnloadSound (TrapContext *ctx) { + int i; uae_u16 sound = m68k_dreg (&ctx->regs, 0); uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); struct DSAHI *dsahip = GETAHI; @@ -1535,8 +1882,15 @@ static uae_u32 AHIsub_UnloadSound (TrapContext *ctx) if (ahi_debug) write_log ("AHI: UnloadSound(%d,%08x)\n", sound, audioctrl); - if (ds) - ds_freebuffer (dsahip, ds); + if (0 && ds) { + for (i = 0; i < dsahip->channels; i++) { + struct dschannel *dc = &dsahip->channel[i]; + if (dc->ds == ds) { + dc->playing = 0; + dc->ds = NULL; + } + } + } return AHIE_OK; } @@ -1546,7 +1900,7 @@ static uae_u32 REGPARAM2 ahi_demux (TrapContext *ctx) uae_u32 sp = m68k_areg (&ctx->regs, 7); uae_u32 offset = get_long (sp + 4); - if (ahi_debug) + if (0 && ahi_debug) write_log ("AHI: %d\n", offset); switch (offset) @@ -1612,7 +1966,10 @@ void init_ahi_v2 (void) org (a); } - - +void free_ahi_v2 (void) +{ + ds_free_record (&dsahi[0]); + ds_free (&dsahi[0]); +} #endif diff --git a/od-win32/ahidsound_new.h b/od-win32/ahidsound_new.h index c8af307a..a76414a3 100755 --- a/od-win32/ahidsound_new.h +++ b/od-win32/ahidsound_new.h @@ -1 +1,3 @@ extern void init_ahi_v2 (void); +extern void free_ahi_v2 (void); +extern void ahi2_pause_sound (int); diff --git a/od-win32/ahidsound_new2.c b/od-win32/ahidsound_new2.c new file mode 100755 index 00000000..a501a93b --- /dev/null +++ b/od-win32/ahidsound_new2.c @@ -0,0 +1,1714 @@ +/* + * UAE - The Un*x Amiga Emulator + * + * DirectSound AHI 7.1 wrapper + * + * Copyright 2008 Toni Wilen + */ + +#include "sysconfig.h" + +#if defined(AHI) + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "sysdeps.h" +#include "options.h" +#include "audio.h" +#include "memory.h" +#include "events.h" +#include "custom.h" +#include "newcpu.h" +#include "autoconf.h" +#include "traps.h" +#include "threaddep/thread.h" +#include "native2amiga.h" +#include "od-win32/win32.h" +#include "sounddep/sound.h" +#include "ahidsound_new.h" +#include "dxwrap.h" + +#include +#include +#include +#include +#include + + +static int ahi_debug = 1; + +#define UAE_MAXCHANNELS 24 +#define UAE_MAXSOUNDS 256 + +#define ub_Flags 34 +#define ub_Pad1 (ub_Flags + 1) +#define ub_Pad2 (ub_Pad1 + 1) +#define ub_SysLib (ub_Pad2 + 2) +#define ub_SegList (ub_SysLib + 4) +#define ub_DOSBase (ub_SegList + 4) +#define ub_AHIFunc (ub_DOSBase + 4) + +#define pub_SizeOf 0 +#define pub_Index (pub_SizeOf + 4) +#define pub_Base (pub_Index + 4) +#define pub_audioctrl (pub_Base + 4) +#define pub_FuncTask (pub_audioctrl + 4) +#define pub_WaitMask (pub_FuncTask + 4) +#define pub_WaitSigBit (pub_WaitMask + 4) +#define pub_FuncMode (pub_WaitSigBit +4) +#define pub_TaskMode (pub_FuncMode + 2) +#define pub_ChannelSignal (pub_TaskMode + 2) + +#define ahiac_AudioCtrl 0 +#define ahiac_Flags ahiac_AudioCtrl + 4 +#define ahiac_SoundFunc ahiac_Flags + 4 +#define ahiac_PlayerFunc ahiac_SoundFunc + 4 +#define ahiac_PlayerFreq ahiac_PlayerFunc + 4 +#define ahiac_MinPlayerFreq ahiac_PlayerFreq + 4 +#define ahiac_MaxPlayerFreq ahiac_MinPlayerFreq + 4 +#define ahiac_MixFreq ahiac_MaxPlayerFreq + 4 +#define ahiac_Channels ahiac_MixFreq + 4 +#define ahiac_Sounds ahiac_Channels + 2 +#define ahiac_DriverData ahiac_Sounds + 2 +#define ahiac_MixerFunc ahiac_DriverData + 4 +#define ahiac_SamplerFunc ahiac_MixerFunc + 4 +#define ahiac_Obsolete ahiac_SamplerFunc + 4 +#define ahiac_BuffSamples ahiac_Obsolete + 4 +#define ahiac_MinBuffSamples ahiac_BuffSamples + 4 +#define ahiac_MaxBuffSamples ahiac_MinBuffSamples + 4 +#define ahiac_BuffSize ahiac_MaxBuffSamples + 4 +#define ahiac_BuffType ahiac_BuffSize + 4 +#define ahiac_PreTimer ahiac_BuffType + 4 +#define ahiac_PostTimer ahiac_PreTimer + 4 +#define ahiac_AntiClickSamples ahiac_PostTimer + 4 +#define ahiac_PreTimerFunc ahiac_AntiClickSamples + 4 +#define ahiac_PostTimerFunc ahiac_PreTimerFunc + 4 + +#if 0 +struct AHISampleInfo +{ + ULONG ahisi_Type; /* Format of samples */ + APTR ahisi_Address; /* Address to array of samples */ + ULONG ahisi_Length; /* Number of samples in array */ +}; +#endif + +#define ahisi_Type 0 +#define ahisi_Address 4 +#define ahisi_Length 8 + +#if 0 +struct AHIAudioCtrlDrv +{ + struct AHIAudioCtrl ahiac_AudioCtrl; + ULONG ahiac_Flags; /* See below for definition */ + struct Hook *ahiac_SoundFunc; /* AHIA_SoundFunc */ + struct Hook *ahiac_PlayerFunc; /* AHIA_PlayerFunc */ + Fixed ahiac_PlayerFreq; /* AHIA_PlayerFreq */ + Fixed ahiac_MinPlayerFreq; /* AHIA_MinPlayerFreq */ + Fixed ahiac_MaxPlayerFreq; /* AHIA_MaxPlayerFreq */ + ULONG ahiac_MixFreq; /* AHIA_MixFreq */ + UWORD ahiac_Channels; /* AHIA_Channels */ + UWORD ahiac_Sounds; /* AHIA_Sounds */ + + APTR ahiac_DriverData; /* Unused. Store whatever you want here. */ + + struct Hook *ahiac_MixerFunc; /* Mixing routine Hook */ + struct Hook *ahiac_SamplerFunc; /* Sampler routine Hook */ + ULONG ahiac_Obsolete; + ULONG ahiac_BuffSamples; /* Samples to mix this pass. */ + ULONG ahiac_MinBuffSamples; /* Min. samples to mix each pass. */ + ULONG ahiac_MaxBuffSamples; /* Max. samples to mix each pass. */ + ULONG ahiac_BuffSize; /* Buffer size ahiac_MixerFunc needs. */ + ULONG ahiac_BuffType; /* Buffer format (V2) */ + BOOL (*ahiac_PreTimer)(void); /* Call before mixing (V4) */ + void (*ahiac_PostTimer)(void); /* Call after mixing (V4) */ + ULONG ahiac_AntiClickSamples; /* AntiClick samples (V6) */ + struct Hook *ahiac_PreTimerFunc; /* A Hook wrapper for ahiac_PreTimer (V6) */ + struct Hook *ahiac_PostTimerFunc; /* A Hook wrapper for ahiac_PostTimer (V6) */ +#endif + +/* AHIsub_AllocAudio return flags */ +#define AHISF_ERROR (1<<0) +#define AHISF_MIXING (1<<1) +#define AHISF_TIMING (1<<2) +#define AHISF_KNOWSTEREO (1<<3) +#define AHISF_KNOWHIFI (1<<4) +#define AHISF_CANRECORD (1<<5) +#define AHISF_CANPOSTPROCESS (1<<6) +#define AHISF_KNOWMULTICHANNEL (1<<7) + +#define AHISB_ERROR (0) +#define AHISB_MIXING (1) +#define AHISB_TIMING (2) +#define AHISB_KNOWSTEREO (3) +#define AHISB_KNOWHIFI (4) +#define AHISB_CANRECORD (5) +#define AHISB_CANPOSTPROCESS (6) +#define AHISB_KNOWMULTICHANNEL (7) + + /* AHIsub_Start() and AHIsub_Stop() flags */ +#define AHISF_PLAY (1<<0) +#define AHISF_RECORD (1<<1) + +#define AHISB_PLAY (0) +#define AHISB_RECORD (1) + + /* ahiac_Flags */ +#define AHIACF_VOL (1<<0) +#define AHIACF_PAN (1<<1) +#define AHIACF_STEREO (1<<2) +#define AHIACF_HIFI (1<<3) +#define AHIACF_PINGPONG (1<<4) +#define AHIACF_RECORD (1<<5) +#define AHIACF_MULTTAB (1<<6) +#define AHIACF_MULTICHANNEL (1<<7) + +#define AHIACB_VOL (0) +#define AHIACB_PAN (1) +#define AHIACB_STEREO (2) +#define AHIACB_HIFI (3) +#define AHIACB_PINGPONG (4) +#define AHIACB_RECORD (5) +#define AHIACB_MULTTAB (6) +#define AHIACB_MULTICHANNEL (7) + +#define AHI_TagBase (0x80000000) +#define AHI_TagBaseR (AHI_TagBase|0x8000) + + /* AHI_AllocAudioA tags */ +#define AHIA_AudioID (AHI_TagBase+1) /* Desired audio mode */ +#define AHIA_MixFreq (AHI_TagBase+2) /* Suggested mixing frequency */ +#define AHIA_Channels (AHI_TagBase+3) /* Suggested number of channels */ +#define AHIA_Sounds (AHI_TagBase+4) /* Number of sounds to use */ +#define AHIA_SoundFunc (AHI_TagBase+5) /* End-of-Sound Hook */ +#define AHIA_PlayerFunc (AHI_TagBase+6) /* Player Hook */ +#define AHIA_PlayerFreq (AHI_TagBase+7) /* Frequency for player Hook (Fixed)*/ +#define AHIA_MinPlayerFreq (AHI_TagBase+8) /* Minimum Frequency for player Hook */ +#define AHIA_MaxPlayerFreq (AHI_TagBase+9) /* Maximum Frequency for player Hook */ +#define AHIA_RecordFunc (AHI_TagBase+10) /* Sample recording Hook */ +#define AHIA_UserData (AHI_TagBase+11) /* What to put in ahiac_UserData */ +#define AHIA_AntiClickSamples (AHI_TagBase+13) /* # of samples to smooth (V6) */ + + /* AHI_PlayA tags (V4) */ +#define AHIP_BeginChannel (AHI_TagBase+40) /* All command tags should be... */ +#define AHIP_EndChannel (AHI_TagBase+41) /* ... enclosed by these tags. */ +#define AHIP_Freq (AHI_TagBase+50) +#define AHIP_Vol (AHI_TagBase+51) +#define AHIP_Pan (AHI_TagBase+52) +#define AHIP_Sound (AHI_TagBase+53) +#define AHIP_Offset (AHI_TagBase+54) +#define AHIP_Length (AHI_TagBase+55) +#define AHIP_LoopFreq (AHI_TagBase+60) +#define AHIP_LoopVol (AHI_TagBase+61) +#define AHIP_LoopPan (AHI_TagBase+62) +#define AHIP_LoopSound (AHI_TagBase+63) +#define AHIP_LoopOffset (AHI_TagBase+64) +#define AHIP_LoopLength (AHI_TagBase+65) + + /* AHI_ControlAudioA tags */ +#define AHIC_Play (AHI_TagBase+80) /* Boolean */ +#define AHIC_Record (AHI_TagBase+81) /* Boolean */ +#define AHIC_MonitorVolume (AHI_TagBase+82) +#define AHIC_MonitorVolume_Query (AHI_TagBase+83) /* ti_Data is pointer to Fixed (LONG) */ +#define AHIC_MixFreq_Query (AHI_TagBase+84) /* ti_Data is pointer to ULONG */ +/* --- New for V2, they will be ignored by V1 --- */ +#define AHIC_InputGain (AHI_TagBase+85) +#define AHIC_InputGain_Query (AHI_TagBase+86) /* ti_Data is pointer to Fixed (LONG) */ +#define AHIC_OutputVolume (AHI_TagBase+87) +#define AHIC_OutputVolume_Query (AHI_TagBase+88) /* ti_Data is pointer to Fixed (LONG) */ +#define AHIC_Input (AHI_TagBase+89) +#define AHIC_Input_Query (AHI_TagBase+90) /* ti_Data is pointer to ULONG */ +#define AHIC_Output (AHI_TagBase+91) +#define AHIC_Output_Query (AHI_TagBase+92) /* ti_Data is pointer to ULONG */ + + /* AHI_GetAudioAttrsA tags */ +#define AHIDB_AudioID (AHI_TagBase+100) +#define AHIDB_Driver (AHI_TagBaseR+101) /* Pointer to name of driver */ +#define AHIDB_Flags (AHI_TagBase+102) /* Private! */ +#define AHIDB_Volume (AHI_TagBase+103) /* Boolean */ +#define AHIDB_Panning (AHI_TagBase+104) /* Boolean */ +#define AHIDB_Stereo (AHI_TagBase+105) /* Boolean */ +#define AHIDB_HiFi (AHI_TagBase+106) /* Boolean */ +#define AHIDB_PingPong (AHI_TagBase+107) /* Boolean */ +#define AHIDB_MultTable (AHI_TagBase+108) /* Private! */ +#define AHIDB_Name (AHI_TagBaseR+109) /* Pointer to name of this mode */ +#define AHIDB_Bits (AHI_TagBase+110) /* Output bits */ +#define AHIDB_MaxChannels (AHI_TagBase+111) /* Max supported channels */ +#define AHIDB_MinMixFreq (AHI_TagBase+112) /* Min mixing freq. supported */ +#define AHIDB_MaxMixFreq (AHI_TagBase+113) /* Max mixing freq. supported */ +#define AHIDB_Record (AHI_TagBase+114) /* Boolean */ +#define AHIDB_Frequencies (AHI_TagBase+115) +#define AHIDB_FrequencyArg (AHI_TagBase+116) /* ti_Data is frequency index */ +#define AHIDB_Frequency (AHI_TagBase+117) +#define AHIDB_Author (AHI_TagBase+118) /* Pointer to driver author name */ +#define AHIDB_Copyright (AHI_TagBase+119) /* Pointer to driver copyright notice */ +#define AHIDB_Version (AHI_TagBase+120) /* Pointer to driver version string */ +#define AHIDB_Annotation (AHI_TagBase+121) /* Pointer to driver annotation text */ +#define AHIDB_BufferLen (AHI_TagBase+122) /* Specifies the string buffer size */ +#define AHIDB_IndexArg (AHI_TagBase+123) /* ti_Data is frequency! */ +#define AHIDB_Index (AHI_TagBase+124) +#define AHIDB_Realtime (AHI_TagBase+125) /* Boolean */ +#define AHIDB_MaxPlaySamples (AHI_TagBase+126) /* It's sample *frames* */ +#define AHIDB_MaxRecordSamples (AHI_TagBase+127) /* It's sample *frames* */ +#define AHIDB_FullDuplex (AHI_TagBase+129) /* Boolean */ +/* --- New for V2, they will be ignored by V1 --- */ +#define AHIDB_MinMonitorVolume (AHI_TagBase+130) +#define AHIDB_MaxMonitorVolume (AHI_TagBase+131) +#define AHIDB_MinInputGain (AHI_TagBase+132) +#define AHIDB_MaxInputGain (AHI_TagBase+133) +#define AHIDB_MinOutputVolume (AHI_TagBase+134) +#define AHIDB_MaxOutputVolume (AHI_TagBase+135) +#define AHIDB_Inputs (AHI_TagBase+136) +#define AHIDB_InputArg (AHI_TagBase+137) /* ti_Data is input index */ +#define AHIDB_Input (AHI_TagBase+138) +#define AHIDB_Outputs (AHI_TagBase+139) +#define AHIDB_OutputArg (AHI_TagBase+140) /* ti_Data is input index */ +#define AHIDB_Output (AHI_TagBase+141) +/* --- New for V4, they will be ignored by V2 and earlier --- */ +#define AHIDB_Data (AHI_TagBaseR+142) /* Private! */ +#define AHIDB_DriverBaseName (AHI_TagBaseR+143) /* Private! */ +/* --- New for V6, they will be ignored by V4 and earlier --- */ +#define AHIDB_MultiChannel (AHI_TagBase+144) /* Boolean */ + + /* AHI_BestAudioIDA tags */ +/* --- New for V4, they will be ignored by V2 and earlier --- */ +#define AHIB_Dizzy (AHI_TagBase+190) + + /* AHI_AudioRequestA tags */ + /* Window control */ +#define AHIR_Window (AHI_TagBase+200) /* Parent window */ +#define AHIR_Screen (AHI_TagBase+201) /* Screen to open on if no window */ +#define AHIR_PubScreenName (AHI_TagBase+202) /* Name of public screen */ +#define AHIR_PrivateIDCMP (AHI_TagBase+203) /* Allocate private IDCMP? */ +#define AHIR_IntuiMsgFunc (AHI_TagBase+204) /* Function to handle IntuiMessages */ +#define AHIR_SleepWindow (AHI_TagBase+205) /* Block input in AHIR_Window? */ +#define AHIR_ObsoleteUserData (AHI_TagBase+206) /* V4 UserData */ +#define AHIR_UserData (AHI_TagBase+207) /* What to put in ahiam_UserData (V6) */ + /* Text display */ +#define AHIR_TextAttr (AHI_TagBase+220) /* Text font to use for gadget text */ +#define AHIR_Locale (AHI_TagBase+221) /* Locale to use for text */ +#define AHIR_TitleText (AHI_TagBase+222) /* Title of requester */ +#define AHIR_PositiveText (AHI_TagBase+223) /* Positive gadget text */ +#define AHIR_NegativeText (AHI_TagBase+224) /* Negative gadget text */ + /* Initial settings */ +#define AHIR_InitialLeftEdge (AHI_TagBase+240) /* Initial requester coordinates */ +#define AHIR_InitialTopEdge (AHI_TagBase+241) +#define AHIR_InitialWidth (AHI_TagBase+242) /* Initial requester dimensions */ +#define AHIR_InitialHeight (AHI_TagBase+243) +#define AHIR_InitialAudioID (AHI_TagBase+244) /* Initial audio mode id */ +#define AHIR_InitialMixFreq (AHI_TagBase+245) /* Initial mixing/sampling frequency */ +#define AHIR_InitialInfoOpened (AHI_TagBase+246) /* Info window initially opened? */ +#define AHIR_InitialInfoLeftEdge (AHI_TagBase+247) /* Initial Info window coords. */ +#define AHIR_InitialInfoTopEdge (AHI_TagBase+248) +#define AHIR_InitialInfoWidth (AHI_TagBase+249) /* Not used! */ +#define AHIR_InitialInfoHeight (AHI_TagBase+250) /* Not used! */ + /* Options */ +#define AHIR_DoMixFreq (AHI_TagBase+260) /* Allow selection of mixing frequency? */ +#define AHIR_DoDefaultMode (AHI_TagBase+261) /* Allow selection of default mode? (V4) */ + /* Filtering */ +#define AHIR_FilterTags (AHI_TagBase+270) /* Pointer to filter taglist */ +#define AHIR_FilterFunc (AHI_TagBase+271) /* Function to filter mode id's */ + +/* Sound Types */ +#define AHIST_NOTYPE (~0UL) /* Private */ +#define AHIST_SAMPLE (0UL) /* 8 or 16 bit sample */ +#define AHIST_DYNAMICSAMPLE (1UL) /* Dynamic sample */ +#define AHIST_INPUT (1UL<<29) /* The input from your sampler */ +#define AHIST_BW (1UL<<30) /* Private */ + + /* Sample types */ +/* Note that only AHIST_M8S, AHIST_S8S, AHIST_M16S and AHIST_S16S + (plus AHIST_M32S, AHIST_S32S and AHIST_L7_1 in V6) + are supported by AHI_LoadSound(). */ +#define AHIST_M8S (0UL) /* Mono, 8 bit signed (BYTE) */ +#define AHIST_M16S (1UL) /* Mono, 16 bit signed (WORD) */ +#define AHIST_S8S (2UL) /* Stereo, 8 bit signed (2×BYTE) */ +#define AHIST_S16S (3UL) /* Stereo, 16 bit signed (2×WORD) */ +#define AHIST_M32S (8UL) /* Mono, 32 bit signed (LONG) */ +#define AHIST_S32S (10UL) /* Stereo, 32 bit signed (2×LONG) */ + +#define AHIST_M8U (4UL) /* OBSOLETE! */ +#define AHIST_L7_1 (0x00c3000aUL) /* 7.1, 32 bit signed (8×LONG) */ + + /* Error codes */ +#define AHIE_OK (0UL) /* No error */ +#define AHIE_NOMEM (1UL) /* Out of memory */ +#define AHIE_BADSOUNDTYPE (2UL) /* Unknown sound type */ +#define AHIE_BADSAMPLETYPE (3UL) /* Unknown/unsupported sample type */ +#define AHIE_ABORTED (4UL) /* User-triggered abortion */ +#define AHIE_UNKNOWN (5UL) /* Error, but unknown */ +#define AHIE_HALFDUPLEX (6UL) /* CMD_WRITE/CMD_READ failure */ + +struct dssample { + int num; + int ch, chout; + int bitspersample; + int bitspersampleout; + int bytespersample; + int bytespersampleout; + uae_u32 addr; + uae_u32 len; + uae_u32 type; + int streaming; + int channel; +}; + +struct dschannel { + int frequency; + int volume; + int panning; + struct dssample *ds; + LPDIRECTSOUNDBUFFER8 dsb; + LPDIRECTSOUNDBUFFER8 dsbback; +}; + +struct DSAHI { + uae_u32 audioctrl; + uae_u32 audioid; + int output; + int mixfreq; + int channels; + int sounds; + uae_u32 soundfunc; + uae_u32 playerfunc; + int playerfreq; + int minplayerfreq; + int maxplayerfreq; + uae_u32 recordfunc; + uae_u32 userdata; + int anticlicksamples; + int enabledisable; + struct dssample *sample; + struct dschannel *channel; + int playing, recording; + evt evttime; + volatile int thread; + HANDLE threadevent; + CRITICAL_SECTION cs; + uae_u32 signalchannelmask; +}; + +static struct DSAHI dsahi[1]; + +#define GETAHI (&dsahi[get_long(get_long(audioctrl + ahiac_DriverData) + pub_Index)]) +#define GETSAMPLE (dsahip && sound >= 0 && sound < UAE_MAXSOUNDS ? &dsahip->sample[sound] : NULL) +#define GETCHANNEL (dsahip && channel >= 0 && channel < UAE_MAXCHANNELS ? &dsahip->channel[channel] : NULL) + +static int default_freq = 44100; +static int cansurround; +static uae_u32 xahi_author, xahi_copyright, xahi_version, xahi_output[MAX_SOUND_DEVICES], xahi_output_num; +static int ahi_paused; +static int ahi_active; + +#define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */ +#define TAG_IGNORE (1L) /* ignore this item, not end of array */ +#define TAG_MORE (2L) /* ti_Data is pointer to another array of TagItems */ +#define TAG_SKIP (3L) /* skip this and the next ti_Data items */ +#define TAG_USER ((uae_u32)(1L << 31)) + +static uae_u32 gettag (uae_u32 *tagpp, uae_u32 *datap) +{ + uae_u32 tagp = *tagpp; + for (;;) { + uae_u32 tag = get_long (tagp); + uae_u32 data = get_long (tagp + 4); + switch (tag) + { + case TAG_DONE: + return 0; + case TAG_IGNORE: + tagp += 8; + break; + case TAG_MORE: + tagp = data; + break; + case TAG_SKIP: + tagp += data * 8; + break; + default: + tagp += 8; + *tagpp = tagp; + *datap = data; + return tag; + } + } +} + + +static int sendsignal (struct DSAHI *dsahip) +{ + uae_u32 audioctrl = dsahip->audioctrl; + uae_u32 puaebase = get_long (audioctrl + ahiac_DriverData); + uae_u32 task, signalmask; + uae_s16 taskmode = get_word (puaebase + pub_TaskMode); + task = get_long (puaebase + pub_FuncTask); + signalmask = get_long (puaebase + pub_WaitMask); + + if (!dsahip->playing || ahi_paused) + return 0; + if (taskmode <= 0) + return 0; + if (dsahip->enabledisable) + return 0; + uae_Signal (task, signalmask); + return 1; +} + +static void setchannelevent (struct DSAHI *dsahip, struct dschannel *dc) +{ + uae_u32 audioctrl = dsahip->audioctrl; + uae_u32 puaebase = get_long (audioctrl + ahiac_DriverData); + int ch = dc - &dsahip->channel[0]; + + if (!dsahip->playing || ahi_paused || dc->ds == NULL || dc->ds->ready <= 0) + return; + //write_log ("AHI: channel signal %d\n", ch); + put_long (puaebase + pub_ChannelSignal, get_long (puaebase + pub_ChannelSignal) | (1 << ch)); + sendsignal (dsahip); +} + +static void evtfunc (uae_u32 v) +{ + if (ahi_active) { + struct DSAHI *dsahip = &dsahi[v]; + uae_u32 audioctrl = dsahip->audioctrl; + uae_u32 puaebase = get_long (audioctrl + ahiac_DriverData); + + put_word (puaebase + pub_FuncMode, get_word (puaebase + pub_FuncMode) | 1); + if (sendsignal (dsahip)) + event2_newevent2 (dsahip->evttime, v, evtfunc); + else + dsahip->evttime = 0; + } +} + +static void setevent (struct DSAHI *dsahip) +{ + uae_u32 audioctrl = dsahip->audioctrl; + uae_u32 freq = get_long (audioctrl + ahiac_PlayerFreq); + double f; + uae_u32 cycles; + evt t; + + f = ((double)(freq >> 16)) + ((double)(freq & 0xffff)) / 65536.0; + write_log ("AHI: playerfunc freq = %.2fHz\n", f); + if (f < 1) + return; + cycles = maxhpos * maxvpos * vblank_hz; + t = (evt)(cycles / f); + if (dsahip->evttime == t) + return; + dsahip->evttime = t; + if (t < 10) + return; + event2_newevent2 (t, dsahip - &dsahi[0], evtfunc); +} + + + +static LPDIRECTSOUND8 lpDS; +const static GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010, + {0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}; +#define KSAUDIO_SPEAKER_QUAD_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ + SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) + +static void ds_freebuffer (struct DSAHI *ahidsp, struct dssample *ds) +{ + if (!ds) + return; + if (ds->dsb) + IDirectSoundBuffer8_Release (ds->dsb); + if (ds->dsbback) + IDirectSoundBuffer8_Release (ds->dsbback); + if (ds->dsnotify) + IDirectSoundNotify_Release (ds->dsnotify); + if (ds->notifyevent) + CloseHandle (ds->notifyevent); + memset (ds, 0, sizeof (struct dssample)); + ds->channel = -1; +} + +static void ds_free (struct DSAHI *dsahip) +{ + int i; + + for (i = 0; i < dsahip->sounds; i++) { + struct dssample *ds = &dsahip->sample[i]; + ds_freebuffer (dsahip, ds); + } + if (lpDS) + IDirectSound_Release (lpDS); + lpDS = NULL; + if (dsahip->thread) { + dsahip->thread = -1; + SetEvent (dsahip->threadevent); + while (dsahip->thread) + Sleep (2); + } + DeleteCriticalSection (&dsahip->cs); + if (ahi_debug) + write_log ("AHI: DSOUND freed\n"); +} + +static unsigned __stdcall waitthread (void *f) +{ + struct DSAHI *dsahip = f; + + dsahip->thread = 1; + if (ahi_debug) + write_log ("AHI: waitthread() started\n"); + while (dsahip->thread > 0) { + HANDLE handles[UAE_MAXCHANNELS + 1]; + struct dssample *dss[UAE_MAXCHANNELS + 1]; + DWORD ob; + int maxnum = UAE_MAXCHANNELS + 1; + int num = 0; + int i; + + EnterCriticalSection (&dsahip->cs); + handles[num++] = dsahip->threadevent; + if (dsahip->playing) { + for (i = 0; i < UAE_MAXSOUNDS && num < maxnum; i++) { + struct dssample *ds = &dsahip->sample[i]; + if (ds->channel >= 0 && ds->notifyevent) { + handles[num] = ds->notifyevent; + dss[num] = ds; + num++; + } + } + } + LeaveCriticalSection (&dsahip->cs); + //write_log ("AHI: WFMO %d\n", num); + ob = WaitForMultipleObjects (num, handles, FALSE, INFINITE); + EnterCriticalSection (&dsahip->cs); + if (ob >= WAIT_OBJECT_0 + 1 && ob < WAIT_OBJECT_0 + num) { + int ch; + struct dssample *ds; + ob -= WAIT_OBJECT_0; + ds = dss[ob]; + if (ds->notloopingyet) { + ds->notloopingyet = 0; + } else { + ch = ds->channel; + dsahip->signalchannelmask |= 1 << ch; + } + } + LeaveCriticalSection (&dsahip->cs); + } + if (ahi_debug) + write_log ("AHI: waitthread() killed\n"); + dsahip->thread = 0; + return 0; +} + +DWORD fillsupportedmodes (LPDIRECTSOUND8 lpDS, int freq, struct dsaudiomodes *dsam); +static struct dsaudiomodes supportedmodes[16]; + +static int ds_init (struct DSAHI *dsahip) +{ + unsigned int ta; + int freq = 48000; + DSCAPS DSCaps; + HRESULT hr; + DWORD speakerconfig; + + InitializeCriticalSection (&dsahip->cs); + + hr = DirectSoundCreate8 (&sound_devices[dsahip->output].guid, &lpDS, NULL); + if (FAILED (hr)) { + write_log ("AHI: DirectSoundCreate8() failure: %s\n", DXError (hr)); + return 0; + } + + hr = IDirectSound_SetCooperativeLevel (lpDS, hMainWnd, DSSCL_PRIORITY); + if (FAILED (hr)) { + write_log ("AHI: Can't set cooperativelevel: %s\n", DXError (hr)); + goto error; + } + + fillsupportedmodes (lpDS, default_freq, supportedmodes); + if (SUCCEEDED (IDirectSound8_GetSpeakerConfig (lpDS, &speakerconfig))) { + if (speakerconfig > DSSPEAKER_STEREO) + cansurround = 1; + } + + memset (&DSCaps, 0, sizeof (DSCaps)); + DSCaps.dwSize = sizeof (DSCaps); + hr = IDirectSound_GetCaps (lpDS, &DSCaps); + if (FAILED(hr)) { + write_log ("AHI: Error getting DirectSound capabilities: %s\n", DXError (hr)); + goto error; + } + if (DSCaps.dwFlags & DSCAPS_EMULDRIVER) { + write_log ("AHI: Emulated DirectSound driver detected, don't complain if sound quality is crap :)\n"); + } + if (DSCaps.dwFlags & DSCAPS_CONTINUOUSRATE) { + int minfreq = DSCaps.dwMinSecondarySampleRate; + int maxfreq = DSCaps.dwMaxSecondarySampleRate; + if (minfreq > freq && freq < 22050) { + freq = minfreq; + write_log ("AHI: minimum supported frequency: %d\n", minfreq); + } + if (maxfreq < freq && freq > 44100) { + freq = maxfreq; + write_log ("AHI: maximum supported frequency: %d\n", maxfreq); + } + } + + dsahip->thread = -1; + dsahip->threadevent = CreateEvent (NULL, FALSE, FALSE, NULL); + _beginthreadex (NULL, 0, waitthread, dsahip, 0, &ta); + + if (ahi_debug) + write_log ("AHI: DSOUND initialized\n"); + + return 1; +error: + if (ahi_debug) + write_log ("AHI: DSOUND initialization failed\n"); + ds_free (dsahip); + return 0; +} + +static void ds_play (struct DSAHI *dsahip, struct dssample *ds) +{ + HRESULT hr; + DWORD status; + + if (ahi_debug) + write_log ("AHI: ds_play(%d)\n", ds->num); + hr = IDirectSoundBuffer8_GetStatus (ds->dsb, &status); + if (FAILED (hr)) + write_log ("AHI: IDirectSoundBuffer8_GetStatus() failed, %s\n", DXError (hr)); + hr = IDirectSoundBuffer8_Play (ds->dsb, 0, 0, DSBPLAY_LOOPING); + if (FAILED (hr)) + write_log ("AHI: IDirectSoundBuffer8_Play() failed, %s\n", DXError (hr)); + if (ds->dsbback) { + hr = IDirectSoundBuffer8_Play (ds->dsbback, 0, 0, DSBPLAY_LOOPING); + if (FAILED (hr)) + write_log ("AHI: IDirectSoundBuffer8_PlayBack() failed, %s\n", DXError (hr)); + } + ds->notloopingyet = 1; + SetEvent (dsahip->threadevent); + ds->ready = -1; +} + +static void ds_initsound (struct dssample *ds) +{ + HRESULT hr; + + hr = IDirectSoundBuffer_SetPan (ds->dsb, DSBPAN_CENTER); + hr = IDirectSoundBuffer_SetVolume (ds->dsb, DSBVOLUME_MIN); + if (ds->dsbback) { + hr = IDirectSoundBuffer_SetPan (ds->dsbback, DSBPAN_CENTER); + hr = IDirectSoundBuffer_SetVolume (ds->dsbback, DSBVOLUME_MIN); + } +} + +static void ds_setvolume (struct dssample *ds, int volume, int panning) +{ + HRESULT hr; + LONG vol, pan; + + // weird AHI features: + // negative pan = output from surround speakers! + // negative volume = invert sample data!! (not yet emulated) + vol = (LONG)((DSBVOLUME_MIN / 2) + (-DSBVOLUME_MIN / 2) * log (1 + (2.718281828 - 1) * (abs (volume) / 65536.0))); + pan = (abs (panning) - 0x8000) * DSBPAN_RIGHT / 32768; + write_log ("%d %d\n", vol, pan); + if (panning >= 0 || ds->chout <= 2) { + hr = IDirectSoundBuffer_SetPan (ds->dsb, pan); + if (FAILED (hr)) + write_log ("AHI: SetPan(%d,%d) failed: %s\n", ds->num, pan, DXError (hr)); + hr = IDirectSoundBuffer_SetVolume (ds->dsb, vol); + if (FAILED (hr)) + write_log ("AHI: SetVolume(%d,%d) failed: %s\n", ds->num, vol, DXError (hr)); + if (ds->dsbback) { + hr = IDirectSoundBuffer_SetVolume (ds->dsbback, DSBVOLUME_MIN); + if (FAILED (hr)) + write_log ("AHI: muteback %d: %s\n", ds->num, DXError (hr)); + } + } else { + hr = IDirectSoundBuffer_SetVolume (ds->dsb, DSBVOLUME_MIN); + if (FAILED (hr)) + write_log ("AHI: mutefront %d: %s\n", ds->num, DXError (hr)); + if (ds->dsbback) { + hr = IDirectSoundBuffer_SetPan (ds->dsbback, pan); + if (FAILED (hr)) + write_log ("AHI: SetPanBack(%d,%d) failed: %s\n", ds->num, pan, DXError (hr)); + hr = IDirectSoundBuffer_SetVolume (ds->dsbback, vol); + if (FAILED (hr)) + write_log ("AHI: SetVolumeBack(%d,%d) failed: %s\n", ds->num, vol, DXError (hr)); + } + } + ds->volume = volume; + ds->panning = panning; +} + +static void ds_setfreq (struct DSAHI *dsahip, struct dssample *ds, int frequency) +{ + HRESULT hr; + + if (frequency == 0) { + hr = IDirectSoundBuffer8_Stop (ds->dsb); + if (ds->dsbback) + hr = IDirectSoundBuffer8_Stop (ds->dsbback); + } else if (ds->frequency != frequency) { + hr = IDirectSoundBuffer8_SetFrequency (ds->dsb, frequency); + if (FAILED (hr)) + write_log ("AHI: SetFrequency(%d,%d) failed: %s\n", ds->num, frequency, DXError (hr)); + if (ds->dsbback) { + hr = IDirectSoundBuffer8_SetFrequency (ds->dsbback, frequency); + if (FAILED (hr)) + write_log ("AHI: SetFrequencyBack(%d,%d) failed: %s\n", ds->num, frequency, DXError (hr)); + } + if (ds->frequency == 0) + ds_play (dsahip, ds); + } + ds->frequency = frequency; +} + +#define US(x) ((x)) + +static void copysampledata (struct dssample *ds, void *srcp, void *dstp, int dstsize, int offset, int srcsize) +{ + int i, j; + uae_u8 *src = (uae_u8*)srcp; + uae_u8 *dst = (uae_u8*)dstp; + int och = ds->chout; + int ich = ds->ch; + + src += offset * ds->ch * ds->bytespersample; + if (dstsize < srcsize) + srcsize = dstsize; + + switch (ds->type) + { + case AHIST_M8S: + for (i = 0; i < srcsize; i++) { + dst[i * 4 + 0] = US (src[i]); + dst[i * 4 + 1] = US (src[i]); + dst[i * 4 + 2] = US (src[i]); + dst[i * 4 + 3] = US (src[i]); + } + break; + case AHIST_S8S: + for (i = 0; i < srcsize; i++) { + dst[i * 4 + 0] = src[i * 2 + 0]; + dst[i * 4 + 1] = src[i * 2 + 0]; + dst[i * 4 + 2] = src[i * 2 + 1]; + dst[i * 4 + 3] = src[i * 2 + 1]; + } + break; + case AHIST_M16S: + for (i = 0; i < srcsize; i++) { + dst[i * 4 + 0] = src[i * 2 + 1]; + dst[i * 4 + 1] = src[i * 2 + 0]; + dst[i * 4 + 2] = src[i * 2 + 1]; + dst[i * 4 + 3] = src[i * 2 + 0]; + } + break; + case AHIST_S16S: + for (i = 0; i < srcsize; i++) { + dst[i * 4 + 0] = src[i * 4 + 1]; + dst[i * 4 + 1] = src[i * 4 + 0]; + dst[i * 4 + 2] = src[i * 4 + 3]; + dst[i * 4 + 3] = src[i * 4 + 2]; + } + break; + case AHIST_M32S: + for (i = 0; i < srcsize; i++) { + dst[i * 4 + 0] = src[i * 4 + 3]; + dst[i * 4 + 1] = src[i * 4 + 2]; + dst[i * 4 + 2] = src[i * 4 + 3]; + dst[i * 4 + 3] = src[i * 4 + 2]; + } + break; + case AHIST_S32S: + for (i = 0; i < srcsize; i++) { + dst[i * 4 + 0] = src[i * 8 + 3]; + dst[i * 4 + 1] = src[i * 8 + 2]; + dst[i * 4 + 2] = src[i * 8 + 7]; + dst[i * 4 + 3] = src[i * 8 + 6]; + } + break; + case AHIST_L7_1: + if (ds->chout == 8) { + for (i = 0; i < srcsize; i++) { + for (j = 0; j < 8; j++) { + dst[j * 4 + 0] = src[j * 4 + 2]; + dst[j * 4 + 1] = src[j * 4 + 1]; + dst[j * 4 + 2] = src[j * 4 + 0]; + dst[j * 4 + 3] = 0; + } + dst += 4 * 8; + src += 4 * 8; + } + } else { /* 7.1 -> 5.1 */ + for (i = 0; i < srcsize; i++) { + for (j = 0; j < 6; j++) { + dst[j * 4 + 0] = src[j * 4 + 2]; + dst[j * 4 + 1] = src[j * 4 + 1]; + dst[j * 4 + 2] = src[j * 4 + 0]; + dst[j * 4 + 3] = 0; + } + dst += 4 * 8; + src += 4 * 8; + } + } + break; + } +} + +static void clearsample (struct dssample *ds, LPDIRECTSOUNDBUFFER8 dsb, int dstlength) +{ + HRESULT hr; + void *buffer1; + DWORD size1, outlen; + + if (!dsb) + return; + outlen = dstlength * ds->bytespersampleout * ds->chout; + hr = IDirectSoundBuffer8_Lock (dsb, 0, outlen, &buffer1, &size1, NULL, NULL, 0); + if (hr == DSERR_BUFFERLOST) { + IDirectSoundBuffer_Restore (dsb); + hr = IDirectSoundBuffer8_Lock (dsb, 0, outlen, &buffer1, &size1, NULL, NULL, 0); + } + if (FAILED (hr)) + return; + memset (buffer1, 0, size1); + IDirectSoundBuffer8_Unlock (dsb, buffer1, size1, NULL, 0); +} + +static void copysample (struct dssample *ds, LPDIRECTSOUNDBUFFER8 dsb, int dstoffset, int dstlength, uae_u32 srcoffset, uae_u32 srclength) +{ + HRESULT hr; + void *buffer1, *buffer2; + DWORD size1, size2, outoffset, outlen; + uae_u32 addr; + + if (!dsb) + return; + outlen = dstlength * ds->bytespersampleout * ds->chout; + outoffset = dstoffset * ds->bytespersampleout * ds->chout; + hr = IDirectSoundBuffer8_Lock (dsb, outoffset, outlen, &buffer1, &size1, &buffer2, &size2, 0); + if (hr == DSERR_BUFFERLOST) { + IDirectSoundBuffer_Restore (dsb); + hr = IDirectSoundBuffer8_Lock (dsb, outoffset, outlen, &buffer1, &size1, &buffer2, &size2, 0); + } + if (FAILED (hr)) + return; + if (ds->addr == 0 && ds->len == 0xffffffff) + addr = srcoffset; + else + addr = ds->addr; + if (valid_address (addr + srcoffset * ds->ch * ds->bytespersample, srclength * ds->ch * ds->bytespersample)) { + uae_u8 *naddr = get_real_address (addr); + int part1 = size1 / (ds->bytespersampleout * ds->chout); + int part2 = size2 / (ds->bytespersampleout * ds->chout); + copysampledata (ds, naddr, buffer1, part1, srcoffset, srclength); + srcoffset += part1; + srclength -= part1; + if (srclength != 0) + copysampledata (ds, naddr, buffer2, part2, srcoffset, srclength); + } + IDirectSoundBuffer8_Unlock (dsb, buffer1, size1, buffer2, size2); +} + +void ahi_hsync (void) +{ + struct DSAHI *dsahip = &dsahi[0]; + uae_u32 audioctrl = dsahip->audioctrl; + uae_u32 puaebase = get_long (audioctrl + ahiac_DriverData); + + if (dsahip->signalchannelmask) { + EnterCriticalSection (&dsahip->cs); + if (dsahip->playing && !ahi_paused) { + write_log ("AHI: channel signal %08x\n", dsahip->signalchannelmask); + put_long (puaebase + pub_ChannelSignal, get_long (puaebase + pub_ChannelSignal) | dsahip->signalchannelmask); + sendsignal (dsahip); + } + dsahip->signalchannelmask = 0; + LeaveCriticalSection (&dsahip->cs); + } +} + +void ahi_vsync (void) +{ + struct DSAHI *dsahip = &dsahi[0]; + int i; + + if (!dsahip->playing || ahi_paused) + return; + return; + for (i = 0; i < UAE_MAXCHANNELS; i++) { + HRESULT hr; + DWORD playc, writec; + struct dssample *ds = dsahip->channel[i].ds; + + if (ds == NULL) + continue; + if (ds->type != AHIST_DYNAMICSAMPLE) + continue; + hr = IDirectSoundBuffer8_GetCurrentPosition (ds->dsb, &playc, &writec); + if (FAILED (hr)) { + write_log ("AHI: GetCurrentPosition(%d) failed, %s\n", ds->channel, DXError (hr)); + continue; + } + write_log ("AHI: ch=%d writec=%d\n", ds->channel, writec / (ds->bytespersampleout * ds->chout)); + copysample (ds, ds->dsb, + writec / (ds->bytespersampleout * ds->chout), + ds->len - 1000, + writec / (ds->bytespersampleout * ds->chout), + ds->len - 1000); + } +} + +static void ds_stop (struct dssample *ds) +{ + HRESULT hr; + + if (!ds->ready) + return; + if (ahi_debug) + write_log ("AHI: ds_stop(%d)\n", ds->num); + hr = IDirectSoundBuffer8_Stop (ds->dsb); + if (FAILED (hr)) + write_log ("AHI: IDirectSoundBuffer8_Stop() failed, %s\n", DXError (hr)); + if (ds->dsbback) { + hr = IDirectSoundBuffer8_Stop (ds->dsbback); + if (FAILED (hr)) + write_log ("AHI: IDirectSoundBuffer8_StopBack() failed, %s\n", DXError (hr)); + } + ds->ready = 1; +} + +void ahi2_pause_sound (int paused) +{ + int i; + struct DSAHI *dsahip = &dsahi[0]; + + ahi_paused = paused; + if (!dsahip->playing && !dsahip->recording) + return; + for (i = 0; i < UAE_MAXCHANNELS; i++) { + struct dssample *ds = dsahip->channel[i].ds; + if (ds == NULL) + continue; + if (paused) { + ds_stop (ds); + } else { + ds_play (dsahip, ds); + } + } +} + +static void ds_setsound (struct DSAHI *dsahip, struct dssample *ds, struct dschannel *dc, int offset, int length) +{ + HRESULT hr; + + ds_setvolume (ds, dc->volume, dc->panning); + ds_setfreq (dsahip, ds, dc->frequency); + clearsample (ds, ds->dsb, ds->len); + clearsample (ds, ds->dsbback, ds->len); + copysample (ds, ds->dsb, 0, ds->len, offset, length); + copysample (ds, ds->dsbback, 0, ds->len, offset, length); + hr = IDirectSoundBuffer8_SetCurrentPosition (ds->dsb, 0); + if (FAILED (hr)) + write_log ("AHI: IDirectSoundBuffer8_SetCurrentPosition() failed, %s\n", DXError (hr)); + if (ds->dsbback) { + hr = IDirectSoundBuffer8_SetCurrentPosition (ds->dsbback, 0); + if (FAILED (hr)) + write_log ("AHI: IDirectSoundBuffer8_SetCurrentPositionBack() failed, %s\n", DXError (hr)); + } +} + +static int ds_allocbuffer (struct DSAHI *ahidsp, struct dssample *ds, int type, uae_u32 len) +{ + HRESULT hr; + DSBUFFERDESC dd; + WAVEFORMATEXTENSIBLE wavfmt; + LPDIRECTSOUNDBUFFER pdsb; + LPDIRECTSOUNDBUFFER8 pdsb8; + int round, chround; + int channels[] = { 2, 4, 6, 8 }; + int ch, chout, bps, bpsout; + DSBPOSITIONNOTIFY pn[1]; + + if (!ds) + return 0; + switch (type) + { + case AHIST_M8S: + case AHIST_M16S: + case AHIST_M32S: + ch = 1; + break; + case AHIST_S8S: + case AHIST_S16S: + case AHIST_S32S: + ch = 2; + break; + case AHIST_L7_1: + ch = 8; + channels[0] = 6; + channels[1] = 8; + channels[2] = 0; + break; + default: + return 0; + } + switch (type) + { + case AHIST_M8S: + case AHIST_S8S: + bps = 8; + break; + case AHIST_M16S: + case AHIST_S16S: + bps = 16; + break; + case AHIST_M32S: + case AHIST_S32S: + case AHIST_L7_1: + bps = 24; + break; + default: + return 0; + } + if (ahi_debug) + write_log ("AHI: AllocBuffer ch=%d,bps=%d\n", ch, bps); + + pdsb = NULL; + bpsout = 16; + for (chround = 0; channels[chround]; chround++) { + chout = channels[chround]; + for (round = 0; supportedmodes[round].ch; round++) { + DWORD ksmode = 0; + + pdsb = NULL; + if (supportedmodes[round].ch != chout) + continue; + + memset (&wavfmt, 0, sizeof (WAVEFORMATEXTENSIBLE)); + wavfmt.Format.nChannels = chout; + wavfmt.Format.nSamplesPerSec = default_freq; + wavfmt.Format.wBitsPerSample = bpsout; + if (chout <= 2) { + wavfmt.Format.wFormatTag = WAVE_FORMAT_PCM; + } else { + DWORD ksmode = 0; + wavfmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + wavfmt.Format.cbSize = sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX); + wavfmt.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + wavfmt.Samples.wValidBitsPerSample = bpsout; + wavfmt.dwChannelMask = supportedmodes[round].ksmode; + } + wavfmt.Format.nBlockAlign = bpsout / 8 * wavfmt.Format.nChannels; + wavfmt.Format.nAvgBytesPerSec = wavfmt.Format.nBlockAlign * wavfmt.Format.nSamplesPerSec; + + memset (&dd, 0, sizeof dd); + dd.dwSize = sizeof dd; + dd.dwBufferBytes = len * bpsout / 8 * chout; + dd.lpwfxFormat = &wavfmt.Format; + dd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY; + dd.dwFlags |= DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; + dd.dwFlags |= chout >= 4 ? DSBCAPS_LOCHARDWARE : DSBCAPS_LOCSOFTWARE; + dd.guid3DAlgorithm = GUID_NULL; + + hr = IDirectSound_CreateSoundBuffer (lpDS, &dd, &pdsb, NULL); + if (SUCCEEDED (hr)) + break; + if (dd.dwFlags & DSBCAPS_LOCHARDWARE) { + HRESULT hr2 = hr; + dd.dwFlags &= ~DSBCAPS_LOCHARDWARE; + dd.dwFlags |= DSBCAPS_LOCSOFTWARE; + hr = IDirectSound_CreateSoundBuffer (lpDS, &dd, &pdsb, NULL); + if (SUCCEEDED (hr)) { + write_log ("AHI: Couldn't use hardware buffer (switched to software): %s\n", DXError (hr2)); + break; + } + } + write_log ("AHI: DS sound buffer failed (ch=%d,bps=%d): %s\n", + chout, bpsout, DXError (hr)); + } + if (pdsb) + break; + } + if (pdsb == NULL) + goto error; + + hr = IDirectSound_QueryInterface (pdsb, &IID_IDirectSoundBuffer8, (LPVOID*)&pdsb8); + if (FAILED (hr)) { + write_log ("AHI: Secondary QueryInterface(IID_IDirectSoundBuffer8) failure: %s\n", DXError (hr)); + goto error; + } + + IDirectSound_Release (pdsb); + ds->dsb = pdsb8; + + hr = IDirectSoundBuffer8_QueryInterface (pdsb, &IID_IDirectSoundNotify8, (void**)&ds->dsnotify); + if (FAILED (hr)) { + write_log ("AHI: Secondary QueryInterface(IID_IDirectSoundNotify8) failure: %s\n", DXError (hr)); + goto error; + } + ds->notifyevent = CreateEvent (NULL, FALSE, FALSE, NULL); + pn[0].dwOffset = 0; + pn[0].hEventNotify = ds->notifyevent; + hr = IDirectSoundNotify_SetNotificationPositions (ds->dsnotify, 1, pn); + if (FAILED (hr)) { + write_log ("AHI: Secondary SetNotificationPositions() failure: %s\n", DXError (hr)); + goto error; + } + + + if (chout > 2) { + // create "surround" sound buffer + hr = IDirectSound_CreateSoundBuffer (lpDS, &dd, &pdsb, NULL); + if (SUCCEEDED (hr)) { + hr = IDirectSound_QueryInterface (pdsb, &IID_IDirectSoundBuffer8, (LPVOID*)&pdsb8); + if (SUCCEEDED (hr)) + ds->dsbback = pdsb8; + IDirectSound_Release (pdsb); + } + } + + ds_initsound (ds); + + ds->bitspersample = bps; + ds->bitspersampleout = bpsout; + ds->ch = ch; + ds->chout = chout; + ds->bytespersample = bps / 8; + ds->bytespersampleout = bpsout / 8; + + SetEvent (ahidsp->threadevent); + + return 1; + +error: + return 0; +} + +static uae_u32 init (TrapContext *ctx) +{ + int num, i; + + num = enumerate_sound_devices (); + xahi_author = ds ("Toni Wilen"); + xahi_copyright = ds ("GPL"); + xahi_version = ds ("uae2 0.1 (xx.xx.2008)\r\n"); + for (i = 0; i < num; i++) + xahi_output[i] = ds (sound_devices[i].name); + xahi_output_num = num; + return 1; +} + +static uae_u32 AHIsub_AllocAudio (TrapContext *ctx) +{ + int i; + uae_u32 tags = m68k_areg (&ctx->regs, 1); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + uae_u32 pbase = get_long (audioctrl + ahiac_DriverData); + uae_u32 tag, data, v; + uae_u32 ret = AHISF_KNOWSTEREO | AHISF_KNOWHIFI; + struct DSAHI *dsahip = &dsahi[0]; + + if (ahi_debug) + write_log ("AHI: AllocAudio(%08x,%08x)\n", tags, audioctrl); + + v = get_long (pbase + pub_Index); + if (v != -1) { + write_log ("AHI: corrupted memory\n"); + return AHISF_ERROR; + } + put_long (pbase + pub_Index, dsahip - dsahi); + dsahip->audioctrl = audioctrl; + + if (!ds_init (dsahip)) + return AHISF_ERROR; + dsahip->sounds = UAE_MAXSOUNDS; + dsahip->channels = UAE_MAXCHANNELS; + + if (cansurround) + ret |= AHISF_KNOWMULTICHANNEL; + + while ((tag = gettag (&tags, &data))) { + if (ahi_debug) + write_log ("- TAG %08x=%d: %08x=%u\n", tag, tag & 0x7fff, data, data); + switch (tag) + { + case AHIA_Sounds: + dsahip->sounds = data; + break; + case AHIA_Channels: + dsahip->channels = data; + break; + case AHIA_SoundFunc: + dsahip->soundfunc = data; + break; + case AHIA_PlayerFunc: + dsahip->playerfunc = data; + break; + case AHIA_MinPlayerFreq: + dsahip->minplayerfreq = data; + break; + case AHIA_MaxPlayerFreq: + dsahip->maxplayerfreq = data; + break; + } + } + if (dsahip->sounds < 0 || dsahip->sounds > 1000) { + ds_free (dsahip); + return AHISF_ERROR; + } + dsahip->sample = xcalloc (sizeof (struct dssample), dsahip->sounds); + dsahip->channel = xcalloc (sizeof (struct dschannel), dsahip->channels); + for (i = 0; i < dsahip->channels; i++) { + struct dschannel *dc = &dsahip->channel[i]; + } + for (i = 0; i < dsahip->sounds; i++) { + struct dssample *ds = &dsahip->sample[i]; + ds->channel = -1; + ds->num = -1; + } + ahi_active = 1; + return ret; +} + +static void AHIsub_Disable (TrapContext *ctx) +{ + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + if (ahi_debug) + write_log ("AHI: Disable(%08x)\n", audioctrl); + dsahip->enabledisable++; +} + +static void AHIsub_Enable (TrapContext *ctx) +{ + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + if (ahi_debug) + write_log ("AHI: Enable(%08x)\n", audioctrl); + dsahip->enabledisable--; + if (dsahip->enabledisable == 0 && dsahip->playing) + setevent (dsahip); +} + +static void AHIsub_FreeAudio (TrapContext *ctx) +{ + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + uae_u32 pbase = get_long (audioctrl + ahiac_DriverData); + struct DSAHI *dsahip = GETAHI; + if (ahi_debug) + write_log ("AHI: FreeAudio(%08x)\n", audioctrl); + put_long (pbase + pub_Index, -1); + if (dsahip) { + ahi_active = 0; + ds_free (dsahip); + xfree (dsahip->channel); + xfree (dsahip->sample); + memset (dsahip, 0, sizeof (struct DSAHI)); + } +} + +static uae_u32 frequencies[] = { 48000, 44100 }; +#define MAX_FREQUENCIES (sizeof (frequencies) / sizeof (uae_u32)) + +static uae_u32 getattr2 (uae_u32 attribute, uae_u32 argument, uae_u32 def) +{ + int i; + + switch (attribute) + { + case AHIDB_Bits: + return 32; + case AHIDB_Frequencies: + return MAX_FREQUENCIES; + case AHIDB_Frequency: + if (argument < 0 || argument >= MAX_FREQUENCIES) + argument = 0; + return frequencies[argument]; + case AHIDB_Index: + if (argument <= frequencies[0]) + return 0; + if (argument >= frequencies[MAX_FREQUENCIES - 1]) + return MAX_FREQUENCIES - 1; + for (i = 1; i < MAX_FREQUENCIES; i++) { + if (frequencies[i] > argument) { + if (argument - frequencies[i - 1] < frequencies[i] - argument) + return i - 1; + else + return i; + } + } + return 0; + case AHIDB_Author: + return xahi_author; + case AHIDB_Copyright: + return xahi_copyright; + case AHIDB_Version: + return xahi_version; + case AHIDB_Record: + return TRUE; + case AHIDB_Realtime: + return TRUE; + case AHIDB_Outputs: + return xahi_output_num; + case AHIDB_MinOutputVolume: + return 0x00000; + case AHIDB_MaxOutputVolume: + return 0x10000; + case AHIDB_Output: + if (argument >= 0 && argument < xahi_output_num) + return xahi_output[argument]; + return 0; + case AHIDB_Volume: + return -1; + case AHIDB_Panning: + return -1; + case AHIDB_HiFi: + return -1; + case AHIDB_MultiChannel: + return cansurround ? -1 : 0; + case AHIDB_MaxChannels: + return UAE_MAXCHANNELS; + case AHIDB_FullDuplex: + return -1; + default: + return def; + } +} + +static uae_u32 AHIsub_GetAttr (TrapContext *ctx) +{ + uae_u32 attribute = m68k_dreg (&ctx->regs, 0); + uae_u32 argument = m68k_dreg (&ctx->regs, 1); + uae_u32 def = m68k_dreg (&ctx->regs, 2); + uae_u32 taglist = m68k_areg (&ctx->regs, 1); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + uae_u32 v; + + v = getattr2 (attribute, argument, def); + if (ahi_debug) + write_log ("AHI: GetAttr(%08x=%d,%08x,%08x)=%08x\n", attribute, (attribute & 0x7fff), argument, def, v); + + return v; +} + +static uae_u32 AHIsub_HardwareControl (TrapContext *ctx) +{ + uae_u32 attribute = m68k_dreg (&ctx->regs, 0); + uae_u32 argument = m68k_dreg (&ctx->regs, 1); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + if (ahi_debug) + write_log ("AHI: HardwareControl(%08x,%08x,%08x)\n", attribute, argument, audioctrl); + return 0; +} + +static uae_u32 AHIsub_Start (TrapContext *ctx) +{ + uae_u32 flags = m68k_dreg (&ctx->regs, 0); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + int i; + + if (ahi_debug) + write_log ("AHI: Play(%08x,%08x)\n", + flags, audioctrl); + if (flags & AHISF_PLAY) + dsahip->playing = 1; + if (flags & AHISF_RECORD) + dsahip->recording = 1; + if (dsahip->playing) { + setevent (dsahip); + for (i = 0; i < dsahip->channels; i++) { + struct dschannel *dc = &dsahip->channel[i]; + if (dc-> + if (ds->ready > 0 && ds->channel >= 0) { + struct dschannel *dc = &dsahip->channel[ds->channel]; + ds_setvolume (ds, dc->volume, dc->panning); + ds->frequency = 0; + ds_setfreq (dsahip, ds, dc->frequency); // this also starts playback + } + } + } + return 0; +} + +static uae_u32 AHIsub_Stop (TrapContext *ctx) +{ + uae_u32 flags = m68k_dreg (&ctx->regs, 0); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + int i; + + if (ahi_debug) + write_log ("AHI: Stop(%08x,%08x)\n", + flags, audioctrl); + if (flags & AHISF_PLAY) + dsahip->playing = 0; + if (flags & AHISF_RECORD) + dsahip->recording = 0; + if (!dsahip->playing) { + for (i = 0; i < dsahip->sounds; i++) { + struct dssample *ds = &dsahip->sample[i]; + if (ds->ready) + ds_stop (ds); + } + } + return 0; +} + +static uae_u32 AHIsub_Update (TrapContext *ctx) +{ + uae_u32 flags = m68k_dreg (&ctx->regs, 0); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + if (ahi_debug) + write_log ("AHI: Update(%08x,%08x)\n", flags, audioctrl); + setevent (dsahip); + return 0; +} + +static uae_u32 AHIsub_SetVol (TrapContext *ctx) +{ + int i; + uae_u16 channel = m68k_dreg (&ctx->regs, 0); + uae_u32 volume = m68k_dreg (&ctx->regs, 1); + uae_u32 pan = m68k_dreg (&ctx->regs, 2); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + uae_u32 flags = m68k_dreg (&ctx->regs, 3); + struct DSAHI *dsahip = GETAHI; + struct dschannel *dc = GETCHANNEL; + + if (ahi_debug) + write_log ("AHI: SetVol(%d,%d,%d,%08x,%08x)\n", + channel, volume, pan, audioctrl, flags); + if (dc) { + dc->volume = volume; + dc->panning = pan; + for (i = 0; i < dsahip->sounds; i++) { + struct dssample *ds = &dsahip->sample[i]; + if (ds->channel == channel) + ds_setvolume (ds, volume, pan); + } + } + return 0; +} + +static uae_u32 AHIsub_SetFreq (TrapContext *ctx) +{ + int i; + uae_u16 channel = m68k_dreg (&ctx->regs, 0); + uae_u32 frequency = m68k_dreg (&ctx->regs, 1); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + uae_u32 flags = m68k_dreg (&ctx->regs, 3); + struct DSAHI *dsahip = GETAHI; + struct dschannel *dc = GETCHANNEL; + + if (ahi_debug) + write_log ("AHI: SetFreq(%d,%d,%08x,%08x)\n", + channel, frequency, audioctrl, flags); + if (dc) { + dc->frequency = frequency; + for (i = 0; i < dsahip->sounds; i++) { + struct dssample *ds = &dsahip->sample[i]; + if (ds->channel == channel) + ds_setfreq (dsahip, ds, frequency); + } + } + return 0; +} + +static uae_u32 AHIsub_SetSound (TrapContext *ctx) +{ + int i; + uae_u16 channel = m68k_dreg (&ctx->regs, 0); + uae_u16 sound = m68k_dreg (&ctx->regs, 1); + uae_u32 offset = m68k_dreg (&ctx->regs, 2); + uae_u32 length = m68k_dreg (&ctx->regs, 3); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + uae_u32 flags = m68k_dreg (&ctx->regs, 4); + struct DSAHI *dsahip = GETAHI; + struct dssample *ds = GETSAMPLE; + struct dschannel *dc = GETCHANNEL; + + if (ahi_debug) + write_log ("AHI: SetSound(%d,%d,%08x,%d,%08x,%08x)\n", + channel, sound, offset, length, audioctrl, flags); + dc->ds = NULL; + if (sound == 0xffff) { + for (i = 0; i < dsahip->sounds; i++) { + struct dssample *ds2 = &dsahip->sample[i]; + if (ds2->channel == channel) { + ds_stop (ds2); + ds2->channel = -1; + + } + } + } else if (ds) { + length = abs (length); + if (length == 0) + length = ds->len; + ds->ready = 1; + ds->channel = channel; + dc->ds = ds; + for (i = 0; i < dsahip->sounds; i++) { + struct dssample *ds2 = &dsahip->sample[i]; + if (ds2 != ds && ds2->channel == channel) { + ds_stop (ds2); + ds2->channel = -1; + } + } + ds_setsound (dsahip, ds, dc, offset, length); + if (dsahip->playing) + ds_play (dsahip, ds); + } + return 0; +} + +static uae_u32 AHIsub_SetEffect (TrapContext *ctx) +{ + uae_u32 effect = m68k_areg (&ctx->regs, 0); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + + if (ahi_debug) + write_log ("AHI: SetEffect(%08x,%08x)\n", effect, audioctrl); + return 0; +} + +static uae_u32 AHIsub_LoadSound (TrapContext *ctx) +{ + uae_u16 sound = m68k_dreg (&ctx->regs, 0); + uae_u32 type = m68k_dreg (&ctx->regs, 1); + uae_u32 info = m68k_areg (&ctx->regs, 0); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + uae_u32 ret = AHIE_BADSOUNDTYPE; + int sampletype = get_long (info + ahisi_Type); + uae_u32 addr = get_long (info + ahisi_Address); + uae_u32 len = get_long (info + ahisi_Length); + struct dssample *ds = GETSAMPLE; + + if (ahi_debug) + write_log ("AHI: LoadSound(%d,%d,%08x,%08x,SMP=%d,ADDR=%08x,LEN=%d)\n", + sound, type, info, audioctrl, sampletype, addr, len); + + if (ds) { + ds->num = sound; + if (!cansurround && type == AHIST_L7_1) + return AHIE_BADSOUNDTYPE; + ds->addr = addr; + ds->type = type; + ds->len = len; + ds->frequency = 0; + if (ds_allocbuffer (dsahip, ds, type, len)) + ret = AHIE_OK; + } + return ret; +} + +static uae_u32 AHIsub_UnloadSound (TrapContext *ctx) +{ + uae_u16 sound = m68k_dreg (&ctx->regs, 0); + uae_u32 audioctrl = m68k_areg (&ctx->regs, 2); + struct DSAHI *dsahip = GETAHI; + struct dssample *ds = GETSAMPLE; + + if (ahi_debug) + write_log ("AHI: UnloadSound(%d,%08x)\n", + sound, audioctrl); + if (ds) + ds_freebuffer (dsahip, ds); + return AHIE_OK; +} + +static uae_u32 REGPARAM2 ahi_demux (TrapContext *ctx) +{ + uae_u32 ret = 0; + uae_u32 sp = m68k_areg (&ctx->regs, 7); + uae_u32 offset = get_long (sp + 4); + + if (0 && ahi_debug) + write_log ("AHI: %d\n", offset); + + switch (offset) + { + case 0xffffffff: + ret = init (ctx); + break; + case 0: + ret = AHIsub_AllocAudio (ctx); + break; + case 1: + AHIsub_FreeAudio (ctx); + break; + case 2: + AHIsub_Disable (ctx); + break; + case 3: + AHIsub_Enable (ctx); + break; + case 4: + ret = AHIsub_Start (ctx); + break; + case 5: + ret = AHIsub_Update (ctx); + break; + case 6: + ret = AHIsub_Stop (ctx); + break; + case 7: + ret = AHIsub_SetVol (ctx); + break; + case 8: + ret = AHIsub_SetFreq (ctx); + break; + case 9: + ret = AHIsub_SetSound (ctx); + break; + case 10: + ret = AHIsub_SetEffect (ctx); + break; + case 11: + ret = AHIsub_LoadSound (ctx); + break; + case 12: + ret = AHIsub_UnloadSound (ctx); + break; + case 13: + ret = AHIsub_GetAttr (ctx); + break; + case 14: + ret = AHIsub_HardwareControl (ctx); + break; + } + return ret; +} + +void init_ahi_v2 (void) +{ + uaecptr a = here (); + org (rtarea_base + 0xFFC8); + calltrap (deftrapres (ahi_demux, 0, "ahi_winuae_v2")); + dw (RTS); + org (a); +} + + + + +#endif diff --git a/od-win32/avioutput.c b/od-win32/avioutput.c index fb19e9fd..4f10ab47 100755 --- a/od-win32/avioutput.c +++ b/od-win32/avioutput.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "sysconfig.h" #include "sysdeps.h" @@ -94,7 +96,7 @@ static PAVISTREAM AVIAudioStream = NULL; // compressed stream pointer static HACMSTREAM has = NULL; // stream handle that can be used to perform conversions static ACMSTREAMHEADER ash; static ACMFORMATCHOOSE acmopt; -static WAVEFORMATEX wfxSrc; // source audio format +static WAVEFORMATEXTENSIBLE wfxSrc; // source audio format static LPWAVEFORMATEX pwfxDst = NULL; // pointer to destination audio format static DWORD wfxMaxFmtSize; static FILE *wavfile; @@ -114,6 +116,8 @@ static int lpbisize (void) static void freeavientry (struct avientry *ae) { + if (!ae) + return; xfree (ae->lpAudio); xfree (ae->lpVideo); xfree (ae->lpbi); @@ -132,9 +136,9 @@ static struct avientry *allocavientry_audio (uae_u8 *snd, int size) static struct avientry *allocavientry_video (void) { struct avientry *ae = xcalloc (sizeof (struct avientry), 1); - ae->lpbi = xmalloc (lpbisize()); + ae->lpbi = xmalloc (lpbisize ()); memcpy (ae->lpbi, lpbi, lpbisize ()); - ae->lpVideo = calloc(lpbi->biSizeImage, 1); + ae->lpVideo = calloc (lpbi->biSizeImage, 1); return ae; } @@ -181,18 +185,18 @@ static void waitqueuefull (void) } } -static UAEREG *openavikey(void) +static UAEREG *openavikey (void) { return regcreatetree (NULL, "AVConfiguration"); } -static void storesettings(UAEREG *avikey) +static void storesettings (UAEREG *avikey) { regsetint (avikey, "FrameLimiter", avioutput_framelimiter); regsetint (avikey, "NoSoundOutput", avioutput_nosoundoutput); regsetint (avikey, "FPS", avioutput_fps); } -static void getsettings(UAEREG *avikey) +static void getsettings (UAEREG *avikey) { DWORD val; if (regqueryint (avikey, "NoSoundOutput", &val)) @@ -205,14 +209,14 @@ static void getsettings(UAEREG *avikey) avioutput_fps = val; } -void AVIOutput_GetSettings(void) +void AVIOutput_GetSettings (void) { UAEREG *avikey = openavikey (); if (avikey) getsettings (avikey); regclosetree (avikey); } -void AVIOutput_SetSettings(void) +void AVIOutput_SetSettings (void) { UAEREG *avikey = openavikey (); if (avikey) @@ -220,27 +224,7 @@ void AVIOutput_SetSettings(void) regclosetree (avikey); } -static UINT CALLBACK acmFilterChooseHookProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if(uMsg == MM_ACM_FORMATCHOOSE) { - switch(wParam) - { - case FORMATCHOOSE_FORMATTAG_VERIFY: - switch(lParam) // remove known error prone codecs - { - case WAVE_FORMAT_ADPCM: // 0x0002 Microsoft Corporation - case WAVE_FORMAT_IMA_ADPCM: // 0x0011 Intel Corporation - case WAVE_FORMAT_GSM610: // 0x0031 Microsoft Corporation - case WAVE_FORMAT_SONY_SCX: // 0x0270 Sony Corp. - return TRUE; - } - break; - } - } - return FALSE; -} - -void AVIOutput_ReleaseAudio(void) +void AVIOutput_ReleaseAudio (void) { if (pwfxDst) { xfree (pwfxDst); @@ -253,6 +237,9 @@ static int AVIOutput_AudioAllocated (void) return pwfxDst ? 1 : 0; } +const static GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010, + {0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}; + static int AVIOutput_AllocateAudio (void) { MMRESULT err; @@ -265,13 +252,32 @@ static int AVIOutput_AllocateAudio (void) } // set the source format - wfxSrc.wFormatTag = WAVE_FORMAT_PCM; - wfxSrc.nChannels = get_audio_nativechannels (); - wfxSrc.nSamplesPerSec = workprefs.sound_freq; - wfxSrc.nBlockAlign = wfxSrc.nChannels * (workprefs.sound_bits / 8); - wfxSrc.nAvgBytesPerSec = wfxSrc.nBlockAlign * wfxSrc.nSamplesPerSec; - wfxSrc.wBitsPerSample = workprefs.sound_bits; - wfxSrc.cbSize = 0; + memset (&wfxSrc, 0, sizeof (wfxSrc)); + wfxSrc.Format.wFormatTag = WAVE_FORMAT_PCM; + wfxSrc.Format.nChannels = get_audio_nativechannels () ? get_audio_nativechannels () : 2; + wfxSrc.Format.nSamplesPerSec = workprefs.sound_freq ? workprefs.sound_freq : 44100; + wfxSrc.Format.nBlockAlign = wfxSrc.Format.nChannels * 16 / 8; + wfxSrc.Format.nAvgBytesPerSec = wfxSrc.Format.nBlockAlign * wfxSrc.Format.nSamplesPerSec; + wfxSrc.Format.wBitsPerSample = 16; + wfxSrc.Format.cbSize = 0; + + if (wfxSrc.Format.nChannels > 2) { + wfxSrc.Format.cbSize = sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX); + wfxSrc.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + wfxSrc.Samples.wValidBitsPerSample = 16; + switch (wfxSrc.Format.nChannels) + { + case 4: + wfxSrc.dwChannelMask = KSAUDIO_SPEAKER_SURROUND; + break; + case 6: + wfxSrc.dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND; + break; + case 8: + wfxSrc.dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND; + break; + } + } if (!(pwfxDst = (LPWAVEFORMATEX) xmalloc (wfxMaxFmtSize))) return 0; @@ -282,13 +288,10 @@ static int AVIOutput_AllocateAudio (void) pwfxDst->cbSize = (WORD) (wfxMaxFmtSize - sizeof (WAVEFORMATEX)); // shrugs memset(&acmopt, 0, sizeof (ACMFORMATCHOOSE)); - acmopt.cbStruct = sizeof (ACMFORMATCHOOSE); - acmopt.fdwStyle = ACMFORMATCHOOSE_STYLEF_ENABLEHOOK | ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT; - + acmopt.fdwStyle = ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT; acmopt.pwfx = pwfxDst; acmopt.cbwfx = wfxMaxFmtSize; - acmopt.pszTitle = "Choose Audio Codec"; //acmopt.szFormatTag =; // not valid until the format is chosen @@ -303,7 +306,7 @@ static int AVIOutput_AllocateAudio (void) //ACM_FORMATENUMF_WBITSPERSAMPLE // MP3 doesn't apply so it will be removed from codec selection //ACM_FORMATENUMF_SUGGEST // with this flag set, only MP3 320kbps is displayed, which is closest to the source format - acmopt.pwfxEnum = &wfxSrc; + acmopt.pwfxEnum = &wfxSrc.Format; return 1; } @@ -385,7 +388,6 @@ int AVIOutput_ChooseAudioCodec (HWND hwnd, char *s, int len) return 0; acmopt.hwndOwner = hwnd; - acmopt.pfnHook = acmFilterChooseHookProc; switch (acmFormatChoose (&acmopt)) { @@ -424,7 +426,7 @@ int AVIOutput_ChooseAudioCodec (HWND hwnd, char *s, int len) break; case MMSYSERR_NODRIVER: - MessageBox (hwnd, "A suitable driver is not available to provide valid format selections.", VersionStr, MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND); + MessageBox (hwnd, "A suitable driver is not available to provide valid format selections.\n(Unsupported channel-mode selected in Sound-panel?)", VersionStr, MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND); break; default: @@ -743,8 +745,8 @@ void AVIOutput_WriteAudio (uae_u8 *sndbuffer, int sndbufsize) if (!avioutput_audio || !avioutput_enabled) return; - if (skipsample > 0 && size > wfxSrc.nBlockAlign) { - size -= wfxSrc.nBlockAlign; + if (skipsample > 0 && size > wfxSrc.Format.nBlockAlign) { + size -= wfxSrc.Format.nBlockAlign; skipsample--; } if (avioutput_audio == AVIAUDIO_WAV) @@ -1107,7 +1109,7 @@ void AVIOutput_Begin (void) goto error; } - if ((err = acmStreamOpen(&has, NULL, &wfxSrc, pwfxDst, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME)) != 0) { + if ((err = acmStreamOpen(&has, NULL, &wfxSrc.Format, pwfxDst, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME)) != 0) { gui_message ("acmStreamOpen() FAILED (%X)\n", err); goto error; } diff --git a/od-win32/blkdev_win32_ioctl.c b/od-win32/blkdev_win32_ioctl.c index 93e1377d..ab56d7fb 100755 --- a/od-win32/blkdev_win32_ioctl.c +++ b/od-win32/blkdev_win32_ioctl.c @@ -844,7 +844,7 @@ static int open_bus (int flags) total_devices = 0; dwDriveMask = GetLogicalDrives(); if (log_scsi) - write_log ("IOCTL: drive mask = %08.8X\n", dwDriveMask); + write_log ("IOCTL: drive mask = %08X\n", dwDriveMask); dwDriveMask >>= 2; // Skip A and B drives... for( drive = 'C'; drive <= 'Z'; drive++) { if (dwDriveMask & 1) { diff --git a/od-win32/blkdev_win32_spti.c b/od-win32/blkdev_win32_spti.c index d8f19f6d..658d68b8 100755 --- a/od-win32/blkdev_win32_spti.c +++ b/od-win32/blkdev_win32_spti.c @@ -317,7 +317,7 @@ static int inquiry (int unitnum, struct dev_info_spti *di, uae_u8 *inquirydata) memcpy (inquirydata, p, inqlen); if (log_scsi) { if (outlen >= INQUIRY_SIZE) - write_log ("SPTI: INQUIRY: %02.2X%02.2X%02.2X %d '%-8.8s' '%-16.16s'\n", + write_log ("SPTI: INQUIRY: %02X%02X%02X %d '%-8s' '%-16s'\n", p[0], p[1], p[2], di->isatapi, p + 8, p + 16); } return inqlen; diff --git a/od-win32/debug_win32.c b/od-win32/debug_win32.c index 344cd7ac..ccfeaf3c 100755 --- a/od-win32/debug_win32.c +++ b/od-win32/debug_win32.c @@ -345,7 +345,7 @@ static void ShowMiscCPU(HWND hwnd) for (i = 0; m2cregs[i].regno>= 0; i++) { if (!movec_illg(m2cregs[i].regno)) { - sprintf(out, "%-4s %08.8X", m2cregs[i].regname, val_move2c(m2cregs[i].regno)); + sprintf(out, "%-4s %08X", m2cregs[i].regname, val_move2c(m2cregs[i].regno)); UpdateListboxString(hwnd, line++, out, TRUE); } } @@ -391,15 +391,15 @@ static void ShowCustomSmall(HWND hwnd) sprintf (out + strlen(out), "/%d", currprefs.fpu_model); sprintf(out + strlen(out), " %s", (currprefs.chipset_mask & CSMASK_AGA) ? "AGA" : ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? "ECS" : "OCS")); ULBST(out); - ULBST("VPOS %04.4X (%d)", vpos, vpos); - ULBST("HPOS %04.4X (%d)", current_hpos(), current_hpos()); + ULBST("VPOS %04X (%d)", vpos, vpos); + ULBST("HPOS %04X (%d)", current_hpos(), current_hpos()); for (i = 0; dcustom[i]; i++) { for (j = 0; custd[j].name; j++) { if (custd[j].adr == (dcustom[i] & 0x1fe) + 0xdff000) { if (dcustom[i] & 0x8000) - ULBST("%-8s %08.8X", custd[j].name, (gw(p1, dcustom[i] & 0x1fe) << 16) | gw(p1, (dcustom[i] & 0x1fe) + 2)); + ULBST("%-8s %08X", custd[j].name, (gw(p1, dcustom[i] & 0x1fe) << 16) | gw(p1, (dcustom[i] & 0x1fe) + 2)); else - ULBST("%-8s %04.4X", custd[j].name, gw(p1, dcustom[i] & 0x1fe)); + ULBST("%-8s %04X", custd[j].name, gw(p1, dcustom[i] & 0x1fe)); break; } } @@ -439,7 +439,7 @@ static void ShowMisc(void) p = p2 = save_disk (i, &len, NULL); ULBS(""); ULBS("Drive DF%d: (%s)", i, (p[4] & 2) ? "disabled" : "enabled"); - ULBS("ID %08.8X Motor %s Cylinder %2d MFMPOS %d", + ULBS("ID %08X Motor %s Cylinder %2d MFMPOS %d", (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3], (p[4] & 1) ? "On" : "Off", p[5], (p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11]); @@ -453,7 +453,7 @@ static void ShowMisc(void) ULBS(""); ULBS("Disk controller:"); ULBS(""); - ULBS("Shift register: Data=%04.4X Shift=%d. DMA=%d,%d", (p[0] << 8) | p[1], p[2], p[3], p[5]); + ULBS("Shift register: Data=%04X Shift=%d. DMA=%d,%d", (p[0] << 8) | p[1], p[2], p[3], p[5]); free (p2); } @@ -495,7 +495,7 @@ static void ShowCustom(void) addr2 = custd[j].adr & 0x1ff; v1 = (p1[addr1 + 0] << 8) | p1[addr1 + 1]; v2 = (p1[addr2 + 0] << 8) | p1[addr2 + 1]; - ULBS("%03.3X %-15s %04.4X %03.3X %-15s %04.4X", + ULBS("%03.3X %-15s %04X %03X %-15s %04X", addr1, custd[i].name, v1, addr2, custd[j].name, v2); } diff --git a/od-win32/dinput.c b/od-win32/dinput.c index c3d54fb7..37f8237f 100755 --- a/od-win32/dinput.c +++ b/od-win32/dinput.c @@ -100,8 +100,8 @@ static int oldleds, oldusedleds, newleds, oldusbleds; static int normalmouse, supermouse, rawmouse, winmouse, winmousenumber, winmousemode, winmousewheelbuttonstart; static int normalkb, superkb, rawkb; -int no_rawinput; int rawkeyboard; +int no_rawinput; int dinput_enum_all; int dinput_winmouse (void) @@ -194,46 +194,54 @@ typedef LRESULT (CALLBACK* DEFRAWINPUTPROC) (PRAWINPUT*, INT, UINT); static DEFRAWINPUTPROC pDefRawInputProc; -static int rawinput_available, rawinput_registered; - -static void unregister_rawinput (void) -{ - rawinput_registered = 0; -} +static int rawinput_available, rawinput_registered_mouse, rawinput_registered_kb; static int register_rawinput (void) { - int num; + int num, rm, rkb; RAWINPUTDEVICE rid[2]; if (!rawinput_available) return 0; + + rm = rawmouse ? 1 : 0; + if (supermouse) + rm = 0; + rkb = rawkb ? 1 : 0; + if (!rawkeyboard) + rkb = 0; + if (rawinput_registered_mouse == rm && rawinput_registered_kb == rkb) + return 1; + memset (rid, 0, sizeof (rid)); num = 0; - /* mouse */ - if (rawmouse) { + if (rawinput_registered_mouse != rm) { + /* mouse */ rid[num].usUsagePage = 1; rid[num].usUsage = 2; - rid[num].dwFlags = RIDEV_INPUTSINK; - rid[num].hwndTarget = hAmigaWnd; + if (!rawmouse) + rid[num].dwFlags = RIDEV_REMOVE; num++; } - /* keyboard */ - if (rawkb) { + if (rawinput_registered_kb != rkb) { + /* keyboard */ rid[num].usUsagePage = 1; rid[num].usUsage = 6; - rid[num].dwFlags = RIDEV_INPUTSINK; - rid[num].hwndTarget = hAmigaWnd; + if (!rawkb) + rid[num].dwFlags = RIDEV_REMOVE; num++; } - if (!num) - return 0; - write_log ("%d\n", num); - if (pRegisterRawInputDevices(rid, num, sizeof (RAWINPUTDEVICE)) == FALSE) { - write_log ("RAWINPUT registration failed %d\n", GetLastError ()); + if (num == 0) + return 1; + if (pRegisterRawInputDevices (rid, num, sizeof (RAWINPUTDEVICE)) == FALSE) { + write_log ("RAWINPUT registration failed %d (%d,%d->%d,%d->%d)\n", + GetLastError (), num, + rawinput_registered_mouse, rm, + rawinput_registered_kb, rkb); return 0; } - rawinput_registered = 1; + rawinput_registered_mouse = rm; + rawinput_registered_kb = rkb; return 1; } @@ -253,7 +261,7 @@ static void cleardid (struct didata *did) static uae_u8 di_keycodes[MAX_INPUT_DEVICES][MAX_KEYCODES]; static int keyboard_german; -static int keyhack (int scancode,int pressed, int num) +static int keyhack (int scancode, int pressed, int num) { static byte backslashstate,apostrophstate; @@ -414,14 +422,14 @@ static int initialize_catweasel(void) } -#define RDP_MOUSE1 "\\??\\Root#RDP_MOU#" -#define RDP_MOUSE2 "\\\\?\\Root#RDP_MOU#" +#define RDP_DEVICE1 "\\??\\Root#RDP_" +#define RDP_DEVICE2 "\\\\?\\Root#RDP_" -static int rdpmouse(char *buf) +static int rdpdevice(char *buf) { - if (!memcmp (RDP_MOUSE1, buf, strlen (RDP_MOUSE1))) + if (!memcmp (RDP_DEVICE1, buf, strlen (RDP_DEVICE1))) return 1; - if (!memcmp (RDP_MOUSE2, buf, strlen (RDP_MOUSE2))) + if (!memcmp (RDP_DEVICE2, buf, strlen (RDP_DEVICE2))) return 1; return 0; } @@ -521,7 +529,7 @@ static int initialize_rawinput (void) bufsize = 10000; buf = xmalloc (bufsize); - register_rawinput(); + register_rawinput (); if (pGetRawInputDeviceList (NULL, &num, sizeof (RAWINPUTDEVICELIST)) != 0) { write_log ("RAWINPUT error %08X\n", GetLastError()); goto error2; @@ -546,7 +554,7 @@ static int initialize_rawinput (void) continue; if (pGetRawInputDeviceInfo (h, RIDI_DEVICENAME, buf, &vtmp) == -1) continue; - if (rdpmouse (buf)) + if (rdpdevice (buf)) continue; if (type == RIM_TYPEMOUSE) rnum_mouse++; @@ -574,7 +582,7 @@ static int initialize_rawinput (void) continue; if (did == di_mouse) { - if (rdpmouse(buf)) + if (rdpdevice (buf)) continue; if (num_mouse >= MAX_INPUT_DEVICES - 1) /* leave space for Windows mouse */ continue; @@ -583,6 +591,8 @@ static int initialize_rawinput (void) rmouse++; v = rmouse; } else if (did == di_keyboard) { + if (rdpdevice (buf)) + continue; if (rnum_kb < 2) continue; if (num_keyboard >= MAX_INPUT_DEVICES - 1) @@ -781,9 +791,9 @@ static void handle_rawinput_2 (RAWINPUT *raw) int istest = inputdevice_istest (); PRAWKEYBOARD rk = &raw->data.keyboard; uae_u8 scancode = (rk->MakeCode & 0x7f) | ((rk->Flags & RI_KEY_E0) ? 0x80 : 0x00); - int pressed = (rk->Flags & RI_KEY_BREAK) ? 1 : 0; + int pressed = (rk->Flags & RI_KEY_BREAK) ? 0 : 1; - #ifdef DI_DEBUG2 +#ifdef DI_DEBUG2 write_log ("HANDLE=%x CODE=%x Flags=%x VK=%x MSG=%x EXTRA=%x\n", raw->header.hDevice, raw->data.keyboard.MakeCode, @@ -797,23 +807,25 @@ static void handle_rawinput_2 (RAWINPUT *raw) return; } + if (scancode == 0xaa) + return; for (num = 0; num < num_keyboard; num++) { did = &di_keyboard[num]; - if (!did->disabled && did->rawinput == raw->header.hDevice) + if (!did->disabled && did->acquired && did->rawinput == raw->header.hDevice) { + if (di_keycodes[num][scancode] == pressed) + return; + di_keycodes[num][scancode] = pressed; break; + } } if (num == num_keyboard) return; - if (scancode == 0xaa) - return; - if (!istest) - scancode = keyhack (scancode, pressed, num); - if (scancode < 0) - return; - di_keycodes[num][scancode] = pressed; if (istest) { inputdevice_do_keyboard (scancode, pressed); } else { + scancode = keyhack (scancode, pressed, num); + if (scancode < 0) + return; if (stopoutput == 0) my_kbd_handler (num, scancode, pressed); } @@ -845,13 +857,13 @@ void handle_rawinput (LPARAM lParam) if (!rawinput_available) return; pGetRawInputData ((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof (RAWINPUTHEADER)); - if (dwSize >= sizeof (lpb)) - return; - if (pGetRawInputData ((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof (RAWINPUTHEADER)) != dwSize ) - return; - raw = (RAWINPUT*)lpb; - handle_rawinput_2 (raw); - pDefRawInputProc (&raw, 1, sizeof (RAWINPUTHEADER)); + if (dwSize <= sizeof (lpb)) { + if (pGetRawInputData ((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof (RAWINPUTHEADER)) == dwSize) { + raw = (RAWINPUT*)lpb; + handle_rawinput_2 (raw); + pDefRawInputProc (&raw, 1, sizeof (RAWINPUTHEADER)); + } + } } static void unacquire (LPDIRECTINPUTDEVICE8 lpdi, char *txt) @@ -1347,7 +1359,7 @@ static int acquire_mouse (int num, int flags) } else { di_mouse[num].acquired = 1; } - if (di_mouse[num].acquired) { + if (di_mouse[num].acquired > 0) { if (di_mouse[num].rawinput) rawmouse++; else if (di_mouse[num].superdevice) @@ -1359,15 +1371,14 @@ static int acquire_mouse (int num, int flags) } else normalmouse++; } - if (!supermouse && rawmouse) - register_rawinput (); + register_rawinput (); return di_mouse[num].acquired > 0 ? 1 : 0; } static void unacquire_mouse (int num) { unacquire (di_mouse[num].lpdi, "mouse"); - if (di_mouse[num].acquired) { + if (di_mouse[num].acquired > 0) { if (di_mouse[num].rawinput) rawmouse--; else if (di_mouse[num].superdevice) @@ -1905,8 +1916,7 @@ static int acquire_kb (int num, int flags) normalkb++; di_keyboard[num].acquired = 1; } - if (rawkb) - register_rawinput (); + register_rawinput (); return di_keyboard[num].acquired > 0 ? 1 : 0; } @@ -1915,7 +1925,7 @@ static void unacquire_kb (int num) LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi; unacquire (lpdi, "keyboard"); - if (di_keyboard[num].acquired) { + if (di_keyboard[num].acquired > 0) { if (di_keyboard[num].rawinput) rawkb--; else if (di_keyboard[num].superdevice) diff --git a/od-win32/direct3d.c b/od-win32/direct3d.c index b73eb50f..e14c6e35 100755 --- a/od-win32/direct3d.c +++ b/od-win32/direct3d.c @@ -19,7 +19,7 @@ #include "direct3d.h" -#define USAGE (D3DCREATE_SOFTWARE_VERTEXPROCESSING) +#define USAGE (D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE) static int tformat; static int d3d_enabled, scanlines_ok; @@ -43,7 +43,7 @@ static char *D3D_ErrorText (HRESULT error) static char *D3D_ErrorString (HRESULT dival) { static char dierr[200]; - sprintf(dierr, "%08.8X S=%d F=%04.4X C=%04.4X (%d) (%s)", + sprintf(dierr, "%08X S=%d F=%04X C=%04X (%d) (%s)", dival, (dival & 0x80000000) ? 1 : 0, HRESULT_FACILITY(dival), HRESULT_CODE(dival), diff --git a/od-win32/dxwarp_old.c b/od-win32/dxwarp_old.c deleted file mode 100755 index 6ec5523a..00000000 --- a/od-win32/dxwarp_old.c +++ /dev/null @@ -1,1950 +0,0 @@ -/* - * UAE - The Ultimate Amiga Emulator - * - * Win32 DirectX Wrappers, to simplify (?) my life. - * - * Copyright 1999 Brian King, under GNU Public License - * - */ -#include "sysconfig.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "sysdeps.h" -#include "options.h" -#include "custom.h" -#include "memory.h" -#include "newcpu.h" -#include "picasso96.h" -#include "dxwrap.h" -#include "win32.h" -#include "win32gfx.h" -#include "machdep/rpt.h" - -static BOOL bColourKeyAvailable = FALSE; -static BOOL bOverlayAvailable = FALSE; -static DDCAPS_DX7 drivercaps, helcaps; -static DWORD overlayflags; -static DDOVERLAYFX overlayfx; -extern COLORREF g_dwBackgroundColor; -static int flipinterval_supported; - -#define dxwrite_log - -static HRESULT restoresurface (LPDIRECTDRAWSURFACE7 surface) -{ - HRESULT hr2, hr; - DDSURFACEDESC2 surfacedesc; - - hr = IDirectDrawSurface7_Restore (surface); - if (SUCCEEDED(hr)) { - DDBLTFX bltfx; - memset (&bltfx, 0, sizeof (bltfx)); - bltfx.dwSize = sizeof (bltfx); - hr2 = IDirectDrawSurface7_Blt (surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx); - if (FAILED(hr2)) { - static int crap = 0; - if (hr2 == DDERR_SURFACELOST) { - if (crap) - return hr; - crap = 1; - write_log ("Restore succeeded but following Blt failed with lost surface. Display driver bug?\n"); - return hr; - } - write_log ("Surface clear failed: %s\n", DXError (hr2)); - } - surfacedesc.dwSize = sizeof surfacedesc; - hr2 = IDirectDrawSurface7_Lock(surface, NULL, &surfacedesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (SUCCEEDED(hr2)) { - write_log ("Surface Pointer: %p\n", surfacedesc.lpSurface); - IDirectDrawSurface7_Unlock(surface, NULL); - } - } - return hr; -} - - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -static void clearsurface(int surface) -{ - DDBLTFX ddbltfx; - memset(&ddbltfx, 0, sizeof(ddbltfx)); - ddbltfx.dwFillColor = 0; - ddbltfx.dwSize = sizeof(ddbltfx); - DirectDraw_Blt(surface, NULL, invalid_surface, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); -} - -void DirectDraw_ClearSurfaces(void) -{ - clearsurface(secondary_surface); - if(DirectDrawState.isoverlay) - clearsurface(overlay_surface); -} - -/* - * FUNCTION:ShowDDCaps - * - * PURPOSE:print out the DirectDraw Capabilities - * - * PARAMETERS: - * caps - DDCAPS_DX7 structure - * hw - flag indicating if this 'caps' is for real hardware or the HEL - * - * RETURNS: none - * - * NOTES:none - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -static void ShowDDCaps( DDCAPS_DX7 caps, int hw ) -{ - static int shown = 0; - static BOOL reset_shown = FALSE; - if( currprefs.win32_logfile && shown >= 4 && !reset_shown) - { - shown = 0; - reset_shown = TRUE; - } - - if( shown < 2) - { - dxwrite_log ( "DirectDraw Capabilities for %s:\n", hw ? "Display Driver Hardware" : "Display Driver Emulation Layer" ); - if( caps.dwCaps & DDCAPS_BLT ) - dxwrite_log ( "DDCAPS_BLT - Capable of blitting\n" ); - if( caps.dwCaps & DDCAPS_BLTCOLORFILL ) - dxwrite_log ( "DDCAPS_BLTCOLORFILL - Color filling with blitter\n" ); - if( caps.dwCaps & DDCAPS_BLTSTRETCH ) - dxwrite_log ( "DDCAPS_BLTSTRETCH - Stretch blitting\n" ); - if( caps.dwCaps & DDCAPS_CANBLTSYSMEM ) - dxwrite_log ( "DDCAPS_CANBLTSYSMEM - Blits from system memory\n" ); - if( caps.dwCaps & DDCAPS_CANCLIP ) - dxwrite_log ( "DDCAPS_CANCLIP - Can clip while blitting\n" ); - if( caps.dwCaps & DDCAPS_CANCLIPSTRETCHED ) - dxwrite_log ( "DDCAPS_CANCLIPSTRETCHED - Can clip while stretch-blitting\n" ); - if( caps.dwCaps & DDCAPS_COLORKEY ) - { - dxwrite_log ( "DDCAPS_COLORKEY - Can color-key with blits/overlays\n" ); - bColourKeyAvailable = TRUE; - } - if( caps.dwCaps & DDCAPS_GDI ) - dxwrite_log ( "DDCAPS_GDI - Display h/w shared with GDI\n" ); - if( caps.dwCaps & DDCAPS_NOHARDWARE ) - dxwrite_log ( "DDCAPS_NOHARDWARE - no h/w support!\n" ); - if( caps.dwCaps & DDCAPS_OVERLAY ) - { - dxwrite_log ( "DDCAPS_OVERLAY - support for %d overlay(s)\n", caps.dwMaxVisibleOverlays ); - if( bColourKeyAvailable ) - { - if( caps.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY ) - { - dxwrite_log ( "DDCKEYCAPS_DESTOVERLAY - colour-keyed overlays\n" ); - bOverlayAvailable = TRUE; - } - } - } - if( caps.dwCaps & DDCAPS_OVERLAYFOURCC ) - dxwrite_log ( "DDCAPS_OVERLAYFOURCC - overlay can do color-space conversions\n" ); - if( caps.dwCaps & DDCAPS_OVERLAYSTRETCH ) - dxwrite_log ( "DDCAPS_OVERLAYSTRETCH - overlay can stretch with min=%d/max=%d\n", caps.dwMinOverlayStretch, caps.dwMaxOverlayStretch ); - if( caps.dwCaps & DDCAPS_VBI ) - dxwrite_log ( "DDCAPS_VBI - h/w can generate a vertical-blanking interrupt\n" ); - if( caps.dwCaps2 & DDCAPS2_CERTIFIED ) - dxwrite_log ( "DDCAPS2_CERTIFIED - certified driver\n" ); - if( caps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED ) - dxwrite_log ( "DDCAPS2_CANRENDERWINDOWED - GDI windows can be seen when in full-screen\n" ); - if( caps.dwCaps2 & DDCAPS2_NOPAGELOCKREQUIRED ) - dxwrite_log ( "DDCAPS2_NOPAGELOCKREQUIRED - no page locking needed for DMA blits\n" ); - if( caps.dwCaps2 & DDCAPS2_FLIPNOVSYNC ) - dxwrite_log ( "DDCAPS2_FLIPNOVSYNC - can pass DDFLIP_NOVSYNC to Flip calls\n" ); - if( caps.dwCaps2 & DDCAPS2_FLIPINTERVAL ) { - dxwrite_log ( "DDCAPS2_FLIPINTERVAL - can pass DDFLIP_INTERVALx to Flip calls\n" ); - flipinterval_supported = 1; - } - - dxwrite_log ( "Video memory: %d/%d\n", caps.dwVidMemFree, caps.dwVidMemTotal ); - } - shown++; -} - -const char *DXError (HRESULT ddrval) -{ - static char dderr[1000]; - sprintf(dderr, "%08.8X S=%d F=%04.4X C=%04.4X (%d) (%s)", - ddrval, (ddrval & 0x80000000) ? 1 : 0, - HRESULT_FACILITY(ddrval), - HRESULT_CODE(ddrval), - HRESULT_CODE(ddrval), - DXGetErrorDescription9 (ddrval)); - return dderr; -} - -struct DirectDrawSurfaceMapper DirectDrawState; - -static int lockcnt = 0; - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -static int LockStub( surface_type_e type ) -{ - int result = 0; - HRESULT ddrval; - LPDIRECTDRAWSURFACE7 surface; - LPDDSURFACEDESC2 surfacedesc; - - switch( type ) - { - case primary_surface: - surface = DirectDrawState.primary.surface; - surfacedesc = &DirectDrawState.primary.desc; - break; - case secondary_surface: - surface = DirectDrawState.secondary.surface; - surfacedesc = &DirectDrawState.secondary.desc; - break; - case tertiary_surface: - surface = DirectDrawState.tertiary.surface; - surfacedesc = &DirectDrawState.tertiary.desc; - break; - case temporary_surface: - surface = DirectDrawState.temporary.surface; - surfacedesc = &DirectDrawState.temporary.desc; - break; - case overlay_surface: - surface = DirectDrawState.overlay.surface; - surfacedesc = &DirectDrawState.overlay.desc; - break; - } - - if(lockcnt) - { -#ifdef _DEBUG - //DebugBreak(); -#endif - return 1; - } - - if(type == secondary_surface && DirectDrawState.flipping != single_buffer) - { - IDirectDrawSurface7_Restore(DirectDrawState.primary.surface); - } - - while (FAILED(ddrval = IDirectDrawSurface7_Lock(surface, NULL, surfacedesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL))) - { - if (ddrval == DDERR_SURFACELOST) { - ddrval = restoresurface (surface); - if (FAILED(ddrval)) - break; - } - else if (ddrval != DDERR_SURFACEBUSY) - { - write_log ("lpDDS->Lock() failed - %s\n", DXError (ddrval)); - break; - } - } - if(SUCCEEDED(ddrval)) { - static int warned = 10; - DWORD_PTR pixels = (DWORD_PTR)(surfacedesc->lpSurface); - if (warned > 0 && (pixels & 7)) { - write_log ("bogus surface pointer %x!\n", pixels); - warned--; - } - lockcnt++; - result = 1; - } - return result; -} - -/* For a given surface-type, update our DirectDrawState structure */ -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -int DirectDraw_SurfaceLock(surface_type_e surface_type) -{ - int result = 0; - - if (surface_type == lockable_surface) - surface_type = DirectDraw_GetLockableType(); - - switch(surface_type) - { - case primary_surface: - DirectDrawState.primary.desc.dwSize = sizeof(DDSURFACEDESC2); - result = LockStub(surface_type); - break; - case secondary_surface: - DirectDrawState.secondary.desc.dwSize = sizeof(DDSURFACEDESC2); - result = LockStub(surface_type); - break; - case tertiary_surface: - DirectDrawState.tertiary.desc.dwSize = sizeof(DDSURFACEDESC2); - result = LockStub(surface_type); - break; - case temporary_surface: - DirectDrawState.temporary.desc.dwSize = sizeof(DDSURFACEDESC2); - result = LockStub(surface_type); - break; - case overlay_surface: - DirectDrawState.overlay.desc.dwSize = sizeof(DDSURFACEDESC2); - result = LockStub(surface_type); - case lockable_surface: - case invalid_surface: - default: - - break; - } - DirectDrawState.locked = result; - - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -char *DirectDraw_GetSurfacePointer(void) -{ - char *pixels = NULL; - - /* Make sure that somebody has done a lock before returning the lpSurface member */ - if(lockcnt) - pixels = DirectDrawState.lockable.lpdesc->lpSurface; - return pixels; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -LONG DirectDraw_GetSurfacePitch(void) -{ - LONG pitch = 0; - - pitch = DirectDrawState.lockable.lpdesc->lPitch; - return pitch; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -DWORD DirectDraw_GetPixelFormatFlags(void) -{ - DWORD flags = 0; - flags = DirectDrawState.lockable.lpdesc->ddpfPixelFormat.dwFlags; - return flags; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -DWORD DirectDraw_GetSurfaceFlags(void) -{ - DWORD flags = 0; - flags = DirectDrawState.lockable.lpdesc->dwFlags; - return flags; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -DWORD DirectDraw_GetSurfaceBitCount(void) -{ - DWORD bits = 0; - //?????JGI begin: - if(DirectDrawState.lockable.lpdesc) - bits = DirectDrawState.lockable.lpdesc->ddpfPixelFormat.dwRGBBitCount; - else - bits = DirectDrawState.current.desc.ddpfPixelFormat.dwRGBBitCount; - //?????JGI end. - return bits; -} - -/* - * FUNCTION:DirectDraw_GetPrimaryBitCount - * - * PURPOSE:Return the bit-depth of the primary surface - * - * PARAMETERS: none - * - * RETURNS: bit-depth - * - * NOTES: - * - * HISTORY: - * 2001.08.25 Brian King Creation - * - */ -DWORD DirectDraw_GetPrimaryBitCount(void) -{ - DWORD bits = 0; - memset(&DirectDrawState.primary.desc,0,sizeof(DirectDrawState.primary.desc)); - DirectDrawState.primary.desc.dwSize = sizeof(DirectDrawState.primary.desc); - - IDirectDrawSurface7_GetSurfaceDesc(DirectDrawState.primary.surface, &DirectDrawState.primary.desc); - bits = DirectDrawState.primary.desc.ddpfPixelFormat.dwRGBBitCount; - return bits; -} - -void DirectDraw_GetPrimaryWidthHeight(int *w, int *h) -{ - memset(&DirectDrawState.primary.desc,0,sizeof(DirectDrawState.primary.desc)); - DirectDrawState.primary.desc.dwSize = sizeof(DirectDrawState.primary.desc); - - IDirectDrawSurface7_GetSurfaceDesc(DirectDrawState.primary.surface, &DirectDrawState.primary.desc); - *w = DirectDrawState.primary.desc.dwWidth; - *h = DirectDrawState.primary.desc.dwHeight; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -DWORD DirectDraw_GetPixelFormatBitMask(DirectDraw_Mask_e mask) -{ - DWORD result = 0; - switch(mask) - { - case red_mask: - result = DirectDrawState.lockable.lpdesc->ddpfPixelFormat.dwRBitMask; - break; - case green_mask: - result = DirectDrawState.lockable.lpdesc->ddpfPixelFormat.dwGBitMask; - break; - case blue_mask: - result = DirectDrawState.lockable.lpdesc->ddpfPixelFormat.dwBBitMask; - break; - } - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -surface_type_e DirectDraw_GetLockableType(void) -{ - return DirectDrawState.surface_type; -} - -/* - * FUNCTION:DirectDraw_IsLocked - * - * PURPOSE:Return whether we're currently locked or unlocked - * - * PARAMETERS: none - * - * RETURNS: TRUE if already locked, FALSE otherwise - * - * NOTES:Used by DX_Blit to possibly unlock during Blit operation - * - * HISTORY: - * 2000.04.30 Brian King Creation - * - */ -BOOL DirectDraw_IsLocked(void) -{ - return DirectDrawState.locked ? TRUE : FALSE; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -static surface_type_e try_surface_locks(int want_fullscreen) -{ - surface_type_e result = invalid_surface; - - if(DirectDrawState.isoverlay && DirectDraw_SurfaceLock(overlay_surface)) - { - result = overlay_surface; - write_log ("try_surface_locks() returning overlay\n"); - } - else if(want_fullscreen && WIN32GFX_IsPicassoScreen()) - { - if(DirectDraw_SurfaceLock(primary_surface)) - { - result = primary_surface; - write_log ("try_surface_locks() returning primary\n"); - } - else if(DirectDraw_SurfaceLock(secondary_surface)) - { - result = secondary_surface; - write_log ("try_surface_locks() returning secondary\n"); - } - } - else - { - if(DirectDraw_SurfaceLock(secondary_surface)) - { - result = secondary_surface; - write_log ("try_surface_locks() returning secondary\n"); - } - } - - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES:Named this way for historical reasons - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -void ddraw_unlockscr(void) -{ - if(lockcnt > 0) { - lockcnt--; - IDirectDrawSurface7_Unlock(DirectDrawState.lockable.surface, - DirectDrawState.lockable.lpdesc->lpSurface); - DirectDrawState.locked = FALSE; - } -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -int DirectDraw_Start(GUID *guid) -{ - HRESULT ddrval; - /* Prepare our DirectDrawState structure */ - ZeroMemory(&DirectDrawState, sizeof(DirectDrawState)); - ZeroMemory(&drivercaps, sizeof(drivercaps)); - ZeroMemory(&helcaps, sizeof(helcaps)); - drivercaps.dwSize = sizeof(drivercaps); - helcaps.dwSize = sizeof(helcaps); - - ddrval = DirectDrawCreate(guid, &DirectDrawState.directdraw.ddx, NULL); - if (FAILED(ddrval)) { - if (guid != NULL) - return 0; - goto oops; - } - - DirectDrawState.initialized = TRUE; - - ddrval = IDirectDraw_QueryInterface(DirectDrawState.directdraw.ddx, - &IID_IDirectDraw7, (LPVOID *)&DirectDrawState.directdraw.dd); - if(FAILED(ddrval)) { - gui_message("start_ddraw(): DirectX 7 or newer required"); - DirectDraw_Release(); - return 0; - } - - DirectDraw_GetCaps(&drivercaps, &helcaps); - ShowDDCaps(drivercaps, 1); - ShowDDCaps(helcaps, 0); - if (SUCCEEDED(DirectDraw_GetDisplayMode ())) - return 1; - if (guid != NULL) { - DirectDraw_Release (); - return 0; - } - - oops: - gui_message ("start_ddraw(): DirectDraw initialization failed with %s\n", DXError (ddrval)); - DirectDraw_Release(); - return 0; -} - -#define releaser(x,y) if( x ) { y( x ); x = NULL; } - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -void DirectDraw_Release(void) -{ - releaser(DirectDrawState.lpDDC, IDirectDrawClipper_Release); - releaser(DirectDrawState.lpDDP, IDirectDrawPalette_Release); - - if (DirectDrawState.directdraw.dd && DirectDrawState.modeset) { - IDirectDraw7_RestoreDisplayMode(DirectDrawState.directdraw.dd); - IDirectDraw7_SetCooperativeLevel(DirectDrawState.directdraw.dd, hAmigaWnd, DDSCL_NORMAL); - } - DirectDrawState.modeset = 0; - - releaser(DirectDrawState.overlay.surface, IDirectDrawSurface7_Release); - releaser(DirectDrawState.primary.surface, IDirectDrawSurface7_Release); - - if(DirectDrawState.flipping == single_buffer) - releaser(DirectDrawState.secondary.surface, IDirectDrawSurface7_Release); - - releaser(DirectDrawState.directdraw.dd, IDirectDraw_Release); - - DirectDrawState.lockable.lpdesc = NULL; - DirectDrawState.lockable.lpdesc = NULL; - DirectDrawState.lockable.surface = NULL; - DirectDrawState.lockable.surface = NULL; - - DirectDrawState.surface_type = invalid_surface; - DirectDrawState.initialized = FALSE; - DirectDrawState.isoverlay = FALSE; -} - -/* - * FUNCTION:DirectDraw_SetCooperativeLevel - * - * PURPOSE:Wrapper for setting the cooperative level (fullscreen or normal) - * - * PARAMETERS: - * window Window to set the cooperative level for - * want_fullscreen fullscreen mode flag - * - * RETURNS: result of underlying DirectDraw call - * - * NOTES: Updates the .fullscreen and .window members. - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_SetCooperativeLevel(HWND window, int want_fullscreen) -{ - HRESULT ddrval; - - ddrval = IDirectDraw7_SetCooperativeLevel(DirectDrawState.directdraw.dd, - window, want_fullscreen ? - DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN : DDSCL_NORMAL); - if(SUCCEEDED(ddrval)) { - DirectDrawState.fullscreen = want_fullscreen; - DirectDrawState.window = window; - } - return ddrval; -} - -/* - * FUNCTION:DirectDraw_GetCooperativeLevel - * - * PURPOSE:Wrapper for setting the cooperative level (fullscreen or normal) - * - * PARAMETERS: - * window Window to set the cooperative level for - * want_fullscreen fullscreen mode flag - * - * RETURNS: result of underlying DirectDraw call - * - * NOTES: Updates the .fullscreen and .window members. - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -BOOL DirectDraw_GetCooperativeLevel(HWND *window, int *fullscreen) -{ - BOOL result = FALSE; - - if(DirectDrawState.initialized) { - *fullscreen = DirectDrawState.fullscreen; - *window = DirectDrawState.window; - result = TRUE; - } - return result; -} - -/* - * FUNCTION:DirectDraw_SetDisplayMode - * - * PURPOSE:Change the display-mode to width x height pixels, with a given - * vertical refresh-rate. - * - * PARAMETERS: - * width - width of display in pixels - * height - height of display in pixels - * freq - vertical refresh-rate in Hz - * - * RETURNS: - * ddrval - HRESULT indicating success (DD_OK) or failure - * - * NOTES:The freq parameter is only obeyed on when we're using DirectX 6 - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_SetDisplayMode(int width, int height, int bits, int freq) -{ - HRESULT ddrval; - - ddrval = IDirectDraw7_SetDisplayMode(DirectDrawState.directdraw.dd, - width, height, bits, freq, 0); - DirectDrawState.modeset = 1; - return ddrval; -} - -/* - * FUNCTION:DirectDraw_GetDisplayMode - * - * PURPOSE:Get the display-mode characteristics. - * - * PARAMETERS: none - * - * RETURNS: - * ddrval - HRESULT indicating success (DD_OK) or failure - * - * NOTES:none - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_GetDisplayMode(void) -{ - HRESULT ddrval; - - /* We fill in the current.desc in all cases */ - DirectDrawState.current.desc.dwSize = sizeof(DDSURFACEDESC2); - ddrval = IDirectDraw7_GetDisplayMode(DirectDrawState.directdraw.dd, - &DirectDrawState.current.desc); - return ddrval; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_GetCaps(DDCAPS_DX7 *driver_caps, DDCAPS_DX7 *hel_caps) -{ - HRESULT ddrval; - - ddrval = IDirectDraw7_GetCaps(DirectDrawState.directdraw.dd, - driver_caps, hel_caps); - return ddrval; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_CreateClipper(void) -{ - HRESULT ddrval; - ddrval = IDirectDraw7_CreateClipper(DirectDrawState.directdraw.dd, - 0, &DirectDrawState.lpDDC, NULL); - return ddrval; -} - -static DWORD ConvertGDIColor(COLORREF dwGDIColor) -{ - COLORREF rgbT; - HDC hdc; - DWORD dw = CLR_INVALID; - DDSURFACEDESC2 ddsd,pdds; - HRESULT hr; - - memset(&pdds,0,sizeof(pdds)); - pdds.dwSize = sizeof(pdds); - - IDirectDrawSurface7_GetSurfaceDesc(DirectDrawState.primary.surface, &pdds); - - // Use GDI SetPixel to color match for us - if(dwGDIColor != CLR_INVALID && SUCCEEDED(IDirectDrawSurface7_GetDC(DirectDrawState.primary.surface, &hdc))) { - rgbT = GetPixel(hdc, 0, 0); // Save current pixel value - SetPixel(hdc, 0, 0, dwGDIColor); // Set our value - IDirectDrawSurface7_ReleaseDC(DirectDrawState.primary.surface,hdc); - } - - // Now lock the surface so we can read back the converted color - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(DirectDrawState.primary.surface, NULL, &ddsd, DDLOCK_WAIT, NULL ); - if(SUCCEEDED(hr)) { - dw = *(DWORD *) ddsd.lpSurface; - if(ddsd.ddpfPixelFormat.dwRGBBitCount < 32) // Mask it to bpp - dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1; - IDirectDrawSurface7_Unlock(DirectDrawState.primary.surface,NULL); - } - - // Now put the color that was there back. - if(dwGDIColor != CLR_INVALID && SUCCEEDED(IDirectDrawSurface7_GetDC(DirectDrawState.primary.surface,&hdc))) { - SetPixel(hdc, 0, 0, rgbT); - IDirectDrawSurface7_ReleaseDC(DirectDrawState.primary.surface,hdc); - } - - return dw; -} - - -HRESULT DirectDraw_CreateOverlaySurface(int width, int height, int bits, int type) -{ - DDSURFACEDESC2 ddsd; - DDPIXELFORMAT ddpfOverlayFormat; - HRESULT ddrval = DDERR_UNSUPPORTED; - DWORD dwDDSColor; - DWORD flags = DDPF_RGB; - - ZeroMemory(&ddpfOverlayFormat, sizeof(ddpfOverlayFormat)); - ddpfOverlayFormat.dwSize = sizeof(ddpfOverlayFormat); - ZeroMemory(&ddsd, sizeof(ddsd)); - - if (bOverlayAvailable) { - write_log ( "CreateOverlaySurface being called with %d-bits!\n", bits ); - if(bits == 16) { - // Set the overlay format to 16 bit RGB 5:6:5 - ddpfOverlayFormat.dwFlags = flags; - ddpfOverlayFormat.dwRGBBitCount = 16; - ddpfOverlayFormat.dwRBitMask = 0xF800; - ddpfOverlayFormat.dwGBitMask = 0x07E0; - ddpfOverlayFormat.dwBBitMask = 0x001F; - } else if(bits == 32) { - // Set the overlay format to 32 bit ARGB 8:8:8:8 - ddpfOverlayFormat.dwFlags = flags; - ddpfOverlayFormat.dwRGBBitCount = 32; - ddpfOverlayFormat.dwRBitMask = 0x00FF0000; - ddpfOverlayFormat.dwGBitMask = 0x0000FF00; - ddpfOverlayFormat.dwBBitMask = 0x000000FF; - } else if(bits == 8) { - // Set the overlay format to 8 bit palette - ddpfOverlayFormat.dwFlags = flags | DDPF_PALETTEINDEXED8; - ddpfOverlayFormat.dwRGBBitCount = 8; - ddpfOverlayFormat.dwRBitMask = 0x00000000; - ddpfOverlayFormat.dwGBitMask = 0x00000000; - ddpfOverlayFormat.dwBBitMask = 0x00000000; - } else { - // We don't handle this case... - return DDERR_INVALIDPIXELFORMAT; - } - - // Setup the overlay surface's attributes in the surface descriptor - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; - ddsd.dwWidth = width; - ddsd.dwHeight = height; - ddsd.ddpfPixelFormat = ddpfOverlayFormat; - - ZeroMemory(&overlayfx, sizeof(overlayfx)); - overlayfx.dwSize = sizeof(overlayfx); - overlayflags = DDOVER_SHOW | DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE; - - dwDDSColor = ConvertGDIColor(g_dwBackgroundColor); - overlayfx.dckDestColorkey.dwColorSpaceLowValue = dwDDSColor; - overlayfx.dckDestColorkey.dwColorSpaceHighValue = dwDDSColor; - - // Attempt to create the surface with theses settings - ddrval = IDirectDraw7_CreateSurface (DirectDrawState.directdraw.dd, &ddsd, &DirectDrawState.overlay.surface, NULL); - if(SUCCEEDED(ddrval)) { - DirectDrawState.isoverlay = 1; - } else { - DirectDrawState.isoverlay = 0; - } - } else { - write_log ( "CreateOverlaySurface being called, but no overlay support with this card...!\n" ); - } - return ddrval; -} - - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_CreateSurface(int width, int height) -{ - HRESULT ddrval; - DWORD xtraflag = 0; - - DirectDrawState.flipping = single_buffer; - - if (DirectDrawState.fullscreen) { // Create a flipping pair! - ZeroMemory (&DirectDrawState.primary.desc, sizeof(DDSURFACEDESC2)); - DirectDrawState.primary.desc.dwSize = sizeof (DDSURFACEDESC2); - DirectDrawState.primary.desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - DirectDrawState.primary.desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; - DirectDrawState.primary.desc.dwBackBufferCount = 2; - ddrval = IDirectDraw7_CreateSurface(DirectDrawState.directdraw.dd, - &DirectDrawState.primary.desc, &DirectDrawState.primary.surface, NULL); - if (FAILED(ddrval)) { - // Create a non-flipping pair, since the flipping pair creation failed... - ZeroMemory (&DirectDrawState.primary.desc, sizeof(DDSURFACEDESC2)); - DirectDrawState.primary.desc.dwSize = sizeof(DDSURFACEDESC2); - DirectDrawState.primary.desc.dwFlags = DDSD_CAPS; - DirectDrawState.primary.desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - ddrval = IDirectDraw7_CreateSurface(DirectDrawState.directdraw.dd, - &DirectDrawState.primary.desc, - &DirectDrawState.primary.surface, - NULL); - } else { - DirectDrawState.flipping = triple_buffer; - } - clearsurface (primary_surface); - } else { - // We're not full-screen, so you cannot create a flipping pair... - ZeroMemory(&DirectDrawState.primary.desc, sizeof(DDSURFACEDESC2)); - DirectDrawState.primary.desc.dwSize = sizeof(DDSURFACEDESC2); - DirectDrawState.primary.desc.dwFlags = DDSD_CAPS; - DirectDrawState.primary.desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - ddrval = IDirectDraw7_CreateSurface(DirectDrawState.directdraw.dd, - &DirectDrawState.primary.desc, &DirectDrawState.primary.surface, NULL); - } - - if(FAILED(ddrval)) { - goto errout; - } else { - write_log ( "DDRAW: Primary %ssurface created in video-memory\n", - DirectDrawState.flipping != single_buffer ? "flipping " : ""); - } - - // Check if we can access the back-buffer of our flipping-pair (if present) - if(DirectDrawState.flipping != single_buffer) { - DDSCAPS2 ddSCaps; - ZeroMemory(&ddSCaps, sizeof(ddSCaps)); - ddSCaps.dwCaps = DDSCAPS_BACKBUFFER; - - ddrval = IDirectDrawSurface7_GetAttachedSurface(DirectDrawState.primary.surface, &ddSCaps, &DirectDrawState.secondary.surface); - if(SUCCEEDED(ddrval)) { - /* get third buffer */ - ZeroMemory(&ddSCaps, sizeof(ddSCaps)); - ddSCaps.dwCaps = DDSCAPS_FLIP; - - ddrval = IDirectDrawSurface7_GetAttachedSurface(DirectDrawState.secondary.surface, &ddSCaps, &DirectDrawState.tertiary.surface); - if(SUCCEEDED(ddrval)) { - clearsurface (tertiary_surface); - } else { - DirectDrawState.flipping = single_buffer; - } - } else { - DirectDrawState.flipping = single_buffer; - } - } - - // We always want a secondary-buffer when creating our primary-surface. If we're a flipping pair, - // the secondary buffer is already allocated. If we failed to create a flipping pair, or because - // we're not full-screen, then lets create ourselves a back-buffer manually. - if(DirectDrawState.flipping == single_buffer) { - ZeroMemory(&DirectDrawState.secondary.desc, sizeof(DDSURFACEDESC2)); - DirectDrawState.secondary.desc.dwSize = sizeof(DDSURFACEDESC2); - DirectDrawState.secondary.desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - DirectDrawState.secondary.desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | xtraflag; - DirectDrawState.secondary.desc.dwWidth = width; - DirectDrawState.secondary.desc.dwHeight = height; - ddrval = IDirectDraw7_CreateSurface(DirectDrawState.directdraw.dd, - &DirectDrawState.secondary.desc, &DirectDrawState.secondary.surface, NULL); - if(FAILED(ddrval)) { - write_log ( "DDRAW:Secondary surface creation attempt #1 failed with %s\n", DXError(ddrval)); - DirectDrawState.secondary.desc.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; - DirectDrawState.secondary.desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - ddrval = IDirectDraw7_CreateSurface(DirectDrawState.directdraw.dd, - &DirectDrawState.secondary.desc, &DirectDrawState.secondary.surface, NULL); - if(SUCCEEDED(ddrval)) - write_log ("DDRAW: Secondary surface created in plain system-memory\n"); - else - goto errout; - } else { - write_log ("DDRAW: Secondary surface created in video-memory\n"); - } - } - DirectDraw_ClearSurfaces (); -errout: - return ddrval; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -int DirectDraw_DetermineLocking( int wantfull ) -{ - int result = 0; - - switch(DirectDrawState.surface_type = try_surface_locks(wantfull)) - { - case invalid_surface: - case lockable_surface: - DirectDrawState.lockable.lpdesc = NULL; - DirectDrawState.lockable.lpdesc = NULL; - DirectDrawState.lockable.surface = NULL; - DirectDrawState.lockable.surface = NULL; - write_log ("set_ddraw: Couldn't lock primary, and no secondary available.\n"); - break; - case primary_surface: - DirectDrawState.lockable.lpdesc = &DirectDrawState.primary.desc; - DirectDrawState.lockable.lpdesc = &DirectDrawState.primary.desc; - DirectDrawState.lockable.surface = DirectDrawState.primary.surface; - DirectDrawState.lockable.surface = DirectDrawState.primary.surface; - result = 1; - break; - case overlay_surface: - DirectDrawState.lockable.lpdesc = &DirectDrawState.overlay.desc; - DirectDrawState.lockable.lpdesc = &DirectDrawState.overlay.desc; - DirectDrawState.lockable.surface = DirectDrawState.overlay.surface; - DirectDrawState.lockable.surface = DirectDrawState.overlay.surface; - result = 1; - break; - case secondary_surface: - DirectDrawState.lockable.lpdesc = &DirectDrawState.secondary.desc; - DirectDrawState.lockable.lpdesc = &DirectDrawState.secondary.desc; - DirectDrawState.lockable.surface = DirectDrawState.secondary.surface; - DirectDrawState.lockable.surface = DirectDrawState.secondary.surface; - result = 1; - break; - case tertiary_surface: - DirectDrawState.lockable.lpdesc = &DirectDrawState.tertiary.desc; - DirectDrawState.lockable.lpdesc = &DirectDrawState.tertiary.desc; - DirectDrawState.lockable.surface = DirectDrawState.tertiary.surface; - DirectDrawState.lockable.surface = DirectDrawState.tertiary.surface; - result = 1; - break; - } - - if(DirectDrawState.lockable.surface) - DirectDraw_SurfaceUnlock(); - - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_SetClipper(HWND hWnd) -{ - HRESULT ddrval; - - ddrval = IDirectDrawSurface7_SetClipper(DirectDrawState.primary.surface, - hWnd ? DirectDrawState.lpDDC : NULL); - if(hWnd && SUCCEEDED(ddrval)) - ddrval = IDirectDrawClipper_SetHWnd(DirectDrawState.lpDDC, 0, hWnd); - return ddrval; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_GetClipList(LPRGNDATA cliplist, LPDWORD size) -{ - HRESULT ddrval; - - ddrval = IDirectDrawClipper_GetClipList(DirectDrawState.lpDDC, NULL, cliplist, size); - - return ddrval; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -int DirectDraw_GetBytesPerPixel(void) -{ - if(DirectDrawState.lockable.lpdesc) - return (DirectDrawState.lockable.lpdesc->ddpfPixelFormat.dwRGBBitCount + 7) >> 3; - return 0; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_SetPalette(int remove) -{ - HRESULT ddrval; - if (DirectDrawState.primary.surface == NULL) - return DDERR_SURFACELOST; - ddrval = IDirectDrawSurface7_SetPalette (DirectDrawState.primary.surface, - remove ? NULL : DirectDrawState.lpDDP); - if (ddrval == DDERR_SURFACELOST) { - ddrval = restoresurface (DirectDrawState.primary.surface); - if (SUCCEEDED(ddrval)) { - ddrval = IDirectDrawSurface7_SetPalette (DirectDrawState.primary.surface, - remove ? NULL : DirectDrawState.lpDDP); - } - } - return ddrval; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_CreatePalette(LPPALETTEENTRY pal) -{ - HRESULT ddrval; - ddrval = IDirectDraw_CreatePalette(DirectDrawState.directdraw.dd, - DDPCAPS_8BIT | DDPCAPS_ALLOW256, pal, &DirectDrawState.lpDDP, NULL); - if(SUCCEEDED(ddrval)) - ddrval = DirectDraw_SetPalette(0); - return ddrval; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_SetPaletteEntries(int start, int count, PALETTEENTRY *palette) -{ - HRESULT ddrval = DDERR_NOPALETTEATTACHED; - if(DirectDrawState.lpDDP) - ddrval = IDirectDrawPalette_SetEntries(DirectDrawState.lpDDP, 0, start, count, palette); - return ddrval; -} - -/* Return one of the pixel formats declared in picasso96.h if the surface - * is usable for us, or RGBFB_NONE if it is not usable. */ -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -RGBFTYPE DirectDraw_GetSurfacePixelFormat(LPDDSURFACEDESC2 surface) -{ - int surface_is = 0; - DDPIXELFORMAT *pfp = NULL; - DWORD r, g, b; - DWORD surf_flags; - - surf_flags = surface->dwFlags; - pfp = &surface->ddpfPixelFormat; - - if((surf_flags & DDSD_PIXELFORMAT) == 0x0) - return RGBFB_NONE; - - if ((pfp->dwFlags & DDPF_RGB) == 0) - return RGBFB_NONE; - - r = pfp->dwRBitMask; - g = pfp->dwGBitMask; - b = pfp->dwBBitMask; - switch (pfp->dwRGBBitCount) { - case 8: - if ((pfp->dwFlags & DDPF_PALETTEINDEXED8) != 0) - return RGBFB_CHUNKY; - break; - - case 16: - if (r == 0xF800 && g == 0x07E0 && b == 0x001F) - return RGBFB_R5G6B5PC; - if (r == 0x7C00 && g == 0x03E0 && b == 0x001F) - return RGBFB_R5G5B5PC; - if (b == 0xF800 && g == 0x07E0 && r == 0x001F) - return RGBFB_B5G6R5PC; - if (b == 0x7C00 && g == 0x03E0 && r == 0x001F) - return RGBFB_B5G5R5PC; - /* This happens under NT - with r == b == g == 0 !!! */ - write_log ("Unknown 16 bit format %d %d %d\n", r, g, b); - break; - - case 24: - if (r == 0xFF0000 && g == 0x00FF00 && b == 0x0000FF) - return RGBFB_B8G8R8; - if (r == 0x0000FF && g == 0x00FF00 && b == 0xFF0000) - return RGBFB_R8G8B8; - break; - - case 32: - if (r == 0x00FF0000 && g == 0x0000FF00 && b == 0x000000FF) - return RGBFB_B8G8R8A8; - if (r == 0x000000FF && g == 0x0000FF00 && b == 0x00FF0000) - return RGBFB_R8G8B8A8; - if (r == 0xFF000000 && g == 0x00FF0000 && b == 0x0000FF00) - return RGBFB_A8B8G8R8; - if (r == 0x0000FF00 && g == 0x00FF0000 && b == 0xFF000000) - return RGBFB_A8R8G8B8; - break; - - default: - write_log ("Unknown %d bit format %d %d %d\n", pfp->dwRGBBitCount, r, g, b); - break; - } - return RGBFB_NONE; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -RGBFTYPE DirectDraw_GetPixelFormat(void) -{ - RGBFTYPE type; - if(DirectDrawState.lockable.lpdesc) - type = DirectDraw_GetSurfacePixelFormat(DirectDrawState.lockable.lpdesc); - else - type = DirectDraw_GetSurfacePixelFormat(&DirectDrawState.current.desc); - return type; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -DWORD DirectDraw_CurrentWidth(void) -{ - DWORD width; - width = DirectDrawState.current.desc.dwWidth; - return width; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -DWORD DirectDraw_CurrentHeight(void) -{ - DWORD height; - height = DirectDrawState.current.desc.dwHeight; - return height; -} - -int DirectDraw_GetVerticalBlankStatus (void) -{ - BOOL status; - if (FAILED(IDirectDraw7_GetVerticalBlankStatus (DirectDrawState.directdraw.dd, &status))) - return -1; - return status; -} - -DWORD DirectDraw_CurrentRefreshRate(void) -{ - DWORD height; - height = DirectDrawState.current.desc.dwRefreshRate; - return height; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -static int DirectDraw_BltFastStub4(LPDIRECTDRAWSURFACE7 dstsurf, DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 srcsurf, LPRECT srcrect) -{ - int result = 0; - HRESULT ddrval; - - while(FAILED(ddrval = IDirectDrawSurface7_BltFast(dstsurf, x, y, srcsurf, srcrect, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT))) { - if (ddrval == DDERR_SURFACELOST) { - ddrval = restoresurface (dstsurf); - if (FAILED(ddrval)) - break; - } else if (ddrval != DDERR_SURFACEBUSY) { - write_log ("BltFastStub7(): DirectDrawSURFACE7_BltFast() failed with %s\n", DXError (ddrval)); - break; - } - } - if(SUCCEEDED(ddrval)) - result = 1; - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_BltFast(surface_type_e dsttype, DWORD left, DWORD top, surface_type_e srctype, LPRECT srcrect) -{ - LPDIRECTDRAWSURFACE7 lpDDS4_dst, lpDDS4_src; - if(dsttype == primary_surface) { - lpDDS4_dst = DirectDrawState.primary.surface; - } else if (dsttype == temporary_surface) { - lpDDS4_dst = DirectDrawState.temporary.surface; - } else { - lpDDS4_dst = DirectDrawState.secondary.surface; - } - if(srctype == primary_surface) { - lpDDS4_src = DirectDrawState.primary.surface; - } else if (srctype == temporary_surface) { - lpDDS4_src = DirectDrawState.temporary.surface; - } else { - lpDDS4_src = DirectDrawState.secondary.surface; - } - return DirectDraw_BltFastStub4(lpDDS4_dst, left, top, lpDDS4_src, srcrect); -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -static HRESULT DirectDraw_BltStub(LPDIRECTDRAWSURFACE7 dstsurf, LPRECT dstrect, LPDIRECTDRAWSURFACE7 srcsurf, LPRECT srcrect, DWORD flags, LPDDBLTFX ddbltfx) -{ - int result = 0, errcnt = 0; - HRESULT ddrval; - - while(FAILED(ddrval = IDirectDrawSurface7_Blt(dstsurf, dstrect, srcsurf, srcrect, flags, ddbltfx))) { - if (ddrval == DDERR_SURFACELOST) { - if (errcnt > 10) - return 1; - errcnt++; - ddrval = restoresurface (dstsurf); - if (FAILED(ddrval)) { - break; - } - } else if (ddrval != DDERR_SURFACEBUSY) { - write_log ("BltStub(): DirectDrawSURFACE7_Blt() failed with %s\n", DXError (ddrval)); - break; - } - } - return ddrval; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ - -int DirectDraw_Flip(int wait) -{ - int result = 0; - HRESULT ddrval = DD_OK; - DWORD flags = DDFLIP_WAIT; - static int skip; - frame_time_t start; - - start = read_processor_time (); - if (DirectDrawState.flipping == triple_buffer) { - if (!currprefs.gfx_afullscreen && !currprefs.gfx_avsync) { - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags | DDFLIP_NOVSYNC); - } else if (currprefs.gfx_avsync) { - if (vblank_skip >= 0) { - skip++; - if (vblank_skip > skip) { - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags | DDFLIP_NOVSYNC); - } else { - skip = 0; - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags); - idletime += read_processor_time() - start; - } - } else { - if (flipinterval_supported) { - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags | DDFLIP_INTERVAL2); - idletime += read_processor_time() - start; - } else { - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags); - idletime += read_processor_time() - start; - result = DirectDraw_BltFast(tertiary_surface, 0, 0, primary_surface, NULL); - start = read_processor_time(); - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags); - idletime += read_processor_time() - start; - } - } - } else { - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags); - } - } else if(DirectDrawState.flipping == double_buffer) { - if (!currprefs.gfx_afullscreen && !currprefs.gfx_avsync) { - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags | DDFLIP_NOVSYNC); - } else { - ddrval = IDirectDrawSurface7_Flip(DirectDrawState.primary.surface, NULL, flags); - idletime += read_processor_time() - start; - } - } else { - return 1; - } - if(SUCCEEDED(ddrval)) { - result = 1; - } else { - if (ddrval == DDERR_SURFACELOST) { - static int recurse; - IDirectDrawSurface7_Restore (DirectDrawState.primary.surface); - if (!recurse) { - recurse++; - DirectDraw_Flip (wait); - recurse--; - } - } else { - write_log ("FLIP: DirectDrawSurface_Flip() failed with %s\n", DXError (ddrval)); - } - } - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_Blt(surface_type_e dsttype, LPRECT dstrect, - surface_type_e srctype, LPRECT srcrect, - DWORD flags, LPDDBLTFX fx) -{ - LPDIRECTDRAWSURFACE7 lpDDS4_dst, lpDDS4_src; - - if(dsttype == primary_surface) { - if(DirectDrawState.isoverlay) - lpDDS4_dst = DirectDrawState.overlay.surface; - else - lpDDS4_dst = DirectDrawState.primary.surface; - } else if(dsttype == secondary_surface) { - lpDDS4_dst = DirectDrawState.secondary.surface; - } else if(dsttype == tertiary_surface) { - lpDDS4_dst = DirectDrawState.tertiary.surface; - } else if(dsttype == temporary_surface) { - lpDDS4_dst = DirectDrawState.temporary.surface; - } else { - lpDDS4_dst = DirectDrawState.overlay.surface; - } - - if(srctype == primary_surface) { - lpDDS4_src = DirectDrawState.primary.surface; - } else if(srctype == secondary_surface) { - lpDDS4_src = DirectDrawState.secondary.surface; - } else if(srctype == tertiary_surface) { - lpDDS4_src = DirectDrawState.tertiary.surface; - } else if(srctype == temporary_surface) { - lpDDS4_src = DirectDrawState.temporary.surface; - } else if(srctype == overlay_surface) { - lpDDS4_src = DirectDrawState.overlay.surface; - } else { - lpDDS4_src = NULL; /* For using BltStub to do rect-fills */ - } - return DirectDraw_BltStub(lpDDS4_dst, dstrect, lpDDS4_src, srcrect, flags, fx); -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_WaitForVerticalBlank(DWORD flags) -{ - HRESULT result; - result = IDirectDraw7_WaitForVerticalBlank(DirectDrawState.directdraw.dd, flags, NULL); - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_EnumDisplayModes(DWORD flags, LPDDENUMMODESCALLBACK2 callback) -{ - HRESULT result; - result = IDirectDraw7_EnumDisplayModes(DirectDrawState.directdraw.dd, flags, NULL, NULL, callback); - return result; -} - -HRESULT DirectDraw_EnumDisplays(LPDDENUMCALLBACKEX callback ) -{ - HRESULT result; - result = DirectDrawEnumerateEx (callback, 0, DDENUM_DETACHEDSECONDARYDEVICES | DDENUM_ATTACHEDSECONDARYDEVICES); - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_FlipToGDISurface(void) -{ - HRESULT result = DDERR_GENERIC; - if(DirectDrawState.initialized) { - result = IDirectDraw7_FlipToGDISurface(DirectDrawState.directdraw.dd); - } - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_GetDC(HDC *hdc, surface_type_e surface) -{ - HRESULT result = ~DD_OK; - if(surface == primary_surface) - result = IDirectDrawSurface7_GetDC (DirectDrawState.primary.surface, hdc); - else if (surface == overlay_surface) - result = IDirectDrawSurface7_GetDC (DirectDrawState.overlay.surface, hdc); - else if (surface == secondary_surface) - result = IDirectDrawSurface7_GetDC (DirectDrawState.secondary.surface, hdc); - return result; -} - -/* - * FUNCTION: - * - * PURPOSE: - * - * PARAMETERS: - * - * RETURNS: - * - * NOTES: - * - * HISTORY: - * 1999.08.02 Brian King Creation - * - */ -HRESULT DirectDraw_ReleaseDC (HDC hdc, surface_type_e surface) -{ - HRESULT result; - if (surface == primary_surface) - result = IDirectDrawSurface7_ReleaseDC(DirectDrawState.primary.surface, hdc); - else if (surface == overlay_surface) - result = IDirectDrawSurface7_ReleaseDC(DirectDrawState.overlay.surface, hdc); - else - result = IDirectDrawSurface7_ReleaseDC(DirectDrawState.secondary.surface, hdc); - return result; -} - -extern int display_change_requested; - -HRESULT DirectDraw_UpdateOverlay(RECT sr, RECT dr) -{ - HRESULT result = DD_OK; - - if (DirectDrawState.isoverlay && DirectDrawState.overlay.surface) { - if ((drivercaps.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && drivercaps.dwAlignBoundarySrc) - sr.left = (sr.left + drivercaps.dwAlignBoundarySrc / 2) & ~(drivercaps.dwAlignBoundarySrc - 1); - if ((drivercaps.dwCaps & DDCAPS_ALIGNSIZESRC) && drivercaps.dwAlignSizeSrc) - sr.right = sr.left + (sr.right - sr.left + drivercaps.dwAlignSizeSrc / 2) & ~(drivercaps.dwAlignSizeSrc - 1); - if ((drivercaps.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && drivercaps.dwAlignBoundaryDest) - dr.left = (dr.left + drivercaps.dwAlignBoundaryDest / 2) & ~(drivercaps.dwAlignBoundaryDest - 1); - if ((drivercaps.dwCaps & DDCAPS_ALIGNSIZEDEST) && drivercaps.dwAlignSizeDest) - dr.right = dr.left + (dr.right - dr.left) & ~(drivercaps.dwAlignSizeDest - 1); - result = IDirectDrawSurface7_UpdateOverlay(DirectDrawState.overlay.surface, &sr, DirectDrawState.primary.surface, &dr, overlayflags, &overlayfx); - - } - if (FAILED(result)) { - if (result == DDERR_SURFACELOST) - display_change_requested++; - write_log ("UpdateOverlay failed %s\n", DXError (result)); - } - return DD_OK; -} - -char *outGUID (GUID *guid) -{ - static char gb[64]; - if (guid == NULL) - return "NULL"; - sprintf(gb, "%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X", - guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], - guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); - return gb; -} - -int DirectDraw_GetPrimaryPixelFormat (LPDDPIXELFORMAT ddpf) -{ - surface_type_e surface_type; - HRESULT ddrval; - - surface_type = DirectDraw_GetLockableType (); - ddpf->dwSize = sizeof (DDPIXELFORMAT); - if (surface_type == overlay_surface) - ddrval = IDirectDrawSurface7_GetPixelFormat (DirectDrawState.overlay.surface, ddpf); - else - ddrval = IDirectDrawSurface7_GetPixelFormat (DirectDrawState.primary.surface, ddpf); - if (FAILED(ddrval)) { - write_log ("GetPixelFormat failed\n%s\n", DXError (ddrval)); - return 0; - } - return 1; -} diff --git a/od-win32/dxwrap.c b/od-win32/dxwrap.c index 65d5579e..ad2bde33 100755 --- a/od-win32/dxwrap.c +++ b/od-win32/dxwrap.c @@ -12,9 +12,11 @@ struct ddstuff dxdata; +struct ddcaps dxcaps; static int flipinterval_supported = 1; int ddforceram = DDFORCED_DEFAULT; int useoverlay = 0; +int ddsoftwarecolorkey = 0; HRESULT DirectDraw_GetDisplayMode (void) { @@ -49,7 +51,7 @@ static void freemainsurface (void) releaser (dxdata.secondary, IDirectDrawSurface7_Release); releaser (dxdata.cursorsurface1, IDirectDrawSurface7_Release); releaser (dxdata.cursorsurface2, IDirectDrawSurface7_Release); -// releaser (dxdata.statussurface, IDirectDrawSurface7_Release); + releaser (dxdata.statussurface, IDirectDrawSurface7_Release); dxdata.backbuffers = 0; } @@ -104,7 +106,7 @@ static HRESULT restoresurfacex (LPDIRECTDRAWSURFACE7 surf1, LPDIRECTDRAWSURFACE7 return r1; } -static void clearsurf (LPDIRECTDRAWSURFACE7 surf) +static void clearsurf (LPDIRECTDRAWSURFACE7 surf, DWORD color) { HRESULT ddrval; DDBLTFX ddbltfx; @@ -112,7 +114,7 @@ static void clearsurf (LPDIRECTDRAWSURFACE7 surf) if (surf == NULL) return; memset(&ddbltfx, 0, sizeof (ddbltfx)); - ddbltfx.dwFillColor = 0; + ddbltfx.dwFillColor = color; ddbltfx.dwSize = sizeof (ddbltfx); while (FAILED (ddrval = IDirectDrawSurface7_Blt (surf, NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx))) { if (ddrval == DDERR_SURFACELOST) { @@ -129,7 +131,7 @@ void clearsurface (LPDIRECTDRAWSURFACE7 surf) { if (surf == NULL) surf = getlocksurface (); - clearsurf (surf); + clearsurf (surf, 0); } @@ -165,7 +167,7 @@ static void setsurfacecap (DDSURFACEDESC2 *desc, int w, int h, int mode) desc->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; if (mode == DDFORCED_VIDMEM) desc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; - if (w > dxdata.maxwidth || h > dxdata.maxheight || mode == DDFORCED_SYSMEM) + if (w > dxcaps.maxwidth || h > dxcaps.maxheight || mode == DDFORCED_SYSMEM) desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; desc->dwWidth = w; desc->dwHeight = h; @@ -191,14 +193,16 @@ LPDIRECTDRAWSURFACE7 allocsurface_3 (int width, int height, uae_u8 *ptr, int pit if (ck) { DWORD mask = 0xff00fe; - desc.dwFlags |= DDSD_CKSRCBLT; if (desc.ddpfPixelFormat.dwRGBBitCount == 16) mask = rgb32torgb16pc (mask); else if (desc.ddpfPixelFormat.dwRGBBitCount == 8) mask = 16; dxdata.colorkey = mask; - desc.ddckCKSrcBlt.dwColorSpaceLowValue = mask; - desc.ddckCKSrcBlt.dwColorSpaceHighValue = mask; + if (dxcaps.cancolorkey) { + desc.dwFlags |= DDSD_CKSRCBLT; + desc.ddckCKSrcBlt.dwColorSpaceLowValue = mask; + desc.ddckCKSrcBlt.dwColorSpaceHighValue = mask; + } } if (ptr) { @@ -210,8 +214,8 @@ LPDIRECTDRAWSURFACE7 allocsurface_3 (int width, int height, uae_u8 *ptr, int pit if (FAILED (ddrval)) { write_log ("IDirectDraw7_CreateSurface (%dx%d,%s): %s\n", width, height, alloctexts[forcemode], DXError (ddrval)); } else { - write_log ("Created %dx%dx%d (%p) surface in %s (%d)\n", width, height, desc.ddpfPixelFormat.dwRGBBitCount, surf, - alloctexts[forcemode], forcemode); + write_log ("Created %dx%dx%d (%p) surface in %s (%d)%s\n", width, height, desc.ddpfPixelFormat.dwRGBBitCount, surf, + alloctexts[forcemode], forcemode, ck ? (dxcaps.cancolorkey ? " hardware colorkey" : " software colorkey") : ""); } return surf; } @@ -227,7 +231,7 @@ static LPDIRECTDRAWSURFACE7 allocsurface_2 (int width, int height, int ck) for (;;) { s = allocsurface_3 (width, height, NULL, 0, ck, mode); if (s) { - clearsurf (s); + clearsurf (s, 0); return s; } if (mode == DDFORCED_NONLOCAL) @@ -261,20 +265,79 @@ void DirectDraw_FreeMainSurface (void) freemainsurface (); } +static int testck2 (LPDIRECTDRAWSURFACE7 tmp, RECT *r) +{ + DDSURFACEDESC2 desc; + if (locksurface (tmp, &desc)) { + uae_u8 *p = (uae_u8*)desc.lpSurface + r->top * desc.lPitch + r->left * desc.ddpfPixelFormat.dwRGBBitCount / 8; + DWORD v1 = ((uae_u32*)p)[0]; + DWORD v2 = ((uae_u32*)p)[1]; + unlocksurface (tmp); + // no more black = failure + if (v1 != 0 || v2 != 0) + return 0; + } + return 1; +} + +int dx_testck (void) +{ + int failed = 0; + LPDIRECTDRAWSURFACE7 cksurf; + LPDIRECTDRAWSURFACE7 tmp; + RECT r1; + int x; + + cksurf = dxdata.cursorsurface1; + tmp = dxdata.secondary; + if (!dxcaps.cancolorkey || !cksurf || !tmp) + return 1; + r1.left = 0; + r1.top = 0; + r1.right = dxcaps.cursorwidth; + r1.bottom = dxcaps.cursorheight; + failed = 0; + // test by blitting surface filled with color key color to destination filled with black + clearsurf (cksurf, dxdata.colorkey); + clearsurf (tmp, 0); + for (x = 0; x < 16; x++) { + DirectDraw_BlitRectCK (tmp, &r1, cksurf, NULL); + if (!testck2 (tmp, &r1)) // non-black = failed + failed = 1; + r1.left++; + r1.right++; + if (x & 1) { + r1.top++; + r1.bottom++; + } + } + clearsurface (cksurf); + clearsurface (tmp); + if (failed) { + write_log ("Color key test failure, display driver bug, falling back to software emulation.\n"); + dxcaps.cancolorkey = 0; + releaser (dxdata.cursorsurface1, IDirectDrawSurface7_Release); + dxdata.cursorsurface1 = allocsurface_2 (dxcaps.cursorwidth, dxcaps.cursorheight, TRUE); + return 0; + } + return 1; +} + static void createcursorsurface (void) { releaser (dxdata.cursorsurface1, IDirectDrawSurface7_Release); releaser (dxdata.cursorsurface2, IDirectDrawSurface7_Release); -// releaser (dxdata.statussurface, IDirectDrawSurface7_Release); - dxdata.cursorsurface1 = allocsurface_2 (dxdata.cursorwidth, dxdata.cursorheight, TRUE); - dxdata.cursorsurface2 = allocsurface_2 (dxdata.cursorwidth, dxdata.cursorheight, FALSE); + releaser (dxdata.statussurface, IDirectDrawSurface7_Release); + dxdata.cursorsurface1 = allocsurface_2 (dxcaps.cursorwidth, dxcaps.cursorheight, TRUE); + dxdata.cursorsurface2 = allocsurface_2 (dxcaps.cursorwidth, dxcaps.cursorheight, FALSE); // dxdata.statussurface = allocsurface_2 (dxdata.statuswidth, dxdata.statusheight, FALSE); if (dxdata.cursorsurface1) - clearsurf (dxdata.cursorsurface1); + clearsurf (dxdata.cursorsurface1, 0); if (dxdata.cursorsurface2) - clearsurf (dxdata.cursorsurface2); -// if (dxdata.statussurface) -// clearsurf (dxdata.statussurface); + clearsurf (dxdata.cursorsurface2, 0); + if (dxdata.statussurface) + clearsurf (dxdata.statussurface, 0); + dx_testck (); } HRESULT DirectDraw_CreateMainSurface (int width, int height) @@ -342,12 +405,12 @@ HRESULT DirectDraw_CreateMainSurface (int width, int height) if (FAILED (ddrval)) write_log ("IDirectDrawSurface7_GetSurfaceDesc: %s\n", DXError (ddrval)); if (dxdata.fsmodeset) { - clearsurf (dxdata.primary); + clearsurf (dxdata.primary, 0); dxdata.fsmodeset = 1; } dxdata.backbuffers = desc.dwBackBufferCount; - clearsurf (dxdata.flipping[0]); - clearsurf (dxdata.flipping[1]); + clearsurf (dxdata.flipping[0], 0); + clearsurf (dxdata.flipping[1], 0); surf = allocsurface (width, height); if (surf) { dxdata.secondary = surf; @@ -447,7 +510,7 @@ char *outGUID (const GUID *guid) const char *DXError (HRESULT ddrval) { static char dderr[1000]; - sprintf (dderr, "%08X S=%d F=%04X C=%04.4X (%d) (%s)", + sprintf (dderr, "%08X S=%d F=%04X C=%04X (%d) (%s)", ddrval, (ddrval & 0x80000000) ? 1 : 0, HRESULT_FACILITY(ddrval), HRESULT_CODE(ddrval), @@ -605,13 +668,13 @@ DWORD DirectDraw_GetBytesPerPixel (void) return (dxdata.native.ddpfPixelFormat.dwRGBBitCount + 7) >> 3; } -HRESULT DirectDraw_GetDC(HDC *hdc) +HRESULT DirectDraw_GetDC (HDC *hdc) { HRESULT result; result = IDirectDrawSurface7_GetDC (getlocksurface (), hdc); return result; } -HRESULT DirectDraw_ReleaseDC(HDC hdc) +HRESULT DirectDraw_ReleaseDC (HDC hdc) { HRESULT result; result = IDirectDrawSurface7_ReleaseDC (getlocksurface (), hdc); @@ -709,7 +772,59 @@ int DirectDraw_BlitToPrimary (RECT *rect) return result; } -static void DirectDraw_Blt (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *srcrect) +static int DirectDraw_Blt_EmuCK (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *srcrect) +{ + DDSURFACEDESC2 dstd, srcd; + int x, y, w, h, bpp; + int sx, sy, dx, dy; + int ok; + DWORD ck; + + ok = 0; + ck = dxdata.colorkey; + sx = sy = dx = dy = 0; + if (srcrect) { + sx = srcrect->left; + sy = srcrect->top; + } + if (dstrect) { + dx = dstrect->left; + dy = dstrect->top; + } + if (locksurface (dst, &dstd)) { + if (locksurface (src, &srcd)) { + bpp = srcd.ddpfPixelFormat.dwRGBBitCount / 8; + h = srcd.dwHeight; + w = srcd.dwWidth; + if (srcrect) + w = srcrect->right - srcrect->left; + if (srcrect) + h = srcrect->bottom - srcrect->top; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + uae_u8 *sp = (uae_u8*)srcd.lpSurface + srcd.lPitch * (y + sy) + (x + sx) * bpp; + uae_u8 *dp = (uae_u8*)dstd.lpSurface + dstd.lPitch * (y + dy) + (x + dx) * bpp; + if (bpp == 1) { + if (*sp != ck) + *dp = *sp; + } else if (bpp == 2) { + if (((uae_u16*)sp)[0] != ck) + ((uae_u16*)dp)[0] = ((uae_u16*)sp)[0]; + } else if (bpp == 4) { + if (((uae_u32*)sp)[0] != ck) + ((uae_u32*)dp)[0] = ((uae_u32*)sp)[0]; + } + } + } + ok = 1; + unlocksurface (src); + } + unlocksurface (dst); + } + return ok; +} + +static int DirectDraw_Blt (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *srcrect, int ck) { HRESULT ddrval; @@ -718,27 +833,32 @@ static void DirectDraw_Blt (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRA if (src == NULL) src = getlocksurface (); if (dst == src) - return; - while (FAILED(ddrval = IDirectDrawSurface7_Blt (dst, dstrect, src, srcrect, DDBLT_WAIT, NULL))) { + return 1; + if (ck && dxcaps.cancolorkey == 0) + return DirectDraw_Blt_EmuCK (dst, dstrect, src, srcrect); + while (FAILED(ddrval = IDirectDrawSurface7_Blt (dst, dstrect, src, srcrect, DDBLT_WAIT | (ck ? DDBLT_KEYSRC : 0), NULL))) { if (ddrval == DDERR_SURFACELOST) { ddrval = restoresurfacex (dst, src); if (FAILED (ddrval)) - break; + return 0; } else if (ddrval != DDERR_SURFACEBUSY) { write_log ("DirectDraw_Blit: %s\n", DXError (ddrval)); - break; + return 0; } } + return 1; } - -void DirectDraw_Blit (LPDIRECTDRAWSURFACE7 dst, LPDIRECTDRAWSURFACE7 src) +int DirectDraw_Blit (LPDIRECTDRAWSURFACE7 dst, LPDIRECTDRAWSURFACE7 src) { - DirectDraw_Blt (dst, NULL, src, NULL); + return DirectDraw_Blt (dst, NULL, src, NULL, FALSE); } - -void DirectDraw_BlitRect (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *scrrect) +int DirectDraw_BlitRect (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *scrrect) +{ + return DirectDraw_Blt (dst, dstrect, src, scrrect, FALSE); +} +int DirectDraw_BlitRectCK (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *scrrect) { - DirectDraw_Blt (dst, dstrect, src, scrrect); + return DirectDraw_Blt (dst, dstrect, src, scrrect, TRUE); } static void DirectDraw_FillSurface (LPDIRECTDRAWSURFACE7 dst, RECT *rect, uae_u32 color) @@ -879,9 +999,110 @@ void DirectDraw_Release (void) memset (&dxdata, 0, sizeof (dxdata)); } +struct dxcap { + int num; + char *name; + DWORD mask; +}; +static struct dxcap dxcapsinfo[] = +{ + { 1, "DDCAPS_BLT", DDCAPS_BLT }, + { 1, "DDCAPS_BLTQUEUE", DDCAPS_BLTQUEUE }, + { 1, "DDCAPS_BLTFOURCC", DDCAPS_BLTFOURCC }, + { 1, "DDCAPS_BLTCOLORFILL", DDCAPS_BLTSTRETCH }, + { 1, "DDCAPS_BLTSTRETCH", DDCAPS_BLTSTRETCH }, + { 1, "DDCAPS_CANBLTSYSMEM", DDCAPS_CANBLTSYSMEM }, + { 1, "DDCAPS_CANCLIP", DDCAPS_CANCLIP }, + { 1, "DDCAPS_CANCLIPSTRETCHED", DDCAPS_CANCLIPSTRETCHED }, + { 1, "DDCAPS_COLORKEY", DDCAPS_COLORKEY }, + { 1, "DDCAPS_COLORKEYHWASSIST", DDCAPS_COLORKEYHWASSIST }, + { 1, "DDCAPS_GDI", DDCAPS_GDI }, + { 1, "DDCAPS_NOHARDWARE", DDCAPS_NOHARDWARE }, + { 1, "DDCAPS_OVERLAY", DDCAPS_OVERLAY }, + { 1, "DDCAPS_VBI", DDCAPS_VBI }, + { 1, "DDCAPS_3D", DDCAPS_3D }, + { 1, "DDCAPS_BANKSWITCHED", DDCAPS_BANKSWITCHED }, + { 1, "DDCAPS_PALETTE", DDCAPS_PALETTE }, + { 1, "DDCAPS_PALETTEVSYNC", DDCAPS_PALETTEVSYNC }, + { 1, "DDCAPS_READSCANLINE", DDCAPS_READSCANLINE }, + { 2, "DDCAPS2_CERTIFIED", DDCAPS2_CERTIFIED }, + { 2, "DDCAPS2_CANRENDERWINDOWED", DDCAPS2_CANRENDERWINDOWED }, + { 2, "DDCAPS2_NOPAGELOCKREQUIRED", DDCAPS2_NOPAGELOCKREQUIRED }, + { 2, "DDCAPS2_FLIPNOVSYNC", DDCAPS2_FLIPNOVSYNC }, + { 2, "DDCAPS2_FLIPINTERVAL", DDCAPS2_FLIPINTERVAL }, + { 2, "DDCAPS2_NO2DDURING3DSCENE", DDCAPS2_NO2DDURING3DSCENE }, + { 2, "DDCAPS2_NONLOCALVIDMEM", DDCAPS2_NONLOCALVIDMEM }, + { 2, "DDCAPS2_NONLOCALVIDMEMCAPS", DDCAPS2_NONLOCALVIDMEMCAPS }, + { 2, "DDCAPS2_WIDESURFACES", DDCAPS2_WIDESURFACES }, + { 3, "DDCKEYCAPS_DESTBLT", DDCKEYCAPS_DESTBLT }, + { 3, "DDCKEYCAPS_DESTBLTCLRSPACE", DDCKEYCAPS_DESTBLTCLRSPACE }, + { 3, "DDCKEYCAPS_SRCBLT", DDCKEYCAPS_SRCBLT }, + { 3, "DDCKEYCAPS_SRCBLTCLRSPACE", DDCKEYCAPS_SRCBLTCLRSPACE }, + { 0, NULL } +}; + +static void showcaps (DDCAPS_DX7 *dc) +{ + int i, out; + write_log ("%08x %08x %08x %08x %08x %08x\n", + dc->dwCaps, dc->dwCaps2, dc->dwCKeyCaps, dc->dwFXCaps, dc->dwFXAlphaCaps, dc->dwPalCaps, dc->ddsCaps); + out = 0; + for (i = 0; dxcapsinfo[i].name; i++) { + DWORD caps = 0; + switch (dxcapsinfo[i].num) + { + case 1: + caps = dc->dwCaps; + break; + case 2: + caps = dc->dwCaps2; + break; + case 3: + caps = dc->dwCKeyCaps; + break; + } + if (caps & dxcapsinfo[i].mask) { + if (out > 0) + write_log (","); + write_log ("%s", dxcapsinfo[i].name); + out++; + } + } + if (out > 0) + write_log ("\n"); + if ((dc->dwCaps & DDCAPS_COLORKEY) && (dc->dwCKeyCaps & DDCKEYCAPS_SRCBLT)) + dxcaps.cancolorkey = TRUE; + if (dc->dwCaps2 & DDCAPS2_NONLOCALVIDMEM) + dxcaps.cannonlocalvidmem = TRUE; + if (ddsoftwarecolorkey) + dxcaps.cancolorkey = FALSE; +} + + +static void getcaps (void) +{ + HRESULT hr; + DDCAPS_DX7 dc, hc; + + memset (&dc, 0, sizeof dc); + memset (&hc, 0, sizeof hc); + dc.dwSize = sizeof dc; + hc.dwSize = sizeof hc; + hr = IDirectDraw7_GetCaps (dxdata.maindd, &dc, &hc); + if (FAILED (hr)) { + write_log ("IDirectDraw7_GetCaps() failed %s\n", DXError (hr)); + return; + } + write_log ("DriverCaps: "); + showcaps (&dc); + write_log ("HELCaps : "); + showcaps (&hc); +} + int DirectDraw_Start (GUID *guid) { static int d3ddone; + static int first; HRESULT ddrval; LPDIRECT3D9 d3d; D3DCAPS9 d3dCaps; @@ -922,17 +1143,17 @@ int DirectDraw_Start (GUID *guid) // dxdata.statuswidth = 800; // dxdata.statusheight = TD_TOTAL_HEIGHT; - dxdata.cursorwidth = 48; - dxdata.cursorheight = 48; + dxcaps.cursorwidth = 48; + dxcaps.cursorheight = 48; if (!d3ddone) { d3dDLL = LoadLibrary ("D3D9.DLL"); if (d3dDLL) { d3d = Direct3DCreate9 (D3D9b_SDK_VERSION); if (d3d) { if (SUCCEEDED (IDirect3D9_GetDeviceCaps (d3d, 0, D3DDEVTYPE_HAL, &d3dCaps))) { - dxdata.maxwidth = d3dCaps.MaxTextureWidth; - dxdata.maxheight = d3dCaps.MaxTextureHeight; - write_log ("Max hardware surface size: %dx%d\n", dxdata.maxwidth, dxdata.maxheight); + dxcaps.maxwidth = d3dCaps.MaxTextureWidth; + dxcaps.maxheight = d3dCaps.MaxTextureHeight; + write_log ("Max hardware surface size: %dx%d\n", dxcaps.maxwidth, dxcaps.maxheight); } IDirect3D9_Release (d3d); } @@ -940,10 +1161,15 @@ int DirectDraw_Start (GUID *guid) } d3ddone = 1; } - if (dxdata.maxwidth < 2048) - dxdata.maxwidth = 2048; - if (dxdata.maxheight < 2048) - dxdata.maxheight = 2048; + if (dxcaps.maxwidth < 2048) + dxcaps.maxwidth = 2048; + if (dxcaps.maxheight < 2048) + dxcaps.maxheight = 2048; + + if (!first) { + first = 1; + getcaps (); + } if (SUCCEEDED (DirectDraw_GetDisplayMode ())) { dxdata.ddinit = 1; diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index 10e5fcb1..c1b36b0e 100755 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -26,17 +26,24 @@ struct ddstuff int lockcnt; DWORD pitch; HWND hwnd; - int maxwidth, maxheight; uae_u32 colorkey; int islost, isoverlay; LPDIRECTDRAWSURFACE7 cursorsurface1; LPDIRECTDRAWSURFACE7 cursorsurface2; - int cursorwidth, cursorheight; LPDIRECTDRAWSURFACE7 statussurface; int statuswidth, statusheight; + +}; +struct ddcaps +{ + int cursorwidth, cursorheight; + int maxwidth, maxheight; + int cancolorkey; + int cannonlocalvidmem; }; extern struct ddstuff dxdata; +extern struct ddcaps dxcaps; struct ScreenResolution { @@ -119,8 +126,9 @@ HRESULT DirectDraw_FlipToGDISurface (void); int DirectDraw_Flip (int doflip); int DirectDraw_BlitToPrimary (RECT *rect); int DirectDraw_BlitToPrimaryScale (RECT *dstrect, RECT *srcrect); -void DirectDraw_Blit (LPDIRECTDRAWSURFACE7 dst, LPDIRECTDRAWSURFACE7 src); -void DirectDraw_BlitRect (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *scrrect); +int DirectDraw_Blit (LPDIRECTDRAWSURFACE7 dst, LPDIRECTDRAWSURFACE7 src); +int DirectDraw_BlitRect (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *scrrect); +int DirectDraw_BlitRectCK (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *scrrect); void DirectDraw_Fill (RECT *rect, uae_u32 color); void DirectDraw_FillPrimary (void); @@ -130,6 +138,7 @@ HRESULT DirectDraw_CreatePalette (LPPALETTEENTRY pal); void dx_check (void); int dx_islost (void); +int dx_testck (void); #define DDFORCED_NONLOCAL 0 #define DDFORCED_DEFAULT 1 diff --git a/od-win32/dxwrap_old.h b/od-win32/dxwrap_old.h deleted file mode 100755 index de338984..00000000 --- a/od-win32/dxwrap_old.h +++ /dev/null @@ -1,258 +0,0 @@ -#ifndef __DXWRAP_H__ -#define __DXWRAP_H__ - -#include "ddraw.h" - -struct ScreenResolution -{ - uae_u32 width; /* in pixels */ - uae_u32 height; /* in pixels */ -}; - -#define MAX_PICASSO_MODES 300 -#define MAX_REFRESH_RATES 100 -struct PicassoResolution -{ - struct ScreenResolution res; - int depth; /* depth in bytes-per-pixel */ - int residx; - int refresh[MAX_REFRESH_RATES]; /* refresh-rates in Hz */ - char name[25]; - /* Bit mask of RGBFF_xxx values. */ - uae_u32 colormodes; -}; -extern struct PicassoResolution *DisplayModes; -extern GUID *displayGUID; - -#define MAX_DISPLAYS 10 -struct MultiDisplay { - int primary, disabled, gdi; - GUID guid; - char *name; - struct PicassoResolution *DisplayModes; - RECT rect; -}; -extern struct MultiDisplay Displays[MAX_DISPLAYS]; - -typedef enum { - BLIT_FALSE, - BLIT_NOR, - BLIT_ONLYDST, - BLIT_NOTSRC, - BLIT_ONLYSRC, - BLIT_NOTDST, - BLIT_EOR, - BLIT_NAND, - BLIT_AND, - BLIT_NEOR, - BLIT_DST, - BLIT_NOTONLYSRC, - BLIT_SRC, - BLIT_NOTONLYDST, - BLIT_OR, - BLIT_TRUE, - BLIT_LAST -} BLIT_OPCODE; - -/* Types for RGBFormat used */ -typedef enum { - RGBFB_NONE, /* no valid RGB format (should not happen) */ - RGBFB_CLUT, /* palette mode, set colors when opening screen using - tags or use SetRGB32/LoadRGB32(...) */ - RGBFB_R8G8B8, /* TrueColor RGB (8 bit each) */ - RGBFB_B8G8R8, /* TrueColor BGR (8 bit each) */ - RGBFB_R5G6B5PC, /* HiColor16 (5 bit R, 6 bit G, 5 bit B), - format: gggbbbbbrrrrrggg */ - RGBFB_R5G5B5PC, /* HiColor15 (5 bit each), format: gggbbbbb0rrrrrgg */ - RGBFB_A8R8G8B8, /* 4 Byte TrueColor ARGB (A unused alpha channel) */ - RGBFB_A8B8G8R8, /* 4 Byte TrueColor ABGR (A unused alpha channel) */ - RGBFB_R8G8B8A8, /* 4 Byte TrueColor RGBA (A unused alpha channel) */ - RGBFB_B8G8R8A8, /* 4 Byte TrueColor BGRA (A unused alpha channel) */ - RGBFB_R5G6B5, /* HiColor16 (5 bit R, 6 bit G, 5 bit B), - format: rrrrrggggggbbbbb */ - RGBFB_R5G5B5, /* HiColor15 (5 bit each), format: 0rrrrrgggggbbbbb */ - RGBFB_B5G6R5PC, /* HiColor16 (5 bit R, 6 bit G, 5 bit B), - format: gggrrrrrbbbbbggg */ - RGBFB_B5G5R5PC, /* HiColor15 (5 bit each), format: gggrrrrr0bbbbbbgg */ - - /* By now, the following formats are for use with a hardware window only - (bitmap operations may be implemented incompletely) */ - - RGBFB_Y4U2V2, /* 2 Byte TrueColor YUV (CCIR recommendation CCIR601). - Each two-pixel unit is stored as one longword - containing luminance (Y) for each of the two pixels, - and chrominance (U,V) for alternate pixels. - The missing chrominance values are generated by - interpolation. (Y1-U0-Y0-V0) */ - RGBFB_Y4U1V1, /* 1 Byte TrueColor ACCUPAK. Four adjacent pixels form - a packet of 5 bits Y (luminance) each pixel and 6 bits - U and V (chrominance) shared by the four pixels */ - - RGBFB_MaxFormats -} RGBFTYPE; - -#define RGBFF_NONE (1<blocksize - 1)) { - gui_message ("hd: poscheck failed, offset not aligned to blocksize! (%I64X & %04.4X = %04.4X\n", pos, hfd->blocksize, pos & hfd->blocksize); + gui_message ("hd: poscheck failed, offset not aligned to blocksize! (%I64X & %04X = %04X\n", pos, hfd->blocksize, pos & hfd->blocksize); abort (); } } @@ -901,7 +901,7 @@ static BOOL GetDevicePropertyFromName(const char *DevicePath, DWORD Index, DWORD PARTITION_INFORMATION *pi = &dli->PartitionEntry[i]; if (pi->PartitionType == PARTITION_ENTRY_UNUSED) continue; - write_log ("%d: num: %d type: %02.2X offset: %I64d size: %I64d, ", i, pi->PartitionNumber, pi->PartitionType, pi->StartingOffset.QuadPart, pi->PartitionLength.QuadPart); + write_log ("%d: num: %d type: %02X offset: %I64d size: %I64d, ", i, pi->PartitionNumber, pi->PartitionType, pi->StartingOffset.QuadPart, pi->PartitionLength.QuadPart); if (pi->RecognizedPartition == 0) { write_log ("unrecognized\n"); continue; diff --git a/od-win32/keyboard_win32.c b/od-win32/keyboard_win32.c index 939e993d..af86730e 100755 --- a/od-win32/keyboard_win32.c +++ b/od-win32/keyboard_win32.c @@ -354,7 +354,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate) if (scancode == specialkeycode ()) return; - //write_log ( "keyboard = %d scancode = 0x%02.2x state = %d\n", keyboard, scancode, newstate ); + //write_log ( "keyboard = %d scancode = 0x%02x state = %d\n", keyboard, scancode, newstate ); if (newstate) { switch (scancode) { diff --git a/od-win32/midi.c b/od-win32/midi.c index 19f607aa..ce3e2338 100755 --- a/od-win32/midi.c +++ b/od-win32/midi.c @@ -428,7 +428,7 @@ static long midi_inptr = 0, midi_inlast = 0; static void add1byte(DWORD_PTR w) //put 1 Byte to Midibuffer { if(midi_inlast >= BUFFLEN - 10) { - TRACE(("add1byte buffer full %d %d (%02.2X)\n", midi_inlast, midi_inptr, w)); + TRACE(("add1byte buffer full %d %d (%02X)\n", midi_inlast, midi_inptr, w)); return; } midibuf[midi_inlast++] = (uae_u8)w; @@ -436,7 +436,7 @@ static void add1byte(DWORD_PTR w) //put 1 Byte to Midibuffer static void add2byte(DWORD_PTR w) //put 2 Byte to Midibuffer { if(midi_inlast >= BUFFLEN - 10) { - TRACE(("add2byte buffer full %d %d (%04.4X)\n", midi_inlast, midi_inptr, w)); + TRACE(("add2byte buffer full %d %d (%04X)\n", midi_inlast, midi_inptr, w)); return; } midibuf[midi_inlast++] = (uae_u8)w; @@ -446,7 +446,7 @@ static void add2byte(DWORD_PTR w) //put 2 Byte to Midibuffer static void add3byte(DWORD_PTR w) //put 3 Byte to Midibuffer { if(midi_inlast >= BUFFLEN - 10) { - TRACE(("add3byte buffer full %d %d (%08.8X)\n", midi_inlast, midi_inptr, w)); + TRACE(("add3byte buffer full %d %d (%08X)\n", midi_inlast, midi_inptr, w)); return; } midibuf[midi_inlast++] = (uae_u8)w; @@ -475,7 +475,7 @@ LONG getmidibyte(void) //return midibyte or -1 if none gui_message(szMessage); overflow = 0; } - TRACE(("getmidibyte(%02.2X)\n", midibuf[midi_inptr])); + TRACE(("getmidibyte(%02X)\n", midibuf[midi_inptr])); if (midibuf[midi_inptr] >= 0xf0) { // only check for free buffers if status sysex for (i = 0;i < MIDI_INBUFFERS;i++) { if (midiin[i].dwFlags == (MHDR_DONE|MHDR_PREPARED)) { @@ -525,7 +525,7 @@ static void CALLBACK MidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD_PTR dwInstance,D if(wMsg == MM_MIM_DATA || wMsg == MM_MIM_MOREDATA) { BYTE state = (BYTE)dwParam1; - TRACE(("%s %08.8X\n", wMsg == MM_MIM_DATA ? "MM_MIM_DATA" : "MM_MIM_MOREDATA", dwParam1)); + TRACE(("%s %08X\n", wMsg == MM_MIM_DATA ? "MM_MIM_DATA" : "MM_MIM_MOREDATA", dwParam1)); if(state == 254) goto end; if(state < 0xf0) diff --git a/od-win32/mman.c b/od-win32/mman.c index 244b2113..5bda50f3 100755 --- a/od-win32/mman.c +++ b/od-win32/mman.c @@ -80,6 +80,8 @@ static uae_u32 lowmem (void) currprefs.gfxmem_size >>= 1; changed_prefs.gfxmem_size = currprefs.gfxmem_size; } + if (currprefs.z3fastmem2_size < 128 * 1024 * 1024) + currprefs.z3fastmem2_size = changed_prefs.z3fastmem2_size = 0; return change; } @@ -213,7 +215,7 @@ void preinit_shm (void) memstats.dwLength = sizeof(memstats); GlobalMemoryStatus(&memstats); totalphys64 = memstats.dwTotalPhys; - total64 = (uae_u64)memstats.dwAvailPageFile + (uae_u64)memstats.dwAvailPhys; + total64 = (uae_u64)memstats.dwAvailPageFile + (uae_u64)memstats.dwTotalPhys; pGlobalMemoryStatusEx = (GLOBALMEMORYSTATUSEX)GetProcAddress(GetModuleHandle("kernel32.dll"), "GlobalMemoryStatusEx"); if (pGlobalMemoryStatusEx) { memstatsex.dwLength = sizeof (MEMORYSTATUSEX); diff --git a/od-win32/picasso96_win.c b/od-win32/picasso96_win.c index 83b62c1b..51a04103 100755 --- a/od-win32/picasso96_win.c +++ b/od-win32/picasso96_win.c @@ -1301,7 +1301,6 @@ static int mouseput; void picasso_putcursor (int sx, int sy, int sw, int sh) { int xdiff, ydiff, xdiff2, ydiff2; - DWORD ddrval; LPDIRECTDRAWSURFACE7 dstsurf = dxdata.secondary; if (!cursorvisible || !hwsprite || !cursorok) @@ -1351,10 +1350,7 @@ void picasso_putcursor (int sx, int sy, int sw, int sh) cursor_r2.right = cursorwidth + xdiff + xdiff2; cursor_r2.bottom = cursorheight + ydiff + ydiff2; - ddrval = IDirectDrawSurface7_Blt (dxdata.cursorsurface2, &cursor_r2, dstsurf, &cursor_r1, DDBLT_WAIT, NULL); - if (FAILED (ddrval)) { - if (ddrval != DDERR_SURFACELOST) - write_log ("Cursor surface blit1 failed: %s\n", DXError (ddrval)); + if (!DirectDraw_BlitRect (dxdata.cursorsurface2, &cursor_r2, dstsurf, &cursor_r1)) { recursor (); return; } @@ -1364,10 +1360,7 @@ void picasso_putcursor (int sx, int sy, int sw, int sh) cursor_r2.right = cursor_r2.left + cursorwidth + xdiff + xdiff2; cursor_r2.bottom = cursor_r2.top + cursorheight + ydiff + ydiff2; - ddrval = IDirectDrawSurface7_Blt (dstsurf, &cursor_r1, dxdata.cursorsurface1, &cursor_r2, DDBLT_WAIT | DDBLT_KEYSRC, NULL); - if (FAILED (ddrval)) { - if (ddrval != DDERR_SURFACELOST) - write_log ("Cursor surface blit2 failed: %s\n", DXError (ddrval)); + if (!DirectDraw_BlitRectCK (dstsurf, &cursor_r1, dxdata.cursorsurface1, &cursor_r2)) { recursor (); return; } @@ -1479,10 +1472,10 @@ static uae_u32 setspriteimage (uaecptr bi) bi, get_long (bi + PSSO_BoardInfo_MouseImage), w, h, hiressprite - 1, doubledsprite, bi + PSSO_BoardInfo_MouseImage)); - if (w > dxdata.cursorwidth) - w = dxdata.cursorwidth; - if (h > dxdata.cursorheight) - h = dxdata.cursorheight; + if (w > dxcaps.cursorwidth) + w = dxcaps.cursorwidth; + if (h > dxcaps.cursorheight) + h = dxcaps.cursorheight; bpp = picasso_vidinfo.pixbytes; if (!w || !h || get_long (bi + PSSO_BoardInfo_MouseImage) == 0) { diff --git a/od-win32/scaler.c b/od-win32/scaler.c index 7cf6ce51..baf1e88d 100755 --- a/od-win32/scaler.c +++ b/od-win32/scaler.c @@ -29,6 +29,9 @@ static uint32 redMask; static uint32 greenMask; static uint32 blueMask; +unsigned int LUT16to32[65536]; +unsigned int RGBtoYUV[65536]; + int Init_2xSaI (int rb, int gb, int bb, int rs, int gs, int bs) { if (rb + gb + bb == 16) { @@ -91,7 +94,7 @@ static _inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) { return x + y; } -void Super2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { +void Super2xSaI_16(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { const uint16 *bP; uint16 *dP; const uint32 nextlineSrc = srcPitch >> 1; @@ -198,7 +201,113 @@ void Super2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstP } } -void SuperEagle(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { +void Super2xSaI_32(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { + const uint16 *bP; + uint32 *dP; + const uint32 nextlineSrc = srcPitch >> 1; + + while (height--) { + int i; + bP = (const uint16 *)srcPtr; + dP = (uint32 *)dstPtr; + + for (i = 0; i < width; ++i) { + uint32 color4, color5, color6; + uint32 color1, color2, color3; + uint32 colorA0, colorA1, colorA2, colorA3; + uint32 colorB0, colorB1, colorB2, colorB3; + uint32 colorS1, colorS2; + uint32 product1a, product1b, product2a, product2b; + +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + + colorB0 = *(bP - nextlineSrc - 1); + colorB1 = *(bP - nextlineSrc); + colorB2 = *(bP - nextlineSrc + 1); + colorB3 = *(bP - nextlineSrc + 2); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + nextlineSrc - 1); + color2 = *(bP + nextlineSrc); + color3 = *(bP + nextlineSrc + 1); + colorS1 = *(bP + nextlineSrc + 2); + + colorA0 = *(bP + 2 * nextlineSrc - 1); + colorA1 = *(bP + 2 * nextlineSrc); + colorA2 = *(bP + 2 * nextlineSrc + 1); + colorA3 = *(bP + 2 * nextlineSrc + 2); + +//-------------------------------------- + if (color2 == color6 && color5 != color3) { + product2b = product1b = color2; + } else if (color5 == color3 && color2 != color6) { + product2b = product1b = color5; + } else if (color5 == color3 && color2 == color6) { + register int r = 0; + + r += GetResult(color6, color5, color1, colorA1); + r += GetResult(color6, color5, color4, colorB1); + r += GetResult(color6, color5, colorA2, colorS1); + r += GetResult(color6, color5, colorB2, colorS2); + + if (r > 0) + product2b = product1b = color6; + else if (r < 0) + product2b = product1b = color5; + else { + product2b = product1b = INTERPOLATE(color5, color6); + } + } else { + if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) + product2b = Q_INTERPOLATE(color3, color3, color3, color2); + else if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) + product2b = Q_INTERPOLATE(color2, color2, color2, color3); + else + product2b = INTERPOLATE(color2, color3); + + if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) + product1b = Q_INTERPOLATE(color6, color6, color6, color5); + else if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) + product1b = Q_INTERPOLATE(color6, color5, color5, color5); + else + product1b = INTERPOLATE(color5, color6); + } + + if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) + product2a = INTERPOLATE(color2, color5); + else if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE(color2, color5); + else + product2a = color2; + + if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) + product1a = INTERPOLATE(color2, color5); + else if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE(color2, color5); + else + product1a = color5; + + *(dP + 0) = LUT16to32[(uint16) product1a]; + *(dP + 1) = LUT16to32[(uint16) product1b]; + *(dP + dstPitch/4 + 0) = LUT16to32[(uint16) product2a]; + *(dP + dstPitch/4 + 1) = LUT16to32[(uint16) product2b]; + + bP += 1; + dP += 2; + } + + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + } +} +void SuperEagle_16(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { const uint16 *bP; uint16 *dP; const uint32 nextlineSrc = srcPitch >> 1; @@ -316,7 +425,124 @@ void SuperEagle(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstP } } -void _2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { +void SuperEagle_32(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { + const uint16 *bP; + uint32 *dP; + const uint32 nextlineSrc = srcPitch >> 1; + + while (height--) { + int i; + bP = (const uint16 *)srcPtr; + dP = (uint32 *)dstPtr; + for (i = 0; i < width; ++i) { + uint32 color4, color5, color6; + uint32 color1, color2, color3; + uint32 colorA1, colorA2, colorB1, colorB2, colorS1, colorS2; + uint32 product1a, product1b, product2a, product2b; + + colorB1 = *(bP - nextlineSrc); + colorB2 = *(bP - nextlineSrc + 1); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + nextlineSrc - 1); + color2 = *(bP + nextlineSrc); + color3 = *(bP + nextlineSrc + 1); + colorS1 = *(bP + nextlineSrc + 2); + + colorA1 = *(bP + 2 * nextlineSrc); + colorA2 = *(bP + 2 * nextlineSrc + 1); + + // -------------------------------------- + if (color5 != color3) + { + if (color2 == color6) + { + product1b = product2a = color2; + if ((color1 == color2) || (color6 == colorB2)) { + product1a = INTERPOLATE(color2, color5); + product1a = INTERPOLATE(color2, product1a); + } else { + product1a = INTERPOLATE(color5, color6); + } + + if ((color6 == colorS2) || (color2 == colorA1)) { + product2b = INTERPOLATE(color2, color3); + product2b = INTERPOLATE(color2, product2b); + } else { + product2b = INTERPOLATE(color2, color3); + } + } + else + { + product2b = product1a = INTERPOLATE(color2, color6); + product2b = Q_INTERPOLATE(color3, color3, color3, product2b); + product1a = Q_INTERPOLATE(color5, color5, color5, product1a); + + product2a = product1b = INTERPOLATE(color5, color3); + product2a = Q_INTERPOLATE(color2, color2, color2, product2a); + product1b = Q_INTERPOLATE(color6, color6, color6, product1b); + } + } + else //if (color5 == color3) + { + if (color2 != color6) + { + product2b = product1a = color5; + + if ((colorB1 == color5) || (color3 == colorS1)) { + product1b = INTERPOLATE(color5, color6); + product1b = INTERPOLATE(color5, product1b); + } else { + product1b = INTERPOLATE(color5, color6); + } + + if ((color3 == colorA2) || (color4 == color5)) { + product2a = INTERPOLATE(color5, color2); + product2a = INTERPOLATE(color5, product2a); + } else { + product2a = INTERPOLATE(color2, color3); + } + } + else //if (color2 != color6) + { + register int r = 0; + + r += GetResult(color6, color5, color1, colorA1); + r += GetResult(color6, color5, color4, colorB1); + r += GetResult(color6, color5, colorA2, colorS1); + r += GetResult(color6, color5, colorB2, colorS2); + + if (r > 0) { + product1b = product2a = color2; + product1a = product2b = INTERPOLATE(color5, color6); + } else if (r < 0) { + product2b = product1a = color5; + product1b = product2a = INTERPOLATE(color5, color6); + } else { + product2b = product1a = color5; + product1b = product2a = color2; + } + } + } + + *(dP + 0) = LUT16to32[(uint16) product1a]; + *(dP + 1) = LUT16to32[(uint16) product1b]; + *(dP + dstPitch/4 + 0) = LUT16to32[(uint16) product2a]; + *(dP + dstPitch/4 + 1) = LUT16to32[(uint16) product2b]; + + bP += 1; + dP += 2; + } + + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + } +} +void _2xSaI_16(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { const uint16 *bP; uint16 *dP; const uint32 nextlineSrc = srcPitch >> 1; @@ -450,6 +676,139 @@ void _2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch } } +void _2xSaI_32(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { + const uint16 *bP; + uint32 *dP; + const uint32 nextlineSrc = srcPitch >> 1; + + while (height--) { + int i; + bP = (const uint16 *)srcPtr; + dP = (uint32 *)dstPtr; + + for (i = 0; i < width; ++i) { + + register uint32 colorA, colorB; + uint32 colorC, colorD, + colorE, colorF, colorG, colorH, colorI, colorJ, colorK, colorL, colorM, colorN, colorO, colorP; + uint32 product, product1, product2; + +//--------------------------------------- +// Map of the pixels: I|E F|J +// G|A B|K +// H|C D|L +// M|N O|P + colorI = *(bP - nextlineSrc - 1); + colorE = *(bP - nextlineSrc); + colorF = *(bP - nextlineSrc + 1); + colorJ = *(bP - nextlineSrc + 2); + + colorG = *(bP - 1); + colorA = *(bP); + colorB = *(bP + 1); + colorK = *(bP + 2); + + colorH = *(bP + nextlineSrc - 1); + colorC = *(bP + nextlineSrc); + colorD = *(bP + nextlineSrc + 1); + colorL = *(bP + nextlineSrc + 2); + + colorM = *(bP + 2 * nextlineSrc - 1); + colorN = *(bP + 2 * nextlineSrc); + colorO = *(bP + 2 * nextlineSrc + 1); + colorP = *(bP + 2 * nextlineSrc + 2); + + if ((colorA == colorD) && (colorB != colorC)) { + if (((colorA == colorE) && (colorB == colorL)) || + ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))) { + product = colorA; + } else { + product = INTERPOLATE(colorA, colorB); + } + + if (((colorA == colorG) && (colorC == colorO)) || + ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))) { + product1 = colorA; + } else { + product1 = INTERPOLATE(colorA, colorC); + } + product2 = colorA; + } else if ((colorB == colorC) && (colorA != colorD)) { + if (((colorB == colorF) && (colorA == colorH)) || + ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))) { + product = colorB; + } else { + product = INTERPOLATE(colorA, colorB); + } + + if (((colorC == colorH) && (colorA == colorF)) || + ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))) { + product1 = colorC; + } else { + product1 = INTERPOLATE(colorA, colorC); + } + product2 = colorB; + } else if ((colorA == colorD) && (colorB == colorC)) { + if (colorA == colorB) { + product = colorA; + product1 = colorA; + product2 = colorA; + } else { + register int r = 0; + + product1 = INTERPOLATE(colorA, colorC); + product = INTERPOLATE(colorA, colorB); + + r += GetResult(colorA, colorB, colorG, colorE); + r -= GetResult(colorB, colorA, colorK, colorF); + r -= GetResult(colorB, colorA, colorH, colorN); + r += GetResult(colorA, colorB, colorL, colorO); + + if (r > 0) + product2 = colorA; + else if (r < 0) + product2 = colorB; + else { + product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD); + } + } + } else { + product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD); + + if ((colorA == colorC) && (colorA == colorF) + && (colorB != colorE) && (colorB == colorJ)) { + product = colorA; + } else if ((colorB == colorE) && (colorB == colorD) + && (colorA != colorF) && (colorA == colorI)) { + product = colorB; + } else { + product = INTERPOLATE(colorA, colorB); + } + + if ((colorA == colorB) && (colorA == colorH) + && (colorG != colorC) && (colorC == colorM)) { + product1 = colorA; + } else if ((colorC == colorG) && (colorC == colorD) + && (colorA != colorH) && (colorA == colorI)) { + product1 = colorC; + } else { + product1 = INTERPOLATE(colorA, colorC); + } + } + + *(dP + 0) = LUT16to32[(uint16) colorA]; + *(dP + 1) = LUT16to32[(uint16) product]; + *(dP + dstPitch/4 + 0) = LUT16to32[(uint16) product1]; + *(dP + dstPitch/4 + 1) = LUT16to32[(uint16) product2]; + + bP += 1; + dP += 2; + } + + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + } +} /* * This file is part of the Advance project. @@ -1498,9 +1857,6 @@ void AdMame2x32(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ -unsigned int LUT16to32[65536]; -unsigned int RGBtoYUV[65536]; - #define swap16(x) (((x >> 24) & 0x000000ff) | ((x >> 8) & 0x0000ff00) | ((x << 8) & 0x00ff0000) | ((x << 16) & 0xff000000)) void hq_init (int rb, int gb, int bb, int rs, int gs, int bs) diff --git a/od-win32/serial_win32.c b/od-win32/serial_win32.c index 07ada736..963ffe82 100755 --- a/od-win32/serial_win32.c +++ b/od-win32/serial_win32.c @@ -136,7 +136,7 @@ static void checkreceive (int mode) } else { ninebitdata = recdata; if ((ninebitdata & ~1) != 0xa8) { - write_log ("SERIAL: 9-bit serial emulation sync lost, %02.2X != %02.2X\n", ninebitdata & ~1, 0xa8); + write_log ("SERIAL: 9-bit serial emulation sync lost, %02X != %02X\n", ninebitdata & ~1, 0xa8); ninebitdata = 0; return; } @@ -154,7 +154,7 @@ static void checkreceive (int mode) data_in_serdatr = 1; serial_check_irq (); #if SERIALDEBUG > 2 - write_log ("SERIAL: received %02.2X (%c)\n", serdatr & 0xff, dochar (serdatr)); + write_log ("SERIAL: received %02X (%c)\n", serdatr & 0xff, dochar (serdatr)); #endif #endif } @@ -183,7 +183,7 @@ static void checksend (int mode) data_in_serdat = 0; INTREQ_f (0x8000 | 0x0001); #if SERIALDEBUG > 2 - write_log ("SERIAL: send %04.4X (%c)\n", serdatshift, dochar (serdatshift)); + write_log ("SERIAL: send %04X (%c)\n", serdatshift, dochar (serdatshift)); #endif } } @@ -265,7 +265,7 @@ uae_u16 SERDATR (void) if (ovrun) serdatr |= 0x8000; #if SERIALDEBUG > 2 - write_log ( "SERIAL: read 0x%04.4x (%c) %x\n", serdatr, dochar (serdatr), m68k_getpc ()); + write_log ( "SERIAL: read 0x%04x (%c) %x\n", serdatr, dochar (serdatr), m68k_getpc ()); #endif ovrun = 0; data_in_serdatr = 0; diff --git a/od-win32/shm.c b/od-win32/shm.c index ace18c53..65552280 100755 --- a/od-win32/shm.c +++ b/od-win32/shm.c @@ -146,8 +146,8 @@ void *shmat(int shmid, LPVOID shmaddr, int shmflg) return shm->addr; shm->addr = MapViewOfFileEx (shm->filemapping, FILE_MAP_WRITE, 0, 0, shm->size, shmaddr); if (addr == NULL) - win32_error("MapViewOfFileEx %08.8X", shmaddr); - write_log ("shmat %08.8X -> %08.8X\n", shmaddr, shm->addr); + win32_error("MapViewOfFileEx %08X", shmaddr); + write_log ("shmat %08X -> %08X\n", shmaddr, shm->addr); shm->attached = 1; return shm->addr; } @@ -157,9 +157,9 @@ int shmdt(const void *shmaddr) int i; if (shmaddr == (void*)0xffffffff) return 0; - write_log ("shmdt: %08.8X\n", shmaddr); + write_log ("shmdt: %08X\n", shmaddr); if (UnmapViewOfFile ((LPCVOID)shmaddr) == FALSE) { - win32_error("UnmapViewOfFile %08.8X", shmaddr); + win32_error("UnmapViewOfFile %08X", shmaddr); return 0; } for( i = 0; i < MAX_SHMID; i++ ) { diff --git a/od-win32/soundcheck.c b/od-win32/soundcheck.c index ad4386b5..ce0c0400 100755 --- a/od-win32/soundcheck.c +++ b/od-win32/soundcheck.c @@ -47,7 +47,7 @@ static void write_log2 (const char *format, ...) static const char *DXError (HRESULT ddrval) { static char dderr[200]; - sprintf(dderr, "%08.8X S=%d F=%04.4X C=%04.4X (%d) (%s)", + sprintf(dderr, "%08X S=%d F=%04X C=%04X (%d) (%s)", ddrval, (ddrval & 0x80000000) ? 1 : 0, HRESULT_FACILITY(ddrval), HRESULT_CODE(ddrval), diff --git a/od-win32/sounddep/sound.c b/od-win32/sounddep/sound.c index 98c0ffc1..030fe7aa 100755 --- a/od-win32/sounddep/sound.c +++ b/od-win32/sounddep/sound.c @@ -57,17 +57,15 @@ uae_u16 sndbuffer[SND_MAX_BUFFER]; uae_u16 *sndbufpt; int sndbufsize; -static int max_sndbufsize, snd_configsize, dsoundbuf; +static int max_sndbufsize, snd_configsize, dsoundbuf, samplesize; static int snd_writeoffset, snd_maxoffset, snd_totalmaxoffset_uf, snd_totalmaxoffset_of; static int waiting_for_buffer; static uae_sem_t sound_sem, sound_init_sem; -#define MAX_SOUND_DEVICES 10 - -static char *sound_devices[MAX_SOUND_DEVICES]; -GUID sound_device_guid[MAX_SOUND_DEVICES]; -static int num_sound_devices; +struct sound_device sound_devices[MAX_SOUND_DEVICES]; +struct sound_device record_devices[MAX_SOUND_DEVICES]; +static int num_sound_devices, num_record_devices; static LPDIRECTSOUND8 lpDS; static LPDIRECTSOUNDBUFFER8 lpDSBsecondary; @@ -297,7 +295,7 @@ static int open_audio_ds (int size) int round, i; DWORD speakerconfig; - enumerate_sound_devices (0); + enumerate_sound_devices (); size *= ch * 2; snd_configsize = size; sndbufsize = size / 32; @@ -319,7 +317,7 @@ static int open_audio_ds (int size) recalc_offsets(); - hr = DirectSoundCreate8 (&sound_device_guid[currprefs.win32_soundcard], &lpDS, NULL); + hr = DirectSoundCreate8 (&sound_devices[currprefs.win32_soundcard].guid, &lpDS, NULL); if (FAILED (hr)) { write_log ("SOUND: DirectSoundCreate8() failure: %s\n", DXError (hr)); return 0; @@ -357,9 +355,9 @@ static int open_audio_ds (int size) } speakerconfig = fillsupportedmodes (lpDS, freq, supportedmodes); - write_log ("SOUND: %08.8X ", speakerconfig); + write_log ("SOUND: %08X ", speakerconfig); for (i = 0; supportedmodes[i].ch; i++) - write_log ("%d:%08.8X ", supportedmodes[i].ch, supportedmodes[i].ksmode); + write_log ("%d:%08X ", supportedmodes[i].ch, supportedmodes[i].ksmode); write_log ("\n"); for (round = 0; supportedmodes[round].ch; round++) { @@ -386,8 +384,10 @@ static int open_audio_ds (int size) wavfmt.Format.nBlockAlign = wavfmt.Format.wBitsPerSample / 8 * wavfmt.Format.nChannels; wavfmt.Format.nAvgBytesPerSec = wavfmt.Format.nBlockAlign * wavfmt.Format.nSamplesPerSec; - write_log ("SOUND: %08.8X,CH=%d,FREQ=%d '%s' buffer %d, dist %d\n", - ksmode, ch, freq, sound_devices[currprefs.win32_soundcard], max_sndbufsize, snd_configsize); + samplesize = ch * 2; + write_log ("SOUND: %08X,CH=%d,FREQ=%d '%s' buffer %d (%d), dist %d\n", + ksmode, ch, freq, sound_devices[currprefs.win32_soundcard].name, + max_sndbufsize / samplesize, max_sndbufsize, snd_configsize / samplesize); memset (&sound_buffer, 0, sizeof (sound_buffer)); sound_buffer.dwSize = sizeof (sound_buffer); @@ -406,7 +406,7 @@ static int open_audio_ds (int size) sound_buffer.dwFlags |= DSBCAPS_LOCSOFTWARE; hr = IDirectSound_CreateSoundBuffer (lpDS, &sound_buffer, &pdsb, NULL); if (SUCCEEDED(hr)) { - write_log ("SOUND: Couldn't use hardware buffer (switched to software): %s\n", DXError (hr2)); + //write_log ("SOUND: Couldn't use hardware buffer (switched to software): %s\n", DXError (hr2)); break; } } @@ -573,7 +573,7 @@ void restart_sound_buffer (void) write_log ("SOUND: DirectSoundBuffer_GetCurrentPosition failed, %s\n", DXError (hr)); return; } - writepos = playpos + snd_writeoffset; + writepos = safed + snd_writeoffset; if (writepos < 0) writepos += dsoundbuf; cf (writepos); @@ -632,7 +632,7 @@ static void finish_sound_buffer_ds (void) break; } } - write_log ("SOUND: %d = (%d - %d)\n", safedist - playpos, safedist, playpos); + write_log ("SOUND: %d = (%d - %d)\n", (safedist - playpos) / samplesize, safedist / samplesize, playpos / samplesize); recalc_offsets (); safedist -= playpos; if (safedist < 64) @@ -651,8 +651,9 @@ static void finish_sound_buffer_ds (void) waiting_for_buffer = -1; restart_sound_buffer (); write_log ("SOUND: bs=%d w=%d max=%d tof=%d tuf=%d\n", - sndbufsize, snd_writeoffset, - snd_maxoffset, snd_totalmaxoffset_of, snd_totalmaxoffset_uf); + sndbufsize / samplesize, snd_writeoffset / samplesize, + snd_maxoffset / samplesize, snd_totalmaxoffset_of / samplesize, + snd_totalmaxoffset_uf / samplesize); tfprev = timeframes + 10; tfprev = (tfprev / 10) * 10; } @@ -670,7 +671,7 @@ static void finish_sound_buffer_ds (void) return; } if ((status & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) != (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) { - write_log ("SOUND: status = %08.8X\n", status); + write_log ("SOUND: status = %08X\n", status); restore (DSERR_BUFFERLOST); return; } @@ -681,10 +682,10 @@ static void finish_sound_buffer_ds (void) write_log ("SOUND: GetCurrentPosition failed: %s\n", DXError (hr)); return; } - if (writepos >= playpos) - diff = writepos - playpos; + if (writepos >= safepos) + diff = writepos - safepos; else - diff = dsoundbuf - playpos + writepos; + diff = dsoundbuf - safepos + writepos; if (diff < sndbufsize || diff > snd_totalmaxoffset_uf) { #if 0 @@ -711,7 +712,7 @@ static void finish_sound_buffer_ds (void) statuscnt = SND_STATUSCNT; restart_sound_buffer (); diff = snd_writeoffset; - write_log ("SOUND: underflow (%d %d)\n", diff, snd_totalmaxoffset_of); + write_log ("SOUND: underflow (%d %d)\n", diff / samplesize, snd_totalmaxoffset_of / samplesize); break; } @@ -734,7 +735,7 @@ static void finish_sound_buffer_ds (void) if (restore (hr)) return; if (FAILED (hr)) { - write_log ("SOUND: lock failed: %s (%d %d)\n", DXError (hr), writepos, sndbufsize); + write_log ("SOUND: lock failed: %s (%d %d)\n", DXError (hr), writepos / samplesize, sndbufsize / samplesize); return; } memcpy (b1, sndbuffer, s1); @@ -770,7 +771,8 @@ static void finish_sound_buffer_ds (void) if (tfprev != timeframes) { if (sound_debug && !(tfprev % 10)) write_log ("b=%4d,%5d,%5d,%5d d=%5d vd=%5.0f s=%+02.1f\n", - sndbufsize, snd_configsize, max_sndbufsize, dsoundbuf, diff, vdiff, skipmode); + sndbufsize / samplesize, snd_configsize / samplesize, max_sndbufsize / samplesize, + dsoundbuf / samplesize, diff / samplesize, vdiff, skipmode); tfprev = timeframes; if (!avioutput_audio) sound_setadjust (skipmode); @@ -829,29 +831,40 @@ void finish_sound_buffer (void) finish_sound_buffer_ds (); } -static BOOL CALLBACK DSEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext) +static BOOL CALLBACK DSEnumProc (LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext) { - int i = num_sound_devices; - if (i == MAX_SOUND_DEVICES) + struct sound_device *sd = lpContext; + int i; + + for (i = 0; i < MAX_SOUND_DEVICES; i++) { + if (sd[i].name == NULL) + break; + } + if (i >= MAX_SOUND_DEVICES) return TRUE; if (lpGUID != NULL) - memcpy (&sound_device_guid[i], lpGUID, sizeof (GUID)); - sound_devices[i] = my_strdup (lpszDesc); - num_sound_devices++; + memcpy (&sd[i].guid, lpGUID, sizeof (GUID)); + sd[i].name = my_strdup (lpszDesc); return TRUE; } -char **enumerate_sound_devices (int *total) +int enumerate_sound_devices (void) { - if (!num_sound_devices) - DirectSoundEnumerate ((LPDSENUMCALLBACK)DSEnumProc, 0); - if (total) - *total = num_sound_devices; + if (!num_sound_devices) { + DirectSoundEnumerate ((LPDSENUMCALLBACK)DSEnumProc, sound_devices); + DirectSoundCaptureEnumerate ((LPDSENUMCALLBACK)DSEnumProc, record_devices); + for (num_sound_devices = 0; num_sound_devices < MAX_SOUND_DEVICES; num_sound_devices++) { + if (sound_devices[num_sound_devices].name == NULL) + break; + } + for (num_record_devices = 0; num_record_devices < MAX_SOUND_DEVICES; num_record_devices++) { + if (record_devices[num_record_devices].name == NULL) + break; + } + } if (currprefs.win32_soundcard >= num_sound_devices) currprefs.win32_soundcard = 0; - if (num_sound_devices) - return sound_devices; - return 0; + return num_sound_devices; } #include diff --git a/od-win32/sounddep/sound.h b/od-win32/sounddep/sound.h index c0307d47..d57f31bf 100755 --- a/od-win32/sounddep/sound.h +++ b/od-win32/sounddep/sound.h @@ -19,7 +19,7 @@ extern void resume_sound (void); extern void pause_sound (void); extern void reset_sound (void); extern void sound_setadjust (double); -extern char **enumerate_sound_devices (int *total); +extern int enumerate_sound_devices (void); extern int drivesound_init (void); extern void drivesound_free (void); extern void sound_mute (int); diff --git a/od-win32/win32.c b/od-win32/win32.c index 2de0252d..0fd98892 100755 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -58,6 +58,7 @@ #include "sys/mman.h" #include "avioutput.h" #include "ahidsound.h" +#include "ahidsound_new.h" #include "zfile.h" #include "savestate.h" #include "ioport.h" @@ -331,6 +332,7 @@ void resumepaused (void) resume_sound (); #ifdef AHI ahi_open_sound (); + ahi2_pause_sound (0); #endif #ifdef CD32 akiko_exitgui (); @@ -353,6 +355,7 @@ void setpaused (void) pause_sound (); #ifdef AHI ahi_close_sound (); + ahi2_pause_sound (1); #endif #ifdef CD32 akiko_entergui (); @@ -424,7 +427,7 @@ void setpriority (struct threadpriorities *pri) int err; err = SetPriorityClass (GetCurrentProcess (), pri->classvalue); if (!err) - write_log ("priority set failed, %08.8X\n", GetLastError ()); + write_log ("priority set failed, %08X\n", GetLastError ()); } static void releasecapture (void) @@ -1023,6 +1026,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, case WM_INPUT: handle_rawinput (lParam); + DefWindowProc (hWnd, message, wParam, lParam); return 0; case WM_NOTIFY: @@ -3037,6 +3041,11 @@ static int process_arg(char **xargv) userdtsc = 1; continue; } + if (!strcmp (arg, "-ddsoftwarecolorkey")) { + extern int ddsoftwarecolorkey; + ddsoftwarecolorkey = 1; + continue; + } if (i + 1 < argc) { char *np = argv[i + 1]; @@ -3387,7 +3396,7 @@ LONG WINAPI WIN32_ExceptionFilter (struct _EXCEPTION_POINTERS *pExceptionPointer efix (&ctx->Edx, p, ps, &got); efix (&ctx->Esi, p, ps, &got); efix (&ctx->Edi, p, ps, &got); - write_log ("Access violation! (68KPC=%08.8X HOSTADDR=%p)\n", M68K_GETPC, p); + write_log ("Access violation! (68KPC=%08X HOSTADDR=%p)\n", M68K_GETPC, p); if (got == 0) { write_log ("failed to find and fix the problem (%p). crashing..\n", p); } else { diff --git a/od-win32/win32.h b/od-win32/win32.h index 56270753..93047698 100755 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,9 +15,9 @@ #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100) #define GETBDD(x) ((x) % 100) -#define WINUAEBETA 1 -#define WINUAEPUBLICBETA 4 -#define WINUAEDATE MAKEBD(2008, 7, 2) +#define WINUAEBETA 5 +#define WINUAEPUBLICBETA 1 +#define WINUAEDATE MAKEBD(2008, 7, 13) #define WINUAEEXTRA "" #define WINUAEREV "" @@ -139,4 +139,13 @@ extern void logging_cleanup (void); extern LONG WINAPI WIN32_ExceptionFilter (struct _EXCEPTION_POINTERS *pExceptionPointers, DWORD ec); +#define MAX_SOUND_DEVICES 10 +struct sound_device +{ + GUID guid; + char *name; +}; +extern struct sound_device sound_devices[MAX_SOUND_DEVICES]; +extern struct sound_device record_devices[MAX_SOUND_DEVICES]; + #endif diff --git a/od-win32/win32_scale2x.c b/od-win32/win32_scale2x.c index 4cd409a7..867b2c6e 100755 --- a/od-win32/win32_scale2x.c +++ b/od-win32/win32_scale2x.c @@ -26,11 +26,11 @@ struct uae_filter uaefilters[] = { UAE_FILTER_HQ, 0, 2, "hq2x/3x/4x", "hqx", 0, 0, UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32, UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32, UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32 }, - { UAE_FILTER_SUPEREAGLE, 0, 2, "SuperEagle", "supereagle", 0, 0, UAE_FILTER_MODE_16_16, 0, 0 }, + { UAE_FILTER_SUPEREAGLE, 0, 2, "SuperEagle", "supereagle", 0, 0, UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32, 0, 0 }, - { UAE_FILTER_SUPER2XSAI, 0, 2, "Super2xSaI", "super2xsai", 0, 0, UAE_FILTER_MODE_16_16, 0, 0 }, + { UAE_FILTER_SUPER2XSAI, 0, 2, "Super2xSaI", "super2xsai", 0, 0, UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32, 0, 0 }, - { UAE_FILTER_2XSAI, 0, 2, "2xSaI", "2xsai", 0, 0, UAE_FILTER_MODE_16_16, 0, 0 }, + { UAE_FILTER_2XSAI, 0, 2, "2xSaI", "2xsai", 0, 0, UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32, 0, 0 }, { UAE_FILTER_PAL, 1, 1, "PAL", "pal", 0, UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_32_32, 0, 0, 0 }, @@ -155,6 +155,7 @@ void S2X_init (int dw, int dh, int aw, int ah, int mult, int ad, int dd) int flags = 0; int res_shift; + S2X_free (); if (currprefs.leds_on_screen & STATUSLINE_CHIPSET) changed_prefs.leds_on_screen = currprefs.leds_on_screen = currprefs.leds_on_screen | STATUSLINE_TARGET; @@ -192,11 +193,11 @@ void S2X_init (int dw, int dh, int aw, int ah, int mult, int ad, int dd) scale = mult; temp_width = dst_width * 3; - if (temp_width > dxdata.maxwidth) - temp_width = dxdata.maxwidth; + if (temp_width > dxcaps.maxwidth) + temp_width = dxcaps.maxwidth; temp_height = dst_height * 3; - if (temp_height > dxdata.maxheight) - temp_height = dxdata.maxheight; + if (temp_height > dxcaps.maxheight) + temp_height = dxcaps.maxheight; if (temp_width < dst_width) temp_width = dst_width; if (temp_height < dst_height) @@ -247,6 +248,8 @@ void S2X_render (void) if (!dptr) /* weird things can happen */ goto end; + if (dptr < (uae_u8*)desc.lpSurface) + goto endfail; if (usedfilter->type == UAE_FILTER_SCALE2X ) { /* 16+32/2X */ @@ -296,25 +299,40 @@ void S2X_render (void) } } - } else if (usedfilter->type == UAE_FILTER_SUPEREAGLE) { /* 16/2X */ + } else if (usedfilter->type == UAE_FILTER_SUPEREAGLE) { /* 16/32/2X */ - if (scale == 2 && amiga_depth == 16 && dst_depth == 16) { - SuperEagle (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); - ok = 1; + if (scale == 2 && amiga_depth == 16) { + if (dst_depth == 16) { + SuperEagle_16 (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); + ok = 1; + } else if (dst_depth == 32) { + SuperEagle_32 (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); + ok = 1; + } } - } else if (usedfilter->type == UAE_FILTER_SUPER2XSAI) { /* 16/2X */ + } else if (usedfilter->type == UAE_FILTER_SUPER2XSAI) { /* 16/32/2X */ - if (scale == 2 && amiga_depth == 16 && dst_depth == 16) { - Super2xSaI (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); - ok = 1; + if (scale == 2 && amiga_depth == 16) { + if (dst_depth == 16) { + Super2xSaI_16 (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); + ok = 1; + } else if (dst_depth == 32) { + Super2xSaI_32 (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); + ok = 1; + } } - } else if (usedfilter->type == UAE_FILTER_2XSAI) { /* 16/2X */ + } else if (usedfilter->type == UAE_FILTER_2XSAI) { /* 16/32/2X */ - if (scale == 2 && amiga_depth == 16 && dst_depth == 16) { - _2xSaI (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); - ok = 1; + if (scale == 2 && amiga_depth == 16) { + if (dst_depth == 16) { + _2xSaI_16 (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); + ok = 1; + } else if (dst_depth == 32) { + _2xSaI_32 (sptr, gfxvidinfo.rowbytes, dptr, pitch, aw, ah); + ok = 1; + } } } else if (usedfilter->type == UAE_FILTER_PAL) { /* 16/32/1X */ @@ -341,6 +359,7 @@ void S2X_render (void) } +endfail: if (ok == 0 && currprefs.gfx_filter) { usedfilter = &uaefilters[0]; changed_prefs.gfx_filter = usedfilter->type; diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index e05a7173..585ab75c 100755 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -262,7 +262,7 @@ static int set_ddraw_2 (void) int rounds = 3; for (;;) { HRESULT olderr; - write_log ("set_ddraw: Trying %dx%d, bits=%d, refreshrate=%d\n", width, height, bits, freq); + write_log ("set_ddraw: trying %dx%d, bits=%d, refreshrate=%d\n", width, height, bits, freq); ddrval = DirectDraw_SetDisplayMode (width, height, bits, freq); if (SUCCEEDED (ddrval)) break; @@ -283,7 +283,7 @@ static int set_ddraw_2 (void) goto oops; ddrval = DirectDraw_CreateMainSurface (width, height); if (FAILED(ddrval)) { - write_log ("set_ddraw: Couldn't CreateSurface() for primary because %s.\n", DXError (ddrval)); + write_log ("set_ddraw: couldn't CreateSurface() for primary because %s.\n", DXError (ddrval)); goto oops; } ddrval = DirectDraw_SetClipper (hAmigaWnd); @@ -297,7 +297,8 @@ static int set_ddraw_2 (void) DirectDraw_CreatePalette (currentmode->pal); } - write_log ("set_ddraw() called, and is %dx%d@%d-bytes\n", width, height, bits); + dx_testck (); + write_log ("set_ddraw: %dx%d@%d-bytes\n", width, height, bits); return 1; oops: return 0; @@ -1001,9 +1002,9 @@ int check_prefs_changed_gfx (void) c |= currprefs.gfx_filter_gamma != changed_prefs.gfx_filter_gamma ? (1|8) : 0; //c |= currprefs.gfx_filter_ != changed_prefs.gfx_filter_ ? (1|8) : 0; - c |= currprefs.gfx_resolution != changed_prefs.gfx_resolution ? 2 : 0; - c |= currprefs.gfx_linedbl != changed_prefs.gfx_linedbl ? 2 : 0; - c |= currprefs.gfx_lores_mode != changed_prefs.gfx_lores_mode ? 1 : 0; + c |= currprefs.gfx_resolution != changed_prefs.gfx_resolution ? (2 | 8) : 0; + c |= currprefs.gfx_linedbl != changed_prefs.gfx_linedbl ? (2 | 8) : 0; + c |= currprefs.gfx_lores_mode != changed_prefs.gfx_lores_mode ? (2 | 8) : 0; c |= currprefs.gfx_display != changed_prefs.gfx_display ? (2|4|8) : 0; c |= strcmp (currprefs.gfx_display_name, changed_prefs.gfx_display_name) ? (2|4|8) : 0; c |= currprefs.win32_alwaysontop != changed_prefs.win32_alwaysontop ? 1 : 0; @@ -1792,8 +1793,6 @@ static int create_windows_2 (void) nw = rc.right - rc.left; nh = rc.bottom - rc.top; } - write_log ("%d %d %d %d\n", x, y, w, h); - write_log ("%d %d %d %d\n", nx, ny, nw, nh); if (w != nw || h != nh || x != nx || y != ny) { w = nw; h = nh; diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 3a1100f4..22144c3e 100755 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -5006,16 +5006,16 @@ static void values_to_chipsetdlg2 (HWND hDlg) SetDlgItemText(hDlg, IDC_CS_RTCADJUST, txt); txt[0] = 0; if (workprefs.cs_fatgaryrev >= 0) - sprintf (txt, "%02.2X", workprefs.cs_fatgaryrev); + sprintf (txt, "%02X", workprefs.cs_fatgaryrev); SetDlgItemText(hDlg, IDC_CS_FATGARYREV, txt); txt[0] = 0; if (workprefs.cs_ramseyrev >= 0) - sprintf (txt, "%02.2X", workprefs.cs_ramseyrev); + sprintf (txt, "%02X", workprefs.cs_ramseyrev); SetDlgItemText(hDlg, IDC_CS_RAMSEYREV, txt); txt[0] = 0; if (workprefs.cs_agnusrev >= 0) { rev = workprefs.cs_agnusrev; - sprintf (txt, "%02.2X", rev); + sprintf (txt, "%02X", rev); } else if (workprefs.cs_compatible) { rev = 0; if (workprefs.ntscmode) @@ -5024,7 +5024,7 @@ static void values_to_chipsetdlg2 (HWND hDlg) rev |= (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0x20 : 0; if (workprefs.chipmem_size > 1024 * 1024 && (workprefs.chipset_mask & CSMASK_ECS_AGNUS)) rev |= 0x21; - sprintf (txt, "%02.2X", rev); + sprintf (txt, "%02X", rev); } SetDlgItemText(hDlg, IDC_CS_AGNUSREV, txt); txt[0] = 0; @@ -6472,8 +6472,8 @@ static void enable_for_sounddlg (HWND hDlg) { int numdevs; - enumerate_sound_devices (&numdevs); - if( numdevs == 0 ) + numdevs = enumerate_sound_devices (); + if (numdevs == 0) ew (hDlg, IDC_SOUNDCARDLIST, FALSE); else ew (hDlg, IDC_SOUNDCARDLIST, workprefs.produce_sound); @@ -6846,7 +6846,6 @@ static INT_PTR CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM static int recursive = 0; int numdevs; int card; - char **sounddevs; switch (msg) { case WM_INITDIALOG: @@ -6860,13 +6859,13 @@ static INT_PTR CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM SendDlgItemMessage (hDlg, IDC_SOUNDDRIVEVOLUME, TBM_SETRANGE, TRUE, MAKELONG (0, 100)); SendDlgItemMessage (hDlg, IDC_SOUNDDRIVEVOLUME, TBM_SETPAGESIZE, 0, 1); - SendDlgItemMessage( hDlg, IDC_SOUNDADJUST, TBM_SETRANGE, TRUE, MAKELONG (-100, +30) ); - SendDlgItemMessage( hDlg, IDC_SOUNDADJUST, TBM_SETPAGESIZE, 0, 1 ); + SendDlgItemMessage (hDlg, IDC_SOUNDADJUST, TBM_SETRANGE, TRUE, MAKELONG (-100, +30)); + SendDlgItemMessage (hDlg, IDC_SOUNDADJUST, TBM_SETPAGESIZE, 0, 1); - SendDlgItemMessage( hDlg, IDC_SOUNDCARDLIST, CB_RESETCONTENT, 0, 0L ); - sounddevs = enumerate_sound_devices (&numdevs); + SendDlgItemMessage (hDlg, IDC_SOUNDCARDLIST, CB_RESETCONTENT, 0, 0L); + numdevs = enumerate_sound_devices (); for (card = 0; card < numdevs; card++) - SendDlgItemMessage (hDlg, IDC_SOUNDCARDLIST, CB_ADDSTRING, 0, (LPARAM)sounddevs[card]); + SendDlgItemMessage (hDlg, IDC_SOUNDCARDLIST, CB_ADDSTRING, 0, (LPARAM)sound_devices[card].name); if (numdevs == 0) workprefs.produce_sound = 0; /* No sound card in system, enable_for_sounddlg will accomodate this */ @@ -7827,7 +7826,7 @@ static void floppytooltip (HWND hDlg, int num, uae_u32 crc32) SendMessage (ToolTipHWND, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); if (crc32 == 0) return; - sprintf (tmp, "CRC=%08.8X", crc32); + sprintf (tmp, "CRC=%08X", crc32); ti.lpszText = tmp; SendMessage (ToolTipHWND, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); } @@ -11551,7 +11550,7 @@ void gui_led (int led, int on) tt = dfx[led - 1]; tt[0] = 0; if (strlen (p + j) > 0) - sprintf (tt, "%s (CRC=%08.8X)", p + j, gui_data.crc32[led - 1]); + sprintf (tt, "%s (CRC=%08X)", p + j, gui_data.crc32[led - 1]); } else if (led == 0) { pos = 3; ptr = strcpy (drive_text + pos * 16, "Power"); diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index b83923ad..05b16a6d 100755 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,26 @@ +Beta 5: + +- avi recording crash fixed if only audio recording was enabled +- native dll support fixed +- do not enable second Z3 board if RAM limit reached (=decrease Z3 size) + and Z3 size is smaller than 256M (4M+2M combination for example is + quite stupid..) +- adjusted max RAM limit calculation (max RAM + max page file instead + of currently available RAM + max page file) +- sound adjustments, previously it was possible to lock non-safe portion + of directsound sound buffer causing glitches in some cases (which may + or may have never happened) +- SuperEagle, Super2xSaI and 2xSaI 32-bit color support added +- disable filter if filter size multiplier is really too big for + configured display size (instead of overflowing buffers..) +- resolution and doubling setting change on the fly updates filter + centering +- added -ddsoftwarecolorkey command line option. Workaround for buggy + Intel integrated laptop chipset Vista graphics driver causing non- + transparent (pink rectangle) RTG hardware cursor +- (new AHI driver will be only available after 1.5.1) + Beta 4: - input panel custom events in slots 2+ were not saved if previous diff --git a/sana2.c b/sana2.c index 18b6456a..b2641f9f 100755 --- a/sana2.c +++ b/sana2.c @@ -246,7 +246,7 @@ static struct priv_devstruct *getpdevstruct (uaecptr request) { int i = get_long (request + 24); if (i < 0 || i >= MAX_OPEN_DEVICES || pdevst[i].inuse == 0) { - write_log ("%s: corrupt iorequest %08.8X %d\n", SANA2NAME, request, i); + write_log ("%s: corrupt iorequest %08X %d\n", SANA2NAME, request, i); return 0; } return &pdevst[i]; @@ -617,7 +617,7 @@ static void abort_async (struct devstruct *dev, uaecptr request) return; } if (log_net) - write_log ("%s:%d asyncronous request=%08.8X aborted\n", getdevname(), dev->unit, request); + write_log ("%s:%d asyncronous request=%08X aborted\n", getdevname(), dev->unit, request); do_abort_async (dev, request); } diff --git a/scsiemul.c b/scsiemul.c index b353ee9e..fc2e6cb3 100755 --- a/scsiemul.c +++ b/scsiemul.c @@ -104,7 +104,7 @@ static struct priv_devstruct *getpdevstruct (uaecptr request) { int i = get_long (request + 24); if (i < 0 || i >= MAX_OPEN_DEVICES || pdevst[i].inuse == 0) { - write_log ("uaescsi.device: corrupt iorequest %08.8X %d\n", request, i); + write_log ("uaescsi.device: corrupt iorequest %08X %d\n", request, i); return 0; } return &pdevst[i]; @@ -158,7 +158,7 @@ static uae_u32 REGPARAM2 dev_close_2 (TrapContext *context) return 0; dev = getdevstruct (pdev->unit); if (log_scsi) - write_log ("%s:%d close, req=%08.8X\n", getdevname (pdev->type), pdev->unit, request); + write_log ("%s:%d close, req=%08X\n", getdevname (pdev->type), pdev->unit, request); if (!dev) return 0; dev_close_3 (dev, pdev); @@ -193,7 +193,7 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context, int type) int i; if (log_scsi) - write_log ("opening %s:%d ioreq=%08.8X\n", getdevname (type), unit, ioreq); + write_log ("opening %s:%d ioreq=%08X\n", getdevname (type), unit, ioreq); if (get_word (ioreq + 0x12) < IOSTDREQ_SIZE) return openfail (ioreq, IOERR_BADLENGTH); if (!dev) @@ -346,7 +346,7 @@ static void abort_async (struct devstruct *dev, uaecptr request, int errcode, in } i = release_async_request (dev, request); if (i >= 0 && log_scsi) - write_log ("asyncronous request=%08.8X aborted, error=%d\n", request, errcode); + write_log ("asyncronous request=%08X aborted, error=%d\n", request, errcode); } static int command_read (int mode, struct devstruct *dev, uaecptr data, uae_u64 offset, uae_u32 length, uae_u32 *io_actual) @@ -662,7 +662,7 @@ static void *dev_thread (void *devs) uae_ReplyMsg (request); } else { if (log_scsi) - write_log ("%s:%d async request %08.8X\n", getdevname(0), dev->unitnum, request); + write_log ("%s:%d async request %08X\n", getdevname(0), dev->unitnum, request); } uae_sem_post (&change_sem); } @@ -703,7 +703,7 @@ static uae_u32 REGPARAM2 dev_abortio (TrapContext *context) } put_byte (request + 31, IOERR_ABORTED); if (log_scsi) - write_log ("abortio %s unit=%d, request=%08.8X\n", getdevname (pdev->type), pdev->unit, request); + write_log ("abortio %s unit=%d, request=%08X\n", getdevname (pdev->type), pdev->unit, request); abort_async (dev, request, IOERR_ABORTED, 0); return 0; } diff --git a/uaeserial.c b/uaeserial.c index 236f338a..4a8755f4 100755 --- a/uaeserial.c +++ b/uaeserial.c @@ -140,7 +140,7 @@ static char *getdevname (void) static void io_log (char *msg, uaecptr request) { if (log_uaeserial) - write_log ("%s: %08X %d %08.8X %d %d io_actual=%d io_error=%d\n", + write_log ("%s: %08X %d %08X %d %d io_actual=%d io_error=%d\n", msg, request, get_word (request + 28), get_long (request + 40), get_long (request + 36), get_long (request + 44), get_long (request + 32), get_byte (request + 31)); @@ -214,7 +214,7 @@ static int setparams (struct devstruct *dev, uaecptr req) rbuffer = get_long (req + io_RBufLen); v = get_long (req + io_ExtFlags); if (v) { - write_log ("UAESER: io_ExtFlags=%08.8x, not supported\n", v); + write_log ("UAESER: io_ExtFlags=%08x, not supported\n", v); return 5; } baud = get_long (req + io_Baud); @@ -238,7 +238,7 @@ static int setparams (struct devstruct *dev, uaecptr req) write_log ("UAESER: Read=%d, Write=%d, Stop=%d, not supported\n", rbits, wbits, sbits); return 5; } - write_log ("%s:%d BAUD=%d BUF=%d BITS=%d+%d RTSCTS=%d PAR=%d XO=%06.6X\n", + write_log ("%s:%d BAUD=%d BUF=%d BITS=%d+%d RTSCTS=%d PAR=%d XO=%06X\n", getdevname(), dev->unit, baud, rbuffer, rbits, sbits, rtscts, parity, xonxoff); v = uaeser_setparams (dev->sysdata, baud, rbuffer, @@ -297,7 +297,7 @@ static uae_u32 REGPARAM2 dev_open (TrapContext *context) return openfail (ioreq, err); } if (log_uaeserial) - write_log ("%s:%d open ioreq=%08.8X\n", getdevname(), unit, ioreq); + write_log ("%s:%d open ioreq=%08X\n", getdevname(), unit, ioreq); start_thread (dev); put_word (m68k_areg (&context->regs, 6) + 32, get_word (m68k_areg (&context->regs, 6) + 32) + 1); @@ -387,7 +387,7 @@ static void abort_async (struct devstruct *dev, uaecptr request) return; } if (log_uaeserial) - write_log ("%s:%d asyncronous request=%08.8X aborted\n", getdevname(), dev->unit, request); + write_log ("%s:%d asyncronous request=%08X aborted\n", getdevname(), dev->unit, request); put_byte (request + 31, IOERR_ABORTED); put_byte (request + 30, get_byte (request + 30) | 0x20); write_comm_pipe_u32 (&dev->requests, request, 1); diff --git a/zfile_archive.c b/zfile_archive.c index 5a0ac44b..d6636ac7 100755 --- a/zfile_archive.c +++ b/zfile_archive.c @@ -467,7 +467,7 @@ static int canrar(void) pRARGetDllVersion = (RARGETDLLVERSION)GetProcAddress (rarlib, "RARGetDllVersion"); if (pRAROpenArchive && pRARReadHeaderEx && pRARProcessFile && pRARCloseArchive && pRARSetCallback) { israr = 1; - write_log ("unrar.dll version %08.8X detected and used\n", pRARGetDllVersion ? pRARGetDllVersion() : -1); + write_log ("unrar.dll version %08X detected and used\n", pRARGetDllVersion ? pRARGetDllVersion() : -1); } }