Subversion Repositories pentevo

Rev

Rev 686 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 lvd 1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/pgmspace.h>
4
#include <util/delay.h>
5
 
6
#include "mytypes.h"
7
#include "zx.h"
219 chrv 8
#include "kbmap.h"
6 lvd 9
#include "pins.h"
126 chrv 10
#include "main.h"
6 lvd 11
#include "spi.h"
70 lvd 12
#include "rs232.h"
71 chrv 13
#include "ps2.h"
94 chrv 14
#include "rtc.h"
6 lvd 15
 
179 chrv 16
//if want Log than comment next string
17
#undef LOGENABLE
18
 
71 chrv 19
//zx mouse registers
20
volatile UBYTE zx_mouse_button;
21
volatile UBYTE zx_mouse_x;
22
volatile UBYTE zx_mouse_y;
6 lvd 23
 
219 chrv 24
// PS/2 keyboard control keys status (for additional functons)
685 lvd 25
volatile UBYTE kb_ctrl_status;
26
// PS/2 keyboard control keys mapped to zx keyboard (mapped keys not used in additional functions)
27
volatile UBYTE kb_ctrl_mapped;
219 chrv 28
 
6 lvd 29
#define ZX_FIFO_SIZE 256 /* do not change this since it must be exactly byte-wise */
30
 
31
UBYTE zx_fifo[ZX_FIFO_SIZE];
32
 
33
UBYTE zx_fifo_in_ptr;
34
UBYTE zx_fifo_out_ptr;
35
 
36
UBYTE zx_counters[40]; // filter ZX keystrokes here to assure every is pressed and released only once
11 lvd 37
UBYTE zx_map[5]; // keys bitmap. send order: LSbit first, from [4] to [0]
6 lvd 38
 
39
volatile UBYTE shift_pause;
40
 
117 ddp 41
UBYTE zx_realkbd[11];
6 lvd 42
 
43
void zx_init(void)
44
{
45
        zx_fifo_in_ptr=zx_fifo_out_ptr=0;
46
 
8 lvd 47
        zx_task(ZX_TASK_INIT);
6 lvd 48
 
219 chrv 49
        //reset Z80
186 chrv 50
        zx_spi_send(SPI_RST_REG, 0, 0);
6 lvd 51
}
52
 
94 chrv 53
UBYTE zx_spi_send(UBYTE addr, UBYTE data, UBYTE mask)
54
{
55
        UBYTE status;
56
        UBYTE ret;
100 chrv 57
        nSPICS_PORT &= ~(1<<nSPICS); // fix for status locking
94 chrv 58
        nSPICS_PORT |= (1<<nSPICS);  // set address of SPI register
59
        status = spi_send(addr);
60
        nSPICS_PORT &= ~(1<<nSPICS); // send data for that register
61
        ret = spi_send(data);
62
        nSPICS_PORT |= (1<<nSPICS);
6 lvd 63
 
94 chrv 64
        //if CPU waited
65
        if ( status&mask ) zx_wait_task(status);
6 lvd 66
 
94 chrv 67
        return ret;
68
}
69
 
