1
0
mirror of https://github.com/mist-devel/mist-firmware.git synced 2026-04-25 03:55:33 +00:00

ACSI and ikbd improvements

This commit is contained in:
harbaum
2013-04-02 19:21:59 +00:00
parent abd932aade
commit 9692e0287c
6 changed files with 420 additions and 370 deletions

View File

@@ -8,7 +8,7 @@ DUMP = $(BASE)-objdump
TODAY = `date +"%m/%d/%y"`
PRJ = firmware
SRC = Cstartup_SAM7.c fat.c fdd.c firmware.c fpga.c hardware.c hdd.c main.c menu.c mmc.c osd.c syscalls.c user_io.c boot_print.c boot_logo.c rafile.c config.c tos.c
SRC = Cstartup_SAM7.c fat.c fdd.c firmware.c fpga.c hardware.c hdd.c main.c menu.c mmc.c osd.c syscalls.c user_io.c boot_print.c boot_logo.c rafile.c config.c tos.c ikbd.c
SRC += usb/max3421e.c usb/usb.c usb/hub.c usb/hid.c usb/timer.c
OBJ = $(SRC:.c=.o)

313
ikbd.c Normal file
View File

@@ -0,0 +1,313 @@
/*
https://www.kernel.org/doc/Documentation/input/atarikbd.txt
ikbd ToDo:
Feature Example using/needing it impl. tested
---------------------------------------------------------------------
mouse y at bottom Bolo X X
mouse button key events Goldrunner/A_008 X X
joystick interrogation mode Xevious/A_004 X X
Absolute mouse mode Backlash/A_008, A-Ball/A50
disable mouse ? X
disable joystick ? X
Joysticks also generate Goldrunner X X
mouse button events!
Pause (cmd 0x13) Wings of Death/A_427
*/
#include <stdio.h>
#include <string.h>
#include "user_io.h"
#include "hardware.h"
#include "ikbd.h"
// atari ikbd stuff
#define IKBD_STATE_JOYSTICK_EVENT_REPORTING 0x01
#define IKBD_STATE_MOUSE_Y_BOTTOM 0x02
#define IKBD_STATE_MOUSE_BUTTON_AS_KEY 0x04 // mouse buttons act like keys
#define IKBD_STATE_MOUSE_DISABLED 0x08
#define IKBD_STATE_MOUSE_ABSOLUTE 0x10
#define IKBD_DEFAULT IKBD_STATE_JOYSTICK_EVENT_REPORTING
#define QUEUE_LEN 16 // power of 2!
static unsigned char tx_queue[QUEUE_LEN];
static unsigned char wptr = 0, rptr = 0;
// structure to keep track of ikbd state
static struct {
unsigned char cmd;
unsigned char state;
unsigned char expect;
// joystick state
unsigned char joystick[2];
// mouse state
unsigned short mouse_pos_x, mouse_pos_y;
unsigned char mouse_buttons;
} ikbd;
// #define IKBD_DEBUG
void ikbd_init() {
// reset ikbd state
memset(&ikbd, 0, sizeof(ikbd));
ikbd.state = IKBD_DEFAULT;
}
static void enqueue(unsigned char b) {
if(((wptr + 1)&(QUEUE_LEN-1)) == rptr) {
iprintf("IKBD: !!!!!!! tx queue overflow !!!!!!!!!\n");
return;
}
tx_queue[wptr] = b;
wptr = (wptr+1)&(QUEUE_LEN-1);
}
// convert internal joystick format into atari ikbd format
static unsigned char joystick_map2ikbd(unsigned in) {
unsigned char out = 0;
if(in & JOY_UP) out |= 0x01;
if(in & JOY_DOWN) out |= 0x02;
if(in & JOY_LEFT) out |= 0x04;
if(in & JOY_RIGHT) out |= 0x08;
if(in & JOY_BTN1) out |= 0x80;
return out;
}
// process inout from atari core into ikbd
void ikbd_handle_input(unsigned char cmd) {
// expecting a second byte for command
if(ikbd.expect) {
ikbd.expect--;
// last byte of command received
if(!ikbd.expect) {
switch(ikbd.cmd) {
case 0x07: // set mouse button action
iprintf("IKBD: mouse button action = %x\n", cmd);
// bit 2: Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
if(cmd & 0x04) ikbd.state |= IKBD_STATE_MOUSE_BUTTON_AS_KEY;
else ikbd.state &= ~IKBD_STATE_MOUSE_BUTTON_AS_KEY;
break;
case 0x80: // ibkd reset
// reply "everything is ok"
enqueue(0xf0);
break;
default:
break;
}
}
return;
}
ikbd.cmd = cmd;
switch(cmd) {
case 0x07:
puts("IKBD: Set mouse button action");
ikbd.expect = 1;
break;
case 0x08:
puts("IKBD: Set relative mouse positioning");
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
ikbd.state &= ~IKBD_STATE_MOUSE_ABSOLUTE;
break;
case 0x09:
puts("IKBD: Set absolute mouse positioning");
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
ikbd.state |= IKBD_STATE_MOUSE_ABSOLUTE;
ikbd.expect = 4;
break;
case 0x0b:
puts("IKBD: Set Mouse threshold");
ikbd.expect = 2;
break;
case 0x0f:
puts("IKBD: Set Y at bottom");
ikbd.state |= IKBD_STATE_MOUSE_Y_BOTTOM;
break;
case 0x10:
puts("IKBD: Set Y at top");
ikbd.state &= ~IKBD_STATE_MOUSE_Y_BOTTOM;
break;
case 0x12:
puts("IKBD: Disable mouse");
ikbd.state |= IKBD_STATE_MOUSE_DISABLED;
break;
case 0x14:
puts("IKBD: Set Joystick event reporting");
ikbd.state |= IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x15:
puts("IKBD: Set Joystick interrogation mode");
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x16: // interrogate joystick
// send reply
enqueue(0xfd);
enqueue(joystick_map2ikbd(ikbd.joystick[0]));
enqueue(joystick_map2ikbd(ikbd.joystick[1]));
break;
case 0x1a:
puts("IKBD: Disable joysticks");
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x1c:
puts("IKBD: Interrogate time of day");
enqueue(0xfc);
enqueue(0x13); // year bcd
enqueue(0x03); // month bcd
enqueue(0x07); // day bcd
enqueue(0x20); // hour bcd
enqueue(0x58); // minute bcd
enqueue(0x00); // second bcd
break;
case 0x80:
puts("IKBD: Reset");
ikbd.expect = 1;
ikbd.state = IKBD_DEFAULT;
break;
default:
iprintf("IKBD: unknown command: %x\n", cmd);
break;
}
}
void ikbd_poll(void) {
static mtimer = 0;
if(CheckTimer(mtimer)) {
mtimer = GetTimer(10);
// check for incoming ikbd data
EnableIO();
SPI(UIO_IKBD_IN);
while(SPI(0))
ikbd_handle_input(SPI(0));
DisableIO();
}
// send data from queue if present
if(rptr == wptr) return;
// transmit data from queue
EnableIO();
SPI(UIO_IKBD_OUT);
SPI(tx_queue[rptr]);
DisableIO();
rptr = (rptr+1)&(QUEUE_LEN-1);
}
void ikbd_joystick(unsigned char joystick, unsigned char map) {
// todo: suppress events for joystick 0 as long as mouse
// is enabled?
if(ikbd.state & IKBD_STATE_JOYSTICK_EVENT_REPORTING) {
#ifdef IKBD_DEBUG
iprintf("IKBD: joy %d %x\n", joystick, map);
#endif
// only report joystick data for joystick 0 if the mouse is disabled
if((ikbd.state & IKBD_STATE_MOUSE_DISABLED) || (joystick == 1)) {
enqueue(0xfe + joystick);
enqueue(joystick_map2ikbd(map));
}
if(!(ikbd.state & IKBD_STATE_MOUSE_DISABLED)) {
// the fire button also generates a mouse event if
// mouse reporting is enabled
if((map & JOY_BTN1) != (ikbd.joystick[joystick] & JOY_BTN1)) {
// generate mouse event (ikbd_joystick_buttons is evaluated inside
// user_io_mouse)
ikbd.joystick[joystick] = map;
ikbd_mouse(0, 0, 0);
}
}
}
#ifdef IKBD_DEBUG
else
iprintf("IKBD: no monitor, drop joy %d %x\n", joystick, map);
#endif
// save state of joystick for interrogation mode
ikbd.joystick[joystick] = map;
}
void ikbd_keyboard(unsigned char code) {
#ifdef IKBD_DEBUG
iprintf("IKBD: send keycode %x%s\n", code&0x7f, (code&0x80)?" BREAK":"");
#endif
enqueue(code);
}
void ikbd_mouse(unsigned char b, char x, char y) {
if(ikbd.state & IKBD_STATE_MOUSE_DISABLED)
return;
// joystick and mouse buttons are wired together in
// atari st
b |= (ikbd.joystick[0] & JOY_BTN1)?1:0;
b |= (ikbd.joystick[1] & JOY_BTN1)?2:0;
static unsigned char b_old = 0;
// monitor state of two mouse buttons
if(b != b_old) {
// check if mouse buttons are supposed to be treated like keys
if(ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) {
// Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
// handle left mouse button
if((b ^ b_old) & 1) ikbd_keyboard(0x74 | ((b&1)?0x00:0x80));
// handle right mouse button
if((b ^ b_old) & 2) ikbd_keyboard(0x75 | ((b&2)?0x00:0x80));
}
b_old = b;
}
#if 0
if(ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) {
b = 0;
// if mouse position is 0/0 quit here
if(!x && !y) return;
}
#endif
if(ikbd.state & IKBD_STATE_MOUSE_ABSOLUTE) {
} else {
// atari has mouse button bits swapped
enqueue(0xf8|((b&1)?2:0)|((b&2)?1:0));
enqueue(x);
enqueue((ikbd.state & IKBD_STATE_MOUSE_Y_BOTTOM)?-y:y);
}
}

