diff --git a/src/acpi.c b/src/acpi.c index cb1f4d91f..350021e00 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -652,10 +652,8 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) static void acpi_i2c_set(acpi_t *dev) { - if (dev->i2c) { - /* Check direction as well to account for the I2C pull-ups. */ + if (dev->i2c) i2c_gpio_set(dev->i2c, !(dev->regs.gpio_dir & 0x02) || (dev->regs.gpio_val & 0x02), !(dev->regs.gpio_dir & 0x04) || (dev->regs.gpio_val & 0x04)); - } } diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index fdb9149ae..19aefe314 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -152,9 +152,9 @@ lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv) return 0; } else if (dev->i2c_state == 0) { dev->i2c_state = 1; - /* Linux lm75.c driver relies on a 3-bit address register that doesn't change if bit 2 is set. */ - if ((dev->as99127f_i2c_addr >= 0x80) && !(data & 0x04)) - dev->addr_register = (data & 0x7); + /* Linux lm75.c driver relies on the address register not changing if bit 2 is set. */ + if ((dev->as99127f_i2c_addr < 0x80) || !(data & 0x04)) + dev->addr_register = data; return 1; } diff --git a/src/device/i2c_gpio.c b/src/device/i2c_gpio.c index bca2e4a1e..e5ea78121 100644 --- a/src/device/i2c_gpio.c +++ b/src/device/i2c_gpio.c @@ -39,7 +39,7 @@ enum { I2C_TRANSMIT_START, I2C_TRANSMIT, I2C_ACKNOWLEDGE, - I2C_NEGACKNOWLEDGE, + I2C_NOTACKNOWLEDGE, I2C_TRANSACKNOWLEDGE, I2C_TRANSMIT_WAIT }; @@ -131,15 +131,13 @@ i2c_gpio_write(i2c_gpio_t *dev) i2c_gpio_log(1, "I2C GPIO %s: Initiating %s address %02X\n", dev->bus_name, dev->slave_read ? "read from" : "write to", dev->slave_addr); - if (!i2c_has_device(dev->i2c, dev->slave_addr)) { + if (!i2c_has_device(dev->i2c, dev->slave_addr) || + ((i == 0xff) && !i2c_start(dev->i2c, dev->slave_addr, dev->slave_read))) { /* start only once per transfer */ dev->slave_state = SLAVE_INVALID; dev->slave_addr = 0xff; - return I2C_NEGACKNOWLEDGE; + return I2C_NOTACKNOWLEDGE; } - if (i == 0xff) /* start only once per transfer */ - i2c_start(dev->i2c, dev->slave_addr, dev->slave_read); - if (dev->slave_read) { dev->slave_state = SLAVE_SENDDATA; dev->transmit = TRANSMITTER_SLAVE; @@ -154,17 +152,17 @@ i2c_gpio_write(i2c_gpio_t *dev) i2c_gpio_log(1, "I2C GPIO %s: Receiving address %02X\n", dev->bus_name, dev->byte); dev->slave_state = dev->slave_read ? SLAVE_SENDDATA : SLAVE_RECEIVEDATA; if (!i2c_write(dev->i2c, dev->slave_addr, dev->byte)) - return I2C_NEGACKNOWLEDGE; + return I2C_NOTACKNOWLEDGE; break; case SLAVE_RECEIVEDATA: i2c_gpio_log(1, "I2C GPIO %s: Receiving data %02X\n", dev->bus_name, dev->byte); if (!i2c_write(dev->i2c, dev->slave_addr, dev->byte)) - return I2C_NEGACKNOWLEDGE; + return I2C_NOTACKNOWLEDGE; break; case SLAVE_INVALID: - return I2C_NEGACKNOWLEDGE; + return I2C_NOTACKNOWLEDGE; } return I2C_ACKNOWLEDGE; @@ -236,9 +234,9 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda) } break; - case I2C_NEGACKNOWLEDGE: + case I2C_NOTACKNOWLEDGE: if (!dev->scl && scl) { - i2c_gpio_log(2, "I2C GPIO %s: Nacking transfer\n", dev->bus_name); + i2c_gpio_log(2, "I2C GPIO %s: Not acknowledging transfer\n", dev->bus_name); sda = 1; dev->pos = 0; dev->state = I2C_IDLE; diff --git a/src/device/serial.c b/src/device/serial.c index b331d4d99..06fd0cfb9 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -186,6 +186,47 @@ write_fifo(serial_t *dev, uint8_t dat) } +#include +#include <86box/pit.h> +HANDLE serialdbg = NULL; +OVERLAPPED serialdbgoverlapped_r; +OVERLAPPED serialdbgoverlapped_w; +uint8_t serialdbg_reading = 0; +DWORD serialdbg_read; +uint8_t serialdbg_buf[1]; +pc_timer_t serialdbgtimer; +void +serial_dbg_timer(void *p) +{ + double dbps = (double) 115200; + double temp = 0.0; + int word_len = 32; + temp = (double) word_len; + temp = (1000000.0 / dbps) * temp; + if (serialdbg_reading) { + if (HasOverlappedIoCompleted(&serialdbgoverlapped_r)) { + if (!GetOverlappedResult(serialdbg, &serialdbgoverlapped_r, &serialdbg_read, FALSE)) { + return; + } + //pclog("overlapped %d\n", serialdbg_read); + for (uint32_t i = 0; i < serialdbg_read; i++) { + pclog("reading %02X\n", serialdbg_buf[i]); + serial_write_fifo((serial_t *) p, serialdbg_buf[i]); + } + serialdbg_reading = 0; + }// else pclog(" not yet\n"); + } else { + if (!ReadFile(serialdbg, serialdbg_buf, sizeof(serialdbg_buf), &serialdbg_read, &serialdbgoverlapped_r) && GetLastError() != ERROR_IO_PENDING) { + pclog("serial broken (read) %08X\n", GetLastError()); + CancelIo(serialdbg); + return; + } + serialdbg_reading = 1; + } + timer_on_auto(&serialdbgtimer, temp);//((serial_t *) p)->transmit_period); +} + + void serial_write_fifo(serial_t *dev, uint8_t dat) { @@ -193,6 +234,8 @@ serial_write_fifo(serial_t *dev, uint8_t dat) if (!(dev->mctrl & 0x10)) write_fifo(dev, dat); + else + pclog("fifo not in rx mode?\n"); } @@ -203,6 +246,14 @@ serial_transmit(serial_t *dev, uint8_t val) write_fifo(dev, val); else if (dev->sd->dev_write) dev->sd->dev_write(dev, dev->sd->priv, val); + if (serialdbg && dev->base_address == SERIAL1_ADDR) { + uint8_t buf[1]; + buf[0] = val; + pclog("writing %02X...", buf[0]); + WriteFile(serialdbg, buf, 1, NULL, &serialdbgoverlapped_w); + //while (!HasOverlappedIoCompleted(&serialdbgoverlapped_w)); + pclog("written\n"); + } } @@ -323,6 +374,7 @@ serial_update_speed(serial_t *dev) if (timer_is_enabled(&dev->timeout_timer)) timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + //pclog("SPEED UPDATED!!! %f\n", dev->transmit_period); } @@ -704,6 +756,15 @@ serial_init(const device_t *info) next_inst++; + if (dev->base_address == SERIAL1_ADDR) { + serialdbg = CreateFileA(TEXT("\\\\.\\COM4"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + pclog("%02X\n", GetLastError()); + if (serialdbg) + timer_add(&serialdbgtimer, serial_dbg_timer, dev, 1); + else + pclog("serial open failed??\n"); + } + return dev; } diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index 1b2554e20..8d457719f 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -98,8 +98,8 @@ static void smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) { smbus_piix4_t *dev = (smbus_piix4_t *) priv; - uint8_t smbus_addr, cmd, read, block_len, prev_stat, timer_bytes = 0; - uint16_t i; + uint8_t smbus_addr, cmd, read, block_len, prev_stat; + uint16_t timer_bytes = 0, i; smbus_piix4_log("SMBus PIIX4: write(%02X, %02X)\n", addr, val); @@ -207,7 +207,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) break; case 0x5: /* block R/W */ - timer_bytes++; /* account for the SMBus length byte now */ + timer_bytes++; /* count the SMBus length byte now */ /* fall-through */ diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index 848210922..3b716028f 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -48,12 +48,12 @@ typedef struct { - const device_t *info; uint8_t slot; uint16_t size; uint16_t row1; uint16_t row2; + uint8_t data[SPD_DATA_SIZE]; void *eeprom; } spd_t; diff --git a/src/mem/spd.c b/src/mem/spd.c index 6ace702c1..36aa5f34f 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -33,8 +33,9 @@ int spd_present = 0; -spd_t *spd_devices[SPD_MAX_SLOTS]; -uint8_t spd_data[SPD_MAX_SLOTS][SPD_DATA_SIZE]; +spd_t *spd_modules[SPD_MAX_SLOTS]; + +static const device_t spd_device; #ifdef ENABLE_SPD_LOG @@ -60,30 +61,30 @@ spd_log(const char *fmt, ...) static void spd_close(void *priv) { - spd_t *dev = (spd_t *) priv; + spd_log("SPD: close()\n"); - spd_log("SPD: closing slot %d (SMBus %02X)\n", dev->slot, SPD_BASE_ADDR + dev->slot); - - i2c_eeprom_close(dev->eeprom); + for (uint8_t i = 0; i < SPD_MAX_SLOTS; i++) { + if (spd_modules[i]) + i2c_eeprom_close(spd_modules[i]->eeprom); + } spd_present = 0; - - free(dev); } static void * spd_init(const device_t *info) { - spd_t *dev = spd_devices[info->local]; + spd_log("SPD: init()\n"); - spd_log("SPD: initializing slot %d (SMBus %02X)\n", dev->slot, SPD_BASE_ADDR + dev->slot); - - dev->eeprom = i2c_eeprom_init(i2c_smbus, SPD_BASE_ADDR + dev->slot, spd_data[info->local], SPD_DATA_SIZE, 0); + for (uint8_t i = 0; i < SPD_MAX_SLOTS; i++) { + if (spd_modules[i]) + spd_modules[i]->eeprom = i2c_eeprom_init(i2c_smbus, SPD_BASE_ADDR + i, spd_modules[i]->data, sizeof(spd_modules[i]->data), 0); + } spd_present = 1; - return dev; + return &spd_modules; } @@ -107,71 +108,71 @@ comp_ui16_rev(const void *elem1, const void *elem2) void -spd_populate(uint16_t *vslots, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym) +spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym) { - uint8_t vslot, next_empty_vslot, split, i; + uint8_t row, next_empty_row, split, i; uint16_t asym; - /* populate vslots with modules in power-of-2 capacities */ - memset(vslots, 0x00, SPD_MAX_SLOTS << 1); - for (vslot = 0; vslot < slot_count && total_size; vslot++) { + /* Populate rows with modules in power-of-2 capacities. */ + memset(rows, 0, SPD_MAX_SLOTS << 1); + for (row = 0; row < slot_count && total_size; row++) { /* populate slot */ - vslots[vslot] = 1 << log2_ui16(MIN(total_size, max_module_size)); - if (total_size >= vslots[vslot]) { - spd_log("SPD: initial vslot %d = %d MB\n", vslot, vslots[vslot]); - total_size -= vslots[vslot]; + rows[row] = 1 << log2_ui16(MIN(total_size, max_module_size)); + if (total_size >= rows[row]) { + spd_log("SPD: Initial row %d = %d MB\n", row, rows[row]); + total_size -= rows[row]; } else { - vslots[vslot] = 0; + rows[row] = 0; break; } } - /* did we populate all the RAM? */ + /* Did we populate all the RAM? */ if (total_size) { - /* work backwards to add the missing RAM as asymmetric modules if possible */ + /* Work backwards to add the missing RAM as asymmetric modules if possible. */ if (enable_asym) { - vslot = slot_count - 1; + row = slot_count - 1; do { - asym = (1 << log2_ui16(MIN(total_size, vslots[vslot]))); - if (vslots[vslot] + asym <= max_module_size) { - vslots[vslot] += asym; + asym = (1 << log2_ui16(MIN(total_size, rows[row]))); + if (rows[row] + asym <= max_module_size) { + rows[row] += asym; total_size -= asym; } - } while ((vslot-- > 0) && total_size); + } while ((row-- > 0) && total_size); } if (total_size) /* still not enough */ - spd_log("SPD: not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size); + spd_log("SPD: Not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size); } - /* populate empty vslots by splitting modules... */ - split = (total_size == 0); /* ...if possible */ + /* Populate empty rows by splitting modules... */ + split = (total_size == 0); /* ...if possible. */ while (split) { - /* look for a module to split */ + /* Look for a module to split. */ split = 0; - for (vslot = 0; vslot < slot_count; vslot++) { - if ((vslots[vslot] < (min_module_size << 1)) || (vslots[vslot] != (1 << log2_ui16(vslots[vslot])))) + for (row = 0; row < slot_count; row++) { + if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2_ui16(rows[row])))) continue; /* no module here, module is too small to be split, or asymmetric module */ - /* find next empty vslot */ - next_empty_vslot = 0; - for (i = vslot + 1; i < slot_count && !next_empty_vslot; i++) { - if (!vslots[i]) - next_empty_vslot = i; + /* Find next empty row. */ + next_empty_row = 0; + for (i = row + 1; i < slot_count && !next_empty_row; i++) { + if (!rows[i]) + next_empty_row = i; } - if (!next_empty_vslot) - break; /* no empty vslots left */ + if (!next_empty_row) + break; /* no empty rows left */ - /* split the module into its own vslot and the next empty vslot */ - spd_log("SPD: splitting vslot %d (%d MB) into %d and %d (%d MB each)\n", vslot, vslots[vslot], vslot, next_empty_vslot, vslots[vslot] >> 1); - vslots[vslot] = vslots[next_empty_vslot] = vslots[vslot] >> 1; + /* Split the module into its own row and the next empty row. */ + spd_log("SPD: splitting row %d (%d MB) into %d and %d (%d MB each)\n", row, rows[row], row, next_empty_row, rows[row] >> 1); + rows[row] = rows[next_empty_row] = rows[row] >> 1; split = 1; break; } - /* sort vslots by descending capacity if any were split */ + /* Sort rows by descending capacity if any were split. */ if (split) - qsort(vslots, slot_count, sizeof(uint16_t), comp_ui16_rev); + qsort(rows, slot_count, sizeof(uint16_t), comp_ui16_rev); } } @@ -179,13 +180,12 @@ spd_populate(uint16_t *vslots, uint8_t slot_count, uint16_t total_size, uint16_t void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) { - uint8_t slot, slot_count, vslot, i; - uint16_t min_module_size, vslots[SPD_MAX_SLOTS], asym; - device_t *info; + uint8_t slot, slot_count, row, i; + uint16_t min_module_size, rows[SPD_MAX_SLOTS], asym; spd_edo_t *edo_data; spd_sdram_t *sdram_data; - /* determine the minimum module size for this RAM type */ + /* Determine the minimum module size for this RAM type. */ switch (ram_type) { case SPD_TYPE_FPM: case SPD_TYPE_EDO: @@ -201,51 +201,42 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) return; } - /* count how many (real) slots are enabled */ + /* Count how many slots are enabled. */ slot_count = 0; for (slot = 0; slot < SPD_MAX_SLOTS; slot++) { - vslots[slot] = 0; - if (slot_mask & (1 << slot)) { + rows[slot] = 0; + if (slot_mask & (1 << slot)) slot_count++; - } } - /* populate vslots */ - spd_populate(vslots, slot_count, (mem_size >> 10), min_module_size, max_module_size, 1); + /* Populate rows. */ + spd_populate(rows, slot_count, (mem_size >> 10), min_module_size, max_module_size, 1); - /* register SPD devices and populate their data according to the vslots */ - vslot = 0; - for (slot = 0; slot < SPD_MAX_SLOTS && vslots[vslot]; slot++) { + /* Register SPD devices and populate their data according to the rows. */ + row = 0; + for (slot = 0; slot < SPD_MAX_SLOTS && rows[row]; slot++) { if (!(slot_mask & (1 << slot))) continue; /* slot disabled */ - info = (device_t *) malloc(sizeof(device_t)); - memset(info, 0, sizeof(device_t)); - info->name = "Serial Presence Detect ROM"; - info->local = slot; - info->init = spd_init; - info->close = spd_close; + spd_modules[slot] = (spd_t *) malloc(sizeof(spd_t)); + memset(spd_modules[slot], 0, sizeof(spd_t)); + spd_modules[slot]->slot = slot; + spd_modules[slot]->size = rows[row]; - spd_devices[slot] = (spd_t *) malloc(sizeof(spd_t)); - memset(spd_devices[slot], 0, sizeof(spd_t)); - spd_devices[slot]->info = info; - spd_devices[slot]->slot = slot; - spd_devices[slot]->size = vslots[vslot]; - - /* determine the second row size, from which the first row size can be obtained */ - asym = vslots[vslot] - (1 << log2_ui16(vslots[vslot])); /* separate the powers of 2 */ + /* Determine the second row size, from which the first row size can be obtained. */ + asym = rows[row] - (1 << log2_ui16(rows[row])); /* separate the powers of 2 */ if (!asym) /* is the module asymmetric? */ - asym = vslots[vslot] >> 1; /* symmetric, therefore divide by 2 */ + asym = rows[row] >> 1; /* symmetric, therefore divide by 2 */ - spd_devices[slot]->row1 = vslots[vslot] - asym; - spd_devices[slot]->row2 = asym; + spd_modules[slot]->row1 = rows[row] - asym; + spd_modules[slot]->row2 = asym; - spd_log("SPD: registering slot %d = vslot %d = %d MB (%d/%d)\n", slot, vslot, vslots[vslot], spd_devices[slot]->row1, spd_devices[slot]->row2); + spd_log("SPD: Registering slot %d = row %d = %d MB (%d/%d)\n", slot, row, rows[row], spd_modules[slot]->row1, spd_modules[slot]->row2); switch (ram_type) { case SPD_TYPE_FPM: case SPD_TYPE_EDO: - edo_data = (spd_edo_t *) &spd_data[slot]; + edo_data = (spd_edo_t *) &spd_modules[slot]->data; memset(edo_data, 0, sizeof(spd_edo_t)); /* EDO SPD is specified by JEDEC and present in some modules, but @@ -254,10 +245,10 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->bytes_used = 0x80; edo_data->spd_size = 0x08; edo_data->mem_type = ram_type; - edo_data->row_bits = SPD_ROLLUP(7 + log2_ui16(spd_devices[slot]->row1)); /* first row */ + edo_data->row_bits = SPD_ROLLUP(7 + log2_ui16(spd_modules[slot]->row1)); /* first row */ edo_data->col_bits = 9; - if (spd_devices[slot]->row1 != spd_devices[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */ - edo_data->row_bits |= SPD_ROLLUP(7 + log2_ui16(spd_devices[slot]->row2)) << 4; /* second row, if different from first */ + if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */ + edo_data->row_bits |= SPD_ROLLUP(7 + log2_ui16(spd_modules[slot]->row2)) << 4; /* second row, if different from first */ edo_data->col_bits |= 9 << 4; /* same as first row, but just in case */ } edo_data->banks = 2; @@ -269,7 +260,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->dram_width = 8; edo_data->spd_rev = 0x12; - sprintf(edo_data->part_no, EMU_NAME "-%s-%03dM", (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", vslots[vslot]); + sprintf(edo_data->part_no, EMU_NAME "-%s-%03dM", (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]); for (i = strlen(edo_data->part_no); i < sizeof(edo_data->part_no); i++) edo_data->part_no[i] = ' '; /* part number should be space-padded */ edo_data->rev_code[0] = BCD8(EMU_VERSION_MAJ); @@ -278,22 +269,22 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->mfg_week = 17; for (i = 0; i < 63; i++) - edo_data->checksum += spd_data[slot][i]; + edo_data->checksum += spd_modules[slot]->data[i]; for (i = 0; i < 129; i++) - edo_data->checksum2 += spd_data[slot][i]; + edo_data->checksum2 += spd_modules[slot]->data[i]; break; case SPD_TYPE_SDRAM: - sdram_data = (spd_sdram_t *) &spd_data[slot]; + sdram_data = (spd_sdram_t *) &spd_modules[slot]->data; memset(sdram_data, 0, sizeof(spd_sdram_t)); sdram_data->bytes_used = 0x80; sdram_data->spd_size = 0x08; sdram_data->mem_type = ram_type; - sdram_data->row_bits = SPD_ROLLUP(6 + log2_ui16(spd_devices[slot]->row1)); /* first row */ + sdram_data->row_bits = SPD_ROLLUP(6 + log2_ui16(spd_modules[slot]->row1)); /* first row */ sdram_data->col_bits = 9; - if (spd_devices[slot]->row1 != spd_devices[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */ - sdram_data->row_bits |= SPD_ROLLUP(6 + log2_ui16(spd_devices[slot]->row2)) << 4; /* second row, if different from first */ + if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */ + sdram_data->row_bits |= SPD_ROLLUP(6 + log2_ui16(spd_modules[slot]->row2)) << 4; /* second row, if different from first */ sdram_data->col_bits |= 9 << 4; /* same as first row, but just in case */ } sdram_data->rows = 2; @@ -313,18 +304,18 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->tclk3 = 0xF0; /* 15 ns = 66.7 MHz */ sdram_data->tac2 = sdram_data->tac3 = 0x10; sdram_data->trp = sdram_data->trrd = sdram_data->trcd = sdram_data->tras = 1; - if (spd_devices[slot]->row1 != spd_devices[slot]->row2) { + if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* Utilities interpret bank_density a bit differently on asymmetric modules. */ - sdram_data->bank_density = 1 << (log2_ui16(spd_devices[slot]->row1 >> 1) - 2); /* first row */ - sdram_data->bank_density |= 1 << (log2_ui16(spd_devices[slot]->row2 >> 1) - 2); /* second row */ + sdram_data->bank_density = 1 << (log2_ui16(spd_modules[slot]->row1 >> 1) - 2); /* first row */ + sdram_data->bank_density |= 1 << (log2_ui16(spd_modules[slot]->row2 >> 1) - 2); /* second row */ } else { - sdram_data->bank_density = 1 << (log2_ui16(spd_devices[slot]->row1 >> 1) - 1); /* symmetric module = only one bit is set */ + sdram_data->bank_density = 1 << (log2_ui16(spd_modules[slot]->row1 >> 1) - 1); /* symmetric module = only one bit is set */ } sdram_data->ca_setup = sdram_data->data_setup = 0x15; sdram_data->ca_hold = sdram_data->data_hold = 0x08; sdram_data->spd_rev = 0x12; - sprintf(sdram_data->part_no, EMU_NAME "-SDR-%03dM", vslots[vslot]); + sprintf(sdram_data->part_no, EMU_NAME "-SDR-%03dM", rows[row]); for (i = strlen(sdram_data->part_no); i < sizeof(sdram_data->part_no); i++) sdram_data->part_no[i] = ' '; /* part number should be space-padded */ sdram_data->rev_code[0] = BCD8(EMU_VERSION_MAJ); @@ -336,15 +327,16 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->features = 0xFF; for (i = 0; i < 63; i++) - sdram_data->checksum += spd_data[slot][i]; + sdram_data->checksum += spd_modules[slot]->data[i]; for (i = 0; i < 129; i++) - sdram_data->checksum2 += spd_data[slot][i]; + sdram_data->checksum2 += spd_modules[slot]->data[i]; break; } - device_add(info); - vslot++; + row++; } + + device_add(&spd_device); } @@ -352,7 +344,7 @@ void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit) { uint8_t row, dimm, drb, apollo = 0; - uint16_t size, vslots[SPD_MAX_SLOTS]; + uint16_t size, rows[SPD_MAX_SLOTS]; /* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */ if (reg_max < reg_min) { @@ -363,26 +355,26 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ if (!spd_present) { dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ - spd_populate(vslots, dimm, mem_size >> 10, drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); + spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); } /* Write DRBs for each row. */ - spd_log("Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit); + spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit); for (row = 0; row <= (reg_max - reg_min); row++) { dimm = (row >> 1); size = 0; if (spd_present) { /* SPD enabled: use SPD info for this slot, if present. */ - if (spd_devices[dimm]) { - if (spd_devices[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */ + if (spd_modules[dimm]) { + if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */ size = (row & 1) ? 0 : drb_unit; else - size = (row & 1) ? spd_devices[dimm]->row2 : spd_devices[dimm]->row1; + size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1; } } else { /* No SPD: use the values calculated above. */ - size = (vslots[dimm] >> 1); + size = (rows[dimm] >> 1); } /* Determine the DRB register to write. */ @@ -399,6 +391,16 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit regs[drb] = regs[drb - 1]; if (size) regs[drb] += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */ - spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]); + spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]); } } + + +static const device_t spd_device = { + "Serial Presence Detect ROMs", + DEVICE_ISA, + 0, + spd_init, spd_close, NULL, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 507bf339b..ca0273cc8 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -186,6 +186,7 @@ /* Flag set if this is a tagged command. */ #define NCR_TAG_VALID (1 << 16) +#define NCR_NVRAM_SIZE 2048 #define NCR_BUF_SIZE 4096 typedef struct ncr53c8xx_request { @@ -226,9 +227,9 @@ typedef struct { int msg_action; int msg_len; uint8_t msg[NCR_MAX_MSGIN_LEN]; - uint8_t nvram[2048]; /* 24C16 EEPROM (16 kbit) */ + uint8_t nvram[NCR_NVRAM_SIZE]; /* 24C16 EEPROM (16 Kbit) */ void *i2c, *eeprom; - uint8_t ram[NCR_BUF_SIZE]; /* NCR 53c875 RAM (4 kB). */ + uint8_t ram[NCR_BUF_SIZE]; /* NCR 53C875 RAM (4 KB) */ /* 0 if SCRIPTS are running or stopped. * 1 if a Wait Reselect instruction has been issued. * 2 if processing DMA from ncr53c8xx_execute_script. @@ -2584,15 +2585,15 @@ ncr53c8xx_close(void *priv) ncr53c8xx_t *dev = (ncr53c8xx_t *)priv; if (dev) { - /* Save the serial EEPROM. */ - ncr53c8xx_eeprom(dev, 1); - if (dev->eeprom) i2c_eeprom_close(dev->eeprom); if (dev->i2c) i2c_gpio_close(dev->i2c); + /* Save the serial EEPROM. */ + ncr53c8xx_eeprom(dev, 1); + free(dev); dev = NULL; } @@ -2611,7 +2612,7 @@ static const device_config_t ncr53c8xx_pci_config[] = { const device_t ncr53c810_pci_device = { - "NCR 53c810", + "NCR 53C810", DEVICE_PCI, 0x01, ncr53c8xx_init, ncr53c8xx_close, NULL, @@ -2621,7 +2622,7 @@ const device_t ncr53c810_pci_device = const device_t ncr53c810_onboard_pci_device = { - "NCR 53c810 On-Board", + "NCR 53C810 On-Board", DEVICE_PCI, 0x8001, ncr53c8xx_init, ncr53c8xx_close, NULL, @@ -2631,7 +2632,7 @@ const device_t ncr53c810_onboard_pci_device = const device_t ncr53c825a_pci_device = { - "NCR 53c825A", + "NCR 53C825A", DEVICE_PCI, CHIP_825, ncr53c8xx_init, ncr53c8xx_close, NULL, @@ -2641,7 +2642,7 @@ const device_t ncr53c825a_pci_device = const device_t ncr53c860_pci_device = { - "NCR 53c860", + "NCR 53C860", DEVICE_PCI, CHIP_860, ncr53c8xx_init, ncr53c8xx_close, NULL, @@ -2651,7 +2652,7 @@ const device_t ncr53c860_pci_device = const device_t ncr53c875_pci_device = { - "NCR 53c875", + "NCR 53C875", DEVICE_PCI, CHIP_875, ncr53c8xx_init, ncr53c8xx_close, NULL, diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index a353fd6e6..52e125af2 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -2383,8 +2383,8 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); ati68860_set_ramdac_type(mach64->svga.ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); data = (val & (1 << 4)) ? ((val & (1 << 1)) ? 1 : 0) : 1; - clk = (val & (1 << 5)) ? ((val & (1 << 2)) ? 1 : 0) : 1; - i2c_gpio_set(mach64->i2c, clk, data); + clk = (val & (1 << 5)) ? ((val & (1 << 2)) ? 1 : 0) : 1; + i2c_gpio_set(mach64->i2c, clk, data); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: @@ -3372,7 +3372,7 @@ static void *mach64_common_init(const device_t *info) mach64->fifo_thread = thread_create(fifo_thread, mach64); mach64->i2c = i2c_gpio_init("ddc_ati_mach64"); - mach64->ddc = ddc_init(i2c_gpio_get_bus(mach64->i2c)); + mach64->ddc = ddc_init(i2c_gpio_get_bus(mach64->i2c)); return mach64; } diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index ef3a0dbe5..108d059f5 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -28,6 +28,8 @@ #include <86box/dma.h> #include <86box/plat.h> #include <86box/video.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> @@ -499,6 +501,8 @@ typedef struct mystique_t mutex_t *lock; } dma; + + void *i2c, *ddc; } mystique_t; @@ -1020,6 +1024,17 @@ mystique_read_xreg(mystique_t *mystique, int reg) break; case XREG_XGENIODATA: ret = mystique->xgeniodata; + + if (!(mystique->xgenioctrl & 0x08)) { + ret &= 0xf7; + if (i2c_gpio_get_scl(mystique->i2c)) + ret |= 0x08; + } + if (!(mystique->xgenioctrl & 0x02)) { + ret &= 0xfd; + if (i2c_gpio_get_sda(mystique->i2c)) + ret |= 0x02; + } break; case XREG_XSYSPLLM: @@ -1154,6 +1169,7 @@ mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) case XREG_XGENIOCTRL: mystique->xgenioctrl = val; + i2c_gpio_set(mystique->i2c, !(mystique->xgenioctrl & 0x08) || (mystique->xgeniodata & 0x08), !(mystique->xgenioctrl & 0x02) || (mystique->xgeniodata & 0x02)); break; case XREG_XGENIODATA: mystique->xgeniodata = val; @@ -5009,6 +5025,9 @@ mystique_init(const device_t *info) mystique->svga.vsync_callback = mystique_vsync_callback; + mystique->i2c = i2c_gpio_init("ddc_mga"); + mystique->ddc = ddc_init(i2c_gpio_get_bus(mystique->i2c)); + return mystique; } @@ -5025,6 +5044,9 @@ mystique_close(void *p) svga_close(&mystique->svga); + ddc_close(mystique->ddc); + i2c_gpio_close(mystique->i2c); + free(mystique); } diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index cc5488a27..3a0d98e73 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -285,7 +285,7 @@ typedef struct virge_t int virge_busy; uint8_t subsys_stat, subsys_cntl, advfunc_cntl; - + uint8_t serialport; void *i2c, *ddc; @@ -901,7 +901,7 @@ s3_virge_mmio_read(uint32_t addr, void *p) ret |= SERIAL_PORT_SCR; if ((virge->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c)) ret |= SERIAL_PORT_SDR; - return ret; + return ret; } return 0xff; } @@ -3848,8 +3848,8 @@ static void *s3_virge_init(const device_t *info) virge->fifo_not_full_event = thread_create_event(); virge->fifo_thread = thread_create(fifo_thread, virge); - virge->i2c = i2c_gpio_init("ddc_s3_virge"); - virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); + virge->i2c = i2c_gpio_init("ddc_s3_virge"); + virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); return virge; }