8 lvd 70
void zx_task(UBYTE operation) // zx task, tracks when there is need to send new keymap to the fpga
6 lvd 71
{
8 lvd 72
        static UBYTE prev_code;
73
        static UBYTE task_state;
644 ddp 74
        //static UBYTE reset_type;
6 lvd 75
 
8 lvd 76
        UBYTE was_data;
77
        UBYTE code,keynum,keybit;
6 lvd 78
 
219 chrv 79
        if ( operation==ZX_TASK_INIT )
8 lvd 80
        {
644 ddp 81
                //reset_type = 0;
8 lvd 82
                prev_code = KEY_V+1; // impossible scancode
83
                task_state = 0;
84
                shift_pause = 0;
6 lvd 85
 
11 lvd 86
                zx_clr_kb();
219 chrv 87
 
685 lvd 88
                //check control keys whoes mapped to zx keyboard
89
                //(mapped keys not used in additional functions)
90
                kb_ctrl_mapped = 0;
91
                if( kbmap_get(0x14,0).tw != (UWORD)NO_KEY+(((UWORD)NO_KEY)<<8) ) kb_ctrl_mapped |= KB_LCTRL_MASK;
92
                if( kbmap_get(0x14,1).tw != (UWORD)NO_KEY+(((UWORD)NO_KEY)<<8) ) kb_ctrl_mapped |= KB_RCTRL_MASK;
93
                if(     kbmap_get(0x11,0).tw != (UWORD)NO_KEY+(((UWORD)NO_KEY)<<8) ) kb_ctrl_mapped |= KB_LALT_MASK;
94
                if( kbmap_get(0x11,1).tw != (UWORD)NO_KEY+(((UWORD)NO_KEY)<<8) ) kb_ctrl_mapped |= KB_RALT_MASK;
95
           /*
219 chrv 96
                //detect if CTRL-ALT-DEL keys mapped
299 chrv 97
//              if ( ((kbmap[0x14*2] == NO_KEY) && (kbmap[0x14*2+1] == NO_KEY)) ||
98
//                       ((kbmap[0x11*2] == NO_KEY) && (kbmap[0x11*2+1] == NO_KEY)) ||
99
//                       ((kbmap_E0[0x11*2] == NO_KEY) && (kbmap[0x11*2+1] == NO_KEY)) )
100
                if( (kbmap_get(0x14,0).tw == (UWORD)NO_KEY+(((UWORD)NO_KEY)<<8)) ||
608 ddp 101
                        (kbmap_get(0x11,0).tw == (UWORD)NO_KEY+(((UWORD)NO_KEY)<<8)) ||
299 chrv 102
                        (kbmap_get(0x11,1).tw == (UWORD)NO_KEY+(((UWORD)NO_KEY)<<8)) )
219 chrv 103
                {
104
                        //not mapped
685 lvd 105
                        kb_ctrl_status &= ~KB_CTRL_ALT_DEL_MAPPED_MASK;
219 chrv 106
                }
107
                else
108
                {
109
                        //mapped
685 lvd 110
                        kb_ctrl_status |= KB_CTRL_ALT_DEL_MAPPED_MASK;
219 chrv 111
                }
685 lvd 112
                */
8 lvd 113
        }
114
        else /*if(operation==ZX_TASK_WORK)*/
115
 
116
        // из фифы приходит: нажатия и отжатия ресетов, нажатия и отжатия кнопков, CLRKYS (только нажание).
117
        // задача: упдейтить в соответствии с этим битмап кнопок, посылать его в фпгу, посылать ресеты.
118
        // кроме того, делать паузу в упдейте битмапа и посылке его в фпга между нажатием CS|SS и последующей не-CS|SS кнопки,
119
        // равно как и между отжатием не-CS|SS кнопки и последующим отжатием CS|SS.
120
 
121
        // сначала делаем тупо без никаких пауз - чтобы работало вообще с фифой
122
 
123
        {
437 chrv 124
                //check and set/reset NMI
125
                if( (flags_ex_register&FLAG_EX_NMI)==0 )
126
                {
127
                        if ( ( NMI_PIN & (1<<NMI) ) == 0 )
128
                        {
129
                                //NMI button pressed
130
                                flags_ex_register |= FLAG_EX_NMI; //set flag
131
                                zx_set_config(0); //set NMI to Z80
132
                        }
133
                }
134
                else
135
                {
136
                        if ( ( NMI_PIN & (1<<NMI) ) != 0 )
137
                        {
138
                                //NMI button pressed
139
                                flags_ex_register &= ~FLAG_EX_NMI; //reset flag
140
                                zx_set_config(0); //reset NMI to Z80
141
                        }
142
                }
143
 
144
 
8 lvd 145
                if( !task_state )
146
                {
147
                        nSPICS_PORT |= (1<<nSPICS);
148
 
149
                        was_data = 0;
150
 
151
                        while( !zx_fifo_isempty() )
152
                        {
12 lvd 153
                                code=zx_fifo_copy(); // don't remove byte from fifo!
8 lvd 154
 
155
                                if( code==CLRKYS )
156
                                {
12 lvd 157
                                        was_data = 1; // we've got something!
158
 
159
                                        zx_fifo_get(); // remove byte from fifo
160
 
644 ddp 161
                                        //reset_type = 0;
8 lvd 162
                                        prev_code  = KEY_V+1;
163
 
11 lvd 164
                                        zx_clr_kb();
8 lvd 165
 
166
                                        break; // flush changes immediately to the fpga
167
                                }
219 chrv 168
//                              else if( (code&KEY_MASK) >= RSTSYS )
169
//                              {
170
//                                      was_data = 1; // we've got something!
12 lvd 171
 
219 chrv 172
//                                      zx_fifo_get(); // remove byte from fifo
12 lvd 173
 
219 chrv 174
//                                      if( code&PRESS_MASK ) // reset key pressed
175
//                                      {
176
//                                              reset_type      = 0x30 & ((code+1)<<4);
177
//                                              reset_type += 2;
8 lvd 178
 
219 chrv 179
//                                              break; // flush immediately
180
//                                      }
181
//                                      else // reset key released
182
//                                      {
183
//                                              reset_type = 0;
184
//                                      }
185
//                              }
8 lvd 186
                                else /*if( (code&KEY_MASK) < 40 )*/
187
                                {
12 lvd 188
                                        if( shift_pause ) // if we inside pause interval and need checking
189
                                        {
190
                                                if( (PRESS_MASK&prev_code) && (PRESS_MASK&code) )
191
                                                {
115 ddp 192
                                                        if( /* prev key was CS|SS down */
12 lvd 193
                                                                ( (PRESS_MASK|KEY_CS)<=prev_code && prev_code<=(PRESS_MASK|KEY_SS) ) &&
194
                                                                /* curr key is not-CS|SS down */
195
                                                                ( code<(PRESS_MASK|KEY_CS) || (PRESS_MASK|KEY_SS)<code )
196
                                                        )
197
                                                                break; // while loop
198
                                                }
199
 
200
                                                if( (!(PRESS_MASK&prev_code)) && (!(PRESS_MASK&code)) )
201
                                                {
115 ddp 202
                                                        if( /* prev key was not-CS|SS up */
12 lvd 203
                                                                ( prev_code<KEY_CS || KEY_SS<prev_code ) &&
204
                                                                /* curr key is CS|SS up */
205
                                                                ( KEY_CS<=prev_code && prev_code<=KEY_SS )
206
                                                        )
207
                                                                break;
208
                                                }
209
                                        }
210
 
211
                                        // just normal processing out of pause interval
8 lvd 212
                                        keynum = (code&KEY_MASK)>>3;
213
 
214
                                        keybit = 0x0080 >> (code&7); // KEY_MASK - надмножество битов 7
215
 
216
                                        if( code&PRESS_MASK )
115 ddp 217
                                                zx_map[keynum] |=       keybit;
8 lvd 218
                                        else
219
                                                zx_map[keynum] &= (~keybit);
11 lvd 220
 
12 lvd 221
                                        prev_code = code;
222
                                        zx_fifo_get();
223
                                        shift_pause = SHIFT_PAUSE; // init wait timer
11 lvd 224
 
12 lvd 225
                                        was_data = 1;
8 lvd 226
                                }
536 chrv 227
                        }//while( !zx_fifo_isempty() )
8 lvd 228
 
117 ddp 229
                        if ( zx_realkbd[10] )
115 ddp 230
                        {
119 ddp 231
                                for (UBYTE i=0; i<5; i++)
115 ddp 232
                                {
119 ddp 233
                                         UBYTE tmp;
234
                                         tmp = zx_realkbd[i+5];
235
                                         was_data |= zx_realkbd[i] ^ tmp;
236
                                         zx_realkbd[i] = tmp;
115 ddp 237
                                }
117 ddp 238
                                zx_realkbd[10] = 0;
115 ddp 239
                        }
240
 
8 lvd 241
                        if( was_data ) // initialize transfer
242
                        {
219 chrv 243
                                task_state = 6;
8 lvd 244
                        }
245
                }
246
                else // sending bytes one by one in each state
247
                {
248
                        task_state--;
70 lvd 249
#ifdef LOGENABLE
250
        char log_task_state[] = "TS..\r\n";
251
        log_task_state[2] = ((task_state >> 4) <= 9 )?'0'+(task_state >> 4):'A'+(task_state >> 4)-10;
252
        log_task_state[3] = ((task_state & 0x0F) <= 9 )?'0'+(task_state & 0x0F):'A'+(task_state & 0x0F)-10;
253
        to_log(log_task_state);
254
#endif
8 lvd 255
 
219 chrv 256
//                      if( task_state==6 ) // send (or not) reset
257
//                      {
258
//                              if( reset_type )
259
//                              {
260
//                                      zx_spi_send(SPI_RST_REG, reset_type, 0x7F);
261
//#ifdef LOGENABLE
262
//      char log_reset_type[] = "TR..\r\n";
263
//      log_reset_type[2] = ((reset_type >> 4) <= 9 )?'0'+(reset_type >> 4):'A'+(reset_type >> 4)-10;
264
//      log_reset_type[3] = ((reset_type & 0x0F) <= 9 )?'0'+(reset_type & 0x0F):'A'+(reset_type & 0x0F)-10;
265
//      to_log(log_reset_type);
266
//#endif
267
//                              }
268
//                      }
269
//                      else
270
                        if( task_state>0 )// task_state==5..1
8 lvd 271
                        {
117 ddp 272
                                UBYTE key_data;
273
                                key_data = zx_map[task_state-1] | ~zx_realkbd[task_state-1];
274
                                zx_spi_send(SPI_KBD_DAT, key_data, 0x7F);
70 lvd 275
#ifdef LOGENABLE
151 chrv 276
        char log_zxmap_task_state[] = "TK.. .. ..\r\n";
117 ddp 277
        log_zxmap_task_state[2] = ((key_data >> 4) <= 9 )?'0'+(key_data >> 4):'A'+(key_data >> 4)-10;
278
        log_zxmap_task_state[3] = ((key_data & 0x0F) <= 9 )?'0'+(key_data & 0x0F):'A'+(key_data & 0x0F)-10;
151 chrv 279
        log_zxmap_task_state[5] = ((zx_map[task_state-1] >> 4) <= 9 )?'0'+(zx_map[task_state-1] >> 4):'A'+(zx_map[task_state-1] >> 4)-10;
280
        log_zxmap_task_state[6] = ((zx_map[task_state-1] & 0x0F) <= 9 )?'0'+(zx_map[task_state-1] & 0x0F):'A'+(zx_map[task_state-1] & 0x0F)-10;
281
        log_zxmap_task_state[8] = ((zx_realkbd[task_state-1] >> 4) <= 9 )?'0'+(zx_realkbd[task_state-1] >> 4):'A'+(zx_realkbd[task_state-1] >> 4)-10;
282
        log_zxmap_task_state[9] = ((zx_realkbd[task_state-1] & 0x0F) <= 9 )?'0'+(zx_realkbd[task_state-1] & 0x0F):'A'+(zx_realkbd[task_state-1] & 0x0F)-10;
70 lvd 283
        to_log(log_zxmap_task_state);
284
#endif
8 lvd 285
                        }
67 lvd 286
                        else // task_state==0
8 lvd 287
                        {
94 chrv 288
                                UBYTE status;
67 lvd 289
                                nSPICS_PORT |= (1<<nSPICS);
94 chrv 290
                                status = spi_send(SPI_KBD_STB);    // strobe input kbd data to the Z80 port engine
8 lvd 291
                                nSPICS_PORT &= ~(1<<nSPICS);
67 lvd 292
                                nSPICS_PORT |= (1<<nSPICS);
94 chrv 293
                                if ( status&0x7F ) zx_wait_task(status);
70 lvd 294
#ifdef LOGENABLE
295
        to_log("STB\r\n");
296
#endif
8 lvd 297
                        }
298
                }
299
        }
300
 
11 lvd 301
}
8 lvd 302
 
