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 | } |