BASIC compiler/interpreter for PIC32MX/MZ-80K
Revisión | ecd98af46c768fc708c2a7f059ed692bc57d95e5 (tree) |
---|---|
Tiempo | 2019-05-03 07:17:04 |
Autor | Katsumi <kmorimatsu@sour...> |
Commiter | Katsumi |
Revise KEYS/INKEY interruptions. Add READKEY() function. Debug using comma in PRINT statement. 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)) |
@@ -11,6 +11,32 @@ | ||
11 | 11 | #include "api.h" |
12 | 12 | |
13 | 13 | /* |
14 | + void printcomma(); | |
15 | + 30, 36, 40, 48, 64, 80 characters per line for Megalopa | |
16 | +*/ | |
17 | + | |
18 | +void printcomma(void){ | |
19 | + switch(textmode){ | |
20 | + case TMODE_STDTEXT: // 36 | |
21 | + // Every 9 characters | |
22 | + printstr(" "+rem9_32((unsigned int)(cursor-TVRAM))); | |
23 | + break; | |
24 | + case TMODE_WIDETEXT: // 48 | |
25 | + case TMODE_WIDETEXT6dot: // 64 | |
26 | + // Every 8 characters | |
27 | + printstr(" "+rem8_32((unsigned int)(cursor-TVRAM))); | |
28 | + break; | |
29 | + case TMODE_T30: // 30 | |
30 | + case TMODE_T40: // 40 | |
31 | + case TMODE_MONOTEXT: // 80 | |
32 | + default: | |
33 | + // Every 10 characters | |
34 | + printstr(" "+rem10_32((unsigned int)(cursor-TVRAM))); | |
35 | + break; | |
36 | + } | |
37 | +} | |
38 | + | |
39 | +/* | |
14 | 40 | int readbuttons(); |
15 | 41 | Read the tact switches. |
16 | 42 | For Zoea, disable PS/2 keyboard and enable tact switches, then read. |
@@ -20,8 +20,11 @@ void pre_run(void); | ||
20 | 20 | void post_run(void); |
21 | 21 | void err_peri_not_init(void); |
22 | 22 | |
23 | -// 30 or 40 characters per line for Zoea | |
24 | -#define printcomma() printstr(" "+rem10_32((unsigned int)(cursor-TVRAM))) | |
23 | +// KEYPORT mask for available button inputs | |
24 | +#define KEYPORTMASK (KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE) | |
25 | + | |
26 | +// 30, 36, 40, 48, 64, 80 characters per line for Megalopa | |
27 | +void printcomma(void); | |
25 | 28 | |
26 | 29 | // Check break key or buttons when executing BASIC code. |
27 | 30 | // In PS/2 mode, detect ctrl-break. |
@@ -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 |
@@ -860,6 +867,7 @@ ON GOTO分やON GOSUB文はサポートしていません。ただし、例え | ||
860 | 867 | ・アイドル機能(IDLEステートメント)を追加。 |
861 | 868 | ・EXEC()関数を追加。 |
862 | 869 | ・変数名などで、英数字に加えてアンダースコアーが使用可能に。 |
870 | + ・PRINTでカンマを使った時の表示不具合を修正。 | |
863 | 871 | ・KM-1302 2019年3月公開。 |
864 | 872 | ・オブジェクト指向プログラミングに対応 |
865 | 873 | ・args(0)で引数の数を取得できるようにした |
@@ -168,7 +168,12 @@ unsigned char ps2readkey(); | ||
168 | 168 | // 上位8ビット:シフト状態(押下:1)、上位から<0><CAPSLK><NUMLK><SCRLK><Win><ALT><CTRL><SHIFT> |
169 | 169 | // 英数・記号文字の場合、戻り値としてASCIIコード(それ以外は0を返す) |
170 | 170 | |
171 | -// Macros for dummy functions | |
171 | +// Macro(s) follows(s) | |
172 | +extern unsigned short * volatile keycodebufp1; //キーコード書き込み先頭ポインタ | |
173 | +extern unsigned short * volatile keycodebufp2; //キーコード読み出し先頭ポインタ | |
174 | +#define keycodeExists() (keycodebufp1!=keycodebufp2) | |
175 | + | |
176 | +// Further macros for dummy functions | |
172 | 177 | #define ps2mode() (0) |
173 | 178 | #define buttonmode() (0) |
174 | 179 | #define inPS2MODE() (1) |
@@ -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,10 @@ 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 | +static unsigned short g_keys_mask; | |
48 | + | |
45 | 49 | /* |
46 | 50 | Initialize and termination |
47 | 51 | */ |
@@ -56,6 +60,7 @@ void init_timer(){ | ||
56 | 60 | g_timer=0; |
57 | 61 | // Disable interrupt |
58 | 62 | IEC0bits.CS1IE=0; |
63 | + IFS0bits.CS1IF=0; | |
59 | 64 | for(i=0;i<NUM_INTERRUPT_TYPES;i++) g_int_vector[i]=0; |
60 | 65 | // CS0 interrupt every 1/60 sec (triggered by Timer2) |
61 | 66 | IPC0bits.CS0IP=3; |
@@ -69,6 +74,8 @@ void init_timer(){ | ||
69 | 74 | asm volatile("ins $t0,$zero,1,15"); |
70 | 75 | asm volatile("mtc0 $t0,$12,0"); |
71 | 76 | asm volatile("ei"); |
77 | + // The other initialization(s) | |
78 | + g_keys_interrupt=-1; | |
72 | 79 | } |
73 | 80 | |
74 | 81 | void stop_timer(){ |
@@ -330,9 +337,7 @@ const int* g_keystatus=(int*)&ps2keystatus[0]; | ||
330 | 337 | |
331 | 338 | #pragma interrupt CS0Handler IPL3SOFT vector 1 |
332 | 339 | void CS0Handler(void){ |
333 | - static int s_keys=-1; | |
334 | - static char s_inkey=0; | |
335 | - int i; | |
340 | + int keys; | |
336 | 341 | IFS0bits.CS0IF=0; |
337 | 342 | // Call music function |
338 | 343 | if (g_music_active) musicint(); |
@@ -341,21 +346,16 @@ void CS0Handler(void){ | ||
341 | 346 | // Raise DRAWCOUNT interrupt flag |
342 | 347 | raise_interrupt_flag(INTERRUPT_DRAWCOUNT); |
343 | 348 | // Check buttons |
344 | - if (0<=s_keys && s_keys!=(KEYPORT&(KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE))) { | |
349 | + keys=KEYPORT&KEYPORTMASK; | |
350 | + if (g_keys_mask==KEYPORTMASK && 0<=g_keys_interrupt && g_keys_interrupt!=keys) { | |
345 | 351 | // Raise KEYS interrupt flag |
346 | 352 | raise_interrupt_flag(INTERRUPT_KEYS); |
347 | 353 | } |
348 | - s_keys=KEYPORT&(KEYUP|KEYDOWN|KEYLEFT|KEYRIGHT|KEYSTART|KEYFIRE); | |
349 | - // Check PS/2 keyboard down | |
354 | + g_keys_interrupt=keys; | |
355 | + g_keys_mask=KEYPORTMASK; | |
356 | + // Check PS/2 keyboard input | |
350 | 357 | 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; | |
358 | + if (keycodeExists()) raise_interrupt_flag(INTERRUPT_INKEY); | |
359 | 359 | } |
360 | 360 | } |
361 | 361 | } |