diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4866c89..1153bc5 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -211,6 +211,11 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) } break; + case 0xb6: /* T3100e - set colour/mono switch */ + if (romset == ROM_T3100E) + t3100e_mono_set(val); + break; + case 0xcb: /*AMI - set keyboard mode*/ break; @@ -410,20 +415,15 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at.mem[0] &= ~0x10; break; - case 0xbb: /* Read 'Fn' key - sent by Toshiba 3100e - BIOS. Return it for right Ctrl and right - Alt; on the real T3100e, these keystrokes - could only be generated using 'Fn'. */ - if (pcem_key[0xb8] || /* Right Alt */ - pcem_key[0x9d]) /* Right Ctrl */ - { - keyboard_at_adddata(0x04); - } - else keyboard_at_adddata(0x00); + case 0xb0: /* T3100e: Turbo on */ + if (romset == ROM_T3100E) + t3100e_turbo_set(1); break; - /* For the T3100e, 0xB0 is 'turbo on' and 0xB1 is - * 'turbo off' */ + case 0xb1: /* T3100e: Turbo off */ + if (romset == ROM_T3100E) + t3100e_turbo_set(0); + break; case 0xb2: /* T3100e: Select external display */ if (romset == ROM_T3100E) @@ -435,12 +435,51 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) t3100e_display_set(0x01); break; + case 0xb4: /* T3100e: Get configuration / status */ + if (romset == ROM_T3100E) + keyboard_at_adddata(t3100e_config_get()); + break; + + case 0xb5: /* T3100e: Get colour / mono byte */ + if (romset == ROM_T3100E) + keyboard_at_adddata(t3100e_mono_get()); + break; + + case 0xb6: /* T3100e: Set colour / mono byte */ + if (romset == ROM_T3100E) + keyboard_at.want60 = 1; + break; + + /* T3100e commands not implemented: + * 0xB7: Emulate PS/2 keyboard + * 0xB8: Emulate AT keyboard */ + + case 0xbb: /* T3100e: Read 'Fn' key. + Return it for right Ctrl and right + Alt; on the real T3100e, these keystrokes + could only be generated using 'Fn'. */ + if (romset == ROM_T3100E) + { + if (pcem_key[0xb8] || /* Right Alt */ + pcem_key[0x9d]) /* Right Ctrl */ + { + keyboard_at_adddata(0x04); + } + else keyboard_at_adddata(0x00); + } + break; + case 0xbc: /* T3100e: Reset Fn+Key notification */ if (romset == ROM_T3100E) t3100e_notify_set(0x00); break; case 0xc0: /*Read input port*/ + /* The T3100e returns all bits set except bit 6 which + * is set by t3100e_mono_set() */ + if (romset == ROM_T3100E) + keyboard_at.input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; + keyboard_at_adddata(keyboard_at.input_port | 4); keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc); break; diff --git a/src/t3100e.c b/src/t3100e.c index ebfbb8e..e9730d7 100644 --- a/src/t3100e.c +++ b/src/t3100e.c @@ -2,6 +2,7 @@ #include "cpu.h" #include "model.h" #include "io.h" +#include "fdd.h" #include "mouse.h" #include "mem.h" #include "device.h" @@ -157,7 +158,10 @@ struct t3100e_ems_regs uint8_t upper_pages; /* Pages of EMS available from upper RAM */ uint8_t upper_is_ems; /* Upper RAM is EMS? */ mem_mapping_t upper_mapping; - uint8_t notify; + uint8_t notify; /* Notification from keyboard controller */ + uint8_t turbo; /* 0 for 6MHz, else full speed */ + uint8_t mono; /* Emulates PC/AT 'mono' motherboard switch */ + /* Bit 0 is 0 for colour, 1 for mono */ } t3100e_ems; void t3100e_ems_out(uint16_t addr, uint8_t val, void *p); @@ -358,6 +362,33 @@ void t3100e_notify_set(uint8_t value) t3100e_ems.notify = value; } +void t3100e_mono_set(uint8_t value) +{ + t3100e_ems.mono = value; +} + +uint8_t t3100e_mono_get(void) +{ + return t3100e_ems.mono; +} + +void t3100e_turbo_set(uint8_t value) +{ + t3100e_ems.turbo = value; + if (!value) + { + int c = cpu; + cpu = 0; /* 286/6 */ + cpu_set(); + cpu = c; + } + else + { + cpu_set(); + } +} + + uint8_t t3100e_sys_in(uint16_t addr, void *p) { @@ -394,6 +425,83 @@ void t3100e_sys_out(uint16_t addr, uint8_t val, void *p) } } + +uint8_t t3100e_config_get(void) +{ +/* The byte returned: + Bit 7: Set if internal plasma display enabled + Bit 6: Set if running at 6MHz, clear at full speed + Bit 5: Always 1? + Bit 4: Set if the FD2MB jumper is present (internal floppy is ?tri-mode) + Bit 3: Clear if the FD2 jumper is present (two internal floppies) + Bit 2: Set if the internal drive is A:, clear if B: + Bit 1: Set if the parallel port is configured as a floppy connector + for the second drive. + Bit 0: Set if the F2HD jumper is present (internal floppy is 720k) + */ + uint8_t value = 0x28; /* Start with bits 5 and 3 set. */ + + int type_a = fdd_get_type(0); + int type_b = fdd_get_type(1); + int prt_switch; /* External drive type: 0=> none, 1=>A, 2=>B */ + +/* Get display setting */ + if (t3100e_display_get()) value |= 0x80; + if (!t3100e_ems.turbo) value |= 0x40; + +/* Try to determine the floppy types.*/ + + prt_switch = (type_b ? 2 : 0); + switch(type_a) + { +/* Since a T3100e cannot have an internal 5.25" drive, mark 5.25" A: drive as + * being external, and set the internal type based on type_b. */ + case 1: /* 360k */ + case 2: /* 1.2Mb */ + case 3: /* 1.2Mb RPMx2*/ + prt_switch = 1; /* External drive is A: */ + switch (type_b) + { + case 1: /* 360k */ + case 4: value |= 1; break; /* 720k */ + case 6: value |= 0x10; break; /* Tri-mode */ + /* All others will be treated as 1.4M */ + } + break; + case 4: value |= 0x01; /* 720k */ + if (type_a == type_b) + { + value &= (~8); /* Two internal drives */ + prt_switch = 0; /* No external drive */ + } + break; + case 5: /* 1.4M */ + case 7: /* 2.8M */ + if (type_a == type_b) + { + value &= (~8); /* Two internal drives */ + prt_switch = 0; /* No external drive */ + } + break; + case 6: /* 3-mode */ + value |= 0x10; + if (type_a == type_b) + { + value &= (~8); /* Two internal drives */ + prt_switch = 0; /* No external drive */ + } + break; + } /* End switch */ + switch (prt_switch) + { + case 0: value |= 4; break; /* No external floppy */ + case 1: value |= 2; break; /* External floppy is A: */ + case 2: value |= 6; break; /* External floppy is B: */ + } + return value; +} + + /* Read EMS page register */ uint8_t t3100e_ems_in(uint16_t addr, void *p) { diff --git a/src/t3100e.h b/src/t3100e.h index d0ada48..ab41153 100644 --- a/src/t3100e.h +++ b/src/t3100e.h @@ -1,2 +1,7 @@ void t3100e_notify_set(uint8_t value); void t3100e_display_set(uint8_t value); +uint8_t t3100e_display_get(); +uint8_t t3100e_config_get(); +void t3100e_turbo_set(uint8_t value); +uint8_t t3100e_mono_get(); +void t3100e_mono_set(uint8_t value); diff --git a/src/vid_t3100e.c b/src/vid_t3100e.c index fcd1227..4172f8f 100644 --- a/src/vid_t3100e.c +++ b/src/vid_t3100e.c @@ -54,6 +54,11 @@ void t3100e_display_set(uint8_t internal) st_display_internal = internal; } +uint8_t t3100e_display_get() +{ + return st_display_internal; +} + typedef struct t3100e_t {