ASIC14::ASIC14() {
init_register();
+ mCurrPlace = 0;
+ for (int i = 0; i < 0x80; i++)
+ prom[i] = 0;
+
+ // defaults expected by the touchscreen code
+ prom[0xA] = 20;
+ prom[0xB] = 20;
+ prom[0xC] = 20;
+ prom[0xD] = 30;
+
+ // some basic stuff to begin with
+ // set up the Psion's unique ID
+ prom[0x1B] = 0xDE;
+ prom[0x1A] = 0xAD;
+ prom[0x19] = 0xBE;
+ prom[0x18] = 0xEF;
+
+ // give ourselves a neat custom device name
+ const char *key = "PSIONPSIONPSION";
+ const char *name = "WindEmu!";
+ prom[0x28] = strlen(name);
+ if (prom[0x28] > 15)
+ prom[0x28] = 15;
+ for (int i = 0; i < prom[0x28]; i++)
+ prom[0x29 + i] = name[i] ^ key[i];
+
+ // calculate the checksum
+ uint8_t chk = 0;
+ for (int i = 0; i < 0x7F; i++)
+ chk ^= prom[i];
+
+ // EPOC is expecting 66
+ prom[0x7F] = chk ^ 66;
+
}
void ASIC14::reset() {
m_IRQ_EDGE = 0;
m_SPI_DATA = 0;
m_SPI_FN = 0;
+ m_STATUS6 = (1 << 1) | (1 << 10) | (1 << 11);
}
void ASIC14::run() {}
- uint16_t ASIC14::get_data(uint32_t const address) const {
+ uint16_t ASIC14::get_data(uint32_t const address) {
switch (address) {
case CTRL0:
printf("ASIC14 read register CTRL0: %04x\n", m_CTRL0);
case IRQ_EDGE:
printf("ASIC14 read register IRQ_EDGE: %04x\n", m_IRQ_EDGE);
return m_IRQ_EDGE;
- case STATUS6:
+ case STATUS6: {
printf("ASIC14 read register STATUS6: %04x\n", m_STATUS6);
- return m_STATUS6 | 2;
+ auto status = m_STATUS6;
+ m_STATUS6 = 0;
+ return status;
+ }
case SPI_DATA:
- printf("ASIC14 read register SPI_DATA: %04x\n", m_SPI_DATA);
- return m_SPI_DATA;
+ printf("ASIC14 read register SPI_DATA: %04x\n", prom[mCurrPlace] | prom[mCurrPlace+1] << 8);
+ return prom[mCurrPlace++] | prom[mCurrPlace++] << 8;
case SPI_FN:
printf("ASIC14 read register SPI_FN: %04x\n", m_SPI_FN);
return m_SPI_FN;
break;
case IRQ_STATUS:
printf("ASIC14 write %04x to register IRQ_STATUS\n", value);
- m_IRQ_STATUS = value;
+ m_IRQ_STATUS &= ~value;
break;
case IRQ_MASK:
printf("ASIC14 write %04x to register IRQ_MASK\n", value);
break;
case STATUS6:
printf("ASIC14 write %04x to register STATUS6\n", value);
- // Clear interrupts on STATUS6 according to the bit mask provided
- m_STATUS6 &= ~value;
+ //m_STATUS6 = value;
break;
case SPI_DATA:
printf("ASIC14 write %04x to register SPI_DATA\n", value);
break;
case SPI_FN:
printf("ASIC14 write %04x to register SPI_FN\n", value);
+ if (value == 4 || value == 6)
+ m_STATUS6 = 2;
m_SPI_FN = value;
break;
default:
typedef enum IRQMaskEnum IRQMaskEnum;
private:
+ uint8_t prom[0x80] = {};
+ int mCurrPlace = 0;
enum
{
CTRL0 = 0x10000000,
m_IRQ_EDGE = 0;
m_SPI_DATA = 0;
m_SPI_FN = 0;
+ m_STATUS6 = ~0;//(1 << 2) | (1 << 10) | (1 << 11);
}
public:
void run();
void reset();
- uint16_t get_data(uint32_t const address) const;
+ uint16_t get_data(uint32_t const address);
void put_data(uint32_t const address, uint16_t const value);
};