Top secrets sources NedoPC pentevo

Rev

Rev 1024 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

#include <avr/io.h>
#include <util/delay.h>

#include "pins.h"
#include "mytypes.h"

#include "rs232.h"
#include "zx.h"
#include "joystick.h"
#include "kbmap.h"

//if want Log than comment next string
#undef LOGENABLE

#define JOY_PIN_R_M   0b00000001
#define JOY_PIN_L_X   0b00000010
#define JOY_PIN_D_Y   0b00000100
#define JOY_PIN_U_Z   0b00001000
#define JOY_PIN_B_A   0b00010000
#define JOY_PIN_RLDUB 0b00011111
#define JOY_PIN_C_S

const UBYTE joymaps[4][12]={
//default                              
//              Right   Left    Down    Up              B               C               A
        {       KEY_P,  KEY_O,  KEY_A,  KEY_Q,  KEY_M,  KEY_SS, KEY_SP,
//              Start   Mode    X               Y               Z
                KEY_EN, KEY_C,  KEY_N,  KEY_Y,  KEY_Z},
//Kempston
//              Right   Left    Down    Up              B               C               A
        {       0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
//              Start   Mode    X               Y               Z
                0x00,   0x00,   KEY_EN, KEY_SP, KEY_Z},
//Super Mario
//              Right   Left    Down    Up              B               C               A
        {       KEY_8,  KEY_5,  KEY_6,  KEY_7,  KEY_S,  KEY_SS, KEY_A,
//              Start   Mode    X               Y               Z
                KEY_EN, KEY_SP, KEY_X,  KEY_Y,  KEY_Z},
//Elite
//              Right   Left    Down    Up              B               C               A
        {       KEY_M,  KEY_N,  KEY_X,  KEY_S,  KEY_A,  KEY_SP, KEY_F,
//              Start   Mode    X               Y               Z
                KEY_D,  KEY_T,  KEY_E,  KEY_J,  KEY_SS}};

#define JOY_MAP_DEFAULT (UBYTE *)joymaps[0]
#define JOY_MAP_KEMPST  (UBYTE *)joymaps[1]
#define JOY_MAP_SMB             (UBYTE *)joymaps[2]
#define JOY_MAP_ELITE   (UBYTE *)joymaps[3]
UBYTE * joymap = JOY_MAP_DEFAULT;
#define J_WAIT 10

volatile UBYTE gamepad_type = JOY_NEED_DETECT;
volatile UWORD jkey_state = 0x0000;

void joystick_init(void){
        UBYTE joy_state;
       
        SEGA_SYNC_UP();
        DDRA  = 0b00000100;
        _delay_us(50000);
        //первый фронт клолка
        _delay_us(J_WAIT);
        //как минимум один из left/right должен быть в 1
        //и как минимум один из up/down должен быть в 1
        joy_state = JOYSTICK_PIN;
        gamepad_type = JOY_SWITCHS;
        if( (joy_state & ( JOY_PIN_L_X|JOY_PIN_R_M ) ) != 0 )
        {
                if( (joy_state & ( JOY_PIN_D_Y|JOY_PIN_U_Z ) ) != 0 )
                {
                        gamepad_type = JOY_SEGA_12KEY;
                }
        }
        if( gamepad_type != JOY_SWITCHS )
        {
                SEGA_SYNC_DOWN();
                //первый спад клока
                _delay_us(J_WAIT);
                //как минимум один из left/right должен быть в 0
                //и как минимум один из up/down должен быть в 1
                gamepad_type = JOY_SWITCHS;
                joy_state = JOYSTICK_PIN;
                if( (joy_state & ( JOY_PIN_L_X|JOY_PIN_R_M ) ) != ( JOY_PIN_L_X|JOY_PIN_R_M ) )
                {
                        if( (joy_state & ( JOY_PIN_D_Y|JOY_PIN_U_Z ) ) != 0 )
                        {
                                gamepad_type = JOY_SEGA_12KEY;
                        }
                }
               
                SEGA_SYNC_UP();
        }
       
        if( gamepad_type != JOY_SWITCHS )
        {
                // sega-pad есть, определим 8 или 12 кнопок
                _delay_us(J_WAIT);
                SEGA_SYNC_DOWN();
                // второй спад клока
                _delay_us(J_WAIT);
                SEGA_SYNC_UP();
                _delay_us(J_WAIT);
                SEGA_SYNC_DOWN();
                // третий спад клока
                // определим 8 или 12 кнопок у джоя
                // left/right/up/down должы быть в 0
                _delay_us(J_WAIT);
                if( ( JOYSTICK_PIN & ( JOY_PIN_D_Y|JOY_PIN_U_Z|JOY_PIN_L_X|JOY_PIN_R_M ) ) == 0 )
                {
                        gamepad_type = JOY_SEGA_12KEY;
                }
                else
                {
                        gamepad_type = JOY_SEGA_8KEY;
                }
                SEGA_SYNC_UP();
        }
       
        if( gamepad_type & JOY_SEGA_12KEY )
        {// для 12 кнопок закончим цикл клока
                _delay_us(J_WAIT);
                SEGA_SYNC_DOWN();
                _delay_us(J_WAIT);
                SEGA_SYNC_UP();
        }
       
        if( gamepad_type != JOY_SWITCHS )
        {//запустим прерывание, если есть sega-pad
                OCR0 = TCNT0 + 255;
                TCCR0 = 0b00111101;
        }
        else
        {
                DDRA  = 0b00000000;
        }
}


void sega_parsing(void){
        static UWORD jkey_state_old = 0x0000;
        static UBYTE kempst_old = 0x00;
        static UBYTE jkey_mode = 0x00;
       
        if( jkey_state_old == jkey_state )
        {//изменений нет, выходим
                return;
        }
       
        jkey_state_old = jkey_state;
       
        zx_realkbd[5] = 0xff;
        zx_realkbd[6] = 0xff;
        zx_realkbd[7] = 0xff;
        zx_realkbd[8] = 0xff;
        zx_realkbd[9] = 0xff;
       
        if((jkey_state & 0x0e00) == 0x0e00){
                if(jkey_mode == 0){
                        jkey_mode = 1;
                        joymap = (UBYTE *)joymaps[(jkey_state & 0x0030) >> 4];
                }
        }else{
                UBYTE i = 0;
                jkey_mode = 0;
                if((joymap == JOY_MAP_SMB) && (jkey_state & 0x000f)) //CAPSSHIFT
                        zx_realkbd[5]&=0xfe;
                if(joymap == JOY_MAP_KEMPST){                  
                        if (kempst_old ^ (jkey_state & 0x00ff))
                        {
                                kempst_old = jkey_state & 0x00ff;
                                zx_spi_send(SPI_KEMPSTON_JOYSTICK, kempst_old, 0x7F);
                        }
                        i = 8;
                        jkey_state >>= 8;
                }
                for(; i < 12; i++){
                        if(jkey_state & 0x0001){
                                zx_realkbd[(joymap[i]>>3)+5] &= ~(0b10000000>>(joymap[i]&0x07));
                        }
                        jkey_state >>= 1;
                }
        }
       
        // UWORD l = jkey_state;
        // rs232_transmit('\r');
        // for(UBYTE j=0;j<16;j++){
                // if(l & 0x8000)rs232_transmit('1');
                // else rs232_transmit('0');
                // l = l << 1;
        // }
}

void joystick_task(void)
{
        static UBYTE joy_state = 0;
       
        if( gamepad_type != JOY_SWITCHS )
        {
                return;
        }
       
        UBYTE temp = (~JOYSTICK_PIN) & JOYSTICK_MASK;

        if ( joy_state ^ temp )
        {
                //change state of joystick pins
                joy_state = temp;

                //send to port
                zx_spi_send(SPI_KEMPSTON_JOYSTICK, joy_state, 0x7F);

#ifdef LOGENABLE
        char log_joystick[] = "JS..\r\n";
        log_joystick[2] = ((temp >> 4) <= 9 )?'0'+(temp >> 4):'A'+(temp >> 4)-10;
        log_joystick[3] = ((temp & 0x0F) <= 9 )?'0'+(temp & 0x0F):'A'+(temp & 0x0F)-10;
        to_log(log_joystick);
#endif
        }
}