11 lvd 303
void zx_clr_kb(void)
304
{
667 chrv 305
        UBYTE i;
6 lvd 306
 
151 chrv 307
        for( i=0; i<sizeof(zx_map)/sizeof(zx_map[0]); i++ )
308
        {
11 lvd 309
                zx_map[i] = 0;
151 chrv 310
        }
6 lvd 311
 
151 chrv 312
        for( i=0; i<sizeof(zx_realkbd)/sizeof(zx_realkbd[0]); i++ )
313
        {
115 ddp 314
                zx_realkbd[i] = 0xff;
151 chrv 315
        }
6 lvd 316
 
151 chrv 317
        for( i=0; i<sizeof(zx_counters)/sizeof(zx_counters[0]); i++ )
318
        {
11 lvd 319
                zx_counters[i] = 0;
151 chrv 320
        }
219 chrv 321
 
685 lvd 322
        kb_ctrl_status = 0;
11 lvd 323
}
6 lvd 324
 
325
void to_zx(UBYTE scancode, UBYTE was_E0, UBYTE was_release)
326
{
299 chrv 327
        KBMAP_VALUE t;
6 lvd 328
 
299 chrv 329
        //F7 code (0x83) converted to 0x7F
330
        if( !was_E0 && (scancode == 0x83) ) scancode = 0x7F;
6 lvd 331
 
299 chrv 332
        //get zx map values
333
        t = kbmap_get(scancode,was_E0);
334
 
6 lvd 335
        if( was_E0 )
336
        {
219 chrv 337
                //additional functionality from ps/2 keyboard
338
                switch( scancode )
163 chrv 339
                {
685 lvd 340
                        //Right Alt (Alt Gr)
608 ddp 341
                        case  0x11:
685 lvd 342
                                if ( !was_release ) kb_ctrl_status |= KB_RALT_MASK;
343
                                else kb_ctrl_status &= ~KB_RALT_MASK;
299 chrv 344
                                break;
685 lvd 345
                        //Right Ctrl
346
                        case  0x14:
347
                                if ( !was_release ) kb_ctrl_status |= KB_RCTRL_MASK;
348
                                else kb_ctrl_status &= ~KB_RCTRL_MASK;
349
                                break;
219 chrv 350
                        //Print Screen
351
                        case 0x7C:
352
                                //set/reset NMI
437 chrv 353
                                if( ((flags_ex_register&FLAG_EX_NMI)==0 ) && (was_release==0) )
354
                                {
355
                                        flags_ex_register |= FLAG_EX_NMI; //set flag
356
                                        zx_set_config(0); //set NMI to Z80
357
                                }
358
                                else if( ((flags_ex_register&FLAG_EX_NMI)!=0 ) && (was_release!=0) )
359
                                {
360
                                        flags_ex_register &= ~FLAG_EX_NMI; //reset flag
361
                                        zx_set_config( 0 ); //reset NMI to Z80
362
                                }
219 chrv 363
                                break;
364
                        //Del
365
                        case 0x71:
366
                                //Ctrl-Alt-Del pressed
367
                                if ( ( !was_release ) &&
685 lvd 368
                                         /*( !(kb_status & KB_CTRL_ALT_DEL_MAPPED_MASK) ) &&*/
369
                                         ( (kb_ctrl_status&(~kb_ctrl_mapped)&(KB_LCTRL_MASK|KB_RCTRL_MASK)) !=0 ) &&
370
                                         ( (kb_ctrl_status&(~kb_ctrl_mapped)&(KB_LALT_MASK|KB_RALT_MASK)) !=0 ) )
219 chrv 371
                                {
372
                                        //hard reset
373
                                        flags_register |= FLAG_HARD_RESET;
644 ddp 374
                                        t.tb.b2=t.tb.b1=NO_KEY;
219 chrv 375
                                }
376
                                break;
299 chrv 377
                }//switch
6 lvd 378
        }
379
        else
380
        {
219 chrv 381
                //additional functionality from ps/2 keyboard
382
                switch( scancode )
383
                {
384
                        //Scroll Lock
385
                        case 0x7E:
386
                                //check key of vga mode switcher
615 ddp 387
                                if ( !was_release )
388
                                {
686 lvd 389
                                        UBYTE m = modes_register | (~MODE_VIDEO_MASK);
390
                                        m++; // increment bits not ORed with 1
391
 
392
                                        m ^= modes_register;
393
                                        m &= MODE_VIDEO_MASK; // prepare modes change mask for zx_mode_switcher()
394
 
395
                                        zx_mode_switcher(m);
396
 
397
                                        /*if (kb_ctrl_status & (KB_LSHIFT_MASK | KB_RSHIFT_MASK))
641 ddp 398
                                        {
399
                                                UBYTE m=~modes_register&MODE_60HZ;
400
                                                if (m==0) m|=MODE_VGA;
401
                                                zx_mode_switcher(m);
402
                                        }
621 ddp 403
                                        else
641 ddp 404
                                        {
405
                                                UBYTE m=modes_register&MODE_60HZ;
406
                                                if (m==0) m|=MODE_VGA;
407
                                                zx_mode_switcher(m);
686 lvd 408
                                        }*/
615 ddp 409
                                }
219 chrv 410
                                break;
292 chrv 411
                        //Num Lock
412
                        case 0x77:
413
                                //check key of tapeout mode switcher
414
                                if ( !was_release ) zx_mode_switcher(MODE_TAPEOUT);
415
                                break;
608 ddp 416
                        //Left Shift
417
                        case  0x12:
685 lvd 418
                                if ( !was_release ) kb_ctrl_status |= KB_LSHIFT_MASK;
419
                                else kb_ctrl_status &= ~KB_LSHIFT_MASK;
219 chrv 420
                                break;
608 ddp 421
                        //Right Shift
422
                        case  0x59:
685 lvd 423
                                if ( !was_release ) kb_ctrl_status |= KB_RSHIFT_MASK;
424
                                else kb_ctrl_status &= ~KB_RSHIFT_MASK;
219 chrv 425
                                break;
615 ddp 426
                        //Left Ctrl
608 ddp 427
                        case  0x14:
685 lvd 428
                                if ( !was_release ) kb_ctrl_status |= KB_LCTRL_MASK;
429
                                else kb_ctrl_status &= ~KB_LCTRL_MASK;
219 chrv 430
                                break;
615 ddp 431
                        //Left Alt
608 ddp 432
                        case  0x11:
685 lvd 433
                                if ( !was_release ) kb_ctrl_status |= KB_LALT_MASK;
434
                                else kb_ctrl_status &= ~KB_LALT_MASK;
219 chrv 435
                                break;
436
                        //F12
437
                        case  0x07:
685 lvd 438
                                if ( !was_release ) kb_ctrl_status |= KB_F12_MASK;
439
                                else kb_ctrl_status &= ~KB_F12_MASK;
219 chrv 440
                                break;
299 chrv 441
                        //keypad '+','-','*' - set ps2mouse resolution
442
                        case  0x79:
443
                        case  0x7B:
444
                        case  0x7C:
445
                                if ( !was_release ) ps2mouse_set_resolution(scancode);
446
                                break;
447
                }//switch
6 lvd 448
        }
449
 
299 chrv 450
        if( t.tb.b1!=NO_KEY )
6 lvd 451
        {
299 chrv 452
                update_keys(t.tb.b1,was_release);
6 lvd 453
 
299 chrv 454
                if( t.tb.b2!=NO_KEY ) update_keys(t.tb.b2,was_release);
6 lvd 455
        }
456
}
457
 