10
ikbd.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef IKBD_H
#define IKBD_H
void ikbd_init(void);
void ikbd_poll(void);
void ikbd_joystick(unsigned char joy, unsigned char map);
void ikbd_mouse(unsigned char buttons, char x, char y);
void ikbd_keyboard(unsigned char code);
#endif // IKBD_H

138
tos.c
View File

@@ -42,26 +42,6 @@ static const char *acsi_cmd_name(int cmd) {
return cmdname[cmd];
}
static void acsi_read_cmd() {
static int cnt = 0;
EnableFpga();
SPI(MIST_READ_ACSI);
unsigned char status = SPI(0);
while(status & 1) {
unsigned char data = SPI(0);
if(!(status & 0x02))
iprintf("ACSI: cmd \"%s\", target %d\n",
acsi_cmd_name(data & 0x1f), data>>5);
else
iprintf("ACSI: cont. data %x\n", data);
status = SPI(0);
}
DisableFpga();
}
static void mist_memory_set_address(unsigned long a) {
a >>= 1; // make word address
@@ -75,9 +55,11 @@ static void mist_memory_set_address(unsigned long a) {
}
static void mist_set_control(unsigned short ctrl) {
static void mist_set_control(unsigned long ctrl) {
EnableFpga();
SPI(MIST_SET_CONTROL);
SPI((ctrl >> 24) & 0xff);
SPI((ctrl >> 16) & 0xff);
SPI((ctrl >> 8) & 0xff);
SPI((ctrl >> 0) & 0xff);
DisableFpga();
@@ -154,67 +136,67 @@ static void handle_acsi(unsigned char *buffer) {
if(length == 0) length = 256;
iprintf("ACSI: target %d, \"%s\"\n", target, acsi_cmd_name(cmd));
// iprintf("ACSI: %02x %02x %02x %02x %02x\n", buffer[10], buffer[11],
// buffer[12], buffer[13], buffer[14]);
iprintf("ACSI: lba %lu, length %u\n", lba, length);
iprintf("DMA: scnt %u, addr %p\n", scnt, dma_address);
mist_memory_set_address(dma_address);
// only a harddisk on ACSI 0 is supported
// ACSI 0 is only supported if a image is loaded
if((target == 0) && (hdd_image.size != 0)) {
mist_memory_set_address(dma_address);
switch(cmd) {
case 0x08: // read sector
DISKLED_ON;
while(length) {
FileSeek(&hdd_image, lba++, SEEK_SET);
FileRead(&hdd_image, dma_buffer);
mist_memory_write(dma_buffer, 256);
length--;
}
DISKLED_OFF;
break;
case 0x0a: // write sector
DISKLED_ON;
while(length) {
mist_memory_read(dma_buffer, 256);
FileSeek(&hdd_image, lba++, SEEK_SET);
FileWrite(&hdd_image, dma_buffer);
length--;
}
DISKLED_OFF;
break;
case 0x12: // inquiry
memset(dma_buffer, 0, 512);
dma_buffer[2] = 1; // ANSI version
dma_buffer[4] = length-8; // len
memcpy(dma_buffer+8, "MIST ", 8); // Vendor
memcpy(dma_buffer+16, " ", 16); // Clear device entry
memcpy(dma_buffer+16, hdd_image.name, 11); // Device
mist_memory_write(dma_buffer, length/2);
break;
case 0x1a: // mode sense
{ unsigned int blocks = hdd_image.size / 512;
iprintf("ACSI: mode sense, blocks = %u\n", blocks);
switch(cmd) {
case 0x08: // read sector
DISKLED_ON;
while(length) {
FileSeek(&hdd_image, lba++, SEEK_SET);
FileRead(&hdd_image, dma_buffer);
mist_memory_write(dma_buffer, 256);
length--;
}
DISKLED_OFF;
break;
case 0x0a: // write sector
DISKLED_ON;
while(length) {
mist_memory_read(dma_buffer, 256);
FileSeek(&hdd_image, lba++, SEEK_SET);
FileWrite(&hdd_image, dma_buffer);
length--;
}
DISKLED_OFF;
break;
case 0x12: // inquiry
memset(dma_buffer, 0, 512);
dma_buffer[3] = 8; // size of extent descriptor list
dma_buffer[5] = blocks >> 16;
dma_buffer[6] = blocks >> 8;
dma_buffer[7] = blocks;
dma_buffer[10] = 2; // byte 1 of block size in bytes (512)
dma_buffer[2] = 1; // ANSI version
dma_buffer[4] = length-8; // len
memcpy(dma_buffer+8, "MIST ", 8); // Vendor
memcpy(dma_buffer+16, " ", 16); // Clear device entry
memcpy(dma_buffer+16, hdd_image.name, 11); // Device
mist_memory_write(dma_buffer, length/2);
break;
case 0x1a: // mode sense
{ unsigned int blocks = hdd_image.size / 512;
iprintf("ACSI: mode sense, blocks = %u\n", blocks);
memset(dma_buffer, 0, 512);
dma_buffer[3] = 8; // size of extent descriptor list
dma_buffer[5] = blocks >> 16;
dma_buffer[6] = blocks >> 8;
dma_buffer[7] = blocks;
dma_buffer[10] = 2; // byte 1 of block size in bytes (512)
mist_memory_write(dma_buffer, length/2);
}
break;
default:
iprintf("ACSI: Unsupported command\n");
break;
}
break;
} else
iprintf("ACSI: Request for unsupported target\n");
default:
iprintf("ACSI: Unsupported command\n");
break;
}
EnableFpga();
SPI(MIST_ACK_DMA);
DisableFpga();
@@ -283,8 +265,6 @@ static void mist_get_dmastate() {
static unsigned char buffer[16];
int i;
// acsi_read_cmd();
EnableFpga();
SPI(MIST_GET_DMASTATE);
for(i=0;i<16;i++)
@@ -550,8 +530,10 @@ void tos_upload() {
// try to open harddisk image
hdd_image.size = 0;
if(FileOpen(&hdd_image, "HARDDISKHD "))
tos_write("Found harddisk image ");
if(FileOpen(&hdd_image, "HARDDISKHD ")) {
tos_write("Found hard disk image ");
tos_system_ctrl |= TOS_ACSI0_ENABLE;
}
tos_write("Booting ... ");

23
tos.h
View File

@@ -13,7 +13,6 @@
#define MIST_SET_CONTROL 0x04
#define MIST_GET_DMASTATE 0x05 // reads state of dma and floppy controller
#define MIST_ACK_DMA 0x06 // acknowledges a dma command
#define MIST_READ_ACSI 0x07
// tos sysconfig bits:
// 0 - RESET
@@ -21,6 +20,8 @@
// 4-5 - CPU configuration
// 6-7 - Floppy A+B write protection
// 8 - Color/Monochrome mode
// 9 - PAL mode in 56 or 50 Hz
// 10-17 - ACSI device enable
// memory configurations (0x02/0x04/0x08)
// (currently 4MB are fixed and cannot be changed)
@@ -40,11 +41,21 @@
#define TOS_CPUCONFIG_68020 (3<<4)
// control bits (all control bits have unknown state after core startup)
#define TOS_CONTROL_CPU_RESET 0x0001
#define TOS_CONTROL_FDC_WR_PROT_A 0x0040
#define TOS_CONTROL_FDC_WR_PROT_B 0x0080
#define TOS_CONTROL_VIDEO_COLOR 0x0100 // input to mfp
#define TOS_CONTROL_PAL50HZ 0x0200 // display pal at 50hz (56 hz otherwise)
#define TOS_CONTROL_CPU_RESET 0x00000001
#define TOS_CONTROL_FDC_WR_PROT_A 0x00000040
#define TOS_CONTROL_FDC_WR_PROT_B 0x00000080
#define TOS_CONTROL_VIDEO_COLOR 0x00000100 // input to mfp
#define TOS_CONTROL_PAL50HZ 0x00000200 // display pal at 50hz (56 hz otherwise)
// up to eight acsi devices can be enabled
#define TOS_ACSI0_ENABLE 0x00000400
#define TOS_ACSI1_ENABLE 0x00000800
#define TOS_ACSI2_ENABLE 0x00001000
#define TOS_ACSI3_ENABLE 0x00002000
#define TOS_ACSI4_ENABLE 0x00004000
#define TOS_ACSI5_ENABLE 0x00008000
#define TOS_ACSI6_ENABLE 0x00010000
#define TOS_ACSI7_ENABLE 0x00020000
extern unsigned long tos_system_ctrl;

304
user_io.c
View File

@@ -1,31 +1,13 @@
/*
https://www.kernel.org/doc/Documentation/input/atarikbd.txt
ikbd ToDo:
Feature Example using/needing it impl. tested
---------------------------------------------------------------------
mouse y at bottom Bolo X X
mouse button key events Goldrunner/A_008 X X
joystick interrogation mode Xevious/A_004
Absolute mouse mode Backlash/A_008
disable mouse ? X
disable joystick ? X
Joysticks also generate Goldrunner X X
mouse button events!
Pause (cmd 0x13) Wings of Death/A_427
*/
#include "AT91SAM7S256.h"
#include "stdio.h"
#include <stdio.h>
#include <string.h>
#include "hardware.h"
#include "user_io.h"
#include "usb.h"
#include "keycodes.h"
#include "ikbd.h"
typedef enum { EMU_NONE, EMU_MOUSE, EMU_JOY0, EMU_JOY1 } emu_mode_t;
static emu_mode_t emu_mode = EMU_NONE;
@@ -40,155 +22,6 @@ AT91PS_PMC a_pPMC = AT91C_BASE_PMC;
static char caps_lock_toggle = 0;
// atari ikbd stuff
#define IKBD_STATE_JOYSTICK_EVENT_REPORTING 0x01
#define IKBD_STATE_MOUSE_Y_BOTTOM 0x02
#define IKBD_STATE_MOUSE_BUTTON_AS_KEY 0x04 // mouse buttons act like keys
#define IKBD_STATE_MOUSE_DISABLED 0x08
#define IKBD_DEFAULT IKBD_STATE_JOYSTICK_EVENT_REPORTING
static unsigned char ikbd_cmd = 0;
static unsigned char ikbd_state = IKBD_DEFAULT;
static unsigned char ikbd_expect = 0;
static unsigned char ikbd_joystick_buttons = 0;
// #define IKBD_DEBUG
void ikbd_ok() {
// this only happens while we are reading
// from the spi. so stop reading
DisableIO();
// send reply
EnableIO();
SPI(UIO_IKBD_OUT);
SPI(0xf0);
DisableIO();
// continue reading
EnableIO();
SPI(UIO_IKBD_IN);
}
// process inout from atari core into ikbd
void ikbd_handle_input(unsigned char cmd) {
// expecting a second byte for command
if(ikbd_expect) {
ikbd_expect--;
// last byte of command received
if(!ikbd_expect) {
switch(ikbd_cmd) {
case 0x07: // set mouse button action
iprintf("IKBD: mouse button action = %x\n", cmd);
// bit 2: Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
if(cmd & 0x04) ikbd_state |= IKBD_STATE_MOUSE_BUTTON_AS_KEY;
else ikbd_state &= ~IKBD_STATE_MOUSE_BUTTON_AS_KEY;
break;
case 0x80: // ibkd reset
// reply "everything is ok"
ikbd_ok();
break;
default:
break;
}
}
return;
}
ikbd_cmd = cmd;
switch(cmd) {
case 0x07:
puts("IKBD: Set mouse button action");
ikbd_expect = 1;
break;
case 0x08:
puts("IKBD: Set relative mouse positioning");
ikbd_state &= ~IKBD_STATE_MOUSE_DISABLED;
break;
case 0x0b:
puts("IKBD: Set Mouse threshold");
ikbd_expect = 2;
break;
case 0x0f:
puts("IKBD: Set Y at bottom");
ikbd_state |= IKBD_STATE_MOUSE_Y_BOTTOM;
break;
case 0x10:
puts("IKBD: Set Y at top");
ikbd_state &= ~IKBD_STATE_MOUSE_Y_BOTTOM;
break;
case 0x12:
puts("IKBD: Disable mouse");
ikbd_state |= IKBD_STATE_MOUSE_DISABLED;
break;
case 0x14:
puts("IKBD: Set Joystick event reporting");
ikbd_state |= IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x15:
puts("IKBD: Set Joystick interrogation mode");
ikbd_state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x1a:
puts("IKBD: Disable joysticks");
ikbd_state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x1c:
puts("IKBD: Interrogate time of day");
// send some date
// stop reading from ikbd queue
DisableIO();
// send reply (the date this routine was written)
EnableIO();
SPI(UIO_IKBD_OUT);
SPI(0xfc);
SPI(0x13); // year bcd
SPI(0x03); // month bcd
SPI(0x07); // day bcd
SPI(0x20); // hour bcd
SPI(0x58); // minute bcd
SPI(0x00); // second bcd
DisableIO();
// continue reading
EnableIO();
SPI(UIO_IKBD_IN);
break;
case 0x80:
puts("IKBD: Reset");
ikbd_expect = 1;
ikbd_state = IKBD_DEFAULT;
break;
default:
iprintf("IKBD: unknown command: %x\n", cmd);
break;
}
}
static void InitADC(void) {
// Enable clock for interface
@@ -229,6 +62,7 @@ static unsigned int GetAdc(unsigned char channel) {
void user_io_init() {
InitADC();
ikbd_init();
}
unsigned char user_io_core_type() {
@@ -269,19 +103,6 @@ void user_io_detect_core_type() {
}
}
// convert internal joystick format into atari ikbd format
unsigned char joystick_map2ikbd(unsigned in) {
unsigned char out = 0;
if(in & JOY_UP) out |= 0x01;
if(in & JOY_DOWN) out |= 0x02;
if(in & JOY_LEFT) out |= 0x04;
if(in & JOY_RIGHT) out |= 0x08;
if(in & JOY_BTN1) out |= 0x80;
return out;
}
void user_io_joystick(unsigned char joystick, unsigned char map) {
if(core_type == CORE_TYPE_MINIMIG || core_type == CORE_TYPE_PACE) {
EnableIO();
@@ -290,39 +111,8 @@ void user_io_joystick(unsigned char joystick, unsigned char map) {
DisableIO();
}
if(core_type == CORE_TYPE_MIST) {
// todo: suppress events for joystick 0 as long as mouse
// is enabled?
if(ikbd_state & IKBD_STATE_JOYSTICK_EVENT_REPORTING) {
#ifdef IKBD_DEBUG
iprintf("IKBD: joy %d %x\n", joystick, map);
#endif
EnableIO();
SPI(UIO_IKBD_OUT);
SPI(0xfe + joystick);
SPI(joystick_map2ikbd(map));
DisableIO();
// the fire button also generates a mouse event if
// mouse reporting is enabled
unsigned char button1 = (map & JOY_BTN1)?(1<<joystick):0;
if(button1 != (ikbd_joystick_buttons & (1<<joystick))) {
// update saved state of joystick buttons
ikbd_joystick_buttons = (ikbd_joystick_buttons & ~(1<<joystick)) | button1;
// generate mouse event (ikbd_joystick_buttons is evaluated inside
// user_io_mouse)
user_io_mouse(0, 0, 0);
}
}
#ifdef IKBD_DEBUG
else
iprintf("IKBD: no monitor, drop joy %d %x\n", joystick, map);
#endif
}
if(core_type == CORE_TYPE_MIST)
ikbd_joystick(joystick, map);
}
void user_io_poll() {
@@ -333,28 +123,16 @@ void user_io_poll() {
}
if(core_type == CORE_TYPE_MIST) {
static mtimer = 0;
if(CheckTimer(mtimer)) {
mtimer = GetTimer(100);
ikbd_poll();
// check for incoming ikbd data
EnableIO();
SPI(UIO_IKBD_IN);
while(SPI(0))
ikbd_handle_input(SPI(0));
DisableIO();
// check for incoming serial data
EnableIO();
SPI(UIO_SERIAL_IN);
while(SPI(0))
putchar(SPI(0));
DisableIO();
}
// check for incoming serial data
EnableIO();
SPI(UIO_SERIAL_IN);
while(SPI(0))
putchar(SPI(0));
DisableIO();
}
// poll db9 joysticks
@@ -445,15 +223,8 @@ static void send_keycode(unsigned short code) {
DisableIO();
}
if(core_type == CORE_TYPE_MIST) {
#ifdef IKBD_DEBUG
iprintf("IKBD: send keycode %x%s\n", code&0x7f, (code&0x80)?" BREAK":"");
#endif
EnableIO();
SPI(UIO_IKBD_OUT);
SPI(code & 0xff);
DisableIO();
}
if(core_type == CORE_TYPE_MIST)
ikbd_keyboard(code);
}
void user_io_mouse(unsigned char b, char x, char y) {
@@ -469,45 +240,8 @@ void user_io_mouse(unsigned char b, char x, char y) {
}
// send mouse data as mist expects it
if(core_type == CORE_TYPE_MIST) {
if(ikbd_state & IKBD_STATE_MOUSE_DISABLED)
return;
// joystick and mouse buttons are wired together in
// atari st
b |= ikbd_joystick_buttons;
static unsigned char b_old = 0;
// monitor state of two mouse buttons
if(b != b_old) {
// check if mouse buttons are supposed to be treated like keys
if(ikbd_state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) {
// Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
// handle left mouse button
if((b ^ b_old) & 1) send_keycode(0x74 | ((b&1)?0x00:0x80));
// handle right mouse button
if((b ^ b_old) & 2) send_keycode(0x75 | ((b&2)?0x00:0x80));
}
b_old = b;
}
#if 0
if(ikbd_state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) {
b = 0;
// if mouse position is 0/0 quit here
if(!x && !y) return;
}
#endif
EnableIO();
SPI(UIO_IKBD_OUT);
// atari has mouse button bits swapped
SPI(0xf8|((b&1)?2:0)|((b&2)?1:0));
SPI(x);
SPI((ikbd_state & IKBD_STATE_MOUSE_Y_BOTTOM)?-y:y);
DisableIO();
}
if(core_type == CORE_TYPE_MIST)
ikbd_mouse(b, x, y);
}
// check if this is a key that's supposed to be suppressed