Removed excess memset()'s from hdd_image.c and did a few other optimizations there, also fixed incorrect zero'ing of the buffer in hdd_image_write_ex();
Did a tweak to mmutranslate() in mem.c, should increase performance again; Added the ATi VGA Wonder and ATi VGA-88, made the ATi VGA Edge-16 use the correct BIOS.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of hard disk image files.
|
||||
*
|
||||
* Version: @(#)hdd_image.c 1.0.10 2018/01/24
|
||||
* Version: @(#)hdd_image.c 1.0.11 2018/02/07
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -76,18 +76,12 @@ int image_is_hdi(const wchar_t *s)
|
||||
char *ws = (char *) s;
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (! wcscasecmp(ext, L".HDI"))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,46 +96,27 @@ image_is_hdx(const wchar_t *s, int check_signature)
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcscasecmp(ext, L".HDX") == 0)
|
||||
{
|
||||
if (check_signature)
|
||||
{
|
||||
if (wcscasecmp(ext, L".HDX") == 0) {
|
||||
if (check_signature) {
|
||||
f = plat_fopen((wchar_t *)s, L"rb");
|
||||
if (!f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fseeko64(f, 0, SEEK_END);
|
||||
filelen = ftello64(f);
|
||||
fseeko64(f, 0, SEEK_SET);
|
||||
if (filelen < 44)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fread(&signature, 1, 8, f);
|
||||
fclose(f);
|
||||
if (signature == 0xD778A82044445459ll)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -161,10 +136,8 @@ int hdd_image_load(int id)
|
||||
|
||||
hdd_images[id].base = 0;
|
||||
|
||||
if (hdd_images[id].loaded)
|
||||
{
|
||||
if (hdd_images[id].file)
|
||||
{
|
||||
if (hdd_images[id].loaded) {
|
||||
if (hdd_images[id].file) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
@@ -175,38 +148,30 @@ int hdd_image_load(int id)
|
||||
is_hdx[1] = image_is_hdx(fn, 1);
|
||||
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == '.')
|
||||
{
|
||||
if (fn[0] == '.') {
|
||||
hdd_image_log("File name starts with .\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
hdd_images[id].file = plat_fopen(fn, L"rb+");
|
||||
if (hdd_images[id].file == NULL)
|
||||
{
|
||||
if (hdd_images[id].file == NULL) {
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
if (errno == ENOENT) {
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
if (hdd[id].wp)
|
||||
{
|
||||
if (hdd[id].wp) {
|
||||
hdd_image_log("A write-protected image must exist\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdd_images[id].file = plat_fopen(fn, L"wb+");
|
||||
if (hdd_images[id].file == NULL)
|
||||
{
|
||||
if (hdd_images[id].file == NULL) {
|
||||
hdd_image_log("Unable to open image\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512;
|
||||
hdd_images[id].base = 0x1000;
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
@@ -218,13 +183,9 @@ int hdd_image_load(int id)
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
{
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
}
|
||||
hdd_images[id].type = 1;
|
||||
}
|
||||
else if (is_hdx[0])
|
||||
{
|
||||
} else if (is_hdx[0]) {
|
||||
full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512;
|
||||
hdd_images[id].base = 0x28;
|
||||
fwrite(&signature, 1, 8, hdd_images[id].file);
|
||||
@@ -238,28 +199,21 @@ int hdd_image_load(int id)
|
||||
hdd_images[id].type = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdd_images[id].type = 0;
|
||||
}
|
||||
hdd_images[id].last_sector = 0;
|
||||
}
|
||||
|
||||
s = full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512;
|
||||
|
||||
goto prepare_new_hard_disk;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Failed for another reason */
|
||||
hdd_image_log("Failed for another reason\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
fseeko64(hdd_images[id].file, 0x8, SEEK_SET);
|
||||
fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0xC, SEEK_SET);
|
||||
@@ -267,8 +221,7 @@ int hdd_image_load(int id)
|
||||
fread(&full_size, 1, 4, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, hdd_images[id].file);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDI: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
@@ -279,10 +232,8 @@ int hdd_image_load(int id)
|
||||
fread(&spt, 1, 4, hdd_images[id].file);
|
||||
fread(&hpc, 1, 4, hdd_images[id].file);
|
||||
fread(&tracks, 1, 4, hdd_images[id].file);
|
||||
if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
if ((spt != hdd[id].spt) || (hpc != hdd[id].hpc) || (tracks != hdd[id].tracks))
|
||||
{
|
||||
if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) {
|
||||
if ((spt != hdd[id].spt) || (hpc != hdd[id].hpc) || (tracks != hdd[id].tracks)) {
|
||||
hdd_image_log("HDI: Geometry mismatch\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
@@ -295,15 +246,13 @@ int hdd_image_load(int id)
|
||||
hdd[id].tracks = tracks;
|
||||
hdd_images[id].type = 1;
|
||||
}
|
||||
else if (is_hdx[1])
|
||||
{
|
||||
else if (is_hdx[1]) {
|
||||
hdd_images[id].base = 0x28;
|
||||
fseeko64(hdd_images[id].file, 8, SEEK_SET);
|
||||
fread(&full_size, 1, 8, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, hdd_images[id].file);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDX: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
@@ -314,10 +263,8 @@ int hdd_image_load(int id)
|
||||
fread(&spt, 1, 4, hdd_images[id].file);
|
||||
fread(&hpc, 1, 4, hdd_images[id].file);
|
||||
fread(&tracks, 1, 4, hdd_images[id].file);
|
||||
if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
if ((spt != hdd[id].spt) || (hpc != hdd[id].hpc) || (tracks != hdd[id].tracks))
|
||||
{
|
||||
if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) {
|
||||
if ((spt != hdd[id].spt) || (hpc != hdd[id].hpc) || (tracks != hdd[id].tracks)) {
|
||||
hdd_image_log("HDX: Geometry mismatch\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
@@ -331,17 +278,14 @@ int hdd_image_load(int id)
|
||||
fread(&(hdd[id].at_spt), 1, 4, hdd_images[id].file);
|
||||
fread(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512;
|
||||
hdd_images[id].type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fseeko64(hdd_images[id].file, 0, SEEK_END);
|
||||
if (ftello64(hdd_images[id].file) < (full_size + hdd_images[id].base))
|
||||
{
|
||||
if (ftello64(hdd_images[id].file) < (full_size + hdd_images[id].base)) {
|
||||
s = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file);
|
||||
prepare_new_hard_disk:
|
||||
s >>= 9;
|
||||
@@ -353,19 +297,15 @@ prepare_new_hard_disk:
|
||||
memset(empty_sector_1mb, 0, 1048576);
|
||||
|
||||
pclog("Writing image sectors: [");
|
||||
if (s > 0)
|
||||
{
|
||||
for (i = 0; i < s; i++)
|
||||
{
|
||||
if (s > 0) {
|
||||
for (i = 0; i < s; i++) {
|
||||
pclog("#");
|
||||
fwrite(empty_sector, 1, 512, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
|
||||
if (t > 0)
|
||||
{
|
||||
for (i = 0; i < t; i++)
|
||||
{
|
||||
if (t > 0) {
|
||||
for (i = 0; i < t; i++) {
|
||||
pclog("#");
|
||||
fwrite(empty_sector_1mb, 1, 1045876, hdd_images[id].file);
|
||||
}
|
||||
@@ -384,20 +324,16 @@ prepare_new_hard_disk:
|
||||
|
||||
void hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
{
|
||||
uint64_t addr = sector;
|
||||
addr <<= 9;
|
||||
addr += hdd_images[id].base;
|
||||
off64_t addr = sector;
|
||||
addr = (uint64_t)sector * 512;
|
||||
|
||||
fseeko64(hdd_images[id].file, addr, SEEK_SET);
|
||||
fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET);
|
||||
}
|
||||
|
||||
void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
count <<= 9;
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
memset(buffer, 0, count);
|
||||
fread(buffer, 1, count, hdd_images[id].file);
|
||||
fread(buffer, 1, count * 512, hdd_images[id].file);
|
||||
}
|
||||
|
||||
uint32_t hdd_sectors(uint8_t id)
|
||||
@@ -412,27 +348,20 @@ int hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buff
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
{
|
||||
transfer_sectors = sectors - sector;
|
||||
}
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
memset(buffer, 0, transfer_sectors << 9);
|
||||
fread(buffer, 1, transfer_sectors << 9, hdd_images[id].file);
|
||||
fread(buffer, 1, transfer_sectors * 512, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
count <<= 9;
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
fwrite(buffer, 1, count, hdd_images[id].file);
|
||||
fwrite(buffer, count * 512, 1, hdd_images[id].file);
|
||||
}
|
||||
|
||||
int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
@@ -441,64 +370,41 @@ int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buf
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
{
|
||||
transfer_sectors = sectors - sector;
|
||||
}
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
memset(buffer, 0, transfer_sectors << 9);
|
||||
fwrite(buffer, 1, transfer_sectors << 9, hdd_images[id].file);
|
||||
fwrite(buffer, transfer_sectors * 512, 1, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t *b;
|
||||
|
||||
b = (uint8_t *) malloc(512);
|
||||
memset(b, 0, 512);
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
fwrite(b, 1, 512, hdd_images[id].file);
|
||||
}
|
||||
|
||||
free(b);
|
||||
fwrite(empty_sector, 512, 1, hdd_images[id].file);
|
||||
}
|
||||
|
||||
int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t *b;
|
||||
|
||||
uint32_t transfer_sectors = count;
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
{
|
||||
transfer_sectors = sectors - sector;
|
||||
}
|
||||
|
||||
b = (uint8_t *) malloc(512);
|
||||
memset(b, 0, 512);
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
for (i = 0; i < transfer_sectors; i++)
|
||||
{
|
||||
fwrite(b, 1, 512, hdd_images[id].file);
|
||||
}
|
||||
fwrite(empty_sector, 1, 512, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -527,14 +433,10 @@ void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt)
|
||||
void hdd_image_unload(uint8_t id, int fn_preserve)
|
||||
{
|
||||
if (wcslen(hdd[id].fn) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdd_images[id].loaded)
|
||||
{
|
||||
if (hdd_images[id].file != NULL)
|
||||
{
|
||||
if (hdd_images[id].loaded) {
|
||||
if (hdd_images[id].file != NULL) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
@@ -551,8 +453,7 @@ void hdd_image_unload(uint8_t id, int fn_preserve)
|
||||
|
||||
void hdd_image_close(uint8_t id)
|
||||
{
|
||||
if (hdd_images[id].file != NULL)
|
||||
{
|
||||
if (hdd_images[id].file != NULL) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
|
80
src/mem.c
80
src/mem.c
@@ -196,7 +196,7 @@ int pctrans=0;
|
||||
|
||||
extern uint32_t testr[9];
|
||||
|
||||
int mem_cpl3_check(void)
|
||||
static __inline__ int mem_cpl3_check(void)
|
||||
{
|
||||
if ((CPL == 3) && !cpl_override)
|
||||
{
|
||||
@@ -205,14 +205,14 @@ int mem_cpl3_check(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mmu_page_fault(uint32_t addr, uint32_t error_code)
|
||||
static __inline__ void mmu_page_fault(uint32_t addr, uint32_t error_code)
|
||||
{
|
||||
cr2 = addr;
|
||||
cpu_state.abrt = ABRT_PF;
|
||||
abrt_error = error_code;
|
||||
}
|
||||
|
||||
int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_abrt)
|
||||
static __inline__ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_abrt)
|
||||
{
|
||||
uint8_t error_code = 0;
|
||||
|
||||
@@ -223,29 +223,22 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_
|
||||
|
||||
/* Apparently, this check should not be done on PSE. */
|
||||
if (!(flags & 1))
|
||||
{
|
||||
is_page_fault = 1;
|
||||
} else
|
||||
else
|
||||
error_code |= 1; /* If the page is present, the error must indicate that it is. */
|
||||
|
||||
if (!(flags & 4) && mem_cpl3_check())
|
||||
{
|
||||
if (!(flags & 4) && mem_cpl3_check()) {
|
||||
/* The user/supervisor check needs to be checked for the table as well, *before* checking it for the page. */
|
||||
is_page_fault = 1;
|
||||
}
|
||||
|
||||
/* Only check the write-protect flag if this is a page directory entry. */
|
||||
if (pde && rw && !(flags & 2) && ((cr0 & WP_FLAG) || mem_cpl3_check()))
|
||||
{
|
||||
is_page_fault = 1;
|
||||
}
|
||||
|
||||
if (is_page_fault)
|
||||
{
|
||||
if (is_page_fault) {
|
||||
if (is_abrt)
|
||||
{
|
||||
mmu_page_fault(addr, error_code);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -256,36 +249,6 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_
|
||||
#define PAGE_DIRTY 0x40
|
||||
#define PAGE_ACCESSED 0x20
|
||||
|
||||
/* This is needed so that mmutranslate reads things from the correct place
|
||||
if it has to read something from a remapped mapping. */
|
||||
uint32_t mem_readl_phys(uint32_t addr)
|
||||
{
|
||||
uint8_t i, temp[4];
|
||||
uint32_t ta, *tv;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ta = addr + i;
|
||||
temp[i] = _mem_exec[ta >> 14][ta & 0x3fff];
|
||||
}
|
||||
|
||||
tv = (uint32_t *) temp;
|
||||
return *tv;
|
||||
}
|
||||
|
||||
void mem_writel_phys(uint32_t addr, uint32_t val)
|
||||
{
|
||||
uint8_t i, temp[4];
|
||||
uint32_t ta, *tv;
|
||||
|
||||
tv = (uint32_t *) temp;
|
||||
*tv = val;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ta = addr + i;
|
||||
_mem_exec[ta >> 14][ta & 0x3fff] = temp[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* rw means 0 = read, 1 = write */
|
||||
uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt)
|
||||
{
|
||||
@@ -299,58 +262,45 @@ uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt)
|
||||
uint32_t page_flags = 0;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
dir_base = cr3 & ~0xfff;
|
||||
table_addr = dir_base + ((addr >> 20) & 0xffc);
|
||||
|
||||
/* First check the flags of the page directory entry. */
|
||||
table_flags = mem_readl_phys(table_addr);
|
||||
table_flags = *(uint32_t *) &_mem_exec[table_addr >> 14][table_addr & 0x3fff];
|
||||
|
||||
if ((table_flags & 0x80) && (cr4 & CR4_PSE))
|
||||
{
|
||||
if ((table_flags & 0x80) && (cr4 & CR4_PSE)) {
|
||||
/* Do a PDE-style page fault check. */
|
||||
if (mmu_page_fault_check(addr, rw, table_flags & 7, 1, is_abrt) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Since PSE is not enabled, there is no page table, so we do a slightly modified skip to the end. */
|
||||
if (is_abrt)
|
||||
{
|
||||
if (is_abrt) {
|
||||
mmu_perm = table_flags & 4;
|
||||
mem_writel_phys(table_addr, table_flags | (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED));
|
||||
*(uint32_t *) &_mem_exec[table_addr >> 14][table_addr & 0x3fff] = table_flags | (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED);
|
||||
}
|
||||
|
||||
return (table_flags & ~0x3FFFFF) + (addr & 0x3FFFFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Do a non-PDE-style page fault check. */
|
||||
if (mmu_page_fault_check(addr, rw, table_flags & 7, 0, is_abrt) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
page_addr = table_flags & ~0xfff;
|
||||
page_addr += ((addr >> 10) & 0xffc);
|
||||
|
||||
/* Then check the flags of the page table entry. */
|
||||
page_flags = mem_readl_phys(page_addr);
|
||||
page_flags = *(uint32_t *) &_mem_exec[page_addr >> 14][page_addr & 0x3fff];
|
||||
|
||||
if (mmu_page_fault_check(addr, rw, page_flags & 7, 1, is_abrt) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_abrt)
|
||||
{
|
||||
if (is_abrt) {
|
||||
mmu_perm = page_flags & 4;
|
||||
mem_writel_phys(table_addr, table_flags | PAGE_ACCESSED);
|
||||
mem_writel_phys(page_addr, page_flags | (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED));
|
||||
*(uint32_t *) &_mem_exec[table_addr >> 14][table_addr & 0x3fff] = table_flags | PAGE_ACCESSED;
|
||||
*(uint32_t *) &_mem_exec[page_addr >> 14][page_addr & 0x3fff] = page_flags | (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED);
|
||||
}
|
||||
|
||||
return (page_flags & ~0xFFF) + (addr & 0xFFF);
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* ATI 18800 emulation (VGA Edge-16)
|
||||
*
|
||||
* Version: @(#)vid_ati18800.c 1.0.4 2018/02/03
|
||||
* Version: @(#)vid_ati18800.c 1.0.5 2018/02/07
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -33,7 +33,15 @@
|
||||
#include "vid_svga.h"
|
||||
|
||||
|
||||
#define BIOS_ROM_PATH L"roms/video/ati18800/vga88.bin"
|
||||
#define BIOS_ROM_PATH_WONDER L"roms/video/ati18800/VGA_Wonder_V3-1.02.bin"
|
||||
#define BIOS_ROM_PATH_VGA88 L"roms/video/ati18800/vga88.bin"
|
||||
#define BIOS_ROM_PATH_EDGE16 L"roms/video/ati18800/vgaedge16.vbi"
|
||||
|
||||
enum {
|
||||
ATI18800_WONDER = 0,
|
||||
ATI18800_VGA88,
|
||||
ATI18800_EDGE16
|
||||
};
|
||||
|
||||
|
||||
typedef struct ati18800_t
|
||||
@@ -93,18 +101,6 @@ static void ati18800_out(uint16_t addr, uint8_t val, void *p)
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
if ((ati18800->regs[0xb4] & 4) && (svga->crtcreg == 9))
|
||||
val = (svga->crtc[9] & ~0x60) | (val & 0x60);
|
||||
if ((ati18800->regs[0xb4] & 8) && ((svga->crtcreg == 6) || (svga->crtcreg == 0x10) || (svga->crtcreg == 0x12) || (svga->crtcreg == 0x15) || (svga->crtcreg == 0x16)))
|
||||
return;
|
||||
if ((ati18800->regs[0xb4] & 8) && (svga->crtcreg == 7))
|
||||
val = (svga->crtc[9] & ~0x10) | (val & 0x10);
|
||||
if ((ati18800->regs[0xb4] & 8) && (svga->crtcreg == 9))
|
||||
val = (svga->crtc[9] & ~0xdf) | (val & 0xdf);
|
||||
if ((ati18800->regs[0xb4] & 8) && (svga->crtcreg == 0x11))
|
||||
val = (svga->crtc[9] & ~0xf0) | (val & 0xf0);
|
||||
if ((ati18800->regs[0xb4] & 0x10) && ((svga->crtcreg == 0x0a) || (svga->crtcreg == 0x0b)))
|
||||
return;
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val)
|
||||
@@ -163,28 +159,23 @@ static uint8_t ati18800_in(uint16_t addr, void *p)
|
||||
return temp;
|
||||
}
|
||||
|
||||
void ati18800_recalctimings(svga_t *svga)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)svga->p;
|
||||
|
||||
svga->ma_latch += (ati18800->regs[0xb0] & 0xc0) << 10;
|
||||
|
||||
if(ati18800->regs[0xb1] & 0x40)
|
||||
{
|
||||
svga->vtotal >>= 1;
|
||||
svga->dispend >>= 1;
|
||||
svga->vsyncstart >>= 1;
|
||||
svga->split >>= 1;
|
||||
svga->vblankstart >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void *ati18800_init(device_t *info)
|
||||
{
|
||||
ati18800_t *ati18800 = malloc(sizeof(ati18800_t));
|
||||
memset(ati18800, 0, sizeof(ati18800_t));
|
||||
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
switch (info->local) {
|
||||
case ATI18800_WONDER:
|
||||
default:
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
case ATI18800_VGA88:
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
case ATI18800_EDGE16:
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
};
|
||||
|
||||
svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/
|
||||
NULL,
|
||||
@@ -202,9 +193,19 @@ static void *ati18800_init(device_t *info)
|
||||
return ati18800;
|
||||
}
|
||||
|
||||
static int ati18800_wonder_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH_WONDER);
|
||||
}
|
||||
|
||||
static int ati18800_vga88_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH_VGA88);
|
||||
}
|
||||
|
||||
static int ati18800_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH);
|
||||
return rom_present(BIOS_ROM_PATH_EDGE16);
|
||||
}
|
||||
|
||||
static void ati18800_close(void *p)
|
||||
@@ -237,10 +238,38 @@ static void ati18800_add_status_info(char *s, int max_len, void *p)
|
||||
svga_add_status_info(s, max_len, &ati18800->svga);
|
||||
}
|
||||
|
||||
device_t ati18800_device =
|
||||
device_t ati18800_wonder_device =
|
||||
{
|
||||
"ATI-18800",
|
||||
DEVICE_ISA, 0,
|
||||
DEVICE_ISA, ATI18800_WONDER,
|
||||
ati18800_init,
|
||||
ati18800_close,
|
||||
NULL,
|
||||
ati18800_wonder_available,
|
||||
ati18800_speed_changed,
|
||||
ati18800_force_redraw,
|
||||
ati18800_add_status_info,
|
||||
NULL
|
||||
};
|
||||
|
||||
device_t ati18800_vga88_device =
|
||||
{
|
||||
"ATI-18800-1",
|
||||
DEVICE_ISA, ATI18800_VGA88,
|
||||
ati18800_init,
|
||||
ati18800_close,
|
||||
NULL,
|
||||
ati18800_vga88_available,
|
||||
ati18800_speed_changed,
|
||||
ati18800_force_redraw,
|
||||
ati18800_add_status_info,
|
||||
NULL
|
||||
};
|
||||
|
||||
device_t ati18800_device =
|
||||
{
|
||||
"ATI-18800-5",
|
||||
DEVICE_ISA, ATI18800_EDGE16,
|
||||
ati18800_init,
|
||||
ati18800_close,
|
||||
NULL,
|
||||
|
@@ -1,4 +1,6 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
extern device_t ati18800_wonder_device;
|
||||
extern device_t ati18800_vga88_device;
|
||||
extern device_t ati18800_device;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Define all known video cards.
|
||||
*
|
||||
* Version: @(#)vid_table.c 1.0.14 2018/02/01
|
||||
* Version: @(#)vid_table.c 1.0.15 2018/02/07
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -87,9 +87,11 @@ video_cards[] = {
|
||||
{ "None", "none", NULL, GFX_NONE },
|
||||
{ "Internal", "internal", NULL, GFX_INTERNAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{ "[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device, GFX_MACH64GX_ISA, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
|
||||
{ "[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device, GFX_VGA88, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{ "[ISA] ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
|
||||
{ "[ISA] ATI VGA Edge-16 (ATI-18800-5)", "ati18800", &ati18800_device, GFX_VGAEDGE16, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{ "[ISA] ATI VGA Wonder (ATI-18800)", "ati18800w", &ati18800_wonder_device, GFX_VGAWONDER, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{ "[ISA] ATI VGA Wonder XL24 (ATI-28800-6)", "ati28800w", &ati28800_wonderxl24_device, GFX_VGAWONDERXL24, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
|
||||
{ "[ISA] ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{ "[ISA] CGA", "cga", &cga_device, GFX_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{ "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
#if defined(DEV_BRANCH) && defined(USE_CIRRUS)
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the video controller module.
|
||||
*
|
||||
* Version: @(#)video.h 1.0.12 2018/02/01
|
||||
* Version: @(#)video.h 1.0.13 2018/02/07
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -57,8 +57,10 @@ enum {
|
||||
GFX_N9_9FX_PCI, /* S3 764/Trio64 (Number Nine 9FX) PCI */
|
||||
GFX_TGUI9440_VLB, /* Trident TGUI9440 VLB */
|
||||
GFX_TGUI9440_PCI, /* Trident TGUI9440 PCI */
|
||||
GFX_VGA88, /* ATI VGA-88 (18800-1) */
|
||||
GFX_VGAEDGE16, /* ATI VGA Edge-16 (18800-1) */
|
||||
GFX_VGACHARGER, /* ATI VGA Charger (28800-5) */
|
||||
GFX_VGAWONDER, /* Compaq ATI VGA Wonder (18800) */
|
||||
GFX_VGAWONDERXL, /* Compaq ATI VGA Wonder XL (28800-5) */
|
||||
GFX_VGAWONDERXL24, /* Compaq ATI VGA Wonder XL24 (28800-6) */
|
||||
GFX_MACH64GX_ISA, /* ATI Graphics Pro Turbo (Mach64) ISA */
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Makefile for Win32 (MinGW32) environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.97 2018/01/28
|
||||
# Version: @(#)Makefile.mingw 1.0.98 2018/02/07
|
||||
#
|
||||
# Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
# Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -216,7 +216,7 @@ else
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
AFLAGS := -msse -msse2 -mfpmath=sse
|
||||
AFLAGS := -fomit-frame-pointer -msse2 -mfpmath=sse -mstackrealign -fno-strict-aliasing
|
||||
RFLAGS := --input-format=rc -O coff
|
||||
ifeq ($(RELEASE), y)
|
||||
OPTS += -DRELEASE_BUILD
|
||||
|
Reference in New Issue
Block a user