458
void update_keys(UBYTE zxcode, UBYTE was_release)
459
{
667 chrv 460
        if( zxcode!=NO_KEY )
6 lvd 461
        {
667 chrv 462
                BYTE i;
6 lvd 463
 
667 chrv 464
                if( (zxcode==CLRKYS) && (!was_release) ) // does not have release option
6 lvd 465
                {
667 chrv 466
                        i=39;
467
                        do zx_counters[i]=0; while( (--i)>=0 );
468
 
469
                        if( !zx_fifo_isfull() )
470
                                zx_fifo_put(CLRKYS);
6 lvd 471
                }
667 chrv 472
        //      else if( zxcode>=RSTSYS ) // resets - press and release
473
        //      {
474
        //              if( !zx_fifo_isfull() )
475
        //                      zx_fifo_put( (was_release ? 0 : PRESS_MASK) | zxcode );
476
        //      }
477
                else if( zxcode < 40 ) // ordinary keys too
6 lvd 478
                {
667 chrv 479
                        if( was_release )
6 lvd 480
                        {
667 chrv 481
                                if( zx_counters[zxcode] && !(--zx_counters[zxcode]) ) // left-to-right evaluation and shortcutting
482
                                {
483
                                        if( !zx_fifo_isfull() )
484
                                                zx_fifo_put(zxcode);
485
                                }
6 lvd 486
                        }
667 chrv 487
                        else // key pressed
488
                        {
489
                                if( !(zx_counters[zxcode]++) )
490
                                {
491
                                        if( !zx_fifo_isfull() )
492
                                                zx_fifo_put( PRESS_MASK | zxcode );
493
                                }
494
                        }
6 lvd 495
                }
496
        }
497
}
498
 
