• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

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

Révision98d48ce13ededa77468aaa3f6af73c953618344d (tree)
l'heure2019-05-20 08:14:14
AuteurKatsumi <kmorimatsu@sour...>
CommiterKatsumi

Message de Log

New MSRA mode.

Change Summary

Modification

--- a/mips/megalopa/app_p32MX370F512H.ld
+++ b/mips/megalopa/app_p32MX370F512H.ld
@@ -102,9 +102,9 @@ _GEN_EXCPT_ADDR = _ebase_address + 0x180;
102102 *************************************************************************/
103103 MEMORY
104104 {
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)
106106 /* 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 */
108108 kseg0_boot_mem : ORIGIN = (0x9D006000+0x1000+0x490), LENGTH = 0 /* dummy */
109109 exception_mem : ORIGIN = 0x9D006000, LENGTH = 0x1000
110110 kseg1_boot_mem : ORIGIN = (0x9D006000+0x1000), LENGTH = 0x490
@@ -145,13 +145,19 @@ SECTIONS
145145 {
146146 KEEP (*\statement.o(.text))
147147 KEEP (*\function.o(.text))
148+ KEEP (*\value.o(.text))
149+ KEEP (*\string.o(.text))
148150 KEEP (*\float.o(.text))
151+ KEEP (*\cmpdata.o(.text))
149152 } >kseg2_program_mem
150153 .machikaniaobjrodata :
151154 {
152155 KEEP (*\statement.o(.rodata))
153156 KEEP (*\function.o(.rodata))
157+ KEEP (*\value.o(.rodata))
158+ KEEP (*\string.o(.rodata))
154159 KEEP (*\float.o(.rodata))
160+ KEEP (*\cmpdata.o(.rodata))
155161 } >kseg2_program_mem
156162
157163 /* Boot Sections */
--- a/mips/megalopa/clib.c
+++ b/mips/megalopa/clib.c
@@ -116,7 +116,7 @@ char* useclib_statement(){
116116 int i;
117117 int* cmpdata;
118118 // Initialize g_data_clib_var[]
119- g_data_clib_var[0]=g_gp;
119+ g_data_clib_var[0]=(void*)g_gp;
120120 do {
121121 next_position();
122122 i=check_var_name();
--- a/mips/megalopa/cmpdata.c
+++ b/mips/megalopa/cmpdata.c
@@ -9,6 +9,13 @@
99 This file is shared by Megalopa and Zoea
1010 */
1111
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+
1219 #include "compiler.h"
1320
1421 /*
--- a/mips/megalopa/compiler.h
+++ b/mips/megalopa/compiler.h
@@ -195,6 +195,8 @@ enum functions{
195195 };
196196
197197 /* Global vars (see globalvers.c) */
198+extern const volatile int g_object_mos;
199+extern const volatile int g_objpos_mos;
198200 extern int g_intconst;
199201 extern char g_valueisconst;
200202 extern unsigned int g_rnd_seed;
@@ -256,6 +258,7 @@ char* compile_file();
256258 int compile_and_link_file(char* buff,char* appname);
257259 int compile_and_link_main_file(char* buff,char* appname);
258260 int compile_and_link_class(char* buff,int class);
261+int create_self_running_hex(char* hexfilename);
259262
260263 void err_break(void);
261264 void err_music(char* str);
@@ -404,6 +407,12 @@ void hex_reinit_file();
404407 void hex_close_file();
405408 char* hex_read_line();
406409 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
407416
408417 /* Error messages */
409418 #define ERR_SYNTAX (char*)(g_err_str[0])
--- a/mips/megalopa/editor.c
+++ b/mips/megalopa/editor.c
@@ -1839,7 +1839,8 @@ void msra(void){
18391839 setcursor(0,0,COLOR_NORMALTEXT);
18401840 printstr("Make Self-Running Application\n\n");
18411841 printstr("(Work on Root Directory)\n");
1842-
1842+// MOS: delete region not required
1843+/*
18431844 //カレントディレクトリを変数cwdpathにコピー
18441845 while(1){
18451846 if(FSgetcwd(cwdpath,PATHNAMEMAX)) break;
@@ -1859,30 +1860,44 @@ void msra(void){
18591860 pd=tempfile;
18601861 while(*ps!=0) *pd++=*ps++;
18611862 *pd=0;
1862-
1863+//*/
18631864 while(1){
18641865 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+
18661870 if(lineinput(tempfile,8+1+3)<0){
18671871 //ESCキーが押された
1868- FSchdir(cwdpath); //カレントディレクトリを元に戻す
1872+// MOS: delete region not required
1873+// FSchdir(cwdpath); //カレントディレクトリを元に戻す
18691874 return;
18701875 }
18711876 ps=tempfile;
18721877 while(*ps!='.' && *ps!=0) ps++;
18731878 if(ps+4>=tempfile+13 ||
18741879 *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') ||
18781887 *(ps+4)!=0){
18791888 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");
18811892 continue;
18821893 }
18831894 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:エラーコード
18861901 if(er==0) break;
18871902 setcursorcolor(COLOR_ERRORTEXT);
18881903 if(er==ERR_CANTFILEOPEN) printstr("Bad File Name or File Error\n");
@@ -1898,6 +1913,8 @@ void msra(void){
18981913 }
18991914 }
19001915 printstr("OK\n\n");
1916+// MOS: delete region not required
1917+/*
19011918 FSremove(TEMPFILENAME); //実行時に生成する一時ファイルを削除
19021919 //tempfileからcurrentfileにコピーして終了
19031920 ps=tempfile;
@@ -1933,6 +1950,7 @@ void msra(void){
19331950 else if(er==ERR_CANTWRITEFILE){
19341951 printstr("Write Error\n");
19351952 }
1953+//*/
19361954 setcursorcolor(COLOR_NORMALTEXT);
19371955 printstr((unsigned char *)Message1);// Hit Any Key
19381956 inputchar(); //1文字入力待ち
@@ -2044,7 +2062,7 @@ void changewidth(void){
20442062 }
20452063 void run(int test){
20462064 //KM-BASICコンパイル&実行
2047-// test 0:コンパイルと実行、0以外:コンパイルのみで終了
2065+// test 0:コンパイルと実行、1:コンパイルのみで終了、2:コンパイルの後、HEXファイルを作製
20482066 int er,er2;
20492067 FSFILE *fp;
20502068 unsigned int disptoppos,cursorpos;
@@ -2120,7 +2138,18 @@ void run(int test){
21202138 // Enable Break key
21212139 g_disable_break=0;
21222140 //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);
21242153
21252154 stopPCG();//システムフォントに戻す
21262155 setcursorcolor(COLOR_NORMALTEXT);
@@ -2163,6 +2192,12 @@ void run(int test){
21632192 FSremove(WORKDIRFILE); //パス名保存ファイル削除
21642193 break;
21652194 }
2195+// MOS: insertion
2196+ if (2==test) {
2197+ // Create HEX file as Self Running Apprication
2198+ msra();
2199+ }
2200+//*/
21662201 while(1){
21672202 //カレントディレクトリを元に戻す
21682203 if(FSchdir(cwdpath)){
@@ -2459,7 +2494,7 @@ void control_code_process(unsigned char k,unsigned char sh){
24592494 break;
24602495 case VK_F2: //F2キー
24612496 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
24632498 else save_as(0); //ファイル名を付けて保存
24642499 break;
24652500 case VK_F3: //F3キー
--- a/mips/megalopa/envspecific.h
+++ b/mips/megalopa/envspecific.h
@@ -11,6 +11,7 @@
1111 #define CPU_CLOCK_HZ 95454533
1212 #define PERSISTENT_RAM_SIZE (1024*100) // 0x19000
1313 #define MACHIKANIA_OBJ_ADDRESS (0x9D080000 - (0x19000))
14+#define MACHIKANIA_OBJ_INFO (MACHIKANIA_OBJ_ADDRESS-16)
1415
1516 int readbuttons();
1617 void scroll(int x, int y);
--- a/mips/megalopa/file.c
+++ b/mips/megalopa/file.c
@@ -300,4 +300,4 @@ int compile_and_link_main_file(char* buff,char* appname){
300300 to use the same long var name in different files (note that g_long_name_var_num is not reseted after
301301 compiling each class code).
302302 */
303-}
\ No newline at end of file
303+}
--- a/mips/megalopa/globalvars.c
+++ b/mips/megalopa/globalvars.c
@@ -12,10 +12,12 @@
1212 #include "compiler.h"
1313 #include "main.h"
1414
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;
1921
2022 // Contain the valus of $gp and $s6 (GPR of MIPS32)
2123 int g_gp;
--- a/mips/megalopa/hexfile.c
+++ b/mips/megalopa/hexfile.c
@@ -22,6 +22,8 @@
2222 | | | | +- Checksum
2323 | | | | |
2424 : 04 0bf0 00 ffffffcf 35
25+ : 02 0000 04 1fc0 1b
26+ : 00 0000 01 FF
2527
2628 Record types:
2729 case 0: // data
@@ -161,9 +163,9 @@ char* hex_read_line(){
161163 return 0;
162164 }
163165
164-static char g_hex_line[46];
166+static char g_hex_line[47]=":";
165167 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];
167169 g_hex_line[pos+1]="0123456789abcdef"[data&15];
168170 g_checksum+=data;
169171 }
@@ -171,22 +173,22 @@ char* hex_construct_line(){
171173 int i;
172174 g_checksum=0;
173175 // Write size
174- hex_construct_byte(g_hexline.size,0);
176+ hex_construct_byte(g_hexline.size,1);
175177 // 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);
178180 // Write type
179- hex_construct_byte(g_hexline.type,6);
181+ hex_construct_byte(g_hexline.type,7);
180182 // Write data
181183 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);
183185 }
184186 // Write checksum
185- hex_construct_byte(0-g_checksum,8+i);
187+ hex_construct_byte(0-g_checksum,9+i*2);
186188 // 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;
190192 return (char*)&g_hex_line[0];
191193 }
192194
@@ -220,3 +222,50 @@ void hex_close_file(){
220222 FSfclose(g_fhandle);
221223 }
222224
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+
--- a/mips/megalopa/main.c
+++ b/mips/megalopa/main.c
@@ -267,6 +267,7 @@ void printhex32(unsigned int d){
267267
268268 int main(void){
269269 char *appname,*s;
270+ int use_editor;
270271
271272 /* ポートの初期設定 */
272273 CNPUB = 0xFFFF; // PORTB全てプルアップ(I/O)
@@ -305,6 +306,18 @@ int main(void){
305306 // Show blue screen if exception before soft reset.
306307 blue_screen();
307308
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+
308321 printstr("MachiKania BASIC System\n");
309322 printstr(" Ver "SYSVER1" "SYSVER2" by KENKEN\n");
310323 printstr("BASIC Compiler "BASVER"\n");
@@ -314,12 +327,17 @@ int main(void){
314327 printstr("Init File System...");
315328 // Initialize the File System
316329 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+ }
323341 }
324342 printstr("OK\n");
325343
@@ -345,19 +363,23 @@ int main(void){
345363 set_videomode(initialvmode,0); //ビデオモード切替
346364
347365 // 実行中HEXファイル名がHEXFILEと一致した場合はエディタ起動
348- appname=(char*)FILENAME_FLASH_ADDRESS;
349- s=HEXFILE;
350- while(*s++==*appname++) if(*s==0) texteditor(); //テキストエディター呼び出し
366+ if(use_editor) texteditor(); //テキストエディター呼び出し
351367
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+ }
362384 while(1) asm(WAIT);
363385 }
--- a/mips/megalopa/run.c
+++ b/mips/megalopa/run.c
@@ -32,10 +32,14 @@ char* printdec(int num){
3232 }
3333 }
3434
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){
3640 // BASICソースのコンパイルと実行
3741 // appname 実行するBASICソースファイル
38-// test 0:コンパイルと実行、0以外:コンパイルのみで終了
42+// mode 0:コンパイルと実行、1:コンパイルのみで終了、2:コンパイル済みオブジェクトを実行
3943 //
4044 // 戻り値
4145 //  0:正常終了
@@ -57,16 +61,18 @@ int runbasic(char *appname,int test){
5761 // Clear object area
5862 for(i=0;i<RAMSIZE/4;i++) g_object[i]=0x00000000;
5963
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();
6875 }
69- close_file();
7076
7177 // Initialize parameters
7278 g_pcg_font=0;
@@ -75,7 +81,6 @@ int runbasic(char *appname,int test){
7581 clearscreen();
7682 setcursor(0,0,7);
7783 g_long_name_var_num=0;
78- cmpdata_init();
7984
8085 // Initialize music system
8186 init_music();
@@ -85,13 +90,24 @@ int runbasic(char *appname,int test){
8590
8691 printstr("Compiling...");
8792
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+ }
92108 // All done
93109 printstr("done\n");
94- if(test) return 0; //コンパイルのみの場合
110+ if(mode==RUNMODE_COMPILE_ONLY) return 0; //コンパイルのみの場合
95111 wait60thsec(15);
96112
97113 // Initialize the other parameters
@@ -131,3 +147,114 @@ int runbasic(char *appname,int test){
131147
132148 return 0;
133149 }
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+}
--- a/mips/megalopa/string.c
+++ b/mips/megalopa/string.c
@@ -15,6 +15,13 @@
1515 char* simple_string(void);
1616 */
1717
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+
1825 #include "api.h"
1926 #include "compiler.h"
2027
--- a/mips/megalopa/value.c
+++ b/mips/megalopa/value.c
@@ -13,6 +13,13 @@
1313 Public function is only get_value().
1414 */
1515
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+
1623 #include "compiler.h"
1724
1825 char* get_value();