BASIC compiler/interpreter for PIC32MX/MZ-80K
Revision | ede891a3c45c56aaec7b1652ea1506d40d6c9446 (tree) |
---|---|
Zeit | 2019-05-03 09:12:02 |
Autor | Katsumi <kmorimatsu@sour...> |
Commiter | Katsumi |
Zoea/Protozoea: Revise KEYS/INKEY interruptions. Add READKEY() function. Revise help.txt
@@ -125,6 +125,7 @@ enum libs{ | ||
125 | 125 | LIB_SETDIR =LIB_STEP*51, |
126 | 126 | LIB_SETDIRFUNC =LIB_STEP*52, |
127 | 127 | LIB_GETDIR =LIB_STEP*53, |
128 | + LIB_READKEY =LIB_STEP*54, | |
128 | 129 | LIB_DEBUG =LIB_STEP*127, |
129 | 130 | }; |
130 | 131 |
@@ -516,6 +517,10 @@ extern int g_int_vector[]; | ||
516 | 517 | // Valid for 31 bits for all cases and 32 bits for some cases |
517 | 518 | #define div32(x,y,z) ((((unsigned long long)((unsigned long)(x)))*((unsigned long long)((unsigned long)(y))))>>(z)) |
518 | 519 | |
520 | +// Divide by 8 (valid for 32 bits) | |
521 | +#define div8_32(x) (((unsigned long)(x))>>3) | |
522 | +#define rem8_32(x) ((x)&0x07) | |
523 | + | |
519 | 524 | // Divide by 9 (valid for 32 bits) |
520 | 525 | #define div9_32(x) div32(x,0xe38e38e4,35) |
521 | 526 | #define rem9_32(x) ((x)-9*div9_32(x)) |
@@ -395,6 +395,11 @@ char* exec_function(){ | ||
395 | 395 | return exec_statement(); |
396 | 396 | } |
397 | 397 | |
398 | +char* readkey_function(){ | |
399 | + call_lib_code(LIB_READKEY); | |
400 | + return 0; | |
401 | +} | |
402 | + | |
398 | 403 | char* float_constant(float val){ |
399 | 404 | volatile int i; |
400 | 405 | ((float*)(&i))[0]=val; |
@@ -603,6 +608,7 @@ static const void* int_func_list[]={ | ||
603 | 608 | "TIMER(",timer_function, |
604 | 609 | "EXEC(",exec_function, |
605 | 610 | "CORETIMER(",coretimer_function, |
611 | + "READKEY(",readkey_function, | |
606 | 612 | // Additional functions follow |
607 | 613 | ADDITIONAL_INT_FUNCTIONS |
608 | 614 | }; |
@@ -227,6 +227,13 @@ PLAYWAVE([x]) | ||
227 | 227 | READ() |
228 | 228 | DATA文の後から、一つずつデーター(32ビット整数値)を読み出す。「CREAD()」 |
229 | 229 | 関数も参照。 |
230 | +READKEY() | |
231 | + キーボードバッファーから一文字読み込み、返す。バッファーが空の時は0を返す。 | |
232 | + 戻り値は24ビット整数で、内容は以下の通り。 | |
233 | + bits 0-7 : ASCII コード | |
234 | + bits 8-15 : 仮想キーコード | |
235 | + bits 16-23 : シフトキー押下状態。 | |
236 | + 上位から<0><CAPSLK><NUMLK><SCRLK><Win><ALT><CTRL><SHIFT>。 | |
230 | 237 | RND() |
231 | 238 | 0から32767までの擬似乱数を返す。 |
232 | 239 | SGN(x) |
@@ -561,7 +568,7 @@ INTERRUPT xxx,yyy[,z1[,z2 ... ]] | ||
561 | 568 | KEYS |
562 | 569 | ボタンの押下状態が変化した時。 |
563 | 570 | INKEY |
564 | - キーボード押下時。 | |
571 | + キーボード押下時。READKEY()関数と組み合わせて使う。 | |
565 | 572 | MUSIC |
566 | 573 | 音楽再生の時、最後の音の再生時に割り込み。 |
567 | 574 | WAVE |
@@ -176,3 +176,5 @@ unsigned char ps2readkey(); | ||
176 | 176 | #define buttonmode() (0) |
177 | 177 | //#define inPS2MODE() ((LATA&2)>>1) // モード確認用マクロ。PS/2モードの場合1、ボタンモードの場合0を返す |
178 | 178 | #define inPS2MODE() (0) |
179 | +//#define keycodeExists() (keycodebufp1!=keycodebufp2) | |
180 | +#define keycodeExists() (0) |
@@ -943,6 +943,11 @@ int lib_file(enum functions func, int a0, int a1, int v0){ | ||
943 | 943 | return v0; |
944 | 944 | } |
945 | 945 | |
946 | +int lib_readkey(){ | |
947 | + int ret=ps2readkey(); | |
948 | + return ret|(vkey<<8); | |
949 | +} | |
950 | + | |
946 | 951 | int _call_library(int a0,int a1,int a2,enum libs a3); |
947 | 952 | |
948 | 953 | void call_library(void){ |
@@ -1011,6 +1016,8 @@ int _call_library(int a0,int a1,int v0,enum libs a3){ | ||
1011 | 1016 | return lib_keys(v0); |
1012 | 1017 | case LIB_INKEY: |
1013 | 1018 | return (int)lib_inkey(v0); |
1019 | + case LIB_READKEY: | |
1020 | + return lib_readkey(); | |
1014 | 1021 | case LIB_CURSOR: |
1015 | 1022 | setcursor(g_libparams[1],v0,cursorcolor); |
1016 | 1023 | return v0; |
@@ -42,6 +42,9 @@ int g_interrupt_flags; | ||
42 | 42 | // Jump address when interrupt |
43 | 43 | int g_int_vector[NUM_INTERRUPT_TYPES]; |
44 | 44 | |
45 | +// Current button status | |
46 | +static int g_keys_interrupt; | |
47 | + | |
45 | 48 | /* |
46 | 49 | Initialize and termination |
47 | 50 | */ |
@@ -56,6 +59,7 @@ void init_timer(){ | ||
56 | 59 | g_timer=0; |
57 | 60 | // Disable interrupt |
58 | 61 | IEC0bits.CS1IE=0; |
62 | + IFS0bits.CS1IF=0; | |
59 | 63 | for(i=0;i<NUM_INTERRUPT_TYPES;i++) g_int_vector[i]=0; |
60 | 64 | // CS0 interrupt every 1/60 sec (triggered by Timer2) |
61 | 65 | IPC0bits.CS0IP=3; |
@@ -69,6 +73,8 @@ void init_timer(){ | ||
69 | 73 | asm volatile("ins $t0,$zero,1,15"); |
70 | 74 | asm volatile("mtc0 $t0,$12,0"); |
71 | 75 | asm volatile("ei"); |
76 | + // The other initialization(s) | |
77 | + g_keys_interrupt=-1; | |
72 | 78 | } |
73 | 79 | |
74 | 80 | void stop_timer(){ |
@@ -330,9 +336,7 @@ const int* g_keystatus=(int*)&ps2keystatus[0]; | ||
330 | 336 | |
331 | 337 | #pragma interrupt CS0Handler IPL3SOFT vector 1 |
332 | 338 | void CS0Handler(void){ |
333 | - static int s_keys=-1; | |
334 | - static char s_inkey=0; | |
335 | - int i; | |
339 | + int keys; | |
336 | 340 | IFS0bits.CS0IF=0; |
337 | 341 | // Call music function |
338 | 342 | if (g_music_active) musicint(); |
@@ -341,21 +345,21 @@ void CS0Handler(void){ | ||
341 | 345 | // Raise DRAWCOUNT interrupt flag |
342 | 346 | raise_interrupt_flag(INTERRUPT_DRAWCOUNT); |
343 | 347 | // Check buttons |
344 | - if (0<=s_keys && s_keys!=(KEYPORT&(KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE))) { | |
348 | + if (inPS2MODE()) { | |
349 | + keys=readbuttons(); | |
350 | + ps2mode(); | |
351 | + } else { | |
352 | + keys=readbuttons(); | |
353 | + } | |
354 | + keys=keys & (KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE); | |
355 | + if (0<=g_keys_interrupt && g_keys_interrupt!=keys) { | |
345 | 356 | // Raise KEYS interrupt flag |
346 | 357 | raise_interrupt_flag(INTERRUPT_KEYS); |
347 | 358 | } |
348 | - s_keys=KEYPORT&(KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE); | |
349 | - // Check PS/2 keyboard down | |
359 | + g_keys_interrupt=keys; | |
360 | + // Check PS/2 keyboard input | |
350 | 361 | if (g_int_vector[INTERRUPT_INKEY]) { |
351 | - for(i=0;i<64;i++){ | |
352 | - if (g_keystatus[i]) { | |
353 | - // Raise INKEY interrupt flag | |
354 | - if (!s_inkey) raise_interrupt_flag(INTERRUPT_INKEY); | |
355 | - break; | |
356 | - } | |
357 | - } | |
358 | - s_inkey=(i==64) ? 0:1; | |
362 | + if (keycodeExists()) raise_interrupt_flag(INTERRUPT_INKEY); | |
359 | 363 | } |
360 | 364 | } |
361 | 365 | } |
@@ -125,6 +125,7 @@ enum libs{ | ||
125 | 125 | LIB_SETDIR =LIB_STEP*51, |
126 | 126 | LIB_SETDIRFUNC =LIB_STEP*52, |
127 | 127 | LIB_GETDIR =LIB_STEP*53, |
128 | + LIB_READKEY =LIB_STEP*54, | |
128 | 129 | LIB_DEBUG =LIB_STEP*127, |
129 | 130 | }; |
130 | 131 |
@@ -516,6 +517,10 @@ extern int g_int_vector[]; | ||
516 | 517 | // Valid for 31 bits for all cases and 32 bits for some cases |
517 | 518 | #define div32(x,y,z) ((((unsigned long long)((unsigned long)(x)))*((unsigned long long)((unsigned long)(y))))>>(z)) |
518 | 519 | |
520 | +// Divide by 8 (valid for 32 bits) | |
521 | +#define div8_32(x) (((unsigned long)(x))>>3) | |
522 | +#define rem8_32(x) ((x)&0x07) | |
523 | + | |
519 | 524 | // Divide by 9 (valid for 32 bits) |
520 | 525 | #define div9_32(x) div32(x,0xe38e38e4,35) |
521 | 526 | #define rem9_32(x) ((x)-9*div9_32(x)) |
@@ -395,6 +395,11 @@ char* exec_function(){ | ||
395 | 395 | return exec_statement(); |
396 | 396 | } |
397 | 397 | |
398 | +char* readkey_function(){ | |
399 | + call_lib_code(LIB_READKEY); | |
400 | + return 0; | |
401 | +} | |
402 | + | |
398 | 403 | char* float_constant(float val){ |
399 | 404 | volatile int i; |
400 | 405 | ((float*)(&i))[0]=val; |
@@ -603,6 +608,7 @@ static const void* int_func_list[]={ | ||
603 | 608 | "TIMER(",timer_function, |
604 | 609 | "EXEC(",exec_function, |
605 | 610 | "CORETIMER(",coretimer_function, |
611 | + "READKEY(",readkey_function, | |
606 | 612 | // Additional functions follow |
607 | 613 | ADDITIONAL_INT_FUNCTIONS |
608 | 614 | }; |
@@ -227,6 +227,13 @@ PLAYWAVE([x]) | ||
227 | 227 | READ() |
228 | 228 | DATA文の後から、一つずつデーター(32ビット整数値)を読み出す。「CREAD()」 |
229 | 229 | 関数も参照。 |
230 | +READKEY() | |
231 | + キーボードバッファーから一文字読み込み、返す。バッファーが空の時は0を返す。 | |
232 | + 戻り値は24ビット整数で、内容は以下の通り。 | |
233 | + bits 0-7 : ASCII コード | |
234 | + bits 8-15 : 仮想キーコード | |
235 | + bits 16-23 : シフトキー押下状態。 | |
236 | + 上位から<0><CAPSLK><NUMLK><SCRLK><Win><ALT><CTRL><SHIFT>。 | |
230 | 237 | RND() |
231 | 238 | 0から32767までの擬似乱数を返す。 |
232 | 239 | SGN(x) |
@@ -561,7 +568,7 @@ INTERRUPT xxx,yyy[,z1[,z2 ... ]] | ||
561 | 568 | KEYS |
562 | 569 | ボタンの押下状態が変化した時。 |
563 | 570 | INKEY |
564 | - キーボード押下時。 | |
571 | + キーボード押下時。READKEY()関数と組み合わせて使う。 | |
565 | 572 | MUSIC |
566 | 573 | 音楽再生の時、最後の音の再生時に割り込み。 |
567 | 574 | WAVE |
@@ -858,6 +865,8 @@ ON GOTO分やON GOSUB文はサポートしていません。ただし、例え | ||
858 | 865 | ・割り込み機能(INTERRUPTステートメント)を追加。 |
859 | 866 | ・オプション機能(OPTIONステートメント)を追加。 |
860 | 867 | ・アイドル機能(IDLEステートメント)を追加。 |
868 | + ・READKEY()関数を追加。 | |
869 | + ・EXEC()関数を追加。 | |
861 | 870 | ・KM-1207 2019年3月公開。 |
862 | 871 | ・PUTBMPの第5引数に長い名前の変数が使えなかったバグの修正 |
863 | 872 | ・オブジェクト指向プログラミングに対応 |
@@ -172,3 +172,8 @@ unsigned char ps2readkey(); | ||
172 | 172 | void ps2mode(); // PS/2を有効にする |
173 | 173 | void buttonmode(); // ボタンを有効にする |
174 | 174 | #define inPS2MODE() ((LATA&2)>>1) // モード確認用マクロ。PS/2モードの場合1、ボタンモードの場合0を返す |
175 | + | |
176 | +// Macro(s) follows(s) | |
177 | +extern unsigned short * volatile keycodebufp1; //キーコード書き込み先頭ポインタ | |
178 | +extern unsigned short * volatile keycodebufp2; //キーコード読み出し先頭ポインタ | |
179 | +#define keycodeExists() (keycodebufp1!=keycodebufp2) |
@@ -943,6 +943,11 @@ int lib_file(enum functions func, int a0, int a1, int v0){ | ||
943 | 943 | return v0; |
944 | 944 | } |
945 | 945 | |
946 | +int lib_readkey(){ | |
947 | + int ret=ps2readkey(); | |
948 | + return ret|(vkey<<8); | |
949 | +} | |
950 | + | |
946 | 951 | int _call_library(int a0,int a1,int a2,enum libs a3); |
947 | 952 | |
948 | 953 | void call_library(void){ |
@@ -1011,6 +1016,8 @@ int _call_library(int a0,int a1,int v0,enum libs a3){ | ||
1011 | 1016 | return lib_keys(v0); |
1012 | 1017 | case LIB_INKEY: |
1013 | 1018 | return (int)lib_inkey(v0); |
1019 | + case LIB_READKEY: | |
1020 | + return lib_readkey(); | |
1014 | 1021 | case LIB_CURSOR: |
1015 | 1022 | setcursor(g_libparams[1],v0,cursorcolor); |
1016 | 1023 | return v0; |
@@ -42,6 +42,9 @@ int g_interrupt_flags; | ||
42 | 42 | // Jump address when interrupt |
43 | 43 | int g_int_vector[NUM_INTERRUPT_TYPES]; |
44 | 44 | |
45 | +// Current button status | |
46 | +static int g_keys_interrupt; | |
47 | + | |
45 | 48 | /* |
46 | 49 | Initialize and termination |
47 | 50 | */ |
@@ -56,6 +59,7 @@ void init_timer(){ | ||
56 | 59 | g_timer=0; |
57 | 60 | // Disable interrupt |
58 | 61 | IEC0bits.CS1IE=0; |
62 | + IFS0bits.CS1IF=0; | |
59 | 63 | for(i=0;i<NUM_INTERRUPT_TYPES;i++) g_int_vector[i]=0; |
60 | 64 | // CS0 interrupt every 1/60 sec (triggered by Timer2) |
61 | 65 | IPC0bits.CS0IP=3; |
@@ -69,6 +73,8 @@ void init_timer(){ | ||
69 | 73 | asm volatile("ins $t0,$zero,1,15"); |
70 | 74 | asm volatile("mtc0 $t0,$12,0"); |
71 | 75 | asm volatile("ei"); |
76 | + // The other initialization(s) | |
77 | + g_keys_interrupt=-1; | |
72 | 78 | } |
73 | 79 | |
74 | 80 | void stop_timer(){ |
@@ -330,9 +336,7 @@ const int* g_keystatus=(int*)&ps2keystatus[0]; | ||
330 | 336 | |
331 | 337 | #pragma interrupt CS0Handler IPL3SOFT vector 1 |
332 | 338 | void CS0Handler(void){ |
333 | - static int s_keys=-1; | |
334 | - static char s_inkey=0; | |
335 | - int i; | |
339 | + int keys; | |
336 | 340 | IFS0bits.CS0IF=0; |
337 | 341 | // Call music function |
338 | 342 | if (g_music_active) musicint(); |
@@ -341,21 +345,21 @@ void CS0Handler(void){ | ||
341 | 345 | // Raise DRAWCOUNT interrupt flag |
342 | 346 | raise_interrupt_flag(INTERRUPT_DRAWCOUNT); |
343 | 347 | // Check buttons |
344 | - if (0<=s_keys && s_keys!=(KEYPORT&(KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE))) { | |
348 | + if (inPS2MODE()) { | |
349 | + keys=readbuttons(); | |
350 | + ps2mode(); | |
351 | + } else { | |
352 | + keys=readbuttons(); | |
353 | + } | |
354 | + keys=keys & (KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE); | |
355 | + if (0<=g_keys_interrupt && g_keys_interrupt!=keys) { | |
345 | 356 | // Raise KEYS interrupt flag |
346 | 357 | raise_interrupt_flag(INTERRUPT_KEYS); |
347 | 358 | } |
348 | - s_keys=KEYPORT&(KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE); | |
349 | - // Check PS/2 keyboard down | |
359 | + g_keys_interrupt=keys; | |
360 | + // Check PS/2 keyboard input | |
350 | 361 | if (g_int_vector[INTERRUPT_INKEY]) { |
351 | - for(i=0;i<64;i++){ | |
352 | - if (g_keystatus[i]) { | |
353 | - // Raise INKEY interrupt flag | |
354 | - if (!s_inkey) raise_interrupt_flag(INTERRUPT_INKEY); | |
355 | - break; | |
356 | - } | |
357 | - } | |
358 | - s_inkey=(i==64) ? 0:1; | |
362 | + if (keycodeExists()) raise_interrupt_flag(INTERRUPT_INKEY); | |
359 | 363 | } |
360 | 364 | } |
361 | 365 | } |