Fixes for FDC and AT keyboard (showing when running AT&T System V/386 R3.2 UNIX.)

Added memory context dumping for debugging.
This commit is contained in:
waltje
2018-06-27 15:03:58 -04:00
parent 097fb38af7
commit 7919fbdb93
9 changed files with 529 additions and 397 deletions

View File

@@ -9,7 +9,7 @@
* Implementation of the NEC uPD-765 and compatible floppy disk * Implementation of the NEC uPD-765 and compatible floppy disk
* controller. * controller.
* *
* Version: @(#)fdc.c 1.0.13 2018/05/14 * Version: @(#)fdc.c 1.0.14 2018/06/25
* *
* Authors: Miran Grca, <mgrca8@gmail.com> * Authors: Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * Sarah Walker, <tommowalker@tommowalker.co.uk>

View File

@@ -10,7 +10,7 @@
* data in the form of FM/MFM-encoded transitions) which also * data in the form of FM/MFM-encoded transitions) which also
* forms the core of the emulator's floppy disk emulation. * forms the core of the emulator's floppy disk emulation.
* *
* Version: @(#)fdd_86f.c 1.0.10 2018/05/06 * Version: @(#)fdd_86f.c 1.0.11 2018/06/25
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -1566,6 +1566,12 @@ d86f_read_sector_data(int drive, int side)
dev->data_find.bytes_obtained++; dev->data_find.bytes_obtained++;
if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) {
#if 0
/*
* This code causes errors on Wyse UNIX
* System V/386 V3.2.1A and was disabled
* at Miran Grca's request. --FvK
*/
/* We've got the data. */ /* We've got the data. */
if (dev->dma_over > 1) { if (dev->dma_over > 1) {
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
@@ -1579,6 +1585,7 @@ d86f_read_sector_data(int drive, int side)
dev->data_find.bits_obtained++; dev->data_find.bits_obtained++;
return; return;
} }
#endif
if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state != STATE_02_READ_DATA)) { if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state != STATE_02_READ_DATA)) {
d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword);
@@ -1700,6 +1707,12 @@ d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
dev->data_find.bytes_obtained++; dev->data_find.bytes_obtained++;
if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) {
#if 0
/*
* This code causes errors on Wyse UNIX
* System V/386 V3.2.1A and was disabled
* at Miran Grca's request. --FvK
*/
if (dev->dma_over > 1) { if (dev->dma_over > 1) {
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
dev->error_condition = 0; dev->error_condition = 0;
@@ -1710,6 +1723,7 @@ d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
dev->data_find.bits_obtained++; dev->data_find.bits_obtained++;
return; return;
} }
#endif
/* We've written the data. */ /* We've written the data. */
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
@@ -2139,6 +2153,12 @@ d86f_turbo_read(int drive, int side)
} }
} }
#if 0
/*
* This code causes errors on Wyse UNIX
* System V/386 V3.2.1A and was disabled
* at Miran Grca's request. --FvK
*/
if (dev->dma_over > 1) { if (dev->dma_over > 1) {
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
dev->error_condition = 0; dev->error_condition = 0;
@@ -2147,6 +2167,7 @@ d86f_turbo_read(int drive, int side)
fdc_overrun(d86f_fdc); fdc_overrun(d86f_fdc);
return; return;
} }
#endif
if (dev->turbo_pos >= (128 << dev->last_sector.id.n)) { if (dev->turbo_pos >= (128 << dev->last_sector.id.n)) {
/* CRC is valid. */ /* CRC is valid. */

View File

@@ -8,7 +8,7 @@
* *
* Intel 8042 (AT keyboard controller) emulation. * Intel 8042 (AT keyboard controller) emulation.
* *
* Version: @(#)keyboard_at.c 1.0.12 2018/05/06 * Version: @(#)keyboard_at.c 1.0.13 2018/06/26
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -62,29 +62,29 @@
#include "../../machines/m_xt_xi8088.h" #include "../../machines/m_xt_xi8088.h"
#define STAT_PARITY 0x80 #define STAT_PARITY 0x80
#define STAT_RTIMEOUT 0x40 #define STAT_RTIMEOUT 0x40
#define STAT_TTIMEOUT 0x20 #define STAT_TTIMEOUT 0x20
#define STAT_MFULL 0x20 #define STAT_MFULL 0x20
#define STAT_LOCK 0x10 #define STAT_LOCK 0x10
#define STAT_CD 0x08 #define STAT_CD 0x08
#define STAT_SYSFLAG 0x04 #define STAT_SYSFLAG 0x04
#define STAT_IFULL 0x02 #define STAT_IFULL 0x02
#define STAT_OFULL 0x01 #define STAT_OFULL 0x01
#define PS2_REFRESH_TIME (16LL * TIMER_USEC) #define PS2_REFRESH_TIME (16LL * TIMER_USEC)
#define CCB_UNUSED 0x80 #define CCB_UNUSED 0x80
#define CCB_TRANSLATE 0x40 #define CCB_TRANSLATE 0x40
#define CCB_PCMODE 0x20 #define CCB_PCMODE 0x20
#define CCB_ENABLEKBD 0x10 #define CCB_ENABLEKBD 0x10
#define CCB_IGNORELOCK 0x08 #define CCB_IGNORELOCK 0x08
#define CCB_SYSTEM 0x04 #define CCB_SYSTEM 0x04
#define CCB_ENABLEMINT 0x02 #define CCB_ENABLEMINT 0x02
#define CCB_ENABLEKINT 0x01 #define CCB_ENABLEKINT 0x01
#define CCB_MASK 0x68 #define CCB_MASK 0x68
#define MODE_MASK 0x6C #define MODE_MASK 0x6c
#define KBC_TYPE_ISA 0x00 #define KBC_TYPE_ISA 0x00
#define KBC_TYPE_PS2_1 0x01 #define KBC_TYPE_PS2_1 0x01
@@ -94,9 +94,9 @@
#define KBC_VEN_GENERIC 0x00 #define KBC_VEN_GENERIC 0x00
#define KBC_VEN_AMI 0x04 #define KBC_VEN_AMI 0x04
#define KBC_VEN_IBM_MCA 0x08 #define KBC_VEN_IBM_MCA 0x08
#define KBC_VEN_QUADTEL 0x0C #define KBC_VEN_QUADTEL 0x0c
#define KBC_VEN_TOSHIBA 0x10 #define KBC_VEN_TOSHIBA 0x10
#define KBC_VEN_MASK 0x1C #define KBC_VEN_MASK 0x1c
typedef struct { typedef struct {
@@ -142,15 +142,15 @@ typedef struct {
/* bit 0 = repeat, bit 1 = makes break code? */ /* bit 0 = repeat, bit 1 = makes break code? */
uint8_t keyboard_set3_flags[512]; uint8_t keyboard_set3_flags[512];
uint8_t keyboard_set3_all_repeat; uint8_t keyboard_set3_all_repeat;
uint8_t keyboard_set3_all_break; uint8_t keyboard_set3_all_break;
/* Bits 0 - 1 = scan code set, bit 6 = translate or not. */ /* Bits 0 - 1 = scan code set, bit 6 = translate or not. */
uint8_t keyboard_mode = 0x42; uint8_t keyboard_mode = 0x42;
int mouse_queue_start = 0, int mouse_queue_start = 0,
mouse_queue_end = 0; mouse_queue_end = 0;
static uint8_t key_ctrl_queue[16]; static uint8_t key_ctrl_queue[16];
@@ -168,38 +168,38 @@ static atkbd_t *CurrentKbd = NULL; // FIXME: remove!!! --FvK
/* Non-translated to translated scan codes. */ /* Non-translated to translated scan codes. */
static const uint8_t nont_to_t[256] = { static const uint8_t nont_to_t[256] = {
0xFF, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, 0x58, 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
0x64, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, 0x59, 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
0x65, 0x38, 0x2A, 0x70, 0x1D, 0x10, 0x02, 0x5A, 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
0x66, 0x71, 0x2C, 0x1F, 0x1E, 0x11, 0x03, 0x5B, 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
0x67, 0x2E, 0x2D, 0x20, 0x12, 0x05, 0x04, 0x5C, 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
0x68, 0x39, 0x2F, 0x21, 0x14, 0x13, 0x06, 0x5D, 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5E, 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
0x6A, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5F, 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
0x6B, 0x33, 0x25, 0x17, 0x18, 0x0B, 0x0A, 0x60, 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
0x6C, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0C, 0x61, 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
0x6D, 0x73, 0x28, 0x74, 0x1A, 0x0D, 0x62, 0x6E, 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
0x3A, 0x36, 0x1C, 0x1B, 0x75, 0x2B, 0x63, 0x76, 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
0x55, 0x56, 0x77, 0x78, 0x79, 0x7A, 0x0E, 0x7B, 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
0x7C, 0x4F, 0x7D, 0x4B, 0x47, 0x7E, 0x7F, 0x6F, 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
0x52, 0x53, 0x50, 0x4C, 0x4D, 0x48, 0x01, 0x45, 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
0x57, 0x4E, 0x51, 0x4A, 0x37, 0x49, 0x46, 0x54, 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
}; };
static const scancode scancode_set1[512] = { static const scancode scancode_set1[512] = {
@@ -742,7 +742,7 @@ kbd_adddata_keyboard(uint16_t val)
/* Allow for scan code translation. */ /* Allow for scan code translation. */
if (translate && (val == 0xf0)) { if (translate && (val == 0xf0)) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("Translate is on, F0 prefix detected\n"); kbd_log("ATkbd: translate is on, F0 prefix detected\n");
#endif #endif
sc_or = 0x80; sc_or = 0x80;
return; return;
@@ -751,7 +751,7 @@ kbd_adddata_keyboard(uint16_t val)
/* Skip break code if translated make code has bit 7 set. */ /* Skip break code if translated make code has bit 7 set. */
if (translate && (sc_or == 0x80) && (val & 0x80)) { if (translate && (sc_or == 0x80) && (val & 0x80)) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("Translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); kbd_log("ATkbd: translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val);
#endif #endif
sc_or = 0; sc_or = 0;
return; return;
@@ -779,7 +779,7 @@ kbd_adddata_keyboard(uint16_t val)
} }
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("Translate is %s, ", translate ? "on" : "off"); kbd_log("ATkbd: translate is %s, ", translate ? "on" : "off");
#endif #endif
switch(val) { switch(val) {
case FAKE_LSHIFT_ON: case FAKE_LSHIFT_ON:
@@ -949,7 +949,7 @@ static void
kbd_output_write(atkbd_t *kbd, uint8_t val) kbd_output_write(atkbd_t *kbd, uint8_t val)
{ {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("Write output port: %02X (old: %02X)\n", val, kbd->output_port); kbd_log("ATkbd: write output port: %02X (old: %02X)\n", val, kbd->output_port);
#endif #endif
if ((kbd->output_port ^ val) & 0x20) { /*IRQ 12*/ if ((kbd->output_port ^ val) & 0x20) { /*IRQ 12*/
if (val & 0x20) if (val & 0x20)
@@ -983,7 +983,7 @@ static void
kbd_cmd_write(atkbd_t *kbd, uint8_t val) kbd_cmd_write(atkbd_t *kbd, uint8_t val)
{ {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("Write command byte: %02X (old: %02X)\n", val, kbd->mem[0]); kbd_log("ATkbd: write command byte: %02X (old: %02X)\n", val, kbd->mem[0]);
#endif #endif
if ((val & 1) && (kbd->status & STAT_OFULL)) if ((val & 1) && (kbd->status & STAT_OFULL))
@@ -1003,7 +1003,7 @@ kbd_cmd_write(atkbd_t *kbd, uint8_t val)
keyboard_scan = !(val & 0x10); keyboard_scan = !(val & 0x10);
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: keyboard is now %s\n", mouse_scan ? "enabled" : "disabled"); kbd_log("ATkbd: keyboard is now %s\n", keyboard_scan ? "enabled" : "disabled");
kbd_log("ATkbd: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled"); kbd_log("ATkbd: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled");
#endif #endif
@@ -1049,6 +1049,12 @@ kbd_keyboard_set(atkbd_t *kbd, uint8_t enable)
{ {
kbd->mem[0] &= 0xef; kbd->mem[0] &= 0xef;
kbd->mem[0] |= (enable ? 0x00 : 0x10); kbd->mem[0] |= (enable ? 0x00 : 0x10);
if (enable)
kbd->status |= STAT_LOCK;
else
kbd->status &= ~STAT_LOCK;
keyboard_scan = enable; keyboard_scan = enable;
} }
@@ -1068,7 +1074,7 @@ kbd_write64_generic(void *p, uint8_t val)
atkbd_t *kbd = (atkbd_t *)p; atkbd_t *kbd = (atkbd_t *)p;
switch (val) { switch (val) {
case 0xa4: /*Check if password installed*/ case 0xa4: /*Check if password installed*/
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: check if password installed\n"); kbd_log("ATkbd: check if password installed\n");
@@ -1082,7 +1088,7 @@ kbd_write64_generic(void *p, uint8_t val)
#endif #endif
break; break;
case 0xa7: /*Disable mouse port*/ case 0xa7: /*Disable mouse port*/
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: disable mouse port\n"); kbd_log("ATkbd: disable mouse port\n");
@@ -1096,7 +1102,7 @@ kbd_write64_generic(void *p, uint8_t val)
#endif #endif
break; break;
case 0xa8: /*Enable mouse port*/ case 0xa8: /*Enable mouse port*/
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: enable mouse port\n"); kbd_log("ATkbd: enable mouse port\n");
@@ -1110,7 +1116,7 @@ kbd_write64_generic(void *p, uint8_t val)
#endif #endif
break; break;
case 0xa9: /*Test mouse port*/ case 0xa9: /*Test mouse port*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: test mouse port\n"); kbd_log("ATkbd: test mouse port\n");
#endif #endif
@@ -1127,14 +1133,14 @@ kbd_write64_generic(void *p, uint8_t val)
#endif #endif
break; break;
case 0xaf: /*Read keyboard version*/ case 0xaf: /*Read keyboard version*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: read keyboard version\n"); kbd_log("ATkbd: read keyboard version\n");
#endif #endif
kbd_adddata(0x00); kbd_adddata(0x00);
return 0; return 0;
case 0xc0: /*Read input port*/ case 0xc0: /*Read input port*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: read input port\n"); kbd_log("ATkbd: read input port\n");
#endif #endif
@@ -1143,7 +1149,7 @@ kbd_write64_generic(void *p, uint8_t val)
kbd->input_port = ((kbd->input_port + 1) & 3) | (kbd->input_port & 0xfc) | fdc_ps1_525(); kbd->input_port = ((kbd->input_port + 1) & 3) | (kbd->input_port & 0xfc) | fdc_ps1_525();
return 0; return 0;
case 0xd3: /*Write mouse output buffer*/ case 0xd3: /*Write mouse output buffer*/
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: write mouse output buffer\n"); kbd_log("ATkbd: write mouse output buffer\n");
@@ -1153,7 +1159,7 @@ kbd_write64_generic(void *p, uint8_t val)
} }
break; break;
case 0xd4: /*Write to mouse*/ case 0xd4: /*Write to mouse*/
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: write to mouse\n"); kbd_log("ATkbd: write to mouse\n");
@@ -1194,16 +1200,16 @@ kbd_write60_ami(void *p, uint8_t val)
case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x58: case 0x59: case 0x5a: case 0x5b:
case 0x5c: case 0x5d: case 0x5e: case 0x5f: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - alias write to register %08X\n", kbd->command); kbd_log("ATkbd: AMI - alias write to %08X\n", kbd->command);
#endif #endif
kbd->mem[kbd->command & 0x1f] = val; kbd->mem[kbd->command & 0x1f] = val;
if (kbd->command == 0x60) if (kbd->command == 0x60)
kbd_cmd_write(kbd, val); kbd_cmd_write(kbd, val);
return 0; return 0;
case 0xaf: /*AMI - set extended controller RAM*/ case 0xaf: /*AMI - set extended controller RAM*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - set extended controller RAM\n"); kbd_log("ATkbd: AMI - set extended controller RAM\n");
#endif #endif
if (kbd->secr_phase == 1) { if (kbd->secr_phase == 1) {
kbd->mem_addr = val; kbd->mem_addr = val;
@@ -1214,9 +1220,10 @@ kbd_write60_ami(void *p, uint8_t val)
kbd->secr_phase = 0; kbd->secr_phase = 0;
} }
return 0; return 0;
case 0xcb: /*AMI - set keyboard mode*/
case 0xcb: /*AMI - set keyboard mode*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - set keyboard mode\n"); kbd_log("ATkbd: AMI - set keyboard mode\n");
#endif #endif
return 0; return 0;
} }
@@ -1240,7 +1247,7 @@ kbd_write64_ami(void *p, uint8_t val)
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x18: case 0x19: case 0x1a: case 0x1b:
case 0x1c: case 0x1d: case 0x1e: case 0x1f: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - alias read from register %08X\n", val); kbd_log("ATkbd: AMI - alias read from %08X\n", val);
#endif #endif
kbd_adddata(kbd->mem[val]); kbd_adddata(kbd->mem[val]);
return 0; return 0;
@@ -1254,21 +1261,21 @@ kbd_write64_ami(void *p, uint8_t val)
case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x58: case 0x59: case 0x5a: case 0x5b:
case 0x5c: case 0x5d: case 0x5e: case 0x5f: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - alias write to register %08X\n", kbd->command); kbd_log("ATkbd: AMI - alias write to %08X\n", kbd->command);
#endif #endif
kbd->want60 = 1; kbd->want60 = 1;
return 0; return 0;
case 0xa1: /*AMI - get controller version*/ case 0xa1: /*AMI - get controller version*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - get controller version\n"); kbd_log("ATkbd: AMI - get controller version\n");
#endif #endif
return 0; return 0;
case 0xa2: /*AMI - reset keyboard controller lines P22 and P23 low*/ case 0xa2: /*AMI - reset keyboard controller lines P22 and P23 low*/
if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - reset keyboard controller lines P22 and P23 low\n"); kbd_log("ATkbd: AMI - clear KBC lines P22 and P23\n");
#endif #endif
kbd_output_write(kbd, kbd->output_port & 0xf3); kbd_output_write(kbd, kbd->output_port & 0xf3);
kbd_adddata(0x00); kbd_adddata(0x00);
@@ -1279,7 +1286,7 @@ kbd_write64_ami(void *p, uint8_t val)
case 0xa3: /*AMI - set keyboard controller lines P22 and P23 high*/ case 0xa3: /*AMI - set keyboard controller lines P22 and P23 high*/
if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - set keyboard controller lines P22 and P23 high\n"); kbd_log("ATkbd: AMI - set KBC lines P22 and P23\n");
#endif #endif
kbd_output_write(kbd, kbd->output_port | 0x0c); kbd_output_write(kbd, kbd->output_port | 0x0c);
kbd_adddata(0x00); kbd_adddata(0x00);
@@ -1287,66 +1294,67 @@ kbd_write64_ami(void *p, uint8_t val)
} }
break; break;
case 0xa4: /* AMI - write clock = low */ case 0xa4: /* AMI - write clock = low */
if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - write clock = low\n"); kbd_log("ATkbd: AMI - write clock = low\n");
#endif #endif
kbd->ami_stat &= 0xfe; kbd->ami_stat &= 0xfe;
return 0; return 0;
} }
break; break;
case 0xa5: /* AMI - write clock = high */ case 0xa5: /* AMI - write clock = high */
if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - write clock = high\n"); kbd_log("ATkbd: AMI - write clock = high\n");
#endif #endif
kbd->ami_stat |= 0x01; kbd->ami_stat |= 0x01;
return 0; return 0;
} }
break; break;
case 0xa6: /* AMI - read clock */
case 0xa6: /* AMI - read clock */
if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - read clock\n"); kbd_log("ATkbd: AMI - read clock\n");
#endif #endif
kbd_adddata(!!(kbd->ami_stat & 1)); kbd_adddata(!!(kbd->ami_stat & 1));
return 0; return 0;
} }
break; break;
case 0xa7: /* AMI - write cache bad */ case 0xa7: /* AMI - write cache bad */
if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - write cache bad\n"); kbd_log("ATkbd: AMI - write cache bad\n");
#endif #endif
kbd->ami_stat &= 0xfd; kbd->ami_stat &= 0xfd;
return 0; return 0;
} }
break; break;
case 0xa8: /* AMI - write cache good */ case 0xa8: /* AMI - write cache good */
if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - write cache good\n"); kbd_log("ATkbd: AMI - write cache good\n");
#endif #endif
kbd->ami_stat |= 0x02; kbd->ami_stat |= 0x02;
return 0; return 0;
} }
break; break;
case 0xa9: /* AMI - read cache */ case 0xa9: /* AMI - read cache */
if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - read cache\n"); kbd_log("ATkbd: AMI - read cache\n");
#endif #endif
kbd_adddata(!!(kbd->ami_stat & 2)); kbd_adddata(!!(kbd->ami_stat & 2));
return 0; return 0;
} }
break; break;
case 0xaf: /*Set extended controller RAM*/ case 0xaf: /*Set extended controller RAM*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: set extended controller RAM\n"); kbd_log("ATkbd: set extended controller RAM\n");
#endif #endif
@@ -1386,7 +1394,7 @@ kbd_write64_ami(void *p, uint8_t val)
(allow command D1 to change bits 2 and 3 of the output (allow command D1 to change bits 2 and 3 of the output
port)*/ port)*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - unblock keyboard controller lines P22 and P23\n"); kbd_log("ATkbd: AMI - unblock KBC lines P22 and P23\n");
#endif #endif
kbd->output_locked = 1; kbd->output_locked = 1;
return 0; return 0;
@@ -1395,28 +1403,28 @@ kbd_write64_ami(void *p, uint8_t val)
(prevent command D1 from changing bits 2 and 3 of the (prevent command D1 from changing bits 2 and 3 of the
output port)*/ output port)*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - block keyboard controller lines P22 and P23\n"); kbd_log("ATkbd: AMI - block KBC lines P22 and P23\n");
#endif #endif
kbd->output_locked = 1; kbd->output_locked = 1;
return 0; return 0;
case 0xca: /*AMI - read keyboard mode*/ case 0xca: /*AMI - read keyboard mode*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - read keyboard mode\n"); kbd_log("ATkbd: AMI - read keyboard mode\n");
#endif #endif
kbd_adddata(0x00); /*ISA mode*/ kbd_adddata(0x00); /*ISA mode*/
return 0; return 0;
case 0xcb: /*AMI - set keyboard mode*/ case 0xcb: /*AMI - set keyboard mode*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("AMI - set keyboard mode\n"); kbd_log("ATkbd: AMI - set keyboard mode\n");
#endif #endif
kbd->want60 = 1; kbd->want60 = 1;
return 0; return 0;
case 0xef: /*??? - sent by AMI486*/ case 0xef: /*??? - sent by AMI486*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("??? - sent by AMI486\n"); kbd_log("ATkbd: ??? - sent by AMI486\n");
#endif #endif
return 0; return 0;
} }
@@ -1449,7 +1457,7 @@ kbd_write64_ibm_mca(void *p, uint8_t val)
case 0xaf: case 0xaf:
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: bad kbc command AF\n"); kbd_log("ATkbd: bad KBC command AF\n");
#endif #endif
return 1; return 1;
@@ -1474,9 +1482,9 @@ kbd_write60_quadtel(void *p, uint8_t val)
atkbd_t *kbd = (atkbd_t *) p; atkbd_t *kbd = (atkbd_t *) p;
switch(kbd->command) { switch(kbd->command) {
case 0xcf: /*??? - sent by MegaPC BIOS*/ case 0xcf: /*??? - sent by MegaPC BIOS*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("??? - sent by MegaPC BIOS\n"); kbd_log("ATkbd: ??? - sent by MegaPC BIOS\n");
#endif #endif
return 0; return 0;
} }
@@ -1493,13 +1501,13 @@ kbd_write64_quadtel(void *p, uint8_t val)
switch (val) { switch (val) {
case 0xaf: case 0xaf:
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: bad kbc command AF\n"); kbd_log("ATkbd: bad KBC command AF\n");
#endif #endif
return 1; return 1;
case 0xcf: /*??? - sent by MegaPC BIOS*/ case 0xcf: /*??? - sent by MegaPC BIOS*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("??? - sent by MegaPC BIOS\n"); kbd_log("ATkbd: ??? - sent by MegaPC BIOS\n");
#endif #endif
kbd->want60 = 1; kbd->want60 = 1;
return 0; return 0;
@@ -1515,7 +1523,7 @@ kbd_write60_toshiba(void *p, uint8_t val)
atkbd_t *kbd = (atkbd_t *) p; atkbd_t *kbd = (atkbd_t *) p;
switch(kbd->command) { switch(kbd->command) {
case 0xb6: /* T3100e - set colour/mono switch */ case 0xb6: /* T3100e - set color/mono switch */
t3100e_mono_set(val); t3100e_mono_set(val);
return 0; return 0;
} }
@@ -1532,64 +1540,64 @@ kbd_write64_toshiba(void *p, uint8_t val)
switch (val) { switch (val) {
case 0xaf: case 0xaf:
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: bad kbc command AF\n"); kbd_log("ATkbd: bad KBC command AF\n");
#endif #endif
return 1; return 1;
case 0xb0: /* T3100e: Turbo on */ case 0xb0: /* T3100e: Turbo on */
t3100e_turbo_set(1); t3100e_turbo_set(1);
return 0; return 0;
case 0xb1: /* T3100e: Turbo off */ case 0xb1: /* T3100e: Turbo off */
t3100e_turbo_set(0); t3100e_turbo_set(0);
return 0; return 0;
case 0xb2: /* T3100e: Select external display */ case 0xb2: /* T3100e: Select external display */
t3100e_display_set(0x00); t3100e_display_set(0x00);
return 0; return 0;
case 0xb3: /* T3100e: Select internal display */ case 0xb3: /* T3100e: Select internal display */
t3100e_display_set(0x01); t3100e_display_set(0x01);
return 0; return 0;
case 0xb4: /* T3100e: Get configuration / status */ case 0xb4: /* T3100e: Get configuration / status */
kbd_adddata(t3100e_config_get()); kbd_adddata(t3100e_config_get());
return 0; return 0;
case 0xb5: /* T3100e: Get colour / mono byte */ case 0xb5: /* T3100e: Get colour / mono byte */
kbd_adddata(t3100e_mono_get()); kbd_adddata(t3100e_mono_get());
return 0; return 0;
case 0xb6: /* T3100e: Set colour / mono byte */ case 0xb6: /* T3100e: Set colour / mono byte */
kbd->want60 = 1; kbd->want60 = 1;
return 0; return 0;
case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */ case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */
case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */ case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */
return 0; return 0;
case 0xbb: /* T3100e: Read 'Fn' key. case 0xbb: /* T3100e: Read 'Fn' key.
Return it for right Ctrl and right Alt; on the real Return it for right Ctrl and right Alt; on the real
T3100e, these keystrokes could only be generated T3100e, these keystrokes could only be generated
using 'Fn'. */ using 'Fn'. */
if (keyboard_recv(0xb8) || /* Right Alt */ if (keyboard_recv(0xb8) || /* Right Alt */
keyboard_recv(0x9d)) /* Right Ctrl */ keyboard_recv(0x9d)) /* Right Ctrl */
kbd_adddata(0x04); kbd_adddata(0x04);
else kbd_adddata(0x00); else kbd_adddata(0x00);
return 0; return 0;
case 0xbc: /* T3100e: Reset Fn+Key notification */ case 0xbc: /* T3100e: Reset Fn+Key notification */
t3100e_notify_set(0x00); t3100e_notify_set(0x00);
return 0; return 0;
case 0xc0: /*Read input port*/ case 0xc0: /*Read input port*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: read input port\n"); kbd_log("ATkbd: read input port\n");
#endif #endif
/* The T3100e returns all bits set except bit 6 which /* The T3100e returns all bits set except bit 6 which
* is set by t3100e_mono_set() */ * is set by t3100e_mono_set() */
kbd->input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; kbd->input_port = (t3100e_mono_get() & 1) ? 0xff : 0xbf;
kbd_adddata(kbd->input_port); kbd_adddata(kbd->input_port);
return 0; return 0;
@@ -1610,6 +1618,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
if (romset == ROM_XI8088 && port == 0x63) if (romset == ROM_XI8088 && port == 0x63)
port = 0x61; port = 0x61;
#ifdef _DEBUG
kbd_log("ATkbd: write(%04X, %02X)\n", port, val);
#endif
switch (port) { switch (port) {
case 0x60: case 0x60:
if (kbd->want60) { if (kbd->want60) {
@@ -1631,7 +1642,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0xd1: /*Write output port*/ case 0xd1: /*Write output port*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
// kbd_log("Write output port\n"); // kbd_log("ATkbd: write output port\n");
#endif #endif
if (kbd->output_locked) { if (kbd->output_locked) {
/*If keyboard controller lines P22-P23 are blocked, /*If keyboard controller lines P22-P23 are blocked,
@@ -1666,7 +1677,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
mouse_write(val, mouse_p); mouse_write(val, mouse_p);
else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) {
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
pclog("Adding 0xFF to queue\n"); kbd_log("ATkbd: adding 0xFF to queue\n");
#endif #endif
keyboard_at_adddata_mouse(0xff); keyboard_at_adddata_mouse(0xff);
} }
@@ -1718,9 +1729,15 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
#endif #endif
break; break;
} }
/* Keyboard command is now done. */
kbd->key_command = 0x00;
} else { } else {
kbd->key_command = val; /* No keyboard command in progress. */
kbd->key_command = 0x00;
kbd_keyboard_set(kbd, 1); kbd_keyboard_set(kbd, 1);
switch (val) { switch (val) {
case 0x00: case 0x00:
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
@@ -1731,7 +1748,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0x05: /*??? - sent by NT 4.0*/ case 0x05: /*??? - sent by NT 4.0*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: nt 4.0 command fe\n"); kbd_log("ATkbd: NT4.0 command FE\n");
#endif #endif
kbd_adddata_keyboard(0xfe); kbd_adddata_keyboard(0xfe);
break; break;
@@ -1739,7 +1756,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0x71: /*These two commands are sent by Pentium-era AMI BIOS'es.*/ case 0x71: /*These two commands are sent by Pentium-era AMI BIOS'es.*/
case 0x82: case 0x82:
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: pentium-era ami bios command %02x\n", val); kbd_log("ATkbd: Pentium-era AMI BIOS command %02X\n", val);
#endif #endif
break; break;
@@ -1747,20 +1764,22 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: set/reset leds\n"); kbd_log("ATkbd: set/reset leds\n");
#endif #endif
kbd->key_wantdata = 1;
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
kbd->key_wantdata = 1;
kbd->key_command = val;
break; break;
case 0xee: /*Diagnostic echo*/ case 0xee: /*Diagnostic echo*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: diagnostic echo\n"); kbd_log("ATkbd: ECHO\n");
#endif #endif
kbd_adddata_keyboard(0xee); kbd_adddata_keyboard(0xee);
break; break;
case 0xef: /*NOP (No OPeration). Reserved for future use.*/ case 0xef: /*NOP (No OPeration). Reserved for future use.*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: kbd nop\n"); kbd_log("ATkbd: NOP\n");
#endif #endif
break; break;
@@ -1768,8 +1787,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: scan code set\n"); kbd_log("ATkbd: scan code set\n");
#endif #endif
kbd->key_wantdata = 1;
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
kbd->key_wantdata = 1;
kbd->key_command = val;
break; break;
case 0xf2: /*Read ID*/ case 0xf2: /*Read ID*/
@@ -1786,35 +1806,37 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: set typematic rate/delay\n"); kbd_log("ATkbd: set typematic rate/delay\n");
#endif #endif
kbd->key_wantdata = 1;
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
kbd->key_wantdata = 1;
kbd->key_command = val;
break; break;
case 0xf4: /*Enable keyboard*/ case 0xf4: /*Enable keyboard*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: enable keyboard via keyboard\n"); kbd_log("ATkbd: enable keyboard via keyboard\n");
#endif #endif
keyboard_scan = 1;
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
keyboard_scan = 1;
break; break;
case 0xf5: /*Disable keyboard*/ case 0xf5: /*Disable keyboard*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: disable keyboard via keyboard\n"); kbd_log("ATkbd: disable keyboard via keyboard\n");
#endif #endif
keyboard_scan = 0;
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
keyboard_scan = 0;
break; break;
case 0xf6: /*Set defaults*/ case 0xf6: /*Set defaults*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: set defaults\n"); kbd_log("ATkbd: set defaults\n");
#endif #endif
kbd_adddata_keyboard(0xfa);
keyboard_set3_all_break = 0; keyboard_set3_all_break = 0;
keyboard_set3_all_repeat = 0; keyboard_set3_all_repeat = 0;
memset(keyboard_set3_flags, 0, 512); memset(keyboard_set3_flags, 0, 512);
keyboard_mode = (keyboard_mode & 0xFC) | 0x02; keyboard_mode = (keyboard_mode & 0xFC) | 0x02;
kbd_adddata_keyboard(0xfa);
kbd_setmap(kbd); kbd_setmap(kbd);
break; break;
@@ -1822,33 +1844,33 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: set all keys to repeat\n"); kbd_log("ATkbd: set all keys to repeat\n");
#endif #endif
keyboard_set3_all_break = 1;
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
keyboard_set3_all_break = 1;
break; break;
case 0xf8: /*Set all keys to give make/break codes*/ case 0xf8: /*Set all keys to give make/break codes*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: set all keys to give make/break codes\n"); kbd_log("ATkbd: set all keys to give make/break codes\n");
#endif #endif
keyboard_set3_all_break = 1;
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
keyboard_set3_all_break = 1;
break; break;
case 0xf9: /*Set all keys to give make codes only*/ case 0xf9: /*Set all keys to give make codes only*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: set all keys to give make codes only\n"); kbd_log("ATkbd: set all keys to give make codes only\n");
#endif #endif
keyboard_set3_all_break = 0;
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
keyboard_set3_all_break = 0;
break; break;
case 0xfa: /*Set all keys to repeat and give make/break codes*/ case 0xfa: /*Set all keys to repeat and give make/break codes*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: set all keys to repeat and give make/break codes\n"); kbd_log("ATkbd: set all keys to repeat and give make/break codes\n");
#endif #endif
kbd_adddata_keyboard(0xfa);
keyboard_set3_all_repeat = 1; keyboard_set3_all_repeat = 1;
keyboard_set3_all_break = 1; keyboard_set3_all_break = 1;
kbd_adddata_keyboard(0xfa);
break; break;
case 0xfe: /*Resend last scan code*/ case 0xfe: /*Resend last scan code*/
@@ -1862,8 +1884,8 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: kbd reset\n"); kbd_log("ATkbd: kbd reset\n");
#endif #endif
key_queue_start = key_queue_end = 0; /*Clear key queue*/
kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xfa);
key_queue_start = key_queue_end = 0; /*Clear key queue*/
kbd_adddata_keyboard(0xaa); kbd_adddata_keyboard(0xaa);
/* Set system flag to 1 and scan code set to 2. */ /* Set system flag to 1 and scan code set to 2. */
keyboard_mode &= 0xFC; keyboard_mode &= 0xFC;
@@ -1903,8 +1925,26 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
break; break;
case 0x64: case 0x64:
/*
* Try to recover from bad commands.
*
* If we get a command here, but seem to be still in
* keyboard-command data mode, abort that...
*/
if (kbd->key_wantdata || kbd->key_command) {
kbd_log("ATkbd: *** BUG ALERT *** aborting previous keyboard command 0x%02X (data %d)\n", kbd->key_command, kbd->key_wantdata);
/* If they were waiting for data.. */
kbd_adddata(0xfa);
/* Abort the previous command. */
kbd->key_command = 0x00;
kbd->key_wantdata = 0;
}
kbd->want60 = 0; kbd->want60 = 0;
kbd->command = val; kbd->command = val;
/*New controller command*/ /*New controller command*/
switch (val) { switch (val) {
case 0x20: case 0x21: case 0x22: case 0x23: case 0x20: case 0x21: case 0x22: case 0x23:
@@ -1929,9 +1969,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
kbd->want60 = 1; kbd->want60 = 1;
break; break;
case 0xaa: /*Self-test*/ case 0xaa: /*Self-test*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("Self-test\n"); kbd_log("ATkbd: self-test\n");
#endif #endif
if ((kbd->flags & KBC_VEN_MASK) == KBC_VEN_TOSHIBA) if ((kbd->flags & KBC_VEN_MASK) == KBC_VEN_TOSHIBA)
kbd->status |= STAT_IFULL; kbd->status |= STAT_IFULL;
@@ -1949,79 +1989,79 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
kbd_adddata(0x55); kbd_adddata(0x55);
break; break;
case 0xab: /*Interface test*/ case 0xab: /*Interface test*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: interface test\n"); kbd_log("ATkbd: interface test\n");
#endif #endif
kbd_adddata(0x00); /*no error*/ kbd_adddata(0x00); /*no error*/
break; break;
case 0xac: /*Diagnostic dump*/ case 0xac: /*Diagnostic dump*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: diagnostic dump\n"); kbd_log("ATkbd: diagnostic dump\n");
#endif #endif
for (i=0; i<16; i++) for (i = 0; i < 16; i++)
kbd_adddata(kbd->mem[i]); kbd_adddata(kbd->mem[i]);
kbd_adddata((kbd->input_port & 0xf0) | 0x80); kbd_adddata((kbd->input_port & 0xf0) | 0x80);
kbd_adddata(kbd->output_port); kbd_adddata(kbd->output_port);
kbd_adddata(kbd->status); kbd_adddata(kbd->status);
break; break;
case 0xad: /*Disable keyboard*/ case 0xad: /*Disable keyboard*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: disable keyboard\n"); kbd_log("ATkbd: disable keyboard\n");
#endif #endif
kbd_keyboard_set(kbd, 0); kbd_keyboard_set(kbd, 0);
break; break;
case 0xae: /*Enable keyboard*/ case 0xae: /*Enable keyboard*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: enable keyboard\n"); kbd_log("ATkbd: enable keyboard\n");
#endif #endif
kbd_keyboard_set(kbd, 1); kbd_keyboard_set(kbd, 1);
break; break;
case 0xd0: /*Read output port*/ case 0xd0: /*Read output port*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: read output port\n"); kbd_log("ATkbd: read output port\n");
#endif #endif
mask = 0xff; mask = 0xff;
if(!keyboard_scan) if (! keyboard_scan)
mask &= 0xbf; mask &= 0xbf;
if(!mouse_scan && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) if (!mouse_scan && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1))
mask &= 0xf7; mask &= 0xf7;
kbd_adddata(kbd->output_port & mask); kbd_adddata(kbd->output_port & mask);
break; break;
case 0xd1: /*Write output port*/ case 0xd1: /*Write output port*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
// kbd_log("ATkbd: write output port\n"); kbd_log("ATkbd: write output port\n");
#endif #endif
kbd->want60 = 1; kbd->want60 = 1;
break; break;
case 0xd2: /*Write keyboard output buffer*/ case 0xd2: /*Write keyboard output buffer*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: write keyboard output buffer\n"); kbd_log("ATkbd: write keyboard output buffer\n");
#endif #endif
kbd->want60 = 1; kbd->want60 = 1;
break; break;
case 0xdd: /* Disable A20 Address Line */ case 0xdd: /* Disable A20 Address Line */
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: disable A20 Address Line\n"); kbd_log("ATkbd: disable A20\n");
#endif #endif
kbd_output_write(kbd, kbd->output_port & 0xfd); kbd_output_write(kbd, kbd->output_port & 0xfd);
break; break;
case 0xdf: /* Enable A20 Address Line */ case 0xdf: /* Enable A20 Address Line */
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: enable A20 address line\n"); kbd_log("ATkbd: enable A20\n");
#endif #endif
kbd_output_write(kbd, kbd->output_port | 0x02); kbd_output_write(kbd, kbd->output_port | 0x02);
break; break;
case 0xe0: /*Read test inputs*/ case 0xe0: /*Read test inputs*/
#ifdef ENABLE_KEYBOARD_LOG #ifdef ENABLE_KEYBOARD_LOG
kbd_log("ATkbd: read test inputs\n"); kbd_log("ATkbd: read test inputs\n");
#endif #endif
@@ -2081,13 +2121,19 @@ kbd_read(uint16_t port, void *priv)
case 0x64: case 0x64:
ret = (kbd->status & 0xFB) | (keyboard_mode & CCB_SYSTEM); ret = (kbd->status & 0xFB) | (keyboard_mode & CCB_SYSTEM);
#if 0
ret |= STAT_LOCK; ret |= STAT_LOCK;
#endif
/* The transmit timeout (TTIMEOUT) flag should *NOT* be cleared, otherwise /* The transmit timeout (TTIMEOUT) flag should *NOT* be cleared, otherwise
the IBM PS/2 Model 80's BIOS gives error 8601 (mouse error). */ the IBM PS/2 Model 80's BIOS gives error 8601 (mouse error). */
kbd->status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/); kbd->status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/);
break; break;
} }
#ifdef _DEBUG
kbd_log("ATkbd: read(%04X) = %02X\n", port, ret);
#endif
return(ret); return(ret);
} }

View File

@@ -8,7 +8,7 @@
* *
* Implementation of the Intel DMA controllers. * Implementation of the Intel DMA controllers.
* *
* Version: @(#)dma.c 1.0.5 2018/05/06 * Version: @(#)dma.c 1.0.6 2018/06/25
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -81,118 +81,110 @@ static struct {
#define DMA_PS2_SIZE16 (1 << 6) #define DMA_PS2_SIZE16 (1 << 6)
static void dma_ps2_run(int channel);
static uint8_t static uint8_t
dma_read(uint16_t addr, UNUSED(void *priv)) _dma_read(int32_t addr)
{ {
int channel = (addr >> 1) & 3; uint8_t temp = mem_readb_phys_dma(addr);
uint8_t temp;
switch (addr & 0xf) { return(temp);
case 0:
case 2:
case 4:
case 6: /*Address registers*/
dma_wp ^= 1;
if (dma_wp)
return(dma[channel].ac & 0xff);
return((dma[channel].ac >> 8) & 0xff);
case 1:
case 3:
case 5:
case 7: /*Count registers*/
dma_wp ^= 1;
if (dma_wp)
temp = dma[channel].cc & 0xff;
else
temp = dma[channel].cc >> 8;
return(temp);
case 8: /*Status register*/
temp = dma_stat & 0xf;
dma_stat &= ~0xf;
return(temp);
case 0xd:
return(0);
}
return(dmaregs[addr & 0xf]);
} }
static void static void
dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) _dma_write(uint32_t addr, uint8_t val)
{ {
int channel = (addr >> 1) & 3; mem_writeb_phys_dma(addr, val);
mem_invalidate_range(addr, addr);
}
dmaregs[addr & 0xf] = val;
switch (addr & 0xf) {
case 0:
case 2:
case 4:
case 6: /*Address registers*/
dma_wp ^= 1;
if (dma_wp)
dma[channel].ab = (dma[channel].ab & 0xffff00) | val;
else
dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8);
dma[channel].ac = dma[channel].ab;
return;
case 1: static void
case 3: dma_ps2_run(int channel)
case 5: {
case 7: /*Count registers*/ dma_t *dma_c = &dma[channel];
dma_wp ^= 1;
if (dma_wp)
dma[channel].cb = (dma[channel].cb & 0xff00) | val;
else
dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8);
dma[channel].cc = dma[channel].cb;
return;
case 8: /*Control register*/ switch (dma_c->ps2_mode & DMA_PS2_XFER_MASK) {
dma_command = val; case DMA_PS2_XFER_MEM_TO_IO:
return; do {
if (! dma_c->size) {
uint8_t temp = _dma_read(dma_c->ac);
case 0xa: /*Mask*/ outb(dma_c->io_addr, temp);
if (val & 4)
dma_m |= (1 << (val & 3));
else
dma_m &= ~(1 << (val & 3));
//pclog("DMA: %s mask for channel %d\n", (val&4)?"set":"clear", val&3);
return;
case 0xb: /*Mode*/ if (dma_c->ps2_mode & DMA_PS2_DEC2)
channel = (val & 3); dma_c->ac--;
dma[channel].mode = val; else
if (dma_ps2.is_ps2) { dma_c->ac++;
dma[channel].ps2_mode &= ~0x1c; } else {
if (val & 0x20) uint16_t temp = _dma_read(dma_c->ac) | (_dma_read(dma_c->ac + 1) << 8);
dma[channel].ps2_mode |= 0x10;
if ((val & 0xc) == 8)
dma[channel].ps2_mode |= 4;
else if ((val & 0xc) == 4)
dma[channel].ps2_mode |= 0xc;
}
return;
case 0xc: /*Clear FF*/ outw(dma_c->io_addr, temp);
dma_wp = 0;
return;
case 0xd: /*Master clear*/ if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_wp = 0; dma_c->ac -= 2;
dma_m |= 0xf; else
return; dma_c->ac += 2;
}
dma_stat_rq |= (1 << channel);
dma_c->cc--;
} while (dma_c->cc > 0);
dma_stat |= (1 << channel);
break;
case DMA_PS2_XFER_IO_TO_MEM:
do {
if (! dma_c->size) {
uint8_t temp = inb(dma_c->io_addr);
_dma_write(dma_c->ac, temp);
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac--;
else
dma_c->ac++;
} else {
uint16_t temp = inw(dma_c->io_addr);
_dma_write(dma_c->ac, temp & 0xff);
_dma_write(dma_c->ac + 1, temp >> 8);
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac -= 2;
else
dma_c->ac += 2;
}
dma_stat_rq |= (1 << channel);
dma_c->cc--;
} while (dma_c->cc > 0);
ps2_cache_clean();
dma_stat |= (1 << channel);
break;
default: /*Memory verify*/
do {
if (! dma_c->size) {
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac--;
else
dma_c->ac++;
} else {
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac -= 2;
else
dma_c->ac += 2;
}
dma_stat_rq |= (1 << channel);
dma->cc--;
} while (dma->cc > 0);
dma_stat |= (1 << channel);
break;
case 0xf: /*Mask write*/
dma_m = (dma_m & 0xf0) | (val & 0xf);
return;
} }
} }
@@ -355,6 +347,118 @@ dma_ps2_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
} }
static uint8_t
dma_read(uint16_t addr, UNUSED(void *priv))
{
int channel = (addr >> 1) & 3;
uint8_t temp;
switch (addr & 0xf) {
case 0:
case 2:
case 4:
case 6: /*Address registers*/
dma_wp ^= 1;
if (dma_wp)
return(dma[channel].ac & 0xff);
return((dma[channel].ac >> 8) & 0xff);
case 1:
case 3:
case 5:
case 7: /*Count registers*/
dma_wp ^= 1;
if (dma_wp)
temp = dma[channel].cc & 0xff;
else
temp = dma[channel].cc >> 8;
return(temp);
case 8: /*Status register*/
temp = dma_stat & 0xf;
dma_stat &= ~0xf;
return(temp);
case 0xd:
return(0);
}
return(dmaregs[addr & 0xf]);
}
static void
dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
{
int channel = (addr >> 1) & 3;
dmaregs[addr & 0xf] = val;
switch (addr & 0xf) {
case 0:
case 2:
case 4:
case 6: /*Address registers*/
dma_wp ^= 1;
if (dma_wp)
dma[channel].ab = (dma[channel].ab & 0xffff00) | val;
else
dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8);
dma[channel].ac = dma[channel].ab;
return;
case 1:
case 3:
case 5:
case 7: /*Count registers*/
dma_wp ^= 1;
if (dma_wp)
dma[channel].cb = (dma[channel].cb & 0xff00) | val;
else
dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8);
dma[channel].cc = dma[channel].cb;
return;
case 8: /*Control register*/
dma_command = val;
return;
case 0xa: /*Mask*/
if (val & 4)
dma_m |= (1 << (val & 3));
else
dma_m &= ~(1 << (val & 3));
return;
case 0xb: /*Mode*/
channel = (val & 3);
dma[channel].mode = val;
if (dma_ps2.is_ps2) {
dma[channel].ps2_mode &= ~0x1c;
if (val & 0x20)
dma[channel].ps2_mode |= 0x10;
if ((val & 0xc) == 8)
dma[channel].ps2_mode |= 4;
else if ((val & 0xc) == 4)
dma[channel].ps2_mode |= 0xc;
}
return;
case 0xc: /*Clear FF*/
dma_wp = 0;
return;
case 0xd: /*Master clear*/
dma_wp = 0;
dma_m |= 0xf;
return;
case 0xf: /*Mask write*/
dma_m = (dma_m & 0xf0) | (val & 0xf);
return;
}
}
static uint8_t static uint8_t
dma16_read(uint16_t addr, UNUSED(void *priv)) dma16_read(uint16_t addr, UNUSED(void *priv))
{ {
@@ -477,6 +581,13 @@ dma16_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
} }
static uint8_t
dma_page_read(uint16_t addr, UNUSED(void *priv))
{
return(dmapages[addr & 0xf]);
}
static void static void
dma_page_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) dma_page_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
{ {
@@ -534,13 +645,6 @@ dma_page_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
} }
static uint8_t
dma_page_read(uint16_t addr, UNUSED(void *priv))
{
return(dmapages[addr & 0xf]);
}
void void
dma_reset(void) dma_reset(void)
{ {
@@ -624,23 +728,6 @@ ps2_dma_init(void)
} }
uint8_t
_dma_read(int32_t addr)
{
uint8_t temp = mem_readb_phys_dma(addr);
return(temp);
}
void
_dma_write(uint32_t addr, uint8_t val)
{
mem_writeb_phys_dma(addr, val);
mem_invalidate_range(addr, addr);
}
int int
dma_channel_read(int channel) dma_channel_read(int channel)
{ {
@@ -786,97 +873,6 @@ dma_channel_write(int channel, uint16_t val)
} }
static void
dma_ps2_run(int channel)
{
dma_t *dma_c = &dma[channel];
switch (dma_c->ps2_mode & DMA_PS2_XFER_MASK) {
case DMA_PS2_XFER_MEM_TO_IO:
do {
if (! dma_c->size) {
uint8_t temp = _dma_read(dma_c->ac);
outb(dma_c->io_addr, temp);
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac--;
else
dma_c->ac++;
} else {
uint16_t temp = _dma_read(dma_c->ac) | (_dma_read(dma_c->ac + 1) << 8);
outw(dma_c->io_addr, temp);
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac -= 2;
else
dma_c->ac += 2;
}
dma_stat_rq |= (1 << channel);
dma_c->cc--;
} while (dma_c->cc > 0);
dma_stat |= (1 << channel);
break;
case DMA_PS2_XFER_IO_TO_MEM:
do {
if (! dma_c->size) {
uint8_t temp = inb(dma_c->io_addr);
_dma_write(dma_c->ac, temp);
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac--;
else
dma_c->ac++;
} else {
uint16_t temp = inw(dma_c->io_addr);
_dma_write(dma_c->ac, temp & 0xff);
_dma_write(dma_c->ac + 1, temp >> 8);
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac -= 2;
else
dma_c->ac += 2;
}
dma_stat_rq |= (1 << channel);
dma_c->cc--;
} while (dma_c->cc > 0);
ps2_cache_clean();
dma_stat |= (1 << channel);
break;
default: /*Memory verify*/
do {
if (! dma_c->size) {
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac--;
else
dma_c->ac++;
} else {
if (dma_c->ps2_mode & DMA_PS2_DEC2)
dma_c->ac -= 2;
else
dma_c->ac += 2;
}
dma_stat_rq |= (1 << channel);
dma->cc--;
} while (dma->cc > 0);
dma_stat |= (1 << channel);
break;
}
}
int int
dma_mode(int channel) dma_mode(int channel)
{ {

View File

@@ -8,7 +8,7 @@
* *
* Definitions for the Intel DMA controller. * Definitions for the Intel DMA controller.
* *
* Version: @(#)dma.h 1.0.2 2018/03/12 * Version: @(#)dma.h 1.0.3 2018/06/25
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -71,24 +71,26 @@ extern void ps2_dma_init(void);
extern void dma_reset(void); extern void dma_reset(void);
extern int dma_mode(int channel); extern int dma_mode(int channel);
extern void readdma0(void);
extern int readdma1(void);
extern uint8_t readdma2(void);
extern int readdma3(void);
extern void writedma2(uint8_t temp);
extern int dma_channel_read(int channel); extern int dma_channel_read(int channel);
extern int dma_channel_write(int channel, uint16_t val); extern int dma_channel_write(int channel, uint16_t val);
extern void dma_alias_set(void);
extern void dma_alias_remove(void);
extern void dma_alias_remove_piix(void);
extern void DMAPageRead(uint32_t PhysAddress, uint8_t *DataRead, extern void DMAPageRead(uint32_t PhysAddress, uint8_t *DataRead,
uint32_t TotalSize); uint32_t TotalSize);
extern void DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite, extern void DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite,
uint32_t TotalSize); uint32_t TotalSize);
#if 0
extern void readdma0(void);
extern int readdma1(void);
extern uint8_t readdma2(void);
extern int readdma3(void);
extern void writedma2(uint8_t temp);
#endif
extern void dma_alias_set(void);
extern void dma_alias_remove(void);
extern void dma_alias_remove_piix(void);
#endif /*EMU_DMA_H*/ #endif /*EMU_DMA_H*/

View File

@@ -8,7 +8,7 @@
* *
* Main include file for the application. * Main include file for the application.
* *
* Version: @(#)emu.h 1.0.25 2018/06/02 * Version: @(#)emu.h 1.0.26 2018/06/25
* *
* Author: Fred N. van Kempen, <decwiz@yahoo.com> * Author: Fred N. van Kempen, <decwiz@yahoo.com>
* *
@@ -167,6 +167,8 @@ extern int config_changed; /* config has changed */
extern void pclog_ex(const char *fmt, va_list); extern void pclog_ex(const char *fmt, va_list);
#endif #endif
extern void pclog(const char *fmt, ...); extern void pclog(const char *fmt, ...);
extern void pclog_repeat(int enabled);
extern void pclog_dump(int num);
extern void fatal(const char *fmt, ...); extern void fatal(const char *fmt, ...);
extern void pc_version(const char *platform); extern void pc_version(const char *platform);
extern void pc_path(wchar_t *dest, int dest_sz, const wchar_t *src); extern void pc_path(wchar_t *dest, int dest_sz, const wchar_t *src);

View File

@@ -260,7 +260,7 @@ Note: the block address is forced to be a multiple of the block size by
ignoring the appropriate number of the least-significant bits ignoring the appropriate number of the least-significant bits
SeeAlso: #P0178,#P0187 SeeAlso: #P0178,#P0187
* *
* Version: @(#)m_at_opti495.c 1.0.5 2018/05/06 * Version: @(#)m_at_opti495.c 1.0.6 2018/06/25
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -316,7 +316,9 @@ opti495_write(uint16_t addr, uint8_t val, void *p)
break; break;
case 0x24: case 0x24:
#if 0
pclog("OPTI: writing reg %02X %02X\n", optireg, val); pclog("OPTI: writing reg %02X %02X\n", optireg, val);
#endif
if (optireg >= 0x20 && optireg <= 0x2C) { if (optireg >= 0x20 && optireg <= 0x2C) {
optiregs[optireg - 0x20] = val; optiregs[optireg - 0x20] = val;
if (optireg == 0x21) { if (optireg == 0x21) {

View File

@@ -8,7 +8,7 @@
* *
* Main emulator module where most things are controlled. * Main emulator module where most things are controlled.
* *
* Version: @(#)pc.c 1.0.47 2018/06/10 * Version: @(#)pc.c 1.0.48 2018/06/26
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -215,8 +215,16 @@ pclog_ex(const char *fmt, va_list ap)
#ifndef RELEASE_BUILD #ifndef RELEASE_BUILD
static char buff[PCLOG_BUFF_SIZE]; static char buff[PCLOG_BUFF_SIZE];
static int seen = 0; static int seen = 0;
static int detect = 1;
char temp[PCLOG_BUFF_SIZE]; char temp[PCLOG_BUFF_SIZE];
if (fmt == NULL) {
/* Initialize. */
detect = (ap != NULL) ? 1 : 0;
seen = 0;
return;
}
if (stdlog == NULL) { if (stdlog == NULL) {
if (log_path[0] != L'\0') { if (log_path[0] != L'\0') {
stdlog = plat_fopen(log_path, L"w"); stdlog = plat_fopen(log_path, L"w");
@@ -236,7 +244,7 @@ pclog_ex(const char *fmt, va_list ap)
} }
vsprintf(temp, fmt, ap); vsprintf(temp, fmt, ap);
if (! strcmp(buff, temp)) { if (detect && !strcmp(buff, temp)) {
seen++; seen++;
} else { } else {
if (seen) { if (seen) {
@@ -266,6 +274,61 @@ pclog(const char *fmt, ...)
} }
/* Enable or disable detection of repeated info being logged. */
void
pclog_repeat(int enabled)
{
pclog_ex(NULL, (va_list)enabled);
}
#ifdef _DEBUG
/* Log a block of code around the current CS:IP. */
void
pclog_dump(int num)
{
char buff[128];
char *sp = NULL;
int i, k;
/* We make the current PC be in the middle of the block. */
num >>= 1;
i = -num;
/* Disable the repeat-detection. */
pclog_repeat(0);
while (i < num) {
if (sp == NULL) {
sp = buff;
sprintf(sp, "%08lx:", cpu_state.pc + i);
sp += strlen(sp);
}
/* Get byte from memory. */
k = readmembl(cpu_state.pc + i);
i++;
sprintf(sp, " %02x", k & 0xff);
sp += strlen(sp);
if ((i % 16) == 0) {
strcat(sp, "\n");
pclog(buff);
sp = NULL;
}
}
if (sp != NULL) {
strcat(sp, "\n");
pclog(buff);
}
/* Re-enable the repeat-detection. */
pclog_repeat(1);
}
#endif
/* Log a fatal error, and display a UI message before exiting. */ /* Log a fatal error, and display a UI message before exiting. */
void void
fatal(const char *fmt, ...) fatal(const char *fmt, ...)

View File

@@ -8,7 +8,7 @@
* *
* Define application version and build info. * Define application version and build info.
* *
* Version: @(#)version.h 1.0.15 2018/05/29 * Version: @(#)version.h 1.0.16 2018/06/25
* *
* Author: Fred N. van Kempen, <decwiz@yahoo.com> * Author: Fred N. van Kempen, <decwiz@yahoo.com>
* *
@@ -55,7 +55,7 @@
#define EMU_VER_MAJOR 0 #define EMU_VER_MAJOR 0
#define EMU_VER_MINOR 1 #define EMU_VER_MINOR 1
#define EMU_VER_REV 6 #define EMU_VER_REV 6
//#define EMU_VER_PATCH 1 #define EMU_VER_PATCH 1
/* Standard C preprocessor macros. */ /* Standard C preprocessor macros. */