499
void zx_fifo_put(UBYTE input)
500
{
501
        zx_fifo[zx_fifo_in_ptr++] = input;
502
}
503
 
504
UBYTE zx_fifo_isfull(void)
505
{
506
        //always one byte unused, to distinguish between totally full fifo and empty fifo
895 lvd 507
        return( ((UBYTE)(zx_fifo_in_ptr+1))==zx_fifo_out_ptr );
6 lvd 508
}
509
 
510
UBYTE zx_fifo_isempty(void)
511
{
512
        return (zx_fifo_in_ptr==zx_fifo_out_ptr);
513
}
514
 
515
UBYTE zx_fifo_get(void)
516
{
517
        return zx_fifo[zx_fifo_out_ptr++]; // get byte permanently
518
}
519
 
520
UBYTE zx_fifo_copy(void)
521
{
522
        return zx_fifo[zx_fifo_out_ptr]; // get byte but leave it in fifo
523
}
524
 
75 chrv 525
void zx_mouse_reset(UBYTE enable)
71 chrv 526
{
75 chrv 527
        if ( enable )
528
        {
529
                //ZX autodetecting found mouse on this values
530
                zx_mouse_x = 0;
531
                zx_mouse_y = 1;
532
        }
533
        else
534
        {
535
                //ZX autodetecting not found mouse on this values
536
                zx_mouse_y = zx_mouse_x = 0xFF;
537
        }
71 chrv 538
        zx_mouse_button = 0xFF;
126 chrv 539
        flags_register|=(FLAG_PS2MOUSE_ZX_READY);
71 chrv 540
}
541
 
