mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-05-09 11:51:09 +08:00
PCjr INT 48h translation
This commit is contained in:
parent
088cf64e0e
commit
36c48c5f3a
@ -403,32 +403,24 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
|
|||||||
phys_writeb(physAddress+0x0e,(uint8_t)0xcf); //An IRET Instruction
|
phys_writeb(physAddress+0x0e,(uint8_t)0xcf); //An IRET Instruction
|
||||||
return (use_cb?0x13:0x0f);
|
return (use_cb?0x13:0x0f);
|
||||||
case CB_IRQ1: // keyboard int9
|
case CB_IRQ1: // keyboard int9
|
||||||
phys_writeb(physAddress+0x00,(uint8_t)0x50); // push ax
|
|
||||||
if (machine == MCH_PCJR) {
|
if (machine == MCH_PCJR) {
|
||||||
/* IBM PCjr reads the infrared input on NMI interrupt, which then calls INT 48h to
|
/* IBM PCjr reads the infrared input on NMI interrupt, which then calls INT 48h to
|
||||||
* translate to IBM PC/XT scan codes before passing AL directly to IRQ1 (INT 9).
|
* translate to IBM PC/XT scan codes before passing AL directly to IRQ1 (INT 9).
|
||||||
* PCjr keyboard handlers, including games made for the PCjr, assume the scan code
|
* PCjr keyboard handlers, including games made for the PCjr, assume the scan code
|
||||||
* is in AL and do not read the I/O port.
|
* is in AL and do not read the I/O port. */
|
||||||
*
|
|
||||||
* PCjr has an XT style keyboard interface where it is necessary to set, then clear,
|
|
||||||
* bit 7 of port 61h to re-enable the keyboard.
|
|
||||||
*
|
|
||||||
* Because we're talking to our own emulation, it is sufficient to just clear bit 7.*/
|
|
||||||
phys_writew(physAddress+0x01,(uint16_t)0x60E4); // in al, 0x60
|
|
||||||
|
|
||||||
if (use_cb) {
|
if (use_cb) {
|
||||||
phys_writeb(physAddress+0x03,(uint8_t)0xFE); //GRP 4
|
phys_writeb(physAddress+0x00,(uint8_t)0xFE); //GRP 4
|
||||||
phys_writeb(physAddress+0x04,(uint8_t)0x38); //Extra Callback instruction
|
phys_writeb(physAddress+0x01,(uint8_t)0x38); //Extra Callback instruction
|
||||||
phys_writew(physAddress+0x05,(uint16_t)callback); //The immediate word
|
phys_writew(physAddress+0x02,(uint16_t)callback); //The immediate word
|
||||||
physAddress+=4;
|
physAddress+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It wasn't an interrupt, so there's no need to ack */
|
/* It wasn't an interrupt, so there's no need to ack */
|
||||||
phys_writeb(physAddress+0x03,(uint8_t)0x58); // pop ax
|
phys_writeb(physAddress+0x00,(uint8_t)0xcf); //An IRET Instruction
|
||||||
phys_writeb(physAddress+0x04,(uint8_t)0xcf); //An IRET Instruction
|
return (use_cb?0x05:0x01);
|
||||||
return (use_cb?0x09:0x05);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
phys_writeb(physAddress+0x00,(uint8_t)0x50); // push ax
|
||||||
if (IS_PC98_ARCH) {
|
if (IS_PC98_ARCH) {
|
||||||
/* NTS: NEC PC-98 does not have keyboard input on port 60h, it's a 8251 UART elsewhere. */
|
/* NTS: NEC PC-98 does not have keyboard input on port 60h, it's a 8251 UART elsewhere. */
|
||||||
phys_writew(physAddress+0x01,(uint16_t)0x9090); // nop, nop
|
phys_writew(physAddress+0x01,(uint16_t)0x9090); // nop, nop
|
||||||
|
@ -1180,19 +1180,45 @@ static Bitu PCjr_NMI_Keyboard_Handler(void) {
|
|||||||
* Fn + 1 into the scan code for F1. */
|
* Fn + 1 into the scan code for F1. */
|
||||||
static Bitu PCjr_INT48_Keyboard_Handler(void) {
|
static Bitu PCjr_INT48_Keyboard_Handler(void) {
|
||||||
uint8_t pcjr_f = mem_readb(BIOS_KEYBOARD_PCJR_FLAG2);
|
uint8_t pcjr_f = mem_readb(BIOS_KEYBOARD_PCJR_FLAG2);
|
||||||
|
uint8_t flags1 = mem_readb(BIOS_KEYBOARD_FLAGS1);
|
||||||
|
|
||||||
switch (reg_al&0x7F) {
|
if ((reg_al&0x7F) == 0x54) {
|
||||||
case 0x54: /* Fn key */
|
if (reg_al&0x80/*release*/) pcjr_f &= ~BIOS_KEYBOARD_PCJR_FLAG2_FN_FLAG;
|
||||||
if (reg_al&0x80/*release*/) pcjr_f &= ~BIOS_KEYBOARD_PCJR_FLAG2_FN_FLAG;
|
else pcjr_f |= BIOS_KEYBOARD_PCJR_FLAG2_FN_FLAG;
|
||||||
else pcjr_f |= BIOS_KEYBOARD_PCJR_FLAG2_FN_FLAG;
|
goto skip_int9;
|
||||||
goto skip_int9;
|
|
||||||
default: /* AL without translation */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define UPDATESHIFT(x) if (x) { flags1 &= ~0x3; /*break*/ } else { flags1 |= 0x3; /*make*/ }
|
||||||
|
#define CLEARSHIFT() UPDATESHIFT(1/*break*/)
|
||||||
|
|
||||||
|
if (pcjr_f & (BIOS_KEYBOARD_PCJR_FLAG2_FN_FLAG|BIOS_KEYBOARD_PCJR_FLAG2_FN_LOCK)) {
|
||||||
|
const uint8_t bc = reg_al & 0x80;
|
||||||
|
switch (reg_al&0x7F) {
|
||||||
|
case 0x02: reg_al=0x3B|bc; break;/*Fn+1 = F1*/
|
||||||
|
case 0x03: reg_al=0x3C|bc; break;/*Fn+2 = F2*/
|
||||||
|
case 0x04: reg_al=0x3D|bc; break;/*Fn+3 = F3*/
|
||||||
|
case 0x05: reg_al=0x3E|bc; break;/*Fn+4 = F4*/
|
||||||
|
case 0x06: reg_al=0x3F|bc; break;/*Fn+5 = F5*/
|
||||||
|
case 0x07: reg_al=0x40|bc; break;/*Fn+6 = F6*/
|
||||||
|
case 0x08: reg_al=0x41|bc; break;/*Fn+7 = F7*/
|
||||||
|
case 0x09: reg_al=0x42|bc; break;/*Fn+8 = F8*/
|
||||||
|
case 0x0A: reg_al=0x43|bc; break;/*Fn+9 = F9*/
|
||||||
|
case 0x0B: reg_al=0x44|bc; break;/*Fn+10 = F10*/
|
||||||
|
case 0x1A: reg_al=0x2B|bc; UPDATESHIFT(bc); break;/*Fn+[ = | which is SHIFT+\ */
|
||||||
|
case 0x1B: reg_al=0x29|bc; UPDATESHIFT(bc); break;/*Fn+] = ~ which is SHIFT+` */
|
||||||
|
case 0x28: reg_al=0x29|bc; CLEARSHIFT(); break;/*Fn+' = ` which is unshifted ` */
|
||||||
|
case 0x35: reg_al=0x2B|bc; CLEARSHIFT(); break;/*Fn+/ = \\ which is unshifted \\ */
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef UPDATESHIFT
|
||||||
|
#undef CLEARSHIFT
|
||||||
|
|
||||||
reg_eip++; /* skip over IRET */
|
reg_eip++; /* skip over IRET */
|
||||||
skip_int9: /* if we do not skip IRET, then INT 48h returns without calling INT 9h */
|
skip_int9: /* if we do not skip IRET, then INT 48h returns without calling INT 9h */
|
||||||
|
|
||||||
|
mem_writeb(BIOS_KEYBOARD_FLAGS1,flags1);
|
||||||
mem_writeb(BIOS_KEYBOARD_PCJR_FLAG2,pcjr_f);
|
mem_writeb(BIOS_KEYBOARD_PCJR_FLAG2,pcjr_f);
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user