• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

BASIC compiler/interpreter for PIC32MX/MZ-80K


Commit MetaInfo

Revisione677a14f0b3a2cf6e37bdc7db4baeedee1abbb4d (tree)
Zeit2019-05-13 09:13:02
AutorKatsumi <kmorimatsu@sour...>
CommiterKatsumi

Log Message

USECLIB and CLIB statements & functions.

Ändern Zusammenfassung

Diff

--- /dev/null
+++ b/mips/megalopa/clib.c
@@ -0,0 +1,329 @@
1+/*
2+ This file is provided under the LGPL license ver 2.1.
3+ Written by K.Tanaka & Katsumi
4+ http://www.ze.em-net.ne.jp/~kenken/index.html
5+ http://hp.vector.co.jp/authors/VA016157/
6+*/
7+
8+/*
9+ This file is shared by Megalopa and Zoea
10+*/
11+
12+#include "compiler.h"
13+#include "api.h"
14+#include "main.h"
15+
16+/*
17+ CMPDATA_USECLIB structure
18+ type: CMPDATA_USECLIB (8)
19+ len: 2
20+ data16: n/a (0)
21+ record[1]: clib name as integer
22+
23+ CMPDATA_CLIBFUNC structure
24+ type: CMPDATA_CLIBFUNC (9)
25+ len: 4
26+ data16: n/a (0)
27+ record[1]: clib name as integer
28+ record[2]: func name as integer
29+ record[3]: pointer to function
30+*/
31+
32+// CLIB name used (name as 31 bit integer)
33+static unsigned int g_clib;
34+
35+char* useclib_statement(){
36+ int i;
37+ int* cmpdata;
38+ do {
39+ next_position();
40+ i=check_var_name();
41+ if (i<65536) return ERR_SYNTAX;
42+ // Check if the clib already exists
43+ cmpdata_reset();
44+ while(cmpdata=cmpdata_find(CMPDATA_USECLIB)){
45+ if (cmpdata[1]==i) {
46+ // The clib was already defined.
47+ i=0;
48+ break;
49+ }
50+ }
51+ if (i) {
52+ // Load new file to define clib.
53+ g_clib=i;
54+ return ERR_COMPILE_CLIB;
55+ }
56+ if (g_source[g_srcpos]==',') {
57+ g_srcpos++;
58+ } else {
59+ break;
60+ }
61+ } while(1);
62+ return 0;
63+}
64+
65+/*
66+ * g_data[] contains the data from MachiKania compiler for this library
67+ * g_data[0] : lib_calloc_memory
68+ * g_data[1] : lib_delete
69+ * g_data[2] : g_gp
70+ * g_data[3-]: Reserved for higher version of CLIB
71+ */
72+void* g_data_for_clib[]={
73+ lib_calloc_memory,
74+ lib_delete,
75+ 0, // = g_gp
76+};
77+
78+void* call_clib_init(void** data, void* address){
79+ // Store gp and ra
80+ asm volatile("#":::"s0");
81+ asm volatile("#":::"ra");
82+ asm volatile("addu $t9,$a1,$zero");
83+ asm volatile("addu $s0,$gp,$zero");
84+ asm volatile("jalr $ra,$t9");
85+ asm volatile("addu $gp,$s0,$zero");
86+}
87+
88+char* clib_main(){
89+ char* err;
90+ unsigned int begin,end,addr;
91+ void* clibdata;
92+ int* functions;
93+ int* got;
94+ int i,opos,adjust;
95+ char* clib;
96+ int record[3];
97+ // Insert CMPDATA_USELIB
98+ record[0]=g_clib;
99+ err=cmpdata_insert(CMPDATA_USECLIB,0,&record[0],1);
100+ if (err) return err;
101+ // Determine begin and end addresses
102+ begin=0x000fffff;
103+ end=0;
104+ while(1){
105+ err=hex_read_line();
106+ if (err) return err;
107+ if (g_hexline.type==1) {
108+ // EOF
109+ break;
110+ } else if (g_hexline.type==4) {
111+ // extended linear address
112+ addr=g_hexline.data[0];
113+ addr=addr<<8;
114+ addr|=g_hexline.data[0];
115+ addr=addr<<16;
116+ } else if (g_hexline.type==0) {
117+ // data
118+ addr&=0xffff0000;
119+ addr|=g_hexline.address;
120+ if (addr<begin) begin=addr;
121+ if (end<addr && addr<0x000fffff) {
122+ end=addr+g_hexline.size;
123+ }
124+ } else {
125+ // Unknown type
126+ return ERR_HEX_ERROR;
127+ }
128+ }
129+ hex_reinit_file();
130+ // Assign and clear region
131+ check_obj_space((end-begin+3)>>2);
132+ clib=(char*)&g_object[g_objpos];
133+ got=(int*)&g_object[g_objpos];
134+ for(i=0;i<((end-begin+3)>>2);i++) g_object[g_objpos++]=0;
135+ // Load binary from HEX file
136+ while(1){
137+ err=hex_read_line();
138+ if (err) return err;
139+ if (g_hexline.type==1) {
140+ // EOF
141+ break;
142+ } else if (g_hexline.type==4) {
143+ // extended linear address
144+ addr=g_hexline.data[0];
145+ addr=addr<<8;
146+ addr|=g_hexline.data[0];
147+ addr=addr<<16;
148+ } else if (g_hexline.type==0) {
149+ // data
150+ addr&=0xffff0000;
151+ addr|=g_hexline.address;
152+ for(i=0;i<g_hexline.size;i++){
153+ clib[addr-begin+i]=g_hexline.data[i];
154+ }
155+ } else {
156+ // Unknown type
157+ return ERR_HEX_ERROR;
158+ }
159+ }
160+ // Calculate the adjustment value.
161+ // Note that the address of clib_init() is 0x8000.
162+ adjust=(int)clib+0x8000-begin-0xA0008000;
163+ // Modify Global Offset Table (GOT)
164+ for(i=0;i<(0x8000-begin)>>2;i++){
165+ if ((got[i]&0xFFF00000)==0xA0000000) {
166+ got[i]+=adjust;
167+ }
168+ }
169+ // Prepare g_data_for_clib[]
170+ g_data_for_clib[2]=(void*)g_gp;
171+ // Call the clib_init() to get the address of clibdata array.
172+ clibdata=call_clib_init(&g_data_for_clib[0],(void*)0xA0008000+adjust);
173+ // Check version
174+ if (((int*)clibdata)[0]>SYSVERI) {
175+ return "Newer version of C library than MachiKania cannot be used.";
176+ }
177+ // Get functions array
178+ clibdata=(void*)(((int*)clibdata)[2])+adjust;
179+ functions=clibdata;
180+ // Construct CMPDATA_CLIBFUNC records.
181+ while(clib=(char*)functions[0]){
182+ clibdata=(void*)functions[1];
183+ functions+=2;
184+ // clib is function name as string
185+ // clibdata is address of C function
186+ clib+=adjust;
187+ clibdata+=adjust;
188+ i=str_to_name_int(clib);
189+ if (i<65536) return "Wrong C library function name";
190+ record[0]=g_clib;
191+ record[1]=i;
192+ record[2]=(int)clibdata;
193+ err=cmpdata_insert(CMPDATA_CLIBFUNC,0,&record[0],3);
194+ if (err) return err;
195+ }
196+ // Initial assembly is a jump statement to jump to the the following routine.
197+ g_object[0]=0x08000000 | ((((int)(&g_object[g_objpos]))&0x0FFFFFFF)>>2); // j xxxxxxxx
198+ // All done
199+ return 0;
200+}
201+
202+char* useclib_begin(char* buff){
203+ int i,j,cwd_id;
204+ char* err;
205+ char* clibname;
206+ char filename[11];
207+ int* record;
208+ // Remove a objects before USECLIB statement
209+ g_objpos=0;
210+ // Insert twp NOP assemblies. This will be replaced by branch statement.
211+ check_obj_space(2);
212+ g_object[g_objpos++]=0x00000000; // nop
213+ g_object[g_objpos++]=0x00000000; // nop
214+ // Construct HEX file name to open
215+ clibname=resolve_label(g_clib);
216+ for(i=0;filename[i]=clibname[i];i++);
217+ filename[i++]='.';
218+ filename[i++]='H';
219+ filename[i++]='E';
220+ filename[i++]='X';
221+ filename[i++]=0;
222+ // Open file in current directory
223+ err=hex_init_file(buff,filename);
224+ if (!err) {
225+ // HEX file found in current directory.
226+ err=clib_main();
227+ hex_close_file();
228+ } else {
229+ // Hex file not found in current directory.
230+ // Find it in LIB directory.
231+ if (!FSgetcwd(buff,256)) return ERR_UNKNOWN;
232+ for(i=0;buff[i];i++);
233+ cwd_id=cmpdata_get_id();
234+ if (!cwd_id) return ERR_UNKNOWN;
235+ err=cmpdata_insert(CMPDATA_TEMP,cwd_id,(int*)(&buff[0]),(i+1+3)>>2);
236+ if (err) return err;
237+ // Change current directory to class library directory
238+ for(i=0;buff[i]="\\LIB\\"[i];i++);
239+ for(j=0;buff[i++]=clibname[j];j++);
240+ buff[i]=0;
241+ FSchdir(buff);
242+ err=hex_init_file(buff,filename);
243+ if (!err) {
244+ // HEX file found in LIB directory
245+ err=clib_main();
246+ hex_close_file();
247+ } else {
248+ err=ERR_NO_CLIB;
249+ }
250+ // Restore current dirctory
251+ cmpdata_reset();
252+ while(record=cmpdata_find(CMPDATA_TEMP)){
253+ if ((record[0]&0xffff)==cwd_id) break;
254+ }
255+ if (!record) return ERR_UNKNOWN;
256+ FSchdir((char*)(&record[1]));
257+ cmpdata_delete(record);
258+ }
259+ return err;
260+}
261+
262+void lib_clib(int* params, void* address){
263+ // Store gp and ra
264+ asm volatile("#":::"s0");
265+ asm volatile("#":::"ra");
266+ asm volatile("addu $t9,$a1,$zero");
267+ asm volatile("addu $s0,$gp,$zero");
268+ asm volatile("lw $a3,16($a0)");
269+ asm volatile("lw $a2,12($a0)");
270+ asm volatile("lw $a1,8($a0)");
271+ asm volatile("lw $a0,4($a0)");
272+ asm volatile("jalr $ra,$t9");
273+ asm volatile("addu $gp,$s0,$zero");
274+}
275+
276+char* clib_statement(){
277+ char* err;
278+ int* record;
279+ int clib,func;
280+ int numparams,stack;
281+ // CLIB name
282+ next_position();
283+ clib=check_var_name();
284+ if (clib<65536) return ERR_SYNTAX;
285+ // Check if the clib exists
286+ cmpdata_reset();
287+ while (record=cmpdata_find(CMPDATA_USECLIB)){
288+ if (record[1]==clib) break;
289+ }
290+ if (!record) return ERR_NO_CLIB;
291+ next_position();
292+ if (g_source[g_srcpos++]!=',') return ERR_SYNTAX;
293+ // Function name
294+ next_position();
295+ func=check_var_name();
296+ if (func<65536) return ERR_SYNTAX;
297+ cmpdata_reset();
298+ while (record=cmpdata_find(CMPDATA_CLIBFUNC)){
299+ if (record[1]==clib && record[2]==func) break;
300+ }
301+ if (!record) return "Function not found in the C library";
302+ // Construct parameter(s)
303+ next_position();
304+ numparams=0;
305+ while (g_source[g_srcpos]==',') {
306+ numparams++;
307+ if (4<numparams) return ERR_SYNTAX;
308+ else if (1==numparams) {
309+ check_obj_space(1);
310+ stack=g_objpos++;
311+ }
312+ g_srcpos++;
313+ g_object[stack]=0x27BD0000|(65536-numparams*4); // addiu sp,sp,-xx
314+ err=get_stringFloatOrValue();
315+ if (err) return err;
316+ check_obj_space(1);
317+ g_object[g_objpos++]=0xAFA20000|(numparams*4); // sw v0,xx(sp)
318+ next_position();
319+ }
320+ // Call CLIB
321+ check_obj_space(2);
322+ g_object[g_objpos++]=0x3C050000|(((unsigned int)record[3])>>16); // lui a1,xxxx
323+ g_object[g_objpos++]=0x34A50000|(((unsigned int)record[3])&0x0000FFFF); // ori a1,a1,xxxx
324+ call_quicklib_code(lib_clib,ASM_ADDU_A0_SP_ZERO); // All done
325+ check_obj_space(1);
326+ if (numparams) g_object[g_objpos++]=0x27BD0000|(numparams*4); // addiu sp,sp,xx
327+ return 0;
328+}
329+
--- a/mips/megalopa/compiler.h
+++ b/mips/megalopa/compiler.h
@@ -40,6 +40,14 @@
4040 // RAM size used for object and heap
4141 #define RAMSIZE (PERSISTENT_RAM_SIZE-EXCEPTION_DATA_SIZE)
4242
43+/* Structures */
44+typedef struct{
45+ unsigned char size;
46+ unsigned short address;
47+ unsigned char type;
48+ unsigned char data[16];
49+} HEXLINE;
50+
4351 /* Enums */
4452 enum variable{
4553 VAR_INTEGER,
@@ -228,6 +236,7 @@ extern int g_class;
228236 extern int g_compiling_class;
229237 extern unsigned char g_num_classes;
230238 extern char g_option_fastfield;
239+extern HEXLINE g_hexline;
231240 extern int g_temp;
232241
233242 /* Prototypes */
@@ -340,6 +349,7 @@ int* cmpdata_findfirst(unsigned char type);
340349 void cmpdata_delete(int* record);
341350
342351 int check_var_name();
352+int str_to_name_int(char* str);
343353 int get_var_number();
344354 int search_var_name(int nameint);
345355 char* register_var_name(int nameint);
@@ -384,6 +394,16 @@ char* coretimer_statement();
384394 char* coretimer_function();
385395 char* interrupt_statement();
386396
397+char* useclib_statement();
398+char* useclib_begin(char* buff);
399+char* clib_statement();
400+
401+char* hex_init_file(char* buff,char* filename);
402+void hex_reinit_file();
403+void hex_close_file();
404+char* hex_read_line();
405+char* hex_construct_line();
406+
387407 /* Error messages */
388408 #define ERR_SYNTAX (char*)(g_err_str[0])
389409 #define ERR_NE_BINARY (char*)(g_err_str[1])
@@ -415,6 +435,9 @@ char* interrupt_statement();
415435 #define ERR_INVALID_CLASS (char*)(g_err_str[27])
416436 #define ERR_NO_INIT (char*)(g_err_str[28])
417437 #define ERR_OPTION_CLASSCODE (char*)(g_err_str[29])
438+#define ERR_COMPILE_CLIB (char*)(g_err_str[30])
439+#define ERR_NO_CLIB (char*)(g_err_str[31])
440+#define ERR_HEX_ERROR (char*)(g_err_str[32])
418441
419442 /* compile data type numbers */
420443 #define CMPDATA_RESERVED 0
@@ -425,6 +448,8 @@ char* interrupt_statement();
425448 #define CMPDATA_UNSOLVED 5
426449 #define CMPDATA_TEMP 6
427450 #define CMPDATA_FASTFIELD 7
451+#define CMPDATA_USECLIB 8
452+#define CMPDATA_CLIBFUNC 9
428453 // Sub types follow
429454 #define CMPTYPE_PUBLIC_FIELD 0
430455 #define CMPTYPE_PRIVATE_FIELD 1
@@ -485,6 +510,7 @@ char* interrupt_statement();
485510 } while (0)
486511
487512 #define ASM_NOP 0x00000000
513+#define ASM_ADDU_A0_SP_ZERO 0x03A02021
488514 #define ASM_ADDU_A0_V0_ZERO 0x00402021
489515 #define ASM_ADDU_A1_V0_ZERO 0x00402821
490516 #define ASM_ADDU_A2_V0_ZERO 0x00403021
--- a/mips/megalopa/debug.c
+++ b/mips/megalopa/debug.c
@@ -34,6 +34,7 @@ static const char initext[];
3434 static const char bastext[];
3535 static const char class1text[];
3636 static const char class2text[];
37+static const char hextext[];
3738
3839 static char* readtext;
3940 static int filepos;
@@ -130,6 +131,9 @@ FSFILE* FSfopen(const char * fileName, const char *mode){
130131 } else if (fileName[i+1]=='I' && fileName[i+2]=='N' && fileName[i+3]=='I') {
131132 // INI file
132133 readtext=(char*)&initext[0];
134+ } else if (fileName[i+1]=='H' && fileName[i+2]=='E' && fileName[i+3]=='X') {
135+ // HEX file
136+ readtext=(char*)&hextext[0];
133137 } else if (fileName[i+1]=='B' && fileName[i+2]=='A' && fileName[i+3]=='S') {
134138 // Select BAS file
135139 if (fileName[i-6]=='C' && fileName[i-5]=='L' && fileName[i-4]=='A' &&
@@ -184,6 +188,7 @@ long FSftell (FSFILE * fo){
184188 return 0;
185189 }
186190 int FSfseek(FSFILE *stream, long offset, int whence){
191+ filepos=offset;
187192 return 0;
188193 }
189194 /*
@@ -228,12 +233,11 @@ static const char initext[]=
228233 "#PRINT\n";
229234
230235 static const char bastext[]=
231-"USECLASS CLASS1,CLASS2\n"
232-"OPTION FASTFIELD\n"
236+"useclib TCLIB\n"
233237 "CLS\n"
234-"o=new(CLASS1)\n"
235-"o.T1=123\n"
236-"print o.T2()\n"
238+"print clib$(TCLIB,TEST,0);\n"
239+"print clib$(TCLIB,TEST,1)\n"
240+"\n"
237241 "\n"
238242 "\n"
239243 "\n"
@@ -255,6 +259,36 @@ static const char class2text[]=
255259 "\n"
256260 "\n";
257261
262+static const char hextext[]=
263+":020000040000fa\n"
264+":1080000000001c3c707f9c2721e09903e0ffbd2706\n"
265+":108010001c00bfaf1000bcaf1880828f000044acc2\n"
266+":108020001c80998f09f82003000000001000bc8f0d\n"
267+":108030002080828f1c00bf8f0800e0032000bd2736\n"
268+":020000040000fa\n"
269+":107f80000000000000000080a07f00a0708000a022\n"
270+":107f9000fc8000a0000001a0788000a0000000008c\n"
271+":020000040000fa\n"
272+":108070000800e0030000000000001c3cf87e9c2784\n"
273+":1080800021e09903040080542480828f2480828f11\n"
274+":108090000800e003d48042240800e003e480422486\n"
275+":1080a00000001c3cd07e9c2721e09903e0ffbd2707\n"
276+":1080b0001c00bfaf1000bcaf2880998f09f82003c7\n"
277+":1080c000000000001000bc8f1c00bf8f0800e00300\n"
278+":0480d0002000bd27a8\n"
279+":020000040000fa\n"
280+":1080d40048656c6c6f20576f726c6421000000005f\n"
281+":1080e4005468697320697320612074657374000097\n"
282+":0880f400544553540000000044\n"
283+":020000040000fa\n"
284+":1080fc0040010000800000001c8100a00000000076\n"
285+":020000040000fa\n"
286+":10810c0000000000222222222222222222222222cb\n"
287+":020000040000fa\n"
288+":0c811c00f48000a0a08000a00000000083\n"
289+":00000001FF\n"
290+;
291+
258292 /*
259293 Test function for constructing assemblies from C codes.
260294 */
@@ -285,6 +319,15 @@ int _debug_test(int a0, int a1, int a2, int a3, int param4, int param5){
285319 return a2+a3;
286320 }
287321
322+int _debug_test2(int a0, int a1, int a2, int a3, int a4){
323+ int v0;
324+ v0=v0+a0;
325+ v0=v0*a1;
326+ v0=v0 & a3;
327+ v0=v0 | a4;
328+ return v0;
329+}
330+
288331 /*
289332 Break point used for debugging object code.
290333
--- a/mips/megalopa/error.c
+++ b/mips/megalopa/error.c
@@ -42,6 +42,9 @@ const char* g_err_str[]={
4242 "Invalid in class file",
4343 "INIT method does not exist",
4444 "ERR_OPTION_CLASSCODE",
45+ "ERR_COMPILE_CLIB",
46+ "C library not found",
47+ "HEX file syntax error",
4548 };
4649
4750 char* resolve_label(int s6){
--- a/mips/megalopa/file.c
+++ b/mips/megalopa/file.c
@@ -13,10 +13,12 @@
1313 #include "api.h"
1414 #include "compiler.h"
1515
16-static FSFILE* g_fhandle;
17-static char* g_fbuff;
18-static int g_size;
19-static int g_filepoint;
16+// Variables used for file handling, shared with the other components
17+// Note that only one file can be open
18+FSFILE* g_fhandle;
19+char* g_fbuff;
20+int g_size;
21+int g_filepoint;
2022
2123 char* init_file(char* buff,char* appname){
2224 // Open file
@@ -147,7 +149,7 @@ int compile_and_link_file(char* buff,char* appname){
147149 err=compile_file();
148150 close_file();
149151
150- // If compiling a class file is required, do it.
152+ // If compiling a class file or a clib is required, do it.
151153 if (err==ERR_COMPILE_CLASS) {
152154 j=g_compiling_class;
153155 i=compile_and_link_class(buff, g_class);
@@ -155,6 +157,11 @@ int compile_and_link_file(char* buff,char* appname){
155157 if (i) return i;
156158 // Continue compiling current file from the beginning.
157159 continue;
160+ } else if (err==ERR_COMPILE_CLIB) {
161+ err=useclib_begin(buff);
162+ // Continue compiling current file from the beginning.
163+ if (err) break;
164+ continue;
158165 }
159166 break;
160167 }
@@ -239,7 +246,7 @@ int compile_and_link_class(char* buff,int class){
239246 // Restore current dirctory
240247 cmpdata_reset();
241248 while(record=cmpdata_find(CMPDATA_TEMP)){
242- if (cwd_id=(record[0]&0xffff)) break;
249+ if ((record[0]&0xffff)==cwd_id) break;
243250 }
244251 if (!record) break;
245252 FSchdir((char*)(&record[1]));
--- a/mips/megalopa/function.c
+++ b/mips/megalopa/function.c
@@ -494,6 +494,8 @@ char* float_function(void){
494494 err=gosub_function();
495495 } else if (nextCodeIs("ARGS#(")) {
496496 err=args_function();
497+ } else if (nextCodeIs("CLIB#(")) {
498+ err=clib_statement();
497499 } else if (nextCodeIs("PI#")) {
498500 return float_constant(3.141593);
499501 } else {
@@ -520,6 +522,7 @@ static const void* str_func_list[]={
520522 "SYSTEM$(",system_function,
521523 "FINPUT$(",finput_function,
522524 "GETDIR$(",getdir_function,
525+ "CLIB$(",clib_statement,
523526 // Additional functions follow
524527 ADDITIONAL_STR_FUNCTIONS
525528 };
@@ -609,6 +612,7 @@ static const void* int_func_list[]={
609612 "EXEC(",exec_function,
610613 "CORETIMER(",coretimer_function,
611614 "READKEY(",readkey_function,
615+ "CLIB(",clib_statement,
612616 // Additional functions follow
613617 ADDITIONAL_INT_FUNCTIONS
614618 };
--- a/mips/megalopa/globalvars.c
+++ b/mips/megalopa/globalvars.c
@@ -95,5 +95,8 @@ unsigned char g_num_classes;
9595 // OPTION FASTFIELD
9696 char g_option_fastfield;
9797
98+// Result of reading a HEX file line
99+HEXLINE g_hexline;
100+
98101 // General purpose integer used for asigning value with pointer
99102 int g_temp;
--- a/mips/megalopa/help.txt
+++ b/mips/megalopa/help.txt
@@ -863,7 +863,7 @@ ON GOTO分やON GOSUB文はサポートしていません。ただし、例え
863863 を扱いたい場合は、同名の変数をVAR指定しないようにして下さい。
864864
865865 <バージョン履歴>
866-・KM-1303 2019年5月公開。
866+・KM-1303 2019年?月公開。
867867  ・タイマー機能(USETIMER,TIMER, CORETIMERステートメントとTIMER(), CORETIMER()関
868868   数)を追加。
869869  ・割り込み機能(INTERRUPTステートメント)を追加。
--- /dev/null
+++ b/mips/megalopa/hexfile.c
@@ -0,0 +1,222 @@
1+/*
2+ This file is provided under the LGPL license ver 2.1.
3+ Written by K.Tanaka & Katsumi
4+ http://www.ze.em-net.ne.jp/~kenken/index.html
5+ http://hp.vector.co.jp/authors/VA016157/
6+*/
7+
8+/*
9+ This file is shared by Megalopa and Zoea
10+*/
11+
12+#include "compiler.h"
13+#include "api.h"
14+
15+/*
16+ Intel HEX format example
17+ :040bf000ffffffcf35
18+ +--------------------- Byte count
19+ | +---------------- Address
20+ | | +------------- Record type (00:Data, 01:EOF, 04: Extended linear addres
21+ | | | +---- Data
22+ | | | | +- Checksum
23+ | | | | |
24+ : 04 0bf0 00 ffffffcf 35
25+
26+ Record types:
27+ case 0: // data
28+ case 4: // extended linear address
29+ case 1: // EOF
30+
31+*/
32+
33+/*
34+ Example of HEX file
35+
36+:020000040000fa
37+:1080000000001c3c707f9c2721e09903e0ffbd2706
38+:108010001c00bfaf1000bcaf0e0080101880828f14
39+:10802000000044ac1c80828f80ff42241c80848f1f
40+:10803000000040a0010042242b184400fdff6054c2
41+:10804000000040a02080998f09f820030000000064
42+:108050001000bc8f2480828f1c00bf8f0800e003bb
43+:048060002000bd2718
44+:020000040000fa
45+:107f80000000000000000080a47f00a0008000a08e
46+:107f9000708000a0fc8000a0000001a0788000a0fc
47+:047fa00000000000dd
48+:020000040000fa
49+:108070000800e0030000000000001c3cf87e9c2784
50+:1080800021e09903040080542880828f2880828f09
51+:108090000800e003d48042240800e003e480422486
52+:1080a00000001c3cd07e9c2721e09903e0ffbd2707
53+:1080b0001c00bfaf1000bcaf2c80998f09f82003c3
54+:1080c000000000001000bc8f1c00bf8f0800e00300
55+:0480d0002000bd27a8
56+:020000040000fa
57+:1080d40048656c6c6f20576f726c6421000000005f
58+:1080e4005468697320697320612074657374000097
59+:0880f400544553540000000044
60+:020000040000fa
61+:1080fc0040010000800000001c8100a00000000076
62+:020000040000fa
63+:10810c0000000000222222222222222222222222cb
64+:020000040000fa
65+:0c811c00f48000a0a08000a00000000083
66+:00000001FF
67+*/
68+
69+// Use the same global vars in file.c
70+extern FSFILE* g_fhandle;
71+extern char* g_fbuff;
72+extern int g_size;
73+extern int g_filepoint;
74+// Vars used only in this file
75+static unsigned char g_checksum;
76+
77+void hex_read_file(int blocklen){
78+ int i;
79+ if (blocklen==512) {
80+ // This is first read. Initialize parameter(s).
81+ g_srcpos=0;
82+ g_filepoint=0;
83+ } else if (g_size<512) {
84+ // Already reached the end of file.
85+ return;
86+ } else {
87+ // Shift buffer and source position 256 bytes.
88+ for(i=0;i<256;i++) g_fbuff[i]=g_fbuff[i+256];
89+ g_srcpos-=256;
90+ g_filepoint+=256;
91+ }
92+ // Read 512 or 256 bytes from SD card.
93+ g_size=512-blocklen+FSfread((void*)&g_fbuff[512-blocklen],1,blocklen,g_fhandle);
94+ // All lower cases
95+ for(i=512-blocklen;i<512;i++){
96+ if ('A'<=g_fbuff[i] && g_fbuff[i]<='F') g_fbuff[i]+=0x20;
97+ }
98+}
99+
100+int hex_read_byte(){
101+ unsigned char b1,b2;
102+ b1=g_fbuff[g_srcpos++];
103+ b2=g_fbuff[g_srcpos++];
104+ if ('0'<=b1 && b1<='9') {
105+ b1-='0';
106+ } else if ('a'<=b1 && b1<='f') {
107+ b1-='a';
108+ b1+=0x0a;
109+ } else {
110+ return -1;
111+ }
112+ if ('0'<=b2 && b2<='9') {
113+ b2-='0';
114+ } else if ('a'<=b2 && b2<='f') {
115+ b2-='a';
116+ b2+=0x0a;
117+ } else {
118+ return -1;
119+ }
120+ b1=(b1<<4)|b2;
121+ g_checksum+=b1;
122+ return b1;
123+}
124+
125+char* hex_read_line(){
126+ int i,j;
127+ // Initialize checksum
128+ g_checksum=0;
129+ // Maintain at least 256 characters in cache.
130+ if (256<=g_srcpos) hex_read_file(256);
131+ // Read a hex file line
132+ if (g_fbuff[g_srcpos++]!=':') return ERR_HEX_ERROR;
133+ // Read size
134+ i=hex_read_byte();
135+ if (i<0) return ERR_HEX_ERROR;
136+ g_hexline.size=(unsigned char)i;
137+ // Read address
138+ i=hex_read_byte();
139+ if (i<0) return ERR_HEX_ERROR;
140+ g_hexline.address=(unsigned short)(i<<8);
141+ i=hex_read_byte();
142+ if (i<0) return ERR_HEX_ERROR;
143+ g_hexline.address|=(unsigned short)(i);
144+ // Ready type
145+ i=hex_read_byte();
146+ if (i<0) return ERR_HEX_ERROR;
147+ g_hexline.type=(unsigned char)i;
148+ // Read data
149+ for(j=0;j<g_hexline.size;j++){
150+ i=hex_read_byte();
151+ if (i<0) return ERR_HEX_ERROR;
152+ g_hexline.data[j]=(unsigned char)i;
153+ }
154+ // Read checksum
155+ i=hex_read_byte();
156+ if (i<0) return ERR_HEX_ERROR;
157+ if (g_checksum) return ERR_HEX_ERROR;
158+ // All done. Remove enter.
159+ if (g_fbuff[g_srcpos]=='\r') g_srcpos++;
160+ if (g_fbuff[g_srcpos]=='\n') g_srcpos++;
161+ return 0;
162+}
163+
164+static char g_hex_line[46];
165+void hex_construct_byte(unsigned char data,int pos){
166+ g_hex_line[pos] ="0123456789abcdef"[data>>8];
167+ g_hex_line[pos+1]="0123456789abcdef"[data&15];
168+ g_checksum+=data;
169+}
170+char* hex_construct_line(){
171+ int i;
172+ g_checksum=0;
173+ // Write size
174+ hex_construct_byte(g_hexline.size,0);
175+ // Write address
176+ hex_construct_byte(g_hexline.address>>8,2);
177+ hex_construct_byte(g_hexline.address&15,4);
178+ // Write type
179+ hex_construct_byte(g_hexline.type,6);
180+ // Write data
181+ for(i=0;i<g_hexline.size;i++){
182+ hex_construct_byte(g_hexline.data[i],8+i);
183+ }
184+ // Write checksum
185+ hex_construct_byte(0-g_checksum,8+i);
186+ // All done. Add CRLF and 0x00
187+ g_hex_line[10+i]=0x0d;
188+ g_hex_line[11+i]=0x0a;
189+ g_hex_line[12+i]=0;
190+ return (char*)&g_hex_line[0];
191+}
192+
193+void hex_reinit_file(){
194+ // Go to point 0
195+ FSfseek(g_fhandle,0,SEEK_SET);
196+ // Initialize parameters
197+ g_srcpos=0;
198+ g_filepoint=0;
199+ // Read first 512 bytes
200+ hex_read_file(512);
201+}
202+
203+char* hex_init_file(char* buff,char* filename){
204+ // Open file
205+ g_fhandle=FSfopen(filename,"r");
206+ if (!g_fhandle) {
207+ return ERR_UNKNOWN;
208+ }
209+ // Initialize parameters
210+ g_fbuff=buff;
211+ g_source=buff;
212+ g_srcpos=0;
213+ g_filepoint=0;
214+ // Read first 512 bytes
215+ hex_read_file(512);
216+ return 0;
217+}
218+
219+void hex_close_file(){
220+ FSfclose(g_fhandle);
221+}
222+
--- a/mips/megalopa/main.h
+++ b/mips/megalopa/main.h
@@ -7,8 +7,9 @@
77
88 #define MEGALOPA
99 #define SYSVER1 "Megalopa"
10-#define SYSVER2 "1.3"
11-#define BASVER "KM-1303"
10+#define SYSVER2 "1.4"
11+#define SYSVERI 0x0140
12+#define BASVER "KM-1304"
1213
1314 #define INIFILE "MACHIKAM.INI" // 初期設定ファイル
1415 #define HEXFILE "MACHIKAM.HEX" // 実行中HEXファイル名がこれと一致した場合はエディタ起動
--- a/mips/megalopa/megalopa.mcp
+++ b/mips/megalopa/megalopa.mcp
@@ -72,6 +72,8 @@ file_044=.
7272 file_045=.
7373 file_046=.
7474 file_047=.
75+file_048=.
76+file_049=.
7577 [GENERATED_FILES]
7678 file_000=no
7779 file_001=no
@@ -121,6 +123,8 @@ file_044=no
121123 file_045=no
122124 file_046=no
123125 file_047=no
126+file_048=no
127+file_049=no
124128 [OTHER_FILES]
125129 file_000=no
126130 file_001=no
@@ -166,10 +170,12 @@ file_040=no
166170 file_041=no
167171 file_042=no
168172 file_043=no
169-file_044=yes
170-file_045=yes
173+file_044=no
174+file_045=no
171175 file_046=yes
172176 file_047=yes
177+file_048=yes
178+file_049=yes
173179 [FILE_INFO]
174180 file_000=compiler.c
175181 file_001=debug.c
@@ -200,25 +206,27 @@ file_025=class.c
200206 file_026=args.c
201207 file_027=interface\keyinput.c
202208 file_028=timer.c
203-file_029=api.h
204-file_030=compiler.h
205-file_031=debug.h
206-file_032=editor.h
207-file_033=main.h
208-file_034=envspecific.h
209-file_035=io.h
210-file_036=interface\keyinput.h
211-file_037=interface\lib_video_megalopa.h
212-file_038=interface\ps2keyboard.h
213-file_039=interface\sdfsio370f.h
214-file_040=interface\lib_videoout_megalopa.X.a
215-file_041=interface\ps2keyboard370f.X.a
216-file_042=interface\sdfsio370fLib.X.a
217-file_043=app_p32MX370F512H.ld
218-file_044=help.txt
219-file_045=reservednames.js
220-file_046=class.txt
221-file_047=sharedfiles.js
209+file_029=clib.c
210+file_030=hexfile.c
211+file_031=api.h
212+file_032=compiler.h
213+file_033=debug.h
214+file_034=editor.h
215+file_035=main.h
216+file_036=envspecific.h
217+file_037=io.h
218+file_038=interface\keyinput.h
219+file_039=interface\lib_video_megalopa.h
220+file_040=interface\ps2keyboard.h
221+file_041=interface\sdfsio370f.h
222+file_042=interface\lib_videoout_megalopa.X.a
223+file_043=interface\ps2keyboard370f.X.a
224+file_044=interface\sdfsio370fLib.X.a
225+file_045=app_p32MX370F512H.ld
226+file_046=help.txt
227+file_047=reservednames.js
228+file_048=class.txt
229+file_049=sharedfiles.js
222230 [SUITE_INFO]
223231 suite_guid={62D235D8-2DB2-49CD-AF24-5489A6015337}
224232 suite_state=
--- a/mips/megalopa/reservednames.js
+++ b/mips/megalopa/reservednames.js
@@ -100,6 +100,7 @@ var namearray=[
100100 'CHR',
101101 'CIRCLE',
102102 'CLEAR',
103+ 'CLIB',
103104 'CLS',
104105 'COLOR',
105106 'COS',
--- a/mips/megalopa/sharedfiles.js
+++ b/mips/megalopa/sharedfiles.js
@@ -12,6 +12,7 @@
1212 var filearray=[
1313 'args.c',
1414 'class.c',
15+ 'clib.c',
1516 'cmpdata.c',
1617 'compiler.c',
1718 'debug.c',
@@ -21,6 +22,7 @@ var filearray=[
2122 'float.c',
2223 'function.c',
2324 'globalvars.c',
25+ 'hexfile.c',
2426 'library.c',
2527 'linker.c',
2628 'memory.c',
--- a/mips/megalopa/statement.c
+++ b/mips/megalopa/statement.c
@@ -1754,6 +1754,8 @@ static const void* statement_list[]={
17541754 "INTERRUPT ",interrupt_statement,
17551755 "IDLE",idle_statement,
17561756 "CORETIMER",coretimer_statement,
1757+ "USECLIB",useclib_statement,
1758+ "CLIB",clib_statement,
17571759 // List of additional statements follows
17581760 ADDITIONAL_STATEMENTS
17591761 };
--- a/mips/megalopa/varname.c
+++ b/mips/megalopa/varname.c
@@ -32,6 +32,7 @@ static const int reserved_var_names[]={
3232 0x0001129b, /*CHR*/
3333 0x0e7f3303, /*CIRCLE*/
3434 0x0067525f, /*CLEAR*/
35+ 0x0003c489, /*CLIB*/
3536 0x00011330, /*CLS*/
3637 0x0069cb6b, /*COLOR*/
3738 0x0001139f, /*COS*/
@@ -194,6 +195,18 @@ int check_var_name(){
194195 return i;
195196 }
196197
198+int str_to_name_int(char* str){
199+ int i;
200+ char* src=g_source;
201+ int pos=g_srcpos;
202+ g_source=str;
203+ g_srcpos=0;
204+ i=check_var_name();
205+ g_source=src;
206+ g_srcpos=pos;
207+ return i;
208+}
209+
197210 /*
198211 int get_var_number();
199212 This function returns variable number that can be used as the index of $s8