예제 #1
0
void KEYBOARD_Reset() {
	/* Init the keyb struct */
	keyb.active=true;
	keyb.scanning=true;
	keyb.pending_key=-1;
	keyb.auxactive=false;
	keyb.pending_key_state=false;
	keyb.command=CMD_NONE;
	keyb.aux_command=ACMD_NONE;
	keyb.p60changed=false;
	keyb.auxchanged=false;
	keyb.led_state = 0x00;
	keyb.repeat.key=KBD_NONE;
	keyb.repeat.pause=200;
	keyb.repeat.rate=33;
	keyb.repeat.wait=0;
	keyb.leftctrl_pressed=false;
	keyb.rightctrl_pressed=false;
	keyb.scanset=1;
	/* command byte */
	keyb.cb_override_inhibit=false;
	keyb.cb_irq12=false;
	keyb.cb_irq1=true;
	keyb.cb_xlat=true;
	keyb.cb_sys=true;
	keyb.reset=false;
	/* OK */
	KEYBOARD_ClrBuffer();
	KEYBOARD_SetLEDs(0);
}
예제 #2
0
static void KEYBOARD_AddBuffer(Bit16u data) {
	if (keyb.used>=KEYBUFSIZE) {
		LOG(LOG_KEYBOARD,LOG_NORMAL)("Buffer full, dropping code");
		KEYBOARD_ClrBuffer(); return;
	}
	Bitu start=keyb.pos+keyb.used;
	if (start>=KEYBUFSIZE) start-=KEYBUFSIZE;
	keyb.buffer[start]=data;
	keyb.used++;
	/* Start up an event to start the first IRQ */
	if (!keyb.scheduled && !keyb.p60changed) {
		keyb.scheduled=true;
		PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY);
	}
}
예제 #3
0
static void KEYBOARD_Add8042Response(Bit8u data) {
	if(!keyb.enable_aux) return;
	if (keyb.buf8042_pos >= keyb.buf8042_len)
		keyb.buf8042_pos = keyb.buf8042_len = 0;
	else if (keyb.buf8042_len == 0)
		keyb.buf8042_pos = 0;

	if (keyb.buf8042_pos >= sizeof(keyb.buf8042)) {
		LOG(LOG_KEYBOARD,LOG_NORMAL)("8042 Buffer full, dropping code");
		KEYBOARD_ClrBuffer(); return;
	}

	keyb.buf8042[keyb.buf8042_len++] = data;
	PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY);
}
예제 #4
0
파일: keyboard.cpp 프로젝트: wwiv/dosbox
void KEYBOARD_Init(Section* sec) {
	IO_RegisterWriteHandler(0x60,write_p60,IO_MB);
	IO_RegisterReadHandler(0x60,read_p60,IO_MB);
	IO_RegisterWriteHandler(0x61,write_p61,IO_MB);
	IO_RegisterReadHandler(0x61,read_p61,IO_MB);
	IO_RegisterWriteHandler(0x64,write_p64,IO_MB);
	IO_RegisterReadHandler(0x64,read_p64,IO_MB);
	TIMER_AddTickHandler(&KEYBOARD_TickHandler);
	write_p61(0,0,0);
	/* Init the keyb struct */
	keyb.active=true;
	keyb.scanning=true;
	keyb.command=CMD_NONE;
	keyb.p60changed=false;
	keyb.repeat.key=KBD_NONE;
	keyb.repeat.pause=500;
	keyb.repeat.rate=33;
	keyb.repeat.wait=0;
	KEYBOARD_ClrBuffer();
}
예제 #5
0
파일: keyboard.cpp 프로젝트: adurdin/fs-uae
static void write_p60(Bitu port,Bitu val,Bitu iolen) {
	switch (keyb.command) {
	case CMD_NONE:	/* None */
		/* No active command this would normally get sent to the keyboard then */
		KEYBOARD_ClrBuffer();
		switch (val) {
		case 0xed:	/* Set Leds */
			keyb.command=CMD_SETLEDS;
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xee:	/* Echo */
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xf2:	/* Identify keyboard */
			/* AT's just send acknowledge */
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xf3: /* Typematic rate programming */
			keyb.command=CMD_SETTYPERATE;
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xf4:	/* Enable keyboard,clear buffer, start scanning */
			LOG(LOG_KEYBOARD,LOG_NORMAL)("Clear buffer,enable Scaning");
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			keyb.scanning=true;
			break;
		case 0xf5:	 /* Reset keyboard and disable scanning */
			LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, disable scanning");			
			keyb.scanning=false;
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xf6:	/* Reset keyboard and enable scanning */
			LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, enable scanning");
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			keyb.scanning=false;
			break;
		case 0xff:
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			KEYBOARD_AddBuffer(0xaa);
			break;
		default:
			/* Just always acknowledge strange commands */
			LOG(LOG_KEYBOARD,LOG_ERROR)("60:Unhandled command %X",val);
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
		}
		return;
	case CMD_SETOUTPORT:
		MEM_A20_Enable((val & 2)>0);
		keyb.outport = val;
		if (!(val & 1)) {
			x86_init_reset();
		}
		keyb.command = CMD_NONE;
		break;
	case CMD_SETTYPERATE: 
		{
			static const int delay[] = { 250, 500, 750, 1000 };
			static const int repeat[] = 
				{ 33,37,42,46,50,54,58,63,67,75,83,92,100,
				  109,118,125,133,149,167,182,200,217,233,
				  250,270,303,333,370,400,435,476,500 };
			keyb.repeat.pause = delay[(val>>5)&3];
			keyb.repeat.rate = repeat[val&0x1f];
			keyb.command=CMD_NONE;
		}
		/* Fallthrough! as setleds does what we want */
	case CMD_SETLEDS:
		keyb.command=CMD_NONE;
		KEYBOARD_ClrBuffer();
		KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
		break;
	}
}
예제 #6
0
static void write_p60(Bitu port,Bitu val,Bitu iolen) {
	switch (keyb.command) {
	case CMD_NONE:	/* None */
		if (keyb.reset)
			return;

		/* No active command this would normally get sent to the keyboard then */
		KEYBOARD_ClrBuffer();
		switch (val) {
		case 0xed:	/* Set Leds */
			keyb.command=CMD_SETLEDS;
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xee:	/* Echo */
			KEYBOARD_AddBuffer(0xee);	/* JC: The correct response is 0xEE, not 0xFA */
			break;
		case 0xf0:	/* set scancode set */
			keyb.command=CMD_SETSCANSET;
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xf2:	/* Identify keyboard */
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			KEYBOARD_AddBuffer(0xab);	/* ID */
			KEYBOARD_AddBuffer(0x83);
			break;
		case 0xf3: /* Typematic rate programming */
			keyb.command=CMD_SETTYPERATE;
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xf4:	/* Enable keyboard,clear buffer, start scanning */
			LOG(LOG_KEYBOARD,LOG_NORMAL)("Clear buffer, enable scanning");
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			keyb.scanning=true;
			break;
		case 0xf5:	 /* Reset keyboard and disable scanning */
			LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, disable scanning");			
			keyb.scanning=false;
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xf6:	/* Reset keyboard and enable scanning */
			LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, enable scanning");
			keyb.scanning=true;		/* JC: Original DOSBox code was wrong, this command enables scanning */
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			break;
		case 0xff:		/* keyboard resets take a long time (about 250ms), most keyboards flash the LEDs during reset */
			KEYBOARD_Reset();
			KEYBOARD_Add8042Response(0xFA);	/* ACK */
			KEYBOARD_Add8042Response(0xAA); /* SELF TEST OK (TODO: Need delay!) */
			keyb.reset=true;
			KEYBOARD_SetLEDs(7); /* most keyboard I test with tend to flash the LEDs during reset */
			PIC_AddEvent(KEYBOARD_ResetDelay,RESETDELAY);
			break;
		default:
			/* Just always acknowledge strange commands */
			LOG(LOG_KEYBOARD,LOG_ERROR)("60:Unhandled command %X",(int)val);
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
		}
		return;
	case CMD_SETSCANSET:
		keyb.command=CMD_NONE;
		if (val == 0) { /* just asking */
			if (keyb.cb_xlat) {
				switch (keyb.scanset) {
					case 1:	KEYBOARD_AddBuffer(0x43); break;
					case 2:	KEYBOARD_AddBuffer(0x41); break;
					case 3:	KEYBOARD_AddBuffer(0x3F); break;
				}
			}
			else {
				KEYBOARD_AddBuffer(keyb.scanset);
			}
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
		}
		else {
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge again */
			if (val > 3) val = 3;
			keyb.scanset = val;
		}
		break;
	case CMD_WRITEAUX:
		keyb.command=CMD_NONE;
		KEYBOARD_AUX_Write(val);
		break;
	case CMD_WRITEOUTPUT:
		keyb.command=CMD_NONE;
		KEYBOARD_ClrBuffer();
		KEYBOARD_AddBuffer(val);	/* and now you return the byte as if it were typed in */
		break;
	case CMD_WRITEAUXOUT:
		KEYBOARD_AddBuffer(AUX|val); /* stuff into AUX output */
		break;
	case CMD_SETOUTPORT:
		if (!(val & 1)) {
			if (allow_keyb_reset) {
				LOG_MSG("Restart by keyboard controller requested\n");
				On_Software_CPU_Reset();
			}
			else {
				LOG_MSG("WARNING: Keyboard output port written with bit 1 clear. Is the guest OS or application attempting to reset the system?\n");
			}
		}
		MEM_A20_Enable((val & 2)>0);
		keyb.command = CMD_NONE;
		break;
	case CMD_SETTYPERATE: 
		if (keyb.reset)
			return;

		{
			static const int delay[] = { 250, 500, 750, 1000 };
			static const int repeat[] =
			{ 33,37,42,46,50,54,58,63,67,75,83,92,100,
			  109,118,125,133,149,167,182,200,217,233,
			  250,270,303,333,370,400,435,476,500 };
			keyb.repeat.pause = delay[(val >> 5) & 3];
			keyb.repeat.rate = repeat[val & 0x1f];
			keyb.command = CMD_NONE;
			KEYBOARD_ClrBuffer();
			KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
		}
		break;
	case CMD_SETLEDS:
		if (keyb.reset)
			return;

		keyb.command=CMD_NONE;
		KEYBOARD_ClrBuffer();
		KEYBOARD_AddBuffer(0xfa);	/* Acknowledge */
		KEYBOARD_SetLEDs(val&7);
		break;
	case CMD_SETCOMMAND: /* 8042 command, not keyboard */
		/* TODO: If biosps2=true and aux=false, disallow the guest OS from changing AUX port parameters including IRQ */
		keyb.command=CMD_NONE;
		keyb.cb_xlat = (val >> 6) & 1;
		keyb.auxactive = !((val >> 5) & 1);
		keyb.active = !((val >> 4) & 1);
		keyb.cb_sys = (val >> 2) & 1;
		keyb.cb_irq12 = (val >> 1) & 1;
		keyb.cb_irq1 = (val >> 0) & 1;
		if (keyb.used && !keyb.scheduled && !keyb.p60changed && keyb.active) {
			keyb.scheduled=true;
			PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY);
		}
		break;
	}
}