542
void zx_mouse_task(void)
543
{
126 chrv 544
        if ( flags_register&FLAG_PS2MOUSE_ZX_READY )
71 chrv 545
        {
546
#ifdef LOGENABLE
547
        char log_zxmouse[] = "ZXM.. .. ..\r\n";
548
        log_zxmouse[3] = ((zx_mouse_button >> 4) <= 9 )?'0'+(zx_mouse_button >> 4):'A'+(zx_mouse_button >> 4)-10;
549
        log_zxmouse[4] = ((zx_mouse_button & 0x0F) <= 9 )?'0'+(zx_mouse_button & 0x0F):'A'+(zx_mouse_button & 0x0F)-10;
550
        log_zxmouse[6] = ((zx_mouse_x >> 4) <= 9 )?'0'+(zx_mouse_x >> 4):'A'+(zx_mouse_x >> 4)-10;
551
        log_zxmouse[7] = ((zx_mouse_x & 0x0F) <= 9 )?'0'+(zx_mouse_x & 0x0F):'A'+(zx_mouse_x & 0x0F)-10;
552
        log_zxmouse[9] = ((zx_mouse_y >> 4) <= 9 )?'0'+(zx_mouse_y >> 4):'A'+(zx_mouse_y >> 4)-10;
553
        log_zxmouse[10] = ((zx_mouse_y & 0x0F) <= 9 )?'0'+(zx_mouse_y & 0x0F):'A'+(zx_mouse_y & 0x0F)-10;
554
        to_log(log_zxmouse);
555
#endif
556
                //TODO: пока сделал скопом, потом сделать по одному байту за заход
94 chrv 557
                zx_spi_send(SPI_MOUSE_BTN, zx_mouse_button, 0x7F);
71 chrv 558
 
97 lvd 559
                zx_spi_send(SPI_MOUSE_X, zx_mouse_x, 0x7F);
71 chrv 560
 
94 chrv 561
                zx_spi_send(SPI_MOUSE_Y, zx_mouse_y, 0x7F);
71 chrv 562
 
563
                //data sended - reset flag
126 chrv 564
                flags_register&=~(FLAG_PS2MOUSE_ZX_READY);
71 chrv 565
        }
566
}
94 chrv 567
 
