BASIC compiler/interpreter for PIC32MX/MZ-80K
Revision | 98d48ce13ededa77468aaa3f6af73c953618344d (tree) |
---|---|
Zeit | 2019-05-20 08:14:14 |
Autor | Katsumi <kmorimatsu@sour...> |
Commiter | Katsumi |
New MSRA mode.
@@ -102,9 +102,9 @@ _GEN_EXCPT_ADDR = _ebase_address + 0x180; | ||
102 | 102 | *************************************************************************/ |
103 | 103 | MEMORY |
104 | 104 | { |
105 | - kseg0_program_mem (rx) : ORIGIN = (0x9D006000+0x1000+0x490), LENGTH = (0x80000-0x6000-0x1000-0x490-0x1000-(0x19000-4)) | |
105 | + kseg0_program_mem (rx) : ORIGIN = (0x9D006000+0x1000+0x490), LENGTH = (0x80000-0x6000-0x1000-0x490-0x1000-0x19000) | |
106 | 106 | /* PERSISTENT_RAM_SIZE: 0x19000, MachiKania object section (MOS) size: 0xD000 (to fit to Zoea) */ |
107 | - kseg2_program_mem (rx) : ORIGIN = (0x9D080000 - (0x19000-4)), LENGTH = (0xD000-4) /* Some C Functions (editor and compiler) will be located here */ | |
107 | + kseg2_program_mem (rx) : ORIGIN = (0x9D080000 - 0x19000), LENGTH = 0xD000 /* Some C Functions (editor and compiler) will be located here */ | |
108 | 108 | kseg0_boot_mem : ORIGIN = (0x9D006000+0x1000+0x490), LENGTH = 0 /* dummy */ |
109 | 109 | exception_mem : ORIGIN = 0x9D006000, LENGTH = 0x1000 |
110 | 110 | kseg1_boot_mem : ORIGIN = (0x9D006000+0x1000), LENGTH = 0x490 |
@@ -145,13 +145,19 @@ SECTIONS | ||
145 | 145 | { |
146 | 146 | KEEP (*\statement.o(.text)) |
147 | 147 | KEEP (*\function.o(.text)) |
148 | + KEEP (*\value.o(.text)) | |
149 | + KEEP (*\string.o(.text)) | |
148 | 150 | KEEP (*\float.o(.text)) |
151 | + KEEP (*\cmpdata.o(.text)) | |
149 | 152 | } >kseg2_program_mem |
150 | 153 | .machikaniaobjrodata : |
151 | 154 | { |
152 | 155 | KEEP (*\statement.o(.rodata)) |
153 | 156 | KEEP (*\function.o(.rodata)) |
157 | + KEEP (*\value.o(.rodata)) | |
158 | + KEEP (*\string.o(.rodata)) | |
154 | 159 | KEEP (*\float.o(.rodata)) |
160 | + KEEP (*\cmpdata.o(.rodata)) | |
155 | 161 | } >kseg2_program_mem |
156 | 162 | |
157 | 163 | /* Boot Sections */ |
@@ -116,7 +116,7 @@ char* useclib_statement(){ | ||
116 | 116 | int i; |
117 | 117 | int* cmpdata; |
118 | 118 | // Initialize g_data_clib_var[] |
119 | - g_data_clib_var[0]=g_gp; | |
119 | + g_data_clib_var[0]=(void*)g_gp; | |
120 | 120 | do { |
121 | 121 | next_position(); |
122 | 122 | i=check_var_name(); |
@@ -9,6 +9,13 @@ | ||
9 | 9 | This file is shared by Megalopa and Zoea |
10 | 10 | */ |
11 | 11 | |
12 | +/* | |
13 | + All the code from this file will be assigned in MachiKania Object Section (MOS). | |
14 | + MOS will be replaced by BASIC object when constructing self-running HEX file. | |
15 | + Therefore, DO NOT place any run-time routine/romdata in this file. | |
16 | + See the MOS definition in liker script. | |
17 | +*/ | |
18 | + | |
12 | 19 | #include "compiler.h" |
13 | 20 | |
14 | 21 | /* |
@@ -195,6 +195,8 @@ enum functions{ | ||
195 | 195 | }; |
196 | 196 | |
197 | 197 | /* Global vars (see globalvers.c) */ |
198 | +extern const volatile int g_object_mos; | |
199 | +extern const volatile int g_objpos_mos; | |
198 | 200 | extern int g_intconst; |
199 | 201 | extern char g_valueisconst; |
200 | 202 | extern unsigned int g_rnd_seed; |
@@ -256,6 +258,7 @@ char* compile_file(); | ||
256 | 258 | int compile_and_link_file(char* buff,char* appname); |
257 | 259 | int compile_and_link_main_file(char* buff,char* appname); |
258 | 260 | int compile_and_link_class(char* buff,int class); |
261 | +int create_self_running_hex(char* hexfilename); | |
259 | 262 | |
260 | 263 | void err_break(void); |
261 | 264 | void err_music(char* str); |
@@ -404,6 +407,12 @@ void hex_reinit_file(); | ||
404 | 407 | void hex_close_file(); |
405 | 408 | char* hex_read_line(); |
406 | 409 | char* hex_construct_line(); |
410 | +#ifdef FS_DOT_H | |
411 | + char* hex_write(FSFILE* fhandle); | |
412 | + char* hex_write_address(FSFILE* fhandle,unsigned short addr); | |
413 | + char* hex_write_data_16(FSFILE* fhandle,unsigned short addr,unsigned int* object); | |
414 | + char* hex_write_eof(FSFILE* fhandle); | |
415 | +#endif | |
407 | 416 | |
408 | 417 | /* Error messages */ |
409 | 418 | #define ERR_SYNTAX (char*)(g_err_str[0]) |
@@ -1839,7 +1839,8 @@ void msra(void){ | ||
1839 | 1839 | setcursor(0,0,COLOR_NORMALTEXT); |
1840 | 1840 | printstr("Make Self-Running Application\n\n"); |
1841 | 1841 | printstr("(Work on Root Directory)\n"); |
1842 | - | |
1842 | +// MOS: delete region not required | |
1843 | +/* | |
1843 | 1844 | //カレントディレクトリを変数cwdpathにコピー |
1844 | 1845 | while(1){ |
1845 | 1846 | if(FSgetcwd(cwdpath,PATHNAMEMAX)) break; |
@@ -1859,30 +1860,44 @@ void msra(void){ | ||
1859 | 1860 | pd=tempfile; |
1860 | 1861 | while(*ps!=0) *pd++=*ps++; |
1861 | 1862 | *pd=0; |
1862 | - | |
1863 | +//*/ | |
1863 | 1864 | while(1){ |
1864 | 1865 | setcursorcolor(COLOR_NORMALTEXT); |
1865 | - printstr("Input File Name (xxx.BAS)\n"); | |
1866 | +// MOS: modification | |
1867 | + printstr("Input File Name (xxx.HEX)\n"); | |
1868 | +// printstr("Input File Name (xxx.BAS)\n"); | |
1869 | + | |
1866 | 1870 | if(lineinput(tempfile,8+1+3)<0){ |
1867 | 1871 | //ESCキーが押された |
1868 | - FSchdir(cwdpath); //カレントディレクトリを元に戻す | |
1872 | +// MOS: delete region not required | |
1873 | +// FSchdir(cwdpath); //カレントディレクトリを元に戻す | |
1869 | 1874 | return; |
1870 | 1875 | } |
1871 | 1876 | ps=tempfile; |
1872 | 1877 | while(*ps!='.' && *ps!=0) ps++; |
1873 | 1878 | if(ps+4>=tempfile+13 || |
1874 | 1879 | *ps!='.' || |
1875 | - (*(ps+1)!='b' && *(ps+1)!='B') || | |
1876 | - (*(ps+2)!='a' && *(ps+2)!='A') || | |
1877 | - (*(ps+3)!='s' && *(ps+3)!='S') || | |
1880 | +// MOS: modification | |
1881 | + (*(ps+1)!='h' && *(ps+1)!='H') || | |
1882 | + (*(ps+2)!='e' && *(ps+2)!='E') || | |
1883 | + (*(ps+3)!='x' && *(ps+3)!='X') || | |
1884 | +// (*(ps+1)!='b' && *(ps+1)!='B') || | |
1885 | +// (*(ps+2)!='a' && *(ps+2)!='A') || | |
1886 | +// (*(ps+3)!='s' && *(ps+3)!='S') || | |
1878 | 1887 | *(ps+4)!=0){ |
1879 | 1888 | setcursorcolor(COLOR_ERRORTEXT); |
1880 | - printstr("File Name Must Be xxx.BAS\n"); | |
1889 | +// MOS: modification | |
1890 | + printstr("File Name Must Be xxx.HEX\n"); | |
1891 | +// printstr("File Name Must Be xxx.BAS\n"); | |
1881 | 1892 | continue; |
1882 | 1893 | } |
1883 | 1894 | if(overwritecheck(tempfile)) continue; |
1884 | - printstr("Writing BASIC File\n"); | |
1885 | - er=savetextfile(tempfile); //ファイル保存、er:エラーコード | |
1895 | +// MOS: modification | |
1896 | + printstr("Writing HEX File\n"); | |
1897 | +// printstr("Writing BASIC File\n"); | |
1898 | +// MOS: modification | |
1899 | + er=create_self_running_hex(tempfile); //ファイル保存、er:エラーコード | |
1900 | +// er=savetextfile(tempfile); //ファイル保存、er:エラーコード | |
1886 | 1901 | if(er==0) break; |
1887 | 1902 | setcursorcolor(COLOR_ERRORTEXT); |
1888 | 1903 | if(er==ERR_CANTFILEOPEN) printstr("Bad File Name or File Error\n"); |
@@ -1898,6 +1913,8 @@ void msra(void){ | ||
1898 | 1913 | } |
1899 | 1914 | } |
1900 | 1915 | printstr("OK\n\n"); |
1916 | +// MOS: delete region not required | |
1917 | +/* | |
1901 | 1918 | FSremove(TEMPFILENAME); //実行時に生成する一時ファイルを削除 |
1902 | 1919 | //tempfileからcurrentfileにコピーして終了 |
1903 | 1920 | ps=tempfile; |
@@ -1933,6 +1950,7 @@ void msra(void){ | ||
1933 | 1950 | else if(er==ERR_CANTWRITEFILE){ |
1934 | 1951 | printstr("Write Error\n"); |
1935 | 1952 | } |
1953 | +//*/ | |
1936 | 1954 | setcursorcolor(COLOR_NORMALTEXT); |
1937 | 1955 | printstr((unsigned char *)Message1);// Hit Any Key |
1938 | 1956 | inputchar(); //1文字入力待ち |
@@ -2044,7 +2062,7 @@ void changewidth(void){ | ||
2044 | 2062 | } |
2045 | 2063 | void run(int test){ |
2046 | 2064 | //KM-BASICコンパイル&実行 |
2047 | -// test 0:コンパイルと実行、0以外:コンパイルのみで終了 | |
2065 | +// test 0:コンパイルと実行、1:コンパイルのみで終了、2:コンパイルの後、HEXファイルを作製 | |
2048 | 2066 | int er,er2; |
2049 | 2067 | FSFILE *fp; |
2050 | 2068 | unsigned int disptoppos,cursorpos; |
@@ -2120,7 +2138,18 @@ void run(int test){ | ||
2120 | 2138 | // Enable Break key |
2121 | 2139 | g_disable_break=0; |
2122 | 2140 | //KM-BASIC実行 |
2123 | - er2=runbasic(TEMPFILENAME,test); | |
2141 | +// MOS: modification | |
2142 | + switch(test){ | |
2143 | + case 2: | |
2144 | + er2=runbasic(TEMPFILENAME,1); | |
2145 | + break; | |
2146 | + case 0: | |
2147 | + case 1: | |
2148 | + default: | |
2149 | + er2=runbasic(TEMPFILENAME,test); | |
2150 | + break; | |
2151 | + } | |
2152 | +// er2=runbasic(TEMPFILENAME,test); | |
2124 | 2153 | |
2125 | 2154 | stopPCG();//システムフォントに戻す |
2126 | 2155 | setcursorcolor(COLOR_NORMALTEXT); |
@@ -2163,6 +2192,12 @@ void run(int test){ | ||
2163 | 2192 | FSremove(WORKDIRFILE); //パス名保存ファイル削除 |
2164 | 2193 | break; |
2165 | 2194 | } |
2195 | +// MOS: insertion | |
2196 | + if (2==test) { | |
2197 | + // Create HEX file as Self Running Apprication | |
2198 | + msra(); | |
2199 | + } | |
2200 | +//*/ | |
2166 | 2201 | while(1){ |
2167 | 2202 | //カレントディレクトリを元に戻す |
2168 | 2203 | if(FSchdir(cwdpath)){ |
@@ -2459,7 +2494,7 @@ void control_code_process(unsigned char k,unsigned char sh){ | ||
2459 | 2494 | break; |
2460 | 2495 | case VK_F2: //F2キー |
2461 | 2496 | if(num==0) break; |
2462 | - if(sh & CHK_SHIFT) msra(); //create direct running file | |
2497 | + if(sh & CHK_SHIFT) run(2); //create direct running file | |
2463 | 2498 | else save_as(0); //ファイル名を付けて保存 |
2464 | 2499 | break; |
2465 | 2500 | case VK_F3: //F3キー |
@@ -11,6 +11,7 @@ | ||
11 | 11 | #define CPU_CLOCK_HZ 95454533 |
12 | 12 | #define PERSISTENT_RAM_SIZE (1024*100) // 0x19000 |
13 | 13 | #define MACHIKANIA_OBJ_ADDRESS (0x9D080000 - (0x19000)) |
14 | +#define MACHIKANIA_OBJ_INFO (MACHIKANIA_OBJ_ADDRESS-16) | |
14 | 15 | |
15 | 16 | int readbuttons(); |
16 | 17 | void scroll(int x, int y); |
@@ -300,4 +300,4 @@ int compile_and_link_main_file(char* buff,char* appname){ | ||
300 | 300 | to use the same long var name in different files (note that g_long_name_var_num is not reseted after |
301 | 301 | compiling each class code). |
302 | 302 | */ |
303 | -} | |
\ No newline at end of file | ||
303 | +} |
@@ -12,10 +12,12 @@ | ||
12 | 12 | #include "compiler.h" |
13 | 13 | #include "main.h" |
14 | 14 | |
15 | -// Insert NOP assembly at the begging of MACHIKANIA_OBJ_ADDRESS | |
16 | -const unsigned int const _obj_start_address[] __attribute__((address(MACHIKANIA_OBJ_ADDRESS))) ={ | |
17 | - 0x00000000, // NOP | |
18 | -}; | |
15 | +// Store g_object/g_objpos values for MOS at jest before MACHIKANIA_OBJ_ADDRESS. | |
16 | +// When these values are 0, MOS code is not loaded. | |
17 | +const volatile int __attribute__((address(MACHIKANIA_OBJ_ADDRESS-16))) _reserved1_mos=0; | |
18 | +const volatile int __attribute__((address(MACHIKANIA_OBJ_ADDRESS-12))) _reserved2_mos=0; | |
19 | +const volatile int __attribute__((address(MACHIKANIA_OBJ_ADDRESS-8))) g_object_mos=0; | |
20 | +const volatile int __attribute__((address(MACHIKANIA_OBJ_ADDRESS-4))) g_objpos_mos=0; | |
19 | 21 | |
20 | 22 | // Contain the valus of $gp and $s6 (GPR of MIPS32) |
21 | 23 | int g_gp; |
@@ -22,6 +22,8 @@ | ||
22 | 22 | | | | | +- Checksum |
23 | 23 | | | | | | |
24 | 24 | : 04 0bf0 00 ffffffcf 35 |
25 | + : 02 0000 04 1fc0 1b | |
26 | + : 00 0000 01 FF | |
25 | 27 | |
26 | 28 | Record types: |
27 | 29 | case 0: // data |
@@ -161,9 +163,9 @@ char* hex_read_line(){ | ||
161 | 163 | return 0; |
162 | 164 | } |
163 | 165 | |
164 | -static char g_hex_line[46]; | |
166 | +static char g_hex_line[47]=":"; | |
165 | 167 | void hex_construct_byte(unsigned char data,int pos){ |
166 | - g_hex_line[pos] ="0123456789abcdef"[data>>8]; | |
168 | + g_hex_line[pos+0]="0123456789abcdef"[data>>4]; | |
167 | 169 | g_hex_line[pos+1]="0123456789abcdef"[data&15]; |
168 | 170 | g_checksum+=data; |
169 | 171 | } |
@@ -171,22 +173,22 @@ char* hex_construct_line(){ | ||
171 | 173 | int i; |
172 | 174 | g_checksum=0; |
173 | 175 | // Write size |
174 | - hex_construct_byte(g_hexline.size,0); | |
176 | + hex_construct_byte(g_hexline.size,1); | |
175 | 177 | // Write address |
176 | - hex_construct_byte(g_hexline.address>>8,2); | |
177 | - hex_construct_byte(g_hexline.address&15,4); | |
178 | + hex_construct_byte(g_hexline.address>>8,3); | |
179 | + hex_construct_byte(g_hexline.address&0xff,5); | |
178 | 180 | // Write type |
179 | - hex_construct_byte(g_hexline.type,6); | |
181 | + hex_construct_byte(g_hexline.type,7); | |
180 | 182 | // Write data |
181 | 183 | for(i=0;i<g_hexline.size;i++){ |
182 | - hex_construct_byte(g_hexline.data[i],8+i); | |
184 | + hex_construct_byte(g_hexline.data[i],9+i*2); | |
183 | 185 | } |
184 | 186 | // Write checksum |
185 | - hex_construct_byte(0-g_checksum,8+i); | |
187 | + hex_construct_byte(0-g_checksum,9+i*2); | |
186 | 188 | // 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; | |
189 | + g_hex_line[11+i*2]=0x0d; | |
190 | + g_hex_line[12+i*2]=0x0a; | |
191 | + g_hex_line[13+i*2]=0; | |
190 | 192 | return (char*)&g_hex_line[0]; |
191 | 193 | } |
192 | 194 |
@@ -220,3 +222,50 @@ void hex_close_file(){ | ||
220 | 222 | FSfclose(g_fhandle); |
221 | 223 | } |
222 | 224 | |
225 | +char* hex_write(FSFILE* fhandle){ | |
226 | + int i,j; | |
227 | + char* str; | |
228 | + // Construct the line string. | |
229 | + str=hex_construct_line(); | |
230 | + // Determine string length | |
231 | + for(i=0;str[i];i++); | |
232 | + j=FSfwrite(str,1,i,fhandle); | |
233 | + if (j<i) return ERR_FILE; | |
234 | + return 0; | |
235 | +} | |
236 | + | |
237 | + | |
238 | +char* hex_write_address(FSFILE* fhandle,unsigned short addr){ | |
239 | + int i,j; | |
240 | + char* str; | |
241 | + addr&=0x7fff; // Write 0x1d00 instead of 0x9d00. | |
242 | + g_hexline.size=2; | |
243 | + g_hexline.type=4; | |
244 | + g_hexline.address=0; | |
245 | + g_hexline.data[0]=addr>>8; | |
246 | + g_hexline.data[1]=addr&0xff; | |
247 | + return hex_write(fhandle); | |
248 | +} | |
249 | + | |
250 | +char* hex_write_data_16(FSFILE* fhandle,unsigned short addr,unsigned int* object){ | |
251 | + int i,j; | |
252 | + char* str; | |
253 | + g_hexline.size=16; | |
254 | + g_hexline.type=0; | |
255 | + g_hexline.address=addr; | |
256 | + for(i=0;i<4;i++){ | |
257 | + g_hexline.data[i*4+0]=object[i]; | |
258 | + g_hexline.data[i*4+1]=object[i]>>8; | |
259 | + g_hexline.data[i*4+2]=object[i]>>16; | |
260 | + g_hexline.data[i*4+3]=object[i]>>24; | |
261 | + } | |
262 | + return hex_write(fhandle); | |
263 | +} | |
264 | + | |
265 | +char* hex_write_eof(FSFILE* fhandle){ | |
266 | + int i; | |
267 | + i=FSfwrite(":00000001FF\x0d\x0a",1,13,fhandle); | |
268 | + if (i<13) return ERR_FILE; | |
269 | + return 0; | |
270 | +} | |
271 | + |
@@ -267,6 +267,7 @@ void printhex32(unsigned int d){ | ||
267 | 267 | |
268 | 268 | int main(void){ |
269 | 269 | char *appname,*s; |
270 | + int use_editor; | |
270 | 271 | |
271 | 272 | /* ポートの初期設定 */ |
272 | 273 | CNPUB = 0xFFFF; // PORTB全てプルアップ(I/O) |
@@ -305,6 +306,18 @@ int main(void){ | ||
305 | 306 | // Show blue screen if exception before soft reset. |
306 | 307 | blue_screen(); |
307 | 308 | |
309 | + // 実行中HEXファイル名がHEXFILEと一致するかどうか | |
310 | + use_editor=0; | |
311 | + appname=(char*)FILENAME_FLASH_ADDRESS; | |
312 | + s=HEXFILE; | |
313 | + while(*s++==*appname++) { | |
314 | + if(*s==0) { | |
315 | + //テキストエディター呼び出し | |
316 | + use_editor=1; | |
317 | + break; | |
318 | + } | |
319 | + } | |
320 | + | |
308 | 321 | printstr("MachiKania BASIC System\n"); |
309 | 322 | printstr(" Ver "SYSVER1" "SYSVER2" by KENKEN\n"); |
310 | 323 | printstr("BASIC Compiler "BASVER"\n"); |
@@ -314,12 +327,17 @@ int main(void){ | ||
314 | 327 | printstr("Init File System..."); |
315 | 328 | // Initialize the File System |
316 | 329 | if(FSInit()==FALSE){ //ファイルシステム初期化 |
317 | - //エラーの場合停止 | |
318 | - setcursorcolor(COLOR_ERRORTEXT); | |
319 | - printstr("\nFile System Error\n"); | |
320 | - printstr("Insert Correct Card\n"); | |
321 | - printstr("And Reset\n"); | |
322 | - while(1) asm("wait"); | |
330 | + if (use_editor) { | |
331 | + //エラーの場合停止 | |
332 | + setcursorcolor(COLOR_ERRORTEXT); | |
333 | + printstr("\nFile System Error\n"); | |
334 | + printstr("Insert Correct Card\n"); | |
335 | + printstr("And Reset\n"); | |
336 | + while(1) asm("wait"); | |
337 | + } else { | |
338 | + // MOSモードの場合は、エラー表示の後、続ける | |
339 | + printstr("Not Initialized\n"); | |
340 | + } | |
323 | 341 | } |
324 | 342 | printstr("OK\n"); |
325 | 343 |
@@ -345,19 +363,23 @@ int main(void){ | ||
345 | 363 | set_videomode(initialvmode,0); //ビデオモード切替 |
346 | 364 | |
347 | 365 | // 実行中HEXファイル名がHEXFILEと一致した場合はエディタ起動 |
348 | - appname=(char*)FILENAME_FLASH_ADDRESS; | |
349 | - s=HEXFILE; | |
350 | - while(*s++==*appname++) if(*s==0) texteditor(); //テキストエディター呼び出し | |
366 | + if(use_editor) texteditor(); //テキストエディター呼び出し | |
351 | 367 | |
352 | - // 実行中HEXファイル名の「.HEX」を「.BAS」に置き換えてBASファイルを実行 | |
353 | - appname=(char*)FILENAME_FLASH_ADDRESS; | |
354 | - s=tempfile; | |
355 | - while(*appname!='.') *s++=*appname++; | |
356 | - appname=".BAS"; | |
357 | - while(*appname!=0) *s++=*appname++; | |
358 | - *s=0; | |
359 | - // buttonmode(); //ボタン有効化 | |
360 | - g_disable_break=1; // Breakキー無効化 | |
361 | - runbasic(tempfile,0); | |
368 | + if (g_objpos_mos) { | |
369 | + // MOSからコードをコピーして実行 | |
370 | + g_disable_break=1; // Breakキー無効化 | |
371 | + runbasic(0,2); | |
372 | + } else { | |
373 | + // 実行中HEXファイル名の「.HEX」を「.BAS」に置き換えてBASファイルを実行 | |
374 | + appname=(char*)FILENAME_FLASH_ADDRESS; | |
375 | + s=tempfile; | |
376 | + while(*appname!='.') *s++=*appname++; | |
377 | + appname=".BAS"; | |
378 | + while(*appname!=0) *s++=*appname++; | |
379 | + *s=0; | |
380 | + // buttonmode(); //ボタン有効化 | |
381 | + g_disable_break=1; // Breakキー無効化 | |
382 | + runbasic(tempfile,0); | |
383 | + } | |
362 | 384 | while(1) asm(WAIT); |
363 | 385 | } |
@@ -32,10 +32,14 @@ char* printdec(int num){ | ||
32 | 32 | } |
33 | 33 | } |
34 | 34 | |
35 | -int runbasic(char *appname,int test){ | |
35 | +#define RUNMODE_COMPILE_AND_RUN 0 | |
36 | +#define RUNMODE_COMPILE_ONLY 1 | |
37 | +#define RUNMODE_COPY_AND_RUN 2 | |
38 | + | |
39 | +int runbasic(char *appname,int mode){ | |
36 | 40 | // BASICソースのコンパイルと実行 |
37 | 41 | // appname 実行するBASICソースファイル |
38 | -// test 0:コンパイルと実行、0以外:コンパイルのみで終了 | |
42 | +// mode 0:コンパイルと実行、1:コンパイルのみで終了、2:コンパイル済みオブジェクトを実行 | |
39 | 43 | // |
40 | 44 | // 戻り値 |
41 | 45 | // 0:正常終了 |
@@ -57,16 +61,18 @@ int runbasic(char *appname,int test){ | ||
57 | 61 | // Clear object area |
58 | 62 | for(i=0;i<RAMSIZE/4;i++) g_object[i]=0x00000000; |
59 | 63 | |
60 | - // Check file error | |
61 | - err=init_file(buff,appname); | |
62 | - if (err) { | |
63 | - setcursorcolor(COLOR_ERRORTEXT); | |
64 | - printstr("Can't Open "); | |
65 | - printstr(appname); | |
66 | - printchar('\n'); | |
67 | - return -1; | |
64 | + if (mode!=RUNMODE_COPY_AND_RUN) { | |
65 | + // Check file error | |
66 | + err=init_file(buff,appname); | |
67 | + if (err) { | |
68 | + setcursorcolor(COLOR_ERRORTEXT); | |
69 | + printstr("Can't Open "); | |
70 | + printstr(appname); | |
71 | + printchar('\n'); | |
72 | + return -1; | |
73 | + } | |
74 | + close_file(); | |
68 | 75 | } |
69 | - close_file(); | |
70 | 76 | |
71 | 77 | // Initialize parameters |
72 | 78 | g_pcg_font=0; |
@@ -75,7 +81,6 @@ int runbasic(char *appname,int test){ | ||
75 | 81 | clearscreen(); |
76 | 82 | setcursor(0,0,7); |
77 | 83 | g_long_name_var_num=0; |
78 | - cmpdata_init(); | |
79 | 84 | |
80 | 85 | // Initialize music system |
81 | 86 | init_music(); |
@@ -85,13 +90,24 @@ int runbasic(char *appname,int test){ | ||
85 | 90 | |
86 | 91 | printstr("Compiling..."); |
87 | 92 | |
88 | - // Compile the file | |
89 | - i=compile_and_link_main_file(buff,appname); | |
90 | - if (i) return i; | |
91 | - | |
93 | + if (mode==RUNMODE_COPY_AND_RUN) { | |
94 | + // Copy the object from MOS | |
95 | + appname=(char*)MACHIKANIA_OBJ_ADDRESS; | |
96 | + for(i=0;i<RAMSIZE;i++) RAM[i]=appname[i]; | |
97 | + // Set g_object/g_objpos for library functions like lib_read(). | |
98 | + // The g_object/g_objpos values are stoared just before MOS. | |
99 | + g_object=(int*)g_object_mos; | |
100 | + g_objpos=g_objpos_mos; | |
101 | + } else { | |
102 | + // Initialize compiler | |
103 | + cmpdata_init(); | |
104 | + // Compile the file | |
105 | + i=compile_and_link_main_file(buff,appname); | |
106 | + if (i) return i; | |
107 | + } | |
92 | 108 | // All done |
93 | 109 | printstr("done\n"); |
94 | - if(test) return 0; //コンパイルのみの場合 | |
110 | + if(mode==RUNMODE_COMPILE_ONLY) return 0; //コンパイルのみの場合 | |
95 | 111 | wait60thsec(15); |
96 | 112 | |
97 | 113 | // Initialize the other parameters |
@@ -131,3 +147,114 @@ int runbasic(char *appname,int test){ | ||
131 | 147 | |
132 | 148 | return 0; |
133 | 149 | } |
150 | + | |
151 | +int create_self_running_hex(char* hexfilename){ | |
152 | + int i,j,fpos; | |
153 | + FSFILE* dst_file; | |
154 | + char* buff; | |
155 | + char* err; | |
156 | + unsigned int* object; | |
157 | + unsigned int addr,adjust; | |
158 | + unsigned int data[4]; | |
159 | + // Set buffer positions | |
160 | + buff=(char*)&(RAM[RAMSIZE-512]); | |
161 | + // Open original and destination HEX files. | |
162 | + if (hex_init_file(buff,HEXFILE)) return -1; | |
163 | + dst_file=FSfopen(hexfilename,"w"); | |
164 | + if (!dst_file) { | |
165 | + hex_close_file(); | |
166 | + return -1; | |
167 | + } | |
168 | + // Copy the HEX file from original MachiKania, except for MOS. | |
169 | + addr=0; | |
170 | + fpos=0; | |
171 | + while(1) { | |
172 | + if (0==((fpos++)&0x3ff)) { | |
173 | + // Indicator works every 1024 lines | |
174 | + printchar('.'); | |
175 | + } | |
176 | + err=hex_read_line(); | |
177 | + if (err) break; | |
178 | + // Determine type and current address. | |
179 | + // If address is OK, write it to destination. | |
180 | + if (g_hexline.type==1) { | |
181 | + // EOF | |
182 | + break; | |
183 | + } else if (g_hexline.type==4) { | |
184 | + // extended linear address | |
185 | + addr=g_hexline.data[0]; | |
186 | + addr=addr<<8; | |
187 | + addr|=g_hexline.data[1]; | |
188 | + addr=addr<<16; | |
189 | + // Highest bit will be 1 for 0x9D0xxxxx instead of 0x1D0xxxxx | |
190 | + addr|=0x80000000; | |
191 | + // Write this anyway | |
192 | + err=hex_write(dst_file); | |
193 | + if (err) break; | |
194 | + } else if (g_hexline.type==0) { | |
195 | + // data | |
196 | + addr&=0xffff0000; | |
197 | + addr|=g_hexline.address; | |
198 | + // Write this line if not in MOS | |
199 | + if (addr<MACHIKANIA_OBJ_INFO || FILENAME_FLASH_ADDRESS<=addr) { | |
200 | + err=hex_write(dst_file); | |
201 | + if (err) break; | |
202 | + } | |
203 | + } else { | |
204 | + // Unknown type | |
205 | + err=ERR_HEX_ERROR; | |
206 | + break; | |
207 | + } | |
208 | + } | |
209 | + hex_close_file(); | |
210 | + if (err) { | |
211 | + FSfclose(dst_file); | |
212 | + printstr(err); | |
213 | + return -1; | |
214 | + } | |
215 | + // Save MACHIKANIA_OBJ_INFO | |
216 | + addr=MACHIKANIA_OBJ_INFO; | |
217 | + err=hex_write_address(dst_file,addr>>16); | |
218 | + if (!err) { | |
219 | + data[2]=(int)g_object; | |
220 | + data[3]=(int)g_objpos; | |
221 | + err=hex_write_data_16(dst_file,addr&0xffff,&data[0]); | |
222 | + } | |
223 | + if (err) { | |
224 | + FSfclose(dst_file); | |
225 | + printstr(err); | |
226 | + return -1; | |
227 | + } | |
228 | + // Add MOS. Adjustment is for changing address from RAM area to MOS. | |
229 | + addr=-1; | |
230 | + object=(unsigned int*)(&RAM[0]); | |
231 | + adjust=(unsigned int)MACHIKANIA_OBJ_ADDRESS-(unsigned int)object; | |
232 | + while(object<(unsigned int*)(&g_object[g_objpos])){ | |
233 | + if (0==((fpos++)&0x3ff)) { | |
234 | + // Indicator works every 1024 lines | |
235 | + printchar('.'); | |
236 | + } | |
237 | + if ((0x7fff0000 & ((unsigned int)object+adjust)) != addr) { | |
238 | + // Construct a hex line for providing Extended linear addres | |
239 | + addr=0x7fff0000 & ((unsigned int)object+adjust); | |
240 | + err=hex_write_address(dst_file,addr>>16); | |
241 | + if (err) break; | |
242 | + } | |
243 | + // Construct a hex line for data | |
244 | + err=hex_write_data_16(dst_file,((unsigned int)object+adjust)&0xffff,object); | |
245 | + if (err) break; | |
246 | + // All OK for these 4 words (16 bytes). | |
247 | + object+=4; | |
248 | + err=0; | |
249 | + } | |
250 | + if (err) { | |
251 | + FSfclose(dst_file); | |
252 | + printstr(err); | |
253 | + return -1; | |
254 | + } | |
255 | + // All done. Write EOF | |
256 | + err=hex_write_eof(dst_file); | |
257 | + FSfclose(dst_file); | |
258 | + if (err) return -1; | |
259 | + return 0; | |
260 | +} |
@@ -15,6 +15,13 @@ | ||
15 | 15 | char* simple_string(void); |
16 | 16 | */ |
17 | 17 | |
18 | +/* | |
19 | + All the code from this file will be assigned in MachiKania Object Section (MOS). | |
20 | + MOS will be replaced by BASIC object when constructing self-running HEX file. | |
21 | + Therefore, DO NOT place any run-time routine/romdata in this file. | |
22 | + See the MOS definition in liker script. | |
23 | +*/ | |
24 | + | |
18 | 25 | #include "api.h" |
19 | 26 | #include "compiler.h" |
20 | 27 |
@@ -13,6 +13,13 @@ | ||
13 | 13 | Public function is only get_value(). |
14 | 14 | */ |
15 | 15 | |
16 | +/* | |
17 | + All the code from this file will be assigned in MachiKania Object Section (MOS). | |
18 | + MOS will be replaced by BASIC object when constructing self-running HEX file. | |
19 | + Therefore, DO NOT place any run-time routine/romdata in this file. | |
20 | + See the MOS definition in liker script. | |
21 | +*/ | |
22 | + | |
16 | 23 | #include "compiler.h" |
17 | 24 | |
18 | 25 | char* get_value(); |