Merge pull request #1049 from richardg867/master
Hardware monitoring overhaul
This commit is contained in:
@@ -70,12 +70,12 @@ acpi_update_irq(void *priv)
|
||||
if (dev->irq_mode == 1)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
else
|
||||
picintlevel(1 << dev->irq_line);
|
||||
pci_set_mirq(0xf0 | dev->irq_line, 1);
|
||||
} else {
|
||||
if (dev->irq_mode == 1)
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
else
|
||||
picintc(1 << dev->irq_line);
|
||||
pci_clear_mirq(0xf0 | dev->irq_line, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -491,7 +491,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (val & 0x01)
|
||||
trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL);
|
||||
pic_set_shadow(!!(val & 0x10));
|
||||
pic_elcr_set_enabled(!!(val & 0x20));
|
||||
pic_elcr_io_handler(!!(val & 0x20));
|
||||
dev->pci_isa_regs[0x47] = val & 0xfe;
|
||||
break;
|
||||
case 0x48:
|
||||
@@ -511,31 +511,38 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
||||
pci_set_irq_level(PCI_INTB, !(val & 4));
|
||||
pci_set_irq_level(PCI_INTC, !(val & 2));
|
||||
pci_set_irq_level(PCI_INTD, !(val & 1));
|
||||
dev->pci_isa_regs[0x54] = val & 0x0f;
|
||||
break;
|
||||
case 0x55:
|
||||
pipc_log("PIPC: PCI INT%c %d\n", (dev->local >= VIA_PIPC_596A) ? 'A' : 'D', val >> 4);
|
||||
pipc_log("PIPC: Steering PIRQ%c to IRQ %d\n", (dev->local >= VIA_PIPC_596A) ? 'A' : 'D', val >> 4);
|
||||
pci_set_irq_routing((dev->local >= VIA_PIPC_596A) ? PCI_INTA : PCI_INTD, (val & 0xf0) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
if (dev->local <= VIA_PIPC_586B)
|
||||
if (dev->local <= VIA_PIPC_586B) {
|
||||
pipc_log("PIPC: Steering MIRQ0 to IRQ %d\n", val & 0x0f);
|
||||
pci_set_mirq_routing(PCI_MIRQ0, (val & 0x0f) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
}
|
||||
dev->pci_isa_regs[0x55] = val;
|
||||
break;
|
||||
case 0x56:
|
||||
pipc_log("PIPC: PCI INT%c %d\n", (dev->local >= VIA_PIPC_596A) ? 'C' : 'A', val >> 4);
|
||||
pipc_log("PIPC: PCI INTB %d\n", val & 0x0f);
|
||||
break;
|
||||
case 0x56:
|
||||
pipc_log("PIPC: Steering PIRQ%c to IRQ %d\n", (dev->local >= VIA_PIPC_596A) ? 'C' : 'A', val >> 4);
|
||||
pipc_log("PIPC: Steering PIRQB to IRQ %d\n", val & 0x0f);
|
||||
pci_set_irq_routing((dev->local >= VIA_PIPC_596A) ? PCI_INTC : PCI_INTA, (val & 0xf0) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTB, (val & 0x0f) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
dev->pci_isa_regs[0x56] = val;
|
||||
break;
|
||||
case 0x57:
|
||||
pipc_log("PIPC: PCI INT%c %d\n", (dev->local >= VIA_PIPC_596A) ? 'D' : 'C', val >> 4);
|
||||
pipc_log("PIPC: Steering PIRQ%c to IRQ %d\n", (dev->local >= VIA_PIPC_596A) ? 'D' : 'C', val >> 4);
|
||||
pci_set_irq_routing((dev->local >= VIA_PIPC_596A) ? PCI_INTD : PCI_INTC, (val & 0xf0) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
if (dev->local <= VIA_PIPC_586B)
|
||||
if (dev->local <= VIA_PIPC_586B) {
|
||||
pipc_log("PIPC: Steering MIRQ1 to IRQ %d\n", val & 0x0f);
|
||||
pci_set_mirq_routing(PCI_MIRQ1, (val & 0x0f) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
}
|
||||
dev->pci_isa_regs[0x57] = val;
|
||||
break;
|
||||
case 0x58:
|
||||
if (dev->local == VIA_PIPC_586B)
|
||||
if (dev->local == VIA_PIPC_586B) {
|
||||
pipc_log("PIPC: Steering MIRQ2 to IRQ %d\n", val & 0x0f);
|
||||
pci_set_mirq_routing(PCI_MIRQ2, (val & 0x0f) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
}
|
||||
dev->pci_isa_regs[0x58] = val;
|
||||
break;
|
||||
case 0x5b:
|
||||
@@ -754,7 +761,9 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x42:
|
||||
dev->power_regs[addr] = (dev->power_regs[0x42] & ~0x0f) | (val & 0x0f);
|
||||
dev->power_regs[addr] &= ~0x0f;
|
||||
dev->power_regs[addr] |= val & 0x0f;
|
||||
acpi_set_irq_line(dev->acpi, dev->power_regs[addr]);
|
||||
break;
|
||||
|
||||
case 0x61: case 0x62: case 0x63:
|
||||
|
@@ -15,23 +15,81 @@
|
||||
* Copyright 2020 RichardG.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/machine.h>
|
||||
#include <86box/hwm.h>
|
||||
|
||||
|
||||
hwm_values_t hwm_values;
|
||||
/* Refer to specific hardware monitor implementations for the meaning of hwm_values. */
|
||||
hwm_values_t hwm_values;
|
||||
|
||||
|
||||
void
|
||||
hwm_set_values(hwm_values_t new_values)
|
||||
uint16_t
|
||||
hwm_get_vcore()
|
||||
{
|
||||
hwm_values = new_values;
|
||||
}
|
||||
/* Determine Vcore for the active CPU. */
|
||||
CPU *cpu = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
|
||||
switch (cpu->cpu_type) {
|
||||
case CPU_WINCHIP:
|
||||
case CPU_WINCHIP2:
|
||||
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
|
||||
case CPU_K5:
|
||||
case CPU_5K86:
|
||||
#endif
|
||||
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
|
||||
case CPU_Cx6x86:
|
||||
#endif
|
||||
return 3520;
|
||||
|
||||
case CPU_PENTIUMMMX:
|
||||
return ((cpu->cpuid_model & 0xf000) == 0x1000) ? 3300 : 2800;
|
||||
|
||||
hwm_values_t*
|
||||
hwm_get_values()
|
||||
{
|
||||
return &hwm_values;
|
||||
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
|
||||
case CPU_Cx6x86MX:
|
||||
return (cpu->rspeed == 208333333) ? 2700 : 2900;
|
||||
|
||||
case CPU_Cx6x86L:
|
||||
#endif
|
||||
case CPU_PENTIUM2:
|
||||
return 2800;
|
||||
|
||||
case CPU_K6_2C:
|
||||
if (cpu->multi == 5.0)
|
||||
return 2400;
|
||||
else if (cpu->rspeed >= 550000000)
|
||||
return 2300;
|
||||
else
|
||||
return 2200;
|
||||
|
||||
case CPU_K6:
|
||||
if ((cpu->cpuid_model & 0x0f0) == 0x070)
|
||||
return 2200;
|
||||
else if (cpu->multi <= 3.0)
|
||||
return 2900;
|
||||
else
|
||||
return 3200;
|
||||
|
||||
case CPU_K6_2:
|
||||
case CPU_K6_3:
|
||||
return 2200;
|
||||
|
||||
case CPU_PENTIUM2D:
|
||||
case CPU_CYRIX3S:
|
||||
return 2050;
|
||||
|
||||
case CPU_K6_2P:
|
||||
case CPU_K6_3P:
|
||||
return 2000;
|
||||
|
||||
default:
|
||||
return 3300;
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,6 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/hwm.h>
|
||||
|
||||
@@ -83,14 +82,14 @@ gl518sm_remap(gl518sm_t *dev, uint8_t addr)
|
||||
gl518sm_log("GL518SM: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
smbus_removehandler(dev->smbus_addr, 1,
|
||||
gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL,
|
||||
gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL,
|
||||
gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
|
||||
if (addr < 0x80) smbus_sethandler(addr, 1,
|
||||
gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL,
|
||||
gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL,
|
||||
gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
|
||||
dev->smbus_addr = addr;
|
||||
}
|
||||
@@ -126,13 +125,14 @@ gl518sm_read(gl518sm_t *dev, uint8_t reg)
|
||||
uint16_t ret = dev->regs[reg & 0x1f];
|
||||
|
||||
switch (reg) {
|
||||
case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c:
|
||||
/* two-byte registers: leave as-is */
|
||||
break;
|
||||
default:
|
||||
/* single-byte registers: duplicate low byte to high byte (real hardware behavior unknown) */
|
||||
ret |= (ret << 8);
|
||||
break;
|
||||
case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c:
|
||||
/* two-byte registers: leave as-is */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* single-byte registers: duplicate low byte to high byte (real hardware behavior unknown) */
|
||||
ret |= (ret << 8);
|
||||
break;
|
||||
}
|
||||
|
||||
gl518sm_log("GL518SM: read(%02X) = %04X\n", reg, ret);
|
||||
@@ -171,36 +171,36 @@ gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val)
|
||||
gl518sm_log("GL518SM: write(%02X, %04X)\n", reg, val);
|
||||
|
||||
switch (reg) {
|
||||
case 0x00: case 0x01: case 0x04: case 0x07: case 0x0d: case 0x12: case 0x13: case 0x14: case 0x15:
|
||||
/* read-only registers */
|
||||
return 0;
|
||||
case 0x00: case 0x01: case 0x04: case 0x07: case 0x0d: case 0x12: case 0x13: case 0x14: case 0x15:
|
||||
/* read-only registers */
|
||||
return 0;
|
||||
|
||||
case 0x0a:
|
||||
dev->regs[0x13] = (val & 0xff);
|
||||
break;
|
||||
case 0x0a:
|
||||
dev->regs[0x13] = (val & 0xff);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
dev->regs[reg] = (val & 0xfc);
|
||||
case 0x03:
|
||||
dev->regs[reg] = (val & 0xfc);
|
||||
|
||||
if (val & 0x80) /* Init */
|
||||
gl518sm_reset(dev);
|
||||
break;
|
||||
if (val & 0x80) /* Init */
|
||||
gl518sm_reset(dev);
|
||||
break;
|
||||
|
||||
case 0x0f:
|
||||
dev->regs[reg] = (val & 0xf8);
|
||||
case 0x0f:
|
||||
dev->regs[reg] = (val & 0xf8);
|
||||
|
||||
/* update fan values to match the new divisor */
|
||||
dev->regs[0x07] = (GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8);
|
||||
dev->regs[0x07] |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3));
|
||||
break;
|
||||
/* update fan values to match the new divisor */
|
||||
dev->regs[0x07] = (GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8);
|
||||
dev->regs[0x07] |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3));
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
dev->regs[reg] = (val & 0x7f);
|
||||
break;
|
||||
case 0x11:
|
||||
dev->regs[reg] = (val & 0x7f);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->regs[reg] = val;
|
||||
break;
|
||||
default:
|
||||
dev->regs[reg] = val;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -250,7 +250,22 @@ gl518sm_init(const device_t *info)
|
||||
memset(dev, 0, sizeof(gl518sm_t));
|
||||
|
||||
dev->local = info->local;
|
||||
dev->values = hwm_get_values();
|
||||
|
||||
/* Set default values. */
|
||||
hwm_values_t defaults = {
|
||||
{ /* fan speeds */
|
||||
3000, /* System */
|
||||
3000 /* CPU */
|
||||
}, { /* temperatures */
|
||||
30 /* CPU */
|
||||
}, { /* voltages */
|
||||
hwm_get_vcore(), /* Vcore */
|
||||
RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the GL518SM datasheet) */
|
||||
3300 /* +3.3V */
|
||||
}
|
||||
};
|
||||
hwm_values = defaults;
|
||||
dev->values = &hwm_values;
|
||||
|
||||
gl518sm_reset(dev);
|
||||
gl518sm_remap(dev, dev->local & 0x7f);
|
||||
@@ -259,6 +274,7 @@ gl518sm_init(const device_t *info)
|
||||
}
|
||||
|
||||
|
||||
/* GL518SM on SMBus address 2Ch */
|
||||
const device_t gl518sm_2c_device = {
|
||||
"Genesys Logic GL518SM Hardware Monitor",
|
||||
DEVICE_ISA,
|
||||
@@ -268,6 +284,7 @@ const device_t gl518sm_2c_device = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* GL518SM on SMBus address 2Dh */
|
||||
const device_t gl518sm_2d_device = {
|
||||
"Genesys Logic GL518SM Hardware Monitor",
|
||||
DEVICE_ISA,
|
||||
|
@@ -65,14 +65,14 @@ lm75_remap(lm75_t *dev, uint8_t addr)
|
||||
lm75_log("LM75: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
if (dev->smbus_addr < 0x80) smbus_removehandler(dev->smbus_addr, 1,
|
||||
lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL,
|
||||
lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL,
|
||||
lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
|
||||
if (addr < 0x80) smbus_sethandler(addr, 1,
|
||||
lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL,
|
||||
lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL,
|
||||
lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
|
||||
dev->smbus_addr = addr;
|
||||
}
|
||||
@@ -101,21 +101,21 @@ lm75_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv)
|
||||
uint8_t retlo = 0;
|
||||
|
||||
switch (cmd & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
rethi = lm75_read(dev, 0x0);
|
||||
retlo = lm75_read(dev, 0x1);
|
||||
break;
|
||||
case 0x1: /* configuration */
|
||||
rethi = retlo = lm75_read(dev, 0x2);
|
||||
break;
|
||||
case 0x2: /* Thyst */
|
||||
rethi = lm75_read(dev, 0x3);
|
||||
retlo = lm75_read(dev, 0x4);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
rethi = lm75_read(dev, 0x5);
|
||||
retlo = lm75_read(dev, 0x6);
|
||||
break;
|
||||
case 0x0: /* temperature */
|
||||
rethi = lm75_read(dev, 0x0);
|
||||
retlo = lm75_read(dev, 0x1);
|
||||
break;
|
||||
case 0x1: /* configuration */
|
||||
rethi = retlo = lm75_read(dev, 0x2);
|
||||
break;
|
||||
case 0x2: /* Thyst */
|
||||
rethi = lm75_read(dev, 0x3);
|
||||
retlo = lm75_read(dev, 0x4);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
rethi = lm75_read(dev, 0x5);
|
||||
retlo = lm75_read(dev, 0x6);
|
||||
break;
|
||||
}
|
||||
|
||||
return (retlo << 8) | rethi; /* byte-swapped for some reason */
|
||||
@@ -131,9 +131,13 @@ lm75_read(lm75_t *dev, uint8_t reg)
|
||||
to access some of its proprietary registers. Pass this operation on to
|
||||
the main monitor address through an internal SMBus call, if necessary. */
|
||||
if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr < 0x80))
|
||||
ret = smbus_read_byte_cmd(dev->as99127f_smbus_addr, reg);
|
||||
ret = smbus_read_byte_cmd(dev->as99127f_smbus_addr, reg);
|
||||
else if ((reg & 0x7) == 0x0) /* temperature high byte */
|
||||
ret = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]) >> 8;
|
||||
else if ((reg & 0x7) == 0x1) /* temperature low byte */
|
||||
ret = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]);
|
||||
else
|
||||
ret = dev->regs[reg & 0x7];
|
||||
ret = dev->regs[reg & 0x7];
|
||||
|
||||
lm75_log("LM75: read(%02X) = %02X\n", reg, ret);
|
||||
|
||||
@@ -165,22 +169,22 @@ lm75_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv)
|
||||
uint8_t vallo = (val & 0xff);
|
||||
|
||||
switch (cmd & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
lm75_write(dev, 0x0, valhi);
|
||||
lm75_write(dev, 0x1, vallo);
|
||||
break;
|
||||
case 0x1: /* configuration */
|
||||
lm75_write(dev, 0x2, vallo);
|
||||
break;
|
||||
case 0x2: /* Thyst */
|
||||
lm75_write(dev, 0x3, valhi);
|
||||
lm75_write(dev, 0x4, vallo);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
lm75_write(dev, 0x5, valhi);
|
||||
lm75_write(dev, 0x6, vallo);
|
||||
break;
|
||||
break;
|
||||
case 0x0: /* temperature */
|
||||
lm75_write(dev, 0x0, valhi);
|
||||
lm75_write(dev, 0x1, vallo);
|
||||
break;
|
||||
case 0x1: /* configuration */
|
||||
lm75_write(dev, 0x2, vallo);
|
||||
break;
|
||||
case 0x2: /* Thyst */
|
||||
lm75_write(dev, 0x3, valhi);
|
||||
lm75_write(dev, 0x4, vallo);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
lm75_write(dev, 0x5, valhi);
|
||||
lm75_write(dev, 0x6, vallo);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,14 +198,14 @@ lm75_write(lm75_t *dev, uint8_t reg, uint8_t val)
|
||||
to access some of its proprietary registers. Pass this operation on to
|
||||
the main monitor address through an internal SMBus call, if necessary. */
|
||||
if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr < 0x80)) {
|
||||
smbus_write_byte_cmd(dev->as99127f_smbus_addr, reg, val);
|
||||
return 1;
|
||||
smbus_write_byte_cmd(dev->as99127f_smbus_addr, reg, val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t reg_idx = (reg & 0x7);
|
||||
|
||||
if ((reg_idx <= 0x1) || (reg_idx == 0x7))
|
||||
return 0; /* read-only registers */
|
||||
return 0; /* read-only registers */
|
||||
|
||||
dev->regs[reg_idx] = val;
|
||||
|
||||
@@ -212,9 +216,6 @@ lm75_write(lm75_t *dev, uint8_t reg, uint8_t val)
|
||||
static void
|
||||
lm75_reset(lm75_t *dev)
|
||||
{
|
||||
uint16_t temp = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]);
|
||||
dev->regs[0x0] = (temp >> 8);
|
||||
dev->regs[0x1] = temp;
|
||||
dev->regs[0x3] = 0x4b;
|
||||
dev->regs[0x5] = 0x50;
|
||||
|
||||
@@ -240,7 +241,11 @@ lm75_init(const device_t *info)
|
||||
memset(dev, 0, sizeof(lm75_t));
|
||||
|
||||
dev->local = info->local;
|
||||
dev->values = hwm_get_values();
|
||||
|
||||
/* Set default value. */
|
||||
if (dev->local)
|
||||
hwm_values.temperatures[dev->local >> 8] = 30;
|
||||
dev->values = &hwm_values;
|
||||
|
||||
dev->as99127f_smbus_addr = 0x80;
|
||||
|
||||
@@ -253,7 +258,7 @@ lm75_init(const device_t *info)
|
||||
/* LM75 on SMBus address 4Ah, reporting temperatures[1]. */
|
||||
const device_t lm75_1_4a_device = {
|
||||
"National Semiconductor LM75 Temperature Sensor",
|
||||
DEVICE_AT,
|
||||
DEVICE_ISA,
|
||||
0x14a,
|
||||
lm75_init, lm75_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
@@ -265,7 +270,7 @@ const device_t lm75_1_4a_device = {
|
||||
the Winbond W83781D family. Not to be used stand-alone. */
|
||||
const device_t lm75_w83781d_device = {
|
||||
"Winbond W83781D Secondary Temperature Sensor",
|
||||
DEVICE_AT,
|
||||
DEVICE_ISA,
|
||||
0,
|
||||
lm75_init, lm75_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
|
@@ -29,12 +29,13 @@
|
||||
#include <86box/hwm.h>
|
||||
|
||||
|
||||
#define LM78_SMBUS 0x10000
|
||||
#define LM78_W83781D 0x20000
|
||||
#define LM78_AS99127F_REV1 0x40000
|
||||
#define LM78_AS99127F_REV2 0x80000
|
||||
#define LM78_SMBUS 0x010000
|
||||
#define LM78_W83781D 0x020000
|
||||
#define LM78_AS99127F_REV1 0x040000
|
||||
#define LM78_AS99127F_REV2 0x080000
|
||||
#define LM78_W83782D 0x100000
|
||||
#define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* special mask covering both _REV1 and _REV2 */
|
||||
#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F) /* special mask covering all Winbond variants */
|
||||
#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F | LM78_W83782D) /* special mask covering all Winbond variants */
|
||||
#define LM78_WINBOND_VENDOR_ID ((dev->local & LM78_AS99127F_REV1) ? 0x12c3 : 0x5ca3)
|
||||
|
||||
#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
|
||||
@@ -48,6 +49,7 @@ typedef struct {
|
||||
device_t *lm75[2];
|
||||
|
||||
uint8_t regs[256];
|
||||
uint8_t regs_782d[2][16];
|
||||
uint8_t addr_register;
|
||||
uint8_t data_register;
|
||||
|
||||
@@ -100,25 +102,25 @@ lm78_remap(lm78_t *dev, uint8_t addr)
|
||||
lm78_log("LM78: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
smbus_removehandler(dev->smbus_addr, 1,
|
||||
lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL,
|
||||
lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL,
|
||||
lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
|
||||
if (addr < 0x80) smbus_sethandler(addr, 1,
|
||||
lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL,
|
||||
lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL,
|
||||
lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL,
|
||||
dev);
|
||||
|
||||
dev->smbus_addr = addr;
|
||||
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
/* Store the main SMBus address on the LM75 devices to ensure reads/writes
|
||||
to the AS99127F's proprietary registers are passed through to this side. */
|
||||
for (uint8_t i = 0; i <= 1; i++) {
|
||||
lm75 = device_get_priv(dev->lm75[i]);
|
||||
if (lm75)
|
||||
lm75->as99127f_smbus_addr = dev->smbus_addr;
|
||||
}
|
||||
/* Store the main SMBus address on the LM75 devices to ensure reads/writes
|
||||
to the AS99127F's proprietary registers are passed through to this side. */
|
||||
for (uint8_t i = 0; i <= 1; i++) {
|
||||
lm75 = device_get_priv(dev->lm75[i]);
|
||||
if (lm75)
|
||||
lm75->as99127f_smbus_addr = dev->smbus_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,22 +132,23 @@ lm78_isa_read(uint16_t port, void *priv)
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port & 0x7) {
|
||||
case 0x5:
|
||||
ret = (dev->addr_register & 0x7f);
|
||||
break;
|
||||
case 0x6:
|
||||
ret = lm78_read(dev, dev->addr_register, dev->active_bank);
|
||||
case 0x5:
|
||||
ret = (dev->addr_register & 0x7f);
|
||||
break;
|
||||
case 0x6:
|
||||
ret = lm78_read(dev, dev->addr_register, dev->active_bank);
|
||||
|
||||
if ((dev->active_bank == 0) &&
|
||||
((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) ||
|
||||
((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lm78_log("LM78: Read from unknown ISA port %d\n", port & 0x7);
|
||||
break;
|
||||
if (((dev->active_bank == 0) &&
|
||||
((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) ||
|
||||
((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) ||
|
||||
((dev->local & LM78_W83782D) && (dev->active_bank == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lm78_log("LM78: Read from unknown ISA port %d\n", port & 0x7);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -179,24 +182,50 @@ lm78_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv)
|
||||
static uint8_t
|
||||
lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint8_t ret = 0, masked_reg = reg;
|
||||
lm75_t *lm75;
|
||||
|
||||
if (((reg & 0xf8) == 0x50) && (bank != 0)) {
|
||||
/* LM75 registers */
|
||||
lm75 = device_get_priv(dev->lm75[bank - 1]);
|
||||
if (lm75)
|
||||
ret = lm75_read(lm75, reg);
|
||||
if (((reg & 0xf8) == 0x50) && ((bank == 1) || (bank == 2))) {
|
||||
/* LM75 registers */
|
||||
lm75 = device_get_priv(dev->lm75[bank - 1]);
|
||||
if (lm75)
|
||||
ret = lm75_read(lm75, reg);
|
||||
} else if (((reg & 0xf8) == 0x50) && ((bank == 4) || (bank == 5) || (bank == 6))) {
|
||||
/* W83782D additional registers */
|
||||
if (dev->local & LM78_W83782D) {
|
||||
if ((bank == 5) && ((reg == 0x50) || (reg == 0x51))) /* voltages */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[7 + (reg & 1)]);
|
||||
else if (bank < 6)
|
||||
ret = dev->regs_782d[bank - 4][reg & 0x0f];
|
||||
}
|
||||
} else {
|
||||
/* regular registers */
|
||||
if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* special case for two-byte vendor ID register */
|
||||
ret = (dev->hbacs ? (LM78_WINBOND_VENDOR_ID >> 8) : LM78_WINBOND_VENDOR_ID);
|
||||
else if ((reg >= 0x60) && (reg <= 0x7f)) /* read auto-increment value RAM registers from their non-auto-increment locations */
|
||||
ret = dev->regs[reg & 0x3f];
|
||||
else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors [0x00:0x12] to [0x80:0x92] */
|
||||
ret = dev->regs[reg & 0x7f];
|
||||
else
|
||||
ret = dev->regs[reg];
|
||||
/* regular registers */
|
||||
ret = dev->regs[reg];
|
||||
if (reg >= 0x40)
|
||||
masked_reg = reg & 0x3f; /* match both non-auto-increment and auto-increment locations */
|
||||
if ((masked_reg >= 0x20) && (masked_reg <= 0x26)) /* voltages */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[reg & 7]);
|
||||
else if (masked_reg == 0x27) /* temperature */
|
||||
ret = dev->values->temperatures[0];
|
||||
else if ((masked_reg >= 0x28) && (masked_reg <= 0x2a)) /* fan speeds */
|
||||
ret = LM78_RPM_TO_REG(dev->values->fans[reg & 3], 1 << ((dev->regs[((reg & 3) == 2) ? 0x4b : 0x47] >> ((reg & 3) ? 6 : 4)) & 0x3));
|
||||
else if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* two-byte vendor ID register */
|
||||
ret = (dev->hbacs ? (LM78_WINBOND_VENDOR_ID >> 8) : LM78_WINBOND_VENDOR_ID);
|
||||
else if ((reg >= 0x60) && (reg <= 0x7f)) /* read auto-increment value RAM registers from their non-auto-increment locations */
|
||||
ret = dev->regs[reg & 0x3f];
|
||||
else if (dev->local & LM78_AS99127F) { /* AS99127F mirrored registers */
|
||||
masked_reg = reg & 0x7f;
|
||||
if (masked_reg == 0x00) /* IN2 Low Limit */
|
||||
ret = dev->regs[0x30];
|
||||
else if ((masked_reg == 0x01) || (masked_reg == 0x04)) /* IN3 */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[3]);
|
||||
else if (masked_reg == 0x05) /* IN2 */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[2]);
|
||||
else if (masked_reg == 0x08) /* IN3 Low Limit */
|
||||
ret = dev->regs[0x32];
|
||||
else if ((reg >= 0x80) && (reg <= 0x92)) /* mirror [0x00:0x12] to [0x80:0x92] */
|
||||
ret = dev->regs[masked_reg];
|
||||
}
|
||||
}
|
||||
|
||||
lm78_log("LM78: read(%02X, %d) = %02X\n", reg, bank, ret);
|
||||
@@ -211,22 +240,23 @@ lm78_isa_write(uint16_t port, uint8_t val, void *priv)
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
switch (port & 0x7) {
|
||||
case 0x5:
|
||||
dev->addr_register = (val & 0x7f);
|
||||
break;
|
||||
case 0x6:
|
||||
lm78_write(dev, dev->addr_register, val, dev->active_bank);
|
||||
case 0x5:
|
||||
dev->addr_register = (val & 0x7f);
|
||||
break;
|
||||
case 0x6:
|
||||
lm78_write(dev, dev->addr_register, val, dev->active_bank);
|
||||
|
||||
if ((dev->active_bank == 0) &&
|
||||
((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) ||
|
||||
((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lm78_log("LM78: Write %02X to unknown ISA port %d\n", val, port & 0x7);
|
||||
break;
|
||||
if (((dev->active_bank == 0) &&
|
||||
((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) ||
|
||||
((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) ||
|
||||
((dev->local & LM78_W83782D) && (dev->active_bank == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lm78_log("LM78: Write %02X to unknown ISA port %d\n", val, port & 0x7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,90 +292,114 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
|
||||
lm78_log("LM78: write(%02X, %d, %02X)\n", reg, bank, val);
|
||||
|
||||
if (((reg & 0xf8) == 0x50) && (bank != 0)) {
|
||||
/* LM75 registers */
|
||||
lm75 = device_get_priv(dev->lm75[bank - 1]);
|
||||
if (lm75)
|
||||
lm75_write(lm75, reg, val);
|
||||
return 1;
|
||||
if ((reg & 0xf8) == 0x50) {
|
||||
if ((bank == 1) || (bank == 2)) {
|
||||
/* LM75 registers */
|
||||
lm75 = device_get_priv(dev->lm75[bank - 1]);
|
||||
if (lm75)
|
||||
lm75_write(lm75, reg, val);
|
||||
return 1;
|
||||
} else if (dev->local & LM78_W83782D) {
|
||||
/* W83782D additional registers */
|
||||
if (bank == 4) {
|
||||
switch (reg) {
|
||||
case 0x50: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
|
||||
case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5d: case 0x5e: case 0x5f:
|
||||
/* read-only registers */
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->regs_782d[0][reg & 0x0f] = val;
|
||||
return 1;
|
||||
} else if (bank == 5) {
|
||||
switch (reg) {
|
||||
case 0x50: case 0x51: case 0x52: case 0x53: case 0x58: case 0x59: case 0x5a:
|
||||
case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
|
||||
/* read-only registers */
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->regs_782d[1][reg & 0x0f] = val;
|
||||
return 1;
|
||||
} else if (bank == 6) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* regular registers */
|
||||
switch (reg) {
|
||||
case 0x41: case 0x42: case 0x4f: case 0x58:
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a:
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a:
|
||||
/* read-only registers */
|
||||
return 0;
|
||||
case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e:
|
||||
/* Winbond-only registers */
|
||||
if (!(dev->local & LM78_WINBOND))
|
||||
return 0;
|
||||
break;
|
||||
case 0x41: case 0x42: case 0x4f: case 0x58:
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a:
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a:
|
||||
/* read-only registers */
|
||||
return 0;
|
||||
|
||||
case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e:
|
||||
/* Winbond-only registers */
|
||||
if (!(dev->local & LM78_WINBOND))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((reg >= 0x60) && (reg <= 0x7f)) /* write auto-increment value RAM registers to their non-auto-increment locations */
|
||||
dev->regs[reg & 0x3f] = val;
|
||||
dev->regs[reg & 0x3f] = val;
|
||||
else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors [0x00:0x12] to [0x80:0x92] */
|
||||
dev->regs[reg & 0x7f] = val;
|
||||
dev->regs[reg & 0x7f] = val;
|
||||
else
|
||||
dev->regs[reg] = val;
|
||||
dev->regs[reg] = val;
|
||||
|
||||
switch (reg) {
|
||||
case 0x40:
|
||||
if (val & 0x80) /* INITIALIZATION bit resets all registers except main SMBus address */
|
||||
lm78_reset(dev, 1);
|
||||
break;
|
||||
case 0x47:
|
||||
/* update FAN1/FAN2 values to match the new divisor */
|
||||
dev->regs[0x28] = LM78_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x47] >> 4) & 0x3));
|
||||
dev->regs[0x29] = LM78_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x47] >> 6) & 0x3));
|
||||
break;
|
||||
case 0x48:
|
||||
/* set main SMBus address */
|
||||
if (dev->local & LM78_SMBUS)
|
||||
lm78_remap(dev, dev->regs[0x48] & 0x7f);
|
||||
break;
|
||||
case 0x49:
|
||||
if (!(dev->local & LM78_WINBOND)) {
|
||||
if (val & 0x20) /* Chip Reset bit (LM78 only) resets all registers */
|
||||
lm78_reset(dev, 0);
|
||||
else
|
||||
dev->regs[0x49] = 0x40;
|
||||
} else {
|
||||
dev->regs[0x49] &= 0x01;
|
||||
}
|
||||
break;
|
||||
case 0x4a:
|
||||
/* set LM75 SMBus addresses (Winbond only) */
|
||||
if (dev->local & LM78_SMBUS) {
|
||||
for (uint8_t i = 0; i <= 1; i++) {
|
||||
lm75 = device_get_priv(dev->lm75[i]);
|
||||
if (!lm75)
|
||||
continue;
|
||||
if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */
|
||||
lm75_remap(lm75, 0x80);
|
||||
else
|
||||
lm75_remap(lm75, 0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x4b:
|
||||
/* update FAN3 value to match the new divisor */
|
||||
dev->regs[0x2a] = LM78_RPM_TO_REG(dev->values->fans[2], 1 << ((dev->regs[0x4b] >> 6) & 0x3));
|
||||
break;
|
||||
case 0x4e:
|
||||
dev->hbacs = (dev->regs[0x4e] & 0x80);
|
||||
/* BANKSEL[0:2] is a bitfield according to the datasheet, but not in reality */
|
||||
dev->active_bank = (dev->regs[0x4e] & 0x07);
|
||||
break;
|
||||
case 0x87:
|
||||
/* fixes AS99127F boards hanging after BIOS save & exit, probably a reset register */
|
||||
if ((dev->local & LM78_AS99127F) && (val == 0x01)) {
|
||||
lm78_log("LM78: Reset requested through AS99127F\n");
|
||||
resetx86();
|
||||
}
|
||||
break;
|
||||
case 0x40:
|
||||
if (val & 0x80) /* INITIALIZATION bit resets all registers except main SMBus address */
|
||||
lm78_reset(dev, 1);
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
/* set main SMBus address */
|
||||
if (dev->local & LM78_SMBUS)
|
||||
lm78_remap(dev, dev->regs[0x48] & 0x7f);
|
||||
break;
|
||||
|
||||
case 0x49:
|
||||
if (!(dev->local & LM78_WINBOND)) {
|
||||
if (val & 0x20) /* Chip Reset bit (LM78 only) resets all registers */
|
||||
lm78_reset(dev, 0);
|
||||
else
|
||||
dev->regs[0x49] = 0x40;
|
||||
} else {
|
||||
dev->regs[0x49] &= 0x01;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
/* set LM75 SMBus addresses (Winbond only) */
|
||||
if (dev->local & LM78_SMBUS) {
|
||||
for (uint8_t i = 0; i <= 1; i++) {
|
||||
lm75 = device_get_priv(dev->lm75[i]);
|
||||
if (!lm75)
|
||||
continue;
|
||||
if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */
|
||||
lm75_remap(lm75, 0x80);
|
||||
else
|
||||
lm75_remap(lm75, 0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4e:
|
||||
dev->hbacs = (dev->regs[0x4e] & 0x80);
|
||||
/* BANKSEL[0:2] is a bitfield according to the datasheet, but not in reality */
|
||||
dev->active_bank = (dev->regs[0x4e] & 0x07);
|
||||
break;
|
||||
|
||||
case 0x87:
|
||||
/* AS99127F boards perform a soft reset through this register */
|
||||
if ((dev->local & LM78_AS99127F) && (val == 0x01)) {
|
||||
lm78_log("LM78: Reset requested through AS99127F\n");
|
||||
resetx86();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -358,69 +412,65 @@ lm78_reset(lm78_t *dev, uint8_t initialization)
|
||||
memset(dev->regs, 0, 256);
|
||||
memset(dev->regs + 0xc0, 0xff, 32); /* C0-DF are 0xFF at least on the AS99127F */
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i <= 6; i++)
|
||||
dev->regs[0x20 + i] = LM78_VOLTAGE_TO_REG(dev->values->voltages[i]);
|
||||
dev->regs[0x27] = dev->values->temperatures[0];
|
||||
for (i = 0; i <= 2; i++)
|
||||
dev->regs[0x28 + i] = LM78_RPM_TO_REG(dev->values->fans[i], 2);
|
||||
dev->regs[0x40] = 0x08;
|
||||
dev->regs[0x46] = 0x40;
|
||||
dev->regs[0x47] = 0x50;
|
||||
if (dev->local & LM78_SMBUS) {
|
||||
if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */
|
||||
dev->smbus_addr = 0x2d;
|
||||
dev->regs[0x48] = dev->smbus_addr;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x01;
|
||||
if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */
|
||||
dev->smbus_addr = 0x2d;
|
||||
dev->regs[0x48] = dev->smbus_addr;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x01;
|
||||
} else {
|
||||
dev->regs[0x48] = 0x00;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x88;
|
||||
dev->regs[0x48] = 0x00;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x88;
|
||||
}
|
||||
if (dev->local & LM78_WINBOND) {
|
||||
dev->regs[0x49] = 0x02;
|
||||
dev->regs[0x4b] = 0x44;
|
||||
dev->regs[0x4c] = 0x01;
|
||||
dev->regs[0x4d] = 0x15;
|
||||
dev->regs[0x4e] = 0x80;
|
||||
dev->hbacs = (dev->regs[0x4e] & 0x80);
|
||||
dev->regs[0x4f] = (LM78_WINBOND_VENDOR_ID >> 8);
|
||||
dev->regs[0x57] = 0x80;
|
||||
dev->regs[0x49] = 0x02;
|
||||
dev->regs[0x4b] = 0x44;
|
||||
dev->regs[0x4c] = 0x01;
|
||||
dev->regs[0x4d] = 0x15;
|
||||
dev->regs[0x4e] = 0x80;
|
||||
dev->hbacs = (dev->regs[0x4e] & 0x80);
|
||||
dev->regs[0x4f] = (LM78_WINBOND_VENDOR_ID >> 8);
|
||||
dev->regs[0x57] = 0x80;
|
||||
|
||||
/* Initialize proprietary registers on the AS99127F. The BIOS accesses some
|
||||
of these on boot through read_byte_cmd on the TEMP2 address, hanging on
|
||||
POST code C1 if they're defaulted to 0. There's no documentation on what
|
||||
these are for. The following values were dumped from a live, initialized
|
||||
AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. */
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
/* 0x00 appears to mirror IN2 Low Limit */
|
||||
dev->regs[0x01] = dev->regs[0x23]; /* appears to mirror IN3 */
|
||||
dev->regs[0x02] = LM78_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; must read 2.8V on P3 boards */
|
||||
dev->regs[0x03] = 0x60;
|
||||
dev->regs[0x04] = dev->regs[0x23]; /* appears to mirror IN3 */
|
||||
dev->regs[0x05] = dev->regs[0x22]; /* appears to mirror IN2 */
|
||||
dev->regs[0x07] = 0xcd;
|
||||
/* 0x08 appears to mirror IN3 Low Limit */
|
||||
dev->regs[0x09] = dev->regs[0x0f] = dev->regs[0x11] = 0xf8; /* three instances of */
|
||||
dev->regs[0x0a] = dev->regs[0x10] = dev->regs[0x12] = 0xa5; /* the same word */
|
||||
dev->regs[0x0b] = 0xac;
|
||||
dev->regs[0x0c] = 0x8c;
|
||||
dev->regs[0x0d] = 0x68;
|
||||
dev->regs[0x0e] = 0x54;
|
||||
/* Initialize proprietary registers on the AS99127F. The BIOS accesses some
|
||||
of these on boot through read_byte_cmd on the TEMP2 address, hanging on
|
||||
POST code C1 if they're defaulted to 0. There's no documentation on what
|
||||
these are for. The following values were dumped from a live, initialized
|
||||
AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. */
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
/* 0x00 appears to mirror IN2 Low Limit */
|
||||
/* 0x01 appears to mirror IN3 */
|
||||
dev->regs[0x02] = LM78_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; must read 2.8V on P3 boards */
|
||||
dev->regs[0x03] = 0x60;
|
||||
/* 0x04 appears to mirror IN3 */
|
||||
/* 0x05 appears to mirror IN2 */
|
||||
dev->regs[0x07] = 0xcd;
|
||||
/* 0x08 appears to mirror IN3 Low Limit */
|
||||
dev->regs[0x09] = dev->regs[0x0f] = dev->regs[0x11] = 0xf8; /* three instances of */
|
||||
dev->regs[0x0a] = dev->regs[0x10] = dev->regs[0x12] = 0xa5; /* the same word */
|
||||
dev->regs[0x0b] = 0xac;
|
||||
dev->regs[0x0c] = 0x8c;
|
||||
dev->regs[0x0d] = 0x68;
|
||||
dev->regs[0x0e] = 0x54;
|
||||
|
||||
dev->regs[0x53] = dev->regs[0x54] = dev->regs[0x55] = 0xff;
|
||||
dev->regs[0x58] = 0x31;
|
||||
dev->regs[0x59] = dev->regs[0x5a] = 0x8f;
|
||||
dev->regs[0x5c] = 0xe0;
|
||||
dev->regs[0x5d] = 0x48;
|
||||
dev->regs[0x5e] = 0xe2;
|
||||
dev->regs[0x5f] = 0x3f;
|
||||
} else {
|
||||
dev->regs[0x58] = 0x10;
|
||||
}
|
||||
dev->regs[0x53] = dev->regs[0x54] = dev->regs[0x55] = 0xff;
|
||||
dev->regs[0x58] = 0x31;
|
||||
dev->regs[0x59] = dev->regs[0x5a] = 0x8f;
|
||||
dev->regs[0x5c] = 0xe0;
|
||||
dev->regs[0x5d] = 0x48;
|
||||
dev->regs[0x5e] = 0xe2;
|
||||
dev->regs[0x5f] = 0x3f;
|
||||
} else if (dev->local & LM78_W83781D) {
|
||||
dev->regs[0x58] = 0x10;
|
||||
} else if (dev->local & LM78_W83782D) {
|
||||
dev->regs[0x58] = 0x30;
|
||||
}
|
||||
} else {
|
||||
dev->regs[0x49] = 0x40;
|
||||
dev->regs[0x49] = 0x40;
|
||||
}
|
||||
|
||||
lm78_remap(dev, dev->smbus_addr);
|
||||
@@ -434,7 +484,7 @@ lm78_close(void *priv)
|
||||
|
||||
uint16_t isa_io = (dev->local & 0xffff);
|
||||
if (isa_io)
|
||||
io_removehandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev);
|
||||
io_removehandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -447,27 +497,61 @@ lm78_init(const device_t *info)
|
||||
memset(dev, 0, sizeof(lm78_t));
|
||||
|
||||
dev->local = info->local;
|
||||
dev->values = hwm_get_values();
|
||||
|
||||
/* initialize secondary/tertiary LM75 sensors on Winbond */
|
||||
/* Set default values. */
|
||||
hwm_values_t defaults = {
|
||||
{ /* fan speeds */
|
||||
3000, /* usually Chassis, sometimes CPU */
|
||||
3000, /* usually CPU, sometimes Chassis */
|
||||
3000 /* usually PSU, sometimes Chassis */
|
||||
}, { /* temperatures */
|
||||
30, /* usually Board, sometimes Chassis */
|
||||
30, /* Winbond only: usually CPU, sometimes Probe */
|
||||
30 /* Winbond only: usually CPU when not the one above */
|
||||
}, { /* voltages */
|
||||
hwm_get_vcore(), /* Vcore */
|
||||
0, /* sometimes Vtt, Vio or second CPU */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
12000 * (604.0 / 2100.0), /* -12V (Rf/Rin negative voltage formula from the W83781D datasheet) */
|
||||
5000 * (604.0 / 909.0), /* -5V (Rf/Rin negative voltage formula from the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(5000, 51, 75), /* W83782D only: +5VSB (5.1K/7.5K divider suggested in the datasheet) */
|
||||
3000 /* W83782D only: VBAT */
|
||||
}
|
||||
};
|
||||
|
||||
/* Set per-chip defaults. */
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
defaults.voltages[5] = 12000 * (604.0 / 2400.0); /* different -12V Rin value for AS99127F (bruteforced) */
|
||||
} else if (dev->local & LM78_W83782D) {
|
||||
/* different negative voltage formula for W83782D (from the datasheet) */
|
||||
defaults.voltages[5] = ((3600 + 12000) * (232.0 / (232.0 + 56.0))) - 12000;
|
||||
defaults.voltages[6] = ((3600 + 5000) * (120.0 / (120.0 + 56.0))) - 5000;
|
||||
}
|
||||
|
||||
hwm_values = defaults;
|
||||
dev->values = &hwm_values;
|
||||
|
||||
/* Initialize secondary/tertiary LM75 sensors on Winbond. */
|
||||
for (uint8_t i = 0; i <= 1; i++) {
|
||||
if (dev->local & LM78_WINBOND) {
|
||||
dev->lm75[i] = (device_t *) malloc(sizeof(device_t));
|
||||
memcpy(dev->lm75[i], &lm75_w83781d_device, sizeof(device_t));
|
||||
dev->lm75[i]->local = ((i + 1) << 8);
|
||||
if (dev->local & LM78_SMBUS)
|
||||
dev->lm75[i]->local |= (0x48 + i);
|
||||
device_add(dev->lm75[i]);
|
||||
} else {
|
||||
dev->lm75[i] = NULL;
|
||||
}
|
||||
if (dev->local & LM78_WINBOND) {
|
||||
dev->lm75[i] = (device_t *) malloc(sizeof(device_t));
|
||||
memcpy(dev->lm75[i], &lm75_w83781d_device, sizeof(device_t));
|
||||
dev->lm75[i]->local = ((i + 1) << 8);
|
||||
if (dev->local & LM78_SMBUS)
|
||||
dev->lm75[i]->local |= (0x48 + i);
|
||||
device_add(dev->lm75[i]);
|
||||
} else {
|
||||
dev->lm75[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lm78_reset(dev, 0);
|
||||
|
||||
uint16_t isa_io = (dev->local & 0xffff);
|
||||
if (isa_io)
|
||||
io_sethandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev);
|
||||
io_sethandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -495,8 +579,8 @@ const device_t w83781d_device = {
|
||||
};
|
||||
|
||||
|
||||
/* The ASUS AS99127F is a customized W83781D with no ISA interface (SMBus only),
|
||||
added proprietary registers and different chip/vendor IDs. */
|
||||
/* The ASUS AS99127F is a customized W83781D with no ISA interface (SMBus
|
||||
only), added proprietary registers and different chip/vendor IDs. */
|
||||
const device_t as99127f_device = {
|
||||
"ASUS AS99127F Rev. 1 Hardware Monitor",
|
||||
DEVICE_ISA,
|
||||
@@ -510,9 +594,20 @@ const device_t as99127f_device = {
|
||||
/* Rev. 2 changes the vendor ID back to Winbond's and brings some other changes. */
|
||||
const device_t as99127f_rev2_device = {
|
||||
"ASUS AS99127F Rev. 2 Hardware Monitor",
|
||||
DEVICE_AT,
|
||||
DEVICE_ISA,
|
||||
LM78_SMBUS | LM78_AS99127F_REV2,
|
||||
lm78_init, lm78_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/* Winbond W83782D on ISA and SMBus. */
|
||||
const device_t w83782d_device = {
|
||||
"Winbond W83782D Hardware Monitor",
|
||||
DEVICE_ISA,
|
||||
0x290 | LM78_SMBUS | LM78_W83782D,
|
||||
lm78_init, lm78_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
@@ -24,16 +24,15 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/hwm.h>
|
||||
|
||||
|
||||
#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
|
||||
#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
|
||||
#define VT82C686_RPM_TO_REG(r, d) ((r) ? CLAMP(1350000 / (r * d), 1, 255) : 0)
|
||||
/* Temperature formula from source comments in Linux's via686a.c driver */
|
||||
/* Temperature/voltage formulas and factors derived from Linux's via686a.c driver */
|
||||
#define VT82C686_TEMP_TO_REG(t) (-1.160370e-10*(t*t*t*t*t*t) + 3.193693e-08*(t*t*t*t*t) - 1.464447e-06*(t*t*t*t) - 2.525453e-04*(t*t*t) + 1.424593e-02*(t*t) + 2.148941e+00*t + 7.275808e+01)
|
||||
#define VT82C686_VOLTAGE_TO_REG(v) ((v) >> 4)
|
||||
#define VT82C686_VOLTAGE_TO_REG(v, f) CLAMP((((v) * (2.628 / (f))) - 120.5) / 25, 0, 255)
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -67,10 +66,10 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv)
|
||||
return;
|
||||
|
||||
switch (reg) {
|
||||
case 0x40:
|
||||
if (val & 0x80)
|
||||
vt82c686_reset(dev, 1);
|
||||
break;
|
||||
case 0x40:
|
||||
if (val & 0x80)
|
||||
vt82c686_reset(dev, 1);
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
val &= 0xf0;
|
||||
@@ -92,19 +91,19 @@ vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv)
|
||||
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||
|
||||
if (dev->io_base)
|
||||
io_removehandler(dev->io_base, 0x0050,
|
||||
io_removehandler(dev->io_base, 0x0050,
|
||||
vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev);
|
||||
|
||||
switch (addr) {
|
||||
case 0x70:
|
||||
dev->io_base &= 0xff00;
|
||||
dev->io_base |= val & 0x80;
|
||||
break;
|
||||
case 0x70:
|
||||
dev->io_base &= 0xff00;
|
||||
dev->io_base |= val & 0x80;
|
||||
break;
|
||||
|
||||
case 0x71:
|
||||
dev->io_base &= 0x00ff;
|
||||
dev->io_base |= val << 8;
|
||||
break;
|
||||
case 0x71:
|
||||
dev->io_base &= 0x00ff;
|
||||
dev->io_base |= val << 8;
|
||||
break;
|
||||
|
||||
case 0x74:
|
||||
dev->enable = val & 0x01;
|
||||
@@ -112,7 +111,7 @@ vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
if (dev->enable && dev->io_base)
|
||||
io_sethandler(dev->io_base, 0x0050,
|
||||
io_sethandler(dev->io_base, 0x0050,
|
||||
vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
@@ -126,11 +125,11 @@ vt82c686_reset(vt82c686_t *dev, uint8_t initialization)
|
||||
dev->regs[0x20] = VT82C686_TEMP_TO_REG(dev->values->temperatures[0]);
|
||||
dev->regs[0x21] = VT82C686_TEMP_TO_REG(dev->values->temperatures[1]);
|
||||
|
||||
dev->regs[0x22] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[0]);
|
||||
dev->regs[0x23] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[1]);
|
||||
dev->regs[0x24] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[2]);
|
||||
dev->regs[0x25] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[3]);
|
||||
dev->regs[0x26] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[4]);
|
||||
dev->regs[0x22] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[0], 1.25);
|
||||
dev->regs[0x23] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[1], 1.25);
|
||||
dev->regs[0x24] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[2], 1.67);
|
||||
dev->regs[0x25] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[3], 2.6);
|
||||
dev->regs[0x26] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[4], 6.3);
|
||||
|
||||
dev->regs[0x29] = VT82C686_RPM_TO_REG(dev->values->fans[0], 2);
|
||||
dev->regs[0x2a] = VT82C686_RPM_TO_REG(dev->values->fans[1], 2);
|
||||
@@ -162,7 +161,26 @@ vt82c686_init(const device_t *info)
|
||||
vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t));
|
||||
memset(dev, 0, sizeof(vt82c686_t));
|
||||
|
||||
dev->values = hwm_get_values();
|
||||
/* Set default values. Since this hardware monitor has a complex voltage factor system,
|
||||
the values struct contains voltage values *before* applying their respective factors. */
|
||||
hwm_values_t defaults = {
|
||||
{ /* fan speeds */
|
||||
3000, /* CPU */
|
||||
3000 /* Chassis */
|
||||
}, { /* temperatures */
|
||||
30, /* CPU */
|
||||
30, /* System */
|
||||
0 /* unused */
|
||||
}, { /* voltages */
|
||||
hwm_get_vcore(), /* Vcore */
|
||||
2500, /* 2.5V */
|
||||
3300, /* 3.3V */
|
||||
5000, /* 5V */
|
||||
12000 /* 12V */
|
||||
}
|
||||
};
|
||||
hwm_values = defaults;
|
||||
dev->values = &hwm_values;
|
||||
|
||||
vt82c686_reset(dev, 0);
|
||||
|
||||
|
@@ -66,16 +66,16 @@ static void
|
||||
postcard_setui(void)
|
||||
{
|
||||
if (!postcard_written)
|
||||
sprintf(postcard_str, "POST: -- --");
|
||||
sprintf(postcard_str, "POST: -- --");
|
||||
else if (postcard_written == 1)
|
||||
sprintf(postcard_str, "POST: %02X --", postcard_code);
|
||||
sprintf(postcard_str, "POST: %02X --", postcard_code);
|
||||
else
|
||||
sprintf(postcard_str, "POST: %02X %02X", postcard_code, postcard_prev_code);
|
||||
sprintf(postcard_str, "POST: %02X %02X", postcard_code, postcard_prev_code);
|
||||
|
||||
ui_sb_bugui(postcard_str);
|
||||
|
||||
if (postcard_do_log) {
|
||||
/* log same string sent to the UI */
|
||||
/* log same string sent to the UI */
|
||||
postcard_log("[%04X:%08X] %s\n", CS, cpu_state.pc, postcard_str);
|
||||
}
|
||||
}
|
||||
@@ -95,12 +95,12 @@ static void
|
||||
postcard_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
if (postcard_written && val == postcard_code)
|
||||
return;
|
||||
return;
|
||||
|
||||
postcard_prev_code = postcard_code;
|
||||
postcard_code = val;
|
||||
if (postcard_written < 2)
|
||||
postcard_written++;
|
||||
postcard_written++;
|
||||
|
||||
postcard_setui();
|
||||
}
|
||||
@@ -112,13 +112,15 @@ postcard_init(const device_t *info)
|
||||
postcard_reset();
|
||||
|
||||
if (machines[machine].flags & MACHINE_MCA)
|
||||
postcard_port = 0x680; /* MCA machines */
|
||||
postcard_port = 0x680; /* MCA machines */
|
||||
else if (strstr(machines[machine].name, " PS/2 ") || strstr(machines[machine].name, " PS/1 "))
|
||||
postcard_port = 0x190; /* ISA PS/2 machines */
|
||||
postcard_port = 0x190; /* ISA PS/2 machines */
|
||||
else if (strstr(machines[machine].name, " IBM XT "))
|
||||
postcard_port = 0x60; /* IBM XT */
|
||||
else if (strstr(machines[machine].name, " Compaq ") && !(machines[machine].flags & MACHINE_PCI))
|
||||
postcard_port = 0x84; /* ISA Compaq machines */
|
||||
postcard_port = 0x84; /* ISA Compaq machines */
|
||||
else
|
||||
postcard_port = 0x80; /* AT and clone machines */
|
||||
postcard_port = 0x80; /* AT and clone machines */
|
||||
postcard_log("POST card initializing on port %04Xh\n", postcard_port);
|
||||
|
||||
if (postcard_port) io_sethandler(postcard_port, 1,
|
||||
|
@@ -2160,6 +2160,13 @@ fdc_set_irq(fdc_t *fdc, int irq)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fdc_set_dma_ch(fdc_t *fdc, int dma_ch)
|
||||
{
|
||||
fdc->dma_ch = dma_ch;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fdc_set_base(fdc_t *fdc, int base)
|
||||
{
|
||||
|
@@ -155,6 +155,7 @@ extern int fdc_is_verify(fdc_t *fdc);
|
||||
extern void fdc_overrun(fdc_t *fdc);
|
||||
extern void fdc_set_base(fdc_t *fdc, int base);
|
||||
extern void fdc_set_irq(fdc_t *fdc, int irq);
|
||||
extern void fdc_set_dma_ch(fdc_t *fdc, int dma_ch);
|
||||
extern int fdc_getdata(fdc_t *fdc, int last);
|
||||
extern int fdc_data(fdc_t *fdc, uint8_t data);
|
||||
|
||||
|
@@ -16,15 +16,16 @@
|
||||
*/
|
||||
#ifndef EMU_HWM_H
|
||||
# define EMU_HWM_H
|
||||
# include <stdint.h>
|
||||
|
||||
|
||||
#define RESISTOR_DIVIDER(v, r1, r2) (((v) * (r2)) / ((r1) + (r2)))
|
||||
|
||||
|
||||
typedef struct _hwm_values_ {
|
||||
typedef struct {
|
||||
uint16_t fans[4];
|
||||
uint8_t temperatures[4];
|
||||
uint16_t voltages[8];
|
||||
uint16_t voltages[9];
|
||||
} hwm_values_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -40,8 +41,7 @@ typedef struct {
|
||||
} lm75_t;
|
||||
|
||||
|
||||
extern void hwm_set_values(hwm_values_t new_values);
|
||||
extern hwm_values_t* hwm_get_values();
|
||||
extern uint16_t hwm_get_vcore();
|
||||
|
||||
extern void lm75_remap(lm75_t *dev, uint8_t addr);
|
||||
extern uint8_t lm75_read(lm75_t *dev, uint8_t reg);
|
||||
@@ -50,6 +50,9 @@ extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val);
|
||||
extern void vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv);
|
||||
|
||||
|
||||
/* Refer to specific hardware monitor implementations for the meaning of hwm_values. */
|
||||
extern hwm_values_t hwm_values;
|
||||
|
||||
extern const device_t lm75_1_4a_device;
|
||||
extern const device_t lm75_w83781d_device;
|
||||
|
||||
@@ -57,6 +60,7 @@ extern const device_t lm78_device;
|
||||
extern const device_t w83781d_device;
|
||||
extern const device_t as99127f_device;
|
||||
extern const device_t as99127f_rev2_device;
|
||||
extern const device_t w83782d_device;
|
||||
|
||||
extern const device_t gl518sm_2c_device;
|
||||
extern const device_t gl518sm_2d_device;
|
||||
|
@@ -918,26 +918,10 @@ machine_at_itoxstar_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&stpc_client_device);
|
||||
device_add(&sst_flash_29ee020_device);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds (incorrect divisor for some reason) */
|
||||
3000, /* Chassis */
|
||||
3000 /* CPU */
|
||||
}, { /* temperatures */
|
||||
30, /* Chassis */
|
||||
30 /* CPU */
|
||||
}, { /* voltages */
|
||||
0, /* unused */
|
||||
0, /* unused */
|
||||
3300, /* Vio */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
device_add(&w83781d_device); /* fans: Chassis, CPU, unused; temperatures: Chassis, CPU, unused */
|
||||
hwm_values.fans[2] = 0; /* unused */
|
||||
hwm_values.temperatures[2] = 0; /* unused */
|
||||
hwm_values.voltages[0] = 0; /* Vcore unused */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -81,26 +81,9 @@ machine_at_kn97_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&w83877f_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds (incorrect divisor for some reason) */
|
||||
6000, /* Chassis */
|
||||
6000, /* CPU */
|
||||
6000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30 /* MB */
|
||||
}, { /* voltages */
|
||||
2800, /* VCORE (2.8V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&lm78_device);
|
||||
device_add(&lm78_device); /* fans: Chassis, CPU, Power; temperature: MB */
|
||||
for (uint8_t i = 0; i < 3; i++)
|
||||
hwm_values.fans[i] *= 2; /* BIOS reports fans with the wrong divisor for some reason */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -159,27 +142,8 @@ machine_at_spitfire_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&fdc37c935_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds (incorrect divisor for some reason) */
|
||||
6000, /* Chassis */
|
||||
6000, /* CPU */
|
||||
6000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30 /* MB */
|
||||
}, { /* voltages */
|
||||
2800, /* VCORE (2.8V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&lm78_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
device_add(&lm78_device); /* no reporting in BIOS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -210,30 +174,9 @@ machine_at_p6i440e2_init(const machine_t *model)
|
||||
device_add(&w83977tf_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x03, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
0, /* unused */
|
||||
27 /* CPU */
|
||||
}, { /* voltages */
|
||||
2050, /* VCORE (2.05V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
device_add(&w83781d_device); /* fans: CPU, CHS, PS; temperatures: unused, CPU, System */
|
||||
hwm_values.temperatures[0] = 0; /* unused */
|
||||
hwm_values.voltages[1] = 1500; /* CPUVTT */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -268,30 +211,9 @@ machine_at_p2bls_init(const machine_t *model)
|
||||
device_add(&w83977ef_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
0, /* unused */
|
||||
27 /* CPU */
|
||||
}, { /* voltages */
|
||||
2050, /* VCORE (2.05V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */
|
||||
hwm_values.temperatures[1] = 0; /* unused */
|
||||
hwm_values.temperatures[2] -= 3; /* CPU offset */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -326,30 +248,8 @@ machine_at_p3bf_init(const machine_t *model)
|
||||
device_add(&w83977ef_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
30, /* JTPWR */
|
||||
30 /* CPU */
|
||||
}, { /* voltages */
|
||||
2050, /* VCORE (2.05V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 3, 1), /* +12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 59, 20), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&as99127f_device);
|
||||
device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */
|
||||
hwm_values.voltages[4] = hwm_values.voltages[5]; /* +12V reading not in line with other boards; appears to be close to the -12V reading */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -418,23 +318,7 @@ machine_at_ax6bc_init(const machine_t *model)
|
||||
device_add(&w83977tf_device);
|
||||
device_add(&sst_flash_29ee020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* System */
|
||||
3000 /* CPU */
|
||||
}, { /* temperatures */
|
||||
30 /* CPU */
|
||||
}, { /* voltages */
|
||||
2050, /* VCORE (2.05V by default) */
|
||||
RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the GL518SM datasheet) */
|
||||
3300 /* +3.3V */
|
||||
}
|
||||
};
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&gl518sm_2d_device);
|
||||
device_add(&gl518sm_2d_device); /* fans: System, CPU; temperature: CPU; no reporting in BIOS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -502,30 +386,11 @@ machine_at_p6sba_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* CPU1 */
|
||||
0, /* CPU2 */
|
||||
3000 /* Thermal Control */
|
||||
}, { /* temperatures */
|
||||
0, /* unused */
|
||||
30, /* CPU1 */
|
||||
0 /* unused (CPU2?) */
|
||||
}, { /* voltages */
|
||||
2050, /* CPU1 (2.05V by default) */
|
||||
0, /* CPU2 */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */
|
||||
hwm_values.fans[1] = 0; /* no CPU2 fan */
|
||||
hwm_values.temperatures[0] = 0; /* unused */
|
||||
hwm_values.temperatures[2] = 0; /* CPU2? */
|
||||
/* no CPU2 voltage */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -67,30 +67,12 @@ machine_at_6gxu_init(const machine_t *model)
|
||||
device_add(&w83977ef_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 512);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
0, /* unused */
|
||||
27 /* CPU */
|
||||
}, { /* voltages */
|
||||
2050, /* VCORE (2.05V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
device_add(&w83782d_device); /* fans: ???, ???, System; temperatures: System, CPU, unused */
|
||||
hwm_values.fans[0] = 2000;
|
||||
hwm_values.fans[1] = 2500;
|
||||
hwm_values.fans[2] = 3000;
|
||||
hwm_values.temperatures[2] = 0; /* unused */
|
||||
hwm_values.voltages[1] = 1500; /* VGTL */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -125,31 +107,11 @@ machine_at_s2dge_init(const machine_t *model)
|
||||
device_add(&w83977tf_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 512);
|
||||
device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */
|
||||
hwm_values.fans[1] = 0; /* no CPU2 fan */
|
||||
hwm_values.temperatures[0] = 0; /* unused */
|
||||
hwm_values.temperatures[2] = 0; /* CPU2? */
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* CPU1 */
|
||||
0, /* CPU2 */
|
||||
3000 /* Thermal Control */
|
||||
}, { /* temperatures */
|
||||
0, /* unused */
|
||||
30, /* CPU1 */
|
||||
20 /* unused (CPU2?) */
|
||||
}, { /* voltages */
|
||||
2050, /* CPU1 (2.05V by default) */
|
||||
0, /* CPU2 */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -183,30 +145,9 @@ machine_at_fw6400gx_init(const machine_t *model)
|
||||
device_add(&pc87309_15c_device);
|
||||
device_add(&sst_flash_29ee020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 512);
|
||||
device_add(&w83781d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */
|
||||
hwm_values.temperatures[3] = 0; /* unused */
|
||||
hwm_values.voltages[1] = 1500; /* Vtt */
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* Power */
|
||||
3000 /* CPU */
|
||||
}, { /* temperatures */
|
||||
30, /* System */
|
||||
30, /* CPU */
|
||||
0 /* unused */
|
||||
}, { /* voltages */
|
||||
2050, /* Vcore (2.05V by default) */
|
||||
1500, /* Vtt */
|
||||
3300, /* Vio */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -64,28 +64,9 @@ machine_at_s370slm_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* CPU */
|
||||
3000, /* Fan 2 */
|
||||
3000 /* Chassis */
|
||||
}, { /* temperatures */
|
||||
0, /* unused */
|
||||
30, /* CPU */
|
||||
0 /* unused */
|
||||
}, { /* voltages */
|
||||
2050, /* CPU1 (2.05V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
device_add(&w83781d_device); /* fans: CPU, Fan 2, Chassis; temperatures: unused, CPU, unused */
|
||||
hwm_values.temperatures[0] = 0; /* unused */
|
||||
hwm_values.temperatures[2] = 0; /* unused */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -117,32 +98,10 @@ machine_at_cubx_init(const machine_t *model)
|
||||
device_add(&i440bx_device);
|
||||
device_add(&piix4e_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
// device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&w83977ef_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
30, /* JTPWR */
|
||||
30 /* CPU */
|
||||
}, { /* voltages */
|
||||
2050, /* VCORE (2.05V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 59, 20), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&as99127f_device);
|
||||
device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -366,27 +325,6 @@ machine_at_6via85x_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
30, /* JTPWR */
|
||||
30 /* CPU */
|
||||
}, { /* voltages */
|
||||
2050, /* VCORE (2.05V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 59, 20), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&via_vt82c686_hwm_device);
|
||||
|
||||
return ret;
|
||||
@@ -419,27 +357,6 @@ machine_at_603tcf_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
30, /* JTPWR */
|
||||
30 /* CPU */
|
||||
}, { /* voltages */
|
||||
2050, /* VCORE (2.05V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 59, 20), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&via_vt82c686_hwm_device);
|
||||
|
||||
return ret;
|
||||
|
@@ -817,41 +817,11 @@ machine_at_nupro592_init(const machine_t *model)
|
||||
device_add(&w83977ef_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000, /* Power */
|
||||
0
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
0, /* unused */
|
||||
27, /* CPU */
|
||||
0
|
||||
}, { /* voltages */
|
||||
3300, /* VCORE (3.3V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */
|
||||
0
|
||||
}
|
||||
};
|
||||
/* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V).
|
||||
Pentium MMX: 2.8 V.
|
||||
AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233.
|
||||
AMD K6 Model 7: 2.2 V. */
|
||||
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX)
|
||||
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */
|
||||
else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6)
|
||||
machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */
|
||||
else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2)
|
||||
machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
device_add(&w83781d_device); /* fans: CPU1, unused, unused; temperatures: System, CPU1, unused */
|
||||
hwm_values.temperatures[2] = 0; /* unused */
|
||||
hwm_values.fans[1] = 0; /* unused */
|
||||
hwm_values.fans[2] = 0; /* unused */
|
||||
/* -5V is not reported by the BIOS, but leave it set */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -884,41 +854,13 @@ machine_at_tx97_init(const machine_t *model)
|
||||
device_add(&w83877tf_acorp_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Chassis */
|
||||
3000, /* CPU */
|
||||
3000 /* Power */
|
||||
}, { /* temperatures */
|
||||
30, /* MB */
|
||||
0, /* unused */
|
||||
8 /* CPU */
|
||||
}, { /* voltages */
|
||||
3300, /* VCORE (3.3V by default) */
|
||||
0, /* unused */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
/* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V).
|
||||
Pentium MMX: 2.8 V.
|
||||
AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233.
|
||||
AMD K6 Model 7: 2.2 V. */
|
||||
switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) {
|
||||
case CPU_PENTIUMMMX:
|
||||
machine_hwm.voltages[0] = 2800;
|
||||
break;
|
||||
case CPU_K6:
|
||||
case CPU_K6_2:
|
||||
machine_hwm.voltages[0] = 2200;
|
||||
break;
|
||||
}
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&w83781d_device);
|
||||
device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */
|
||||
hwm_values.temperatures[1] = 0; /* unused */
|
||||
/* CPU offset */
|
||||
if (hwm_values.temperatures[2] < 32) /* prevent underflow */
|
||||
hwm_values.temperatures[2] = 0;
|
||||
else
|
||||
hwm_values.temperatures[2] -= 32;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1014,41 +956,8 @@ machine_at_p5mms98_init(const machine_t *model)
|
||||
device_add(&w83977tf_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* Thermal */
|
||||
3000, /* CPU */
|
||||
3000 /* Chassis */
|
||||
}, { /* temperatures */
|
||||
0, /* unused */
|
||||
30 /* CPU */
|
||||
}, { /* voltages */
|
||||
3300, /* VCORE (3.3V by default) */
|
||||
3300, /* VIO (3.3V) */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */
|
||||
}
|
||||
};
|
||||
/* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V).
|
||||
Pentium MMX: 2.8 V.
|
||||
AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233.
|
||||
AMD K6 Model 7: 2.2 V. */
|
||||
switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) {
|
||||
case CPU_PENTIUMMMX:
|
||||
machine_hwm.voltages[0] = 2800;
|
||||
break;
|
||||
case CPU_K6:
|
||||
case CPU_K6_2:
|
||||
machine_hwm.voltages[0] = 2200;
|
||||
break;
|
||||
}
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&lm78_device);
|
||||
device_add(&lm75_1_4a_device);
|
||||
device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */
|
||||
device_add(&lm75_1_4a_device); /* temperature: CPU */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -83,7 +83,7 @@ machine_at_mb600n_init(const machine_t *model)
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
@@ -209,7 +209,7 @@ machine_at_8500ttc_init(const machine_t *model)
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
@@ -238,7 +238,7 @@ machine_at_m6mi_init(const machine_t *model)
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
|
@@ -135,54 +135,6 @@ machine_at_ficva503a_init(const machine_t *model)
|
||||
device_add(&via_vt82c686_sio_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||
|
||||
hwm_values_t machine_hwm = {
|
||||
{ /* fan speeds */
|
||||
3000, /* CPUFAN1 */
|
||||
3000 /* ChassisFAN */
|
||||
}, { /* temperatures */
|
||||
32, /* CPU */
|
||||
32, /* System */
|
||||
0 /* unused */
|
||||
}, { /* voltages */
|
||||
3300, /* Vcore (3.3V by default) */
|
||||
2500, /* 2.5V (unused) */
|
||||
3300, /* 3.3V */
|
||||
RESISTOR_DIVIDER(5000, 9, 16), /* 5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10) /* 12V (28K/10K divider applies to W83781D but is close enough) */
|
||||
}
|
||||
};
|
||||
/* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V).
|
||||
Pentium MMX: 2.8 V.
|
||||
AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233.
|
||||
AMD K6 Model 7: 2.2 V. */
|
||||
switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) {
|
||||
case CPU_WINCHIP:
|
||||
case CPU_WINCHIP2:
|
||||
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
|
||||
case CPU_Cx6x86:
|
||||
#endif
|
||||
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
|
||||
case CPU_K5:
|
||||
case CPU_5K86:
|
||||
#endif
|
||||
machine_hwm.voltages[0] = 3500;
|
||||
break;
|
||||
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
|
||||
case CPU_Cx6x86MX:
|
||||
machine_hwm.voltages[0] = 2900;
|
||||
break;
|
||||
#endif
|
||||
case CPU_PENTIUMMMX:
|
||||
machine_hwm.voltages[0] = 2800;
|
||||
break;
|
||||
case CPU_K6:
|
||||
case CPU_K6_2:
|
||||
machine_hwm.voltages[0] = 2200;
|
||||
break;
|
||||
}
|
||||
machine_hwm.voltages[0] *= 1.32; /* multiplier bruteforced */
|
||||
hwm_set_values(machine_hwm);
|
||||
device_add(&via_vt82c686_hwm_device);
|
||||
|
||||
return ret;
|
||||
|
72
src/pci.c
72
src/pci.c
@@ -331,21 +331,28 @@ void
|
||||
pci_set_mirq(uint8_t mirq, int level)
|
||||
{
|
||||
uint8_t irq_line = 0;
|
||||
uint8_t irq_bit;
|
||||
|
||||
if (! pci_mirqs[mirq].enabled) {
|
||||
pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq);
|
||||
return;
|
||||
if (mirq >= 0xf0) {
|
||||
irq_line = mirq & 0x0f;
|
||||
irq_bit = 0x1D;
|
||||
} else {
|
||||
if (! pci_mirqs[mirq].enabled) {
|
||||
pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pci_mirqs[mirq].irq_line > 0x0f) {
|
||||
pci_log("pci_set_mirq(%02X): IRQ line is disabled\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
irq_line = pci_mirqs[mirq].irq_line;
|
||||
irq_bit = (0x1E + mirq);
|
||||
}
|
||||
|
||||
if (pci_mirqs[mirq].irq_line > 0x0f) {
|
||||
pci_log("pci_set_mirq(%02X): IRQ line is disabled\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
irq_line = pci_mirqs[mirq].irq_line;
|
||||
pci_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line);
|
||||
|
||||
if (level && (pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
|
||||
if (level && (pci_irq_hold[irq_line] & (1ULL << irq_bit))) {
|
||||
/* IRQ already held, do nothing. */
|
||||
pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq);
|
||||
return;
|
||||
@@ -367,7 +374,7 @@ pci_set_mirq(uint8_t mirq, int level)
|
||||
/* If the IRQ is level-triggered, mark that this MIRQ is holding it. */
|
||||
if (level) {
|
||||
pci_log("pci_set_mirq(%02X): Marking that this card is holding the IRQ\n", mirq);
|
||||
pci_irq_hold[irq_line] |= (1ULL << (0x1E + mirq));
|
||||
pci_irq_hold[irq_line] |= (1ULL << irq_bit);
|
||||
}
|
||||
|
||||
pci_log("pci_set_mirq(%02X): Edge-triggered interrupt, not marking\n", mirq);
|
||||
@@ -450,26 +457,33 @@ void
|
||||
pci_clear_mirq(uint8_t mirq, int level)
|
||||
{
|
||||
uint8_t irq_line = 0;
|
||||
uint8_t irq_bit;
|
||||
|
||||
if (mirq > 1) {
|
||||
pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq);
|
||||
return;
|
||||
if (mirq >= 0xf0) {
|
||||
irq_line = mirq & 0x0f;
|
||||
irq_bit = 0x1D;
|
||||
} else {
|
||||
if (mirq > 1) {
|
||||
pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (! pci_mirqs[mirq].enabled) {
|
||||
pci_log("pci_clear_mirq(%02X): MIRQ0 disabled\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pci_mirqs[mirq].irq_line > 0x0f) {
|
||||
pci_log("pci_clear_mirq(%02X): IRQ line is disabled\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
irq_line = pci_mirqs[mirq].irq_line;
|
||||
irq_bit = (0x1E + mirq);
|
||||
}
|
||||
|
||||
if (! pci_mirqs[mirq].enabled) {
|
||||
pci_log("pci_clear_mirq(%02X): MIRQ0 disabled\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pci_mirqs[mirq].irq_line > 0x0f) {
|
||||
pci_log("pci_clear_mirq(%02X): IRQ line is disabled\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
irq_line = pci_mirqs[mirq].irq_line;
|
||||
pci_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line);
|
||||
|
||||
if (level && !(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
|
||||
if (level && !(pci_irq_hold[irq_line] & (1ULL << irq_bit))) {
|
||||
/* IRQ not held, do nothing. */
|
||||
pci_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq);
|
||||
return;
|
||||
@@ -477,7 +491,7 @@ pci_clear_mirq(uint8_t mirq, int level)
|
||||
|
||||
if (level) {
|
||||
pci_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", mirq);
|
||||
pci_irq_hold[irq_line] &= ~(1 << (0x1E + mirq));
|
||||
pci_irq_hold[irq_line] &= ~(1 << irq_bit);
|
||||
|
||||
if (! pci_irq_hold[irq_line]) {
|
||||
pci_log("pci_clear_mirq(%02X): IRQ no longer held by any card, clearing it\n", mirq);
|
||||
|
@@ -62,6 +62,7 @@ vt82c686_fdc_handler(vt82c686_t *dev)
|
||||
if (dev->regs[0x02] & 0x10)
|
||||
fdc_set_base(dev->fdc, io_base);
|
||||
|
||||
fdc_set_dma_ch(dev->fdc, dev->fdc_dma);
|
||||
fdc_set_irq(dev->fdc, dev->fdc_irq);
|
||||
}
|
||||
|
||||
@@ -104,19 +105,24 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv)
|
||||
return;
|
||||
|
||||
if (!(port & 1)) {
|
||||
/* Registers start at 0xE0 but we cut them down to start at 0x00. */
|
||||
dev->cur_reg = (val & 0x1f);
|
||||
dev->cur_reg = val;
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTE: Registers are [0xE0:0xFF] but we store them as [0x00:0x1F]. */
|
||||
if (dev->cur_reg < 0xe0)
|
||||
return;
|
||||
uint8_t reg = dev->cur_reg & 0x1f;
|
||||
|
||||
/* Read-only registers */
|
||||
if ((dev->cur_reg < 0x02) || (dev->cur_reg == 0x04) || (dev->cur_reg == 0x05) || ((dev->cur_reg >= 0xe9) && (dev->cur_reg < 0xee)) ||
|
||||
(dev->cur_reg == 0xf3) || (dev->cur_reg == 0xf5) || (dev->cur_reg == 0xf7) || (dev->cur_reg >= 0xf9))
|
||||
if ((reg < 0x02) || (reg == 0x04) || (reg == 0x05) || ((reg >= 0x09) && (reg < 0x0e)) ||
|
||||
(reg == 0x13) || (reg == 0x15) || (reg == 0x17) || (reg >= 0x19))
|
||||
return;
|
||||
|
||||
switch (dev->cur_reg) {
|
||||
dev->regs[reg] = val;
|
||||
|
||||
switch (reg) {
|
||||
case 0x02:
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
vt82c686_lpt_handler(dev);
|
||||
vt82c686_serial_handler(dev, 0);
|
||||
vt82c686_serial_handler(dev, 1);
|
||||
@@ -124,28 +130,20 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
vt82c686_fdc_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
vt82c686_lpt_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
vt82c686_serial_handler(dev, 0);
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
vt82c686_serial_handler(dev, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,10 +154,13 @@ vt82c686_read(uint16_t port, void *priv)
|
||||
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
/* NOTE: Registers are [0xE0:0xFF] but we store them as [0x00:0x1F]. */
|
||||
if (!(port & 1))
|
||||
ret = dev->cur_reg | 0xe0;
|
||||
ret = dev->cur_reg;
|
||||
else if (dev->cur_reg < 0xe0)
|
||||
ret = 0xff;
|
||||
else
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
ret = dev->regs[dev->cur_reg & 0x1f];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user