568
void zx_wait_task(UBYTE status)
569
{
100 chrv 570
        UBYTE addr = 0;
94 chrv 571
        UBYTE data = 0xFF;
572
 
573
        //reset flag
126 chrv 574
        flags_register &= ~FLAG_SPI_INT;
94 chrv 575
 
576
        //prepare data
577
        switch( status&0x7F )
578
        {
579
        case ZXW_GLUK_CLOCK:
580
                {
581
                        addr = zx_spi_send(SPI_GLUK_ADDR, data, 0);
104 chrv 582
                        if ( status&0x80 ) data = gluk_get_reg(addr);
94 chrv 583
                        break;
584
                }
263 chrv 585
        case ZXW_KONDR_RS232:
586
                {
587
                        addr = zx_spi_send(SPI_RS232_ADDR, data, 0);
588
                        if ( status&0x80 ) data = rs232_zx_read(addr);
589
                        break;
590
                }
94 chrv 591
        }
592
 
100 chrv 593
        if ( status&0x80 ) zx_spi_send(SPI_WAIT_DATA, data, 0);
594
        else data = zx_spi_send(SPI_WAIT_DATA, data, 0);
94 chrv 595
 
596
        if ( !(status&0x80) )
597
        {
598
                //save data
100 chrv 599
                switch( status&0x7F )
600
                {
601
                case ZXW_GLUK_CLOCK:
602
                        {
104 chrv 603
                                gluk_set_reg(addr, data);
100 chrv 604
                                break;
605
                        }
263 chrv 606
                case ZXW_KONDR_RS232:
607
                        {
608
                                rs232_zx_write(addr, data);
609
                                break;
610
                        }
100 chrv 611
                }
94 chrv 612
        }
105 chrv 613
/*#ifdef LOGENABLE
100 chrv 614
        char log_wait[] = "W..A..D..\r\n";
94 chrv 615
        log_wait[1] = ((status >> 4) <= 9 )?'0'+(status >> 4):'A'+(status >> 4)-10;
616
        log_wait[2] = ((status & 0x0F) <= 9 )?'0'+(status & 0x0F):'A'+(status & 0x0F)-10;
617
        log_wait[4] = ((addr >> 4) <= 9 )?'0'+(addr >> 4):'A'+(addr >> 4)-10;
618
        log_wait[5] = ((addr & 0x0F) <= 9 )?'0'+(addr & 0x0F):'A'+(addr & 0x0F)-10;
100 chrv 619
        log_wait[7] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+(data >> 4)-10;
620
        log_wait[8] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+(data & 0x0F)-10;
94 chrv 621
        to_log(log_wait);
115 ddp 622
#endif   */
94 chrv 623
}
100 chrv 624
 
292 chrv 625
void zx_mode_switcher(UBYTE mode)
100 chrv 626
{
292 chrv 627
        //invert mode
628
        modes_register ^= mode;
100 chrv 629
 
163 chrv 630
        //send configuration to FPGA
292 chrv 631
        zx_set_config((flags_register&FLAG_LAST_TAPE_VALUE)?SPI_TAPE_FLAG:0);
126 chrv 632
 
633
        //save mode register to RTC NVRAM
634
        rtc_write(RTC_COMMON_MODE_REG, modes_register);
149 chrv 635
 
636
        //set led on keyboard
637
        ps2keyboard_send_cmd(PS2KEYBOARD_CMD_SETLED);
100 chrv 638
}
163 chrv 639
 
640
void zx_set_config(UBYTE flags)
641
{
642
        //send configuration to FPGA
292 chrv 643
        zx_spi_send(SPI_CONFIG_REG,
608 ddp 644
                (modes_register&MODE_VIDEO_MASK) |
292 chrv 645
                ((modes_register&MODE_TAPEOUT)?SPI_TAPEOUT_MODE_FLAG:0) |
437 chrv 646
                ((flags_ex_register&FLAG_EX_NMI)?SPI_CONFIG_NMI_FLAG:0) |
608 ddp 647
                (flags & ~(MODE_VIDEO_MASK|SPI_TAPEOUT_MODE_FLAG|SPI_CONFIG_NMI_FLAG)),
292 chrv 648
                0x7F);
163 chrv 649
}