OSDN Git Service

d9368b46bc1480899907a897514b46e2e37ad6f9
[nxt-jsp/lejos_nxj.git] / nxtOSEK / lejos_nxj / src / nxtvm / platform / unix / nativeemul.c
1 /**
2  * nativeemul.c
3  * Native method handling for unix_impl (emulation).
4  */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <strings.h>
8 #include "types.h"
9 #include "trace.h"
10 #include "constants.h"
11 #include "specialsignatures.h"
12 #include "specialclasses.h"
13 #include "stack.h"
14 #include "memory.h"
15 #include "threads.h"
16 #include "classes.h"
17 #include "language.h"
18 #include "configure.h"
19 #include "interpreter.h"
20 #include "exceptions.h"
21 #include "platform_config.h"
22 #include "sensors.h"
23 #include "poll.h"
24
25 #define MAJOR_VERSION 0
26 #define MINOR_VERSION 6
27
28 #undef push_word
29 #undef push_ref
30 #define push_word( a) push_word_cur( a)
31 #define push_ref( a)  push_ref_cur( a)
32
33 static TWOBYTES gSensorValue = 0;
34
35 static char* sensorReadTypes[3] = {
36   "RAW",
37   "CANONICAL",
38   "BOOLEAN"
39 };
40
41 static char *sensorSetTypes[5] = {
42   "RAW",
43   "TOUCH",
44   "TEMP",
45   "LIGHT",
46   "ROT"
47 };
48
49 #define DISPLAY_WIDTH 100
50 #define DISPLAY_DEPTH 8
51
52 static struct
53 {
54   Object hdr;
55   unsigned char display[DISPLAY_DEPTH+1][DISPLAY_WIDTH];
56 } __attribute__((packed)) display_array;
57
58 static char display_init() 
59 {
60   // Initialise the array parameters so that the display can
61   // be memory mapped into the Java address space
62   display_array.hdr.flags.arrays.isArray = 1;
63   // NOTE This object must always be marked, otherwise very, very bad
64   // things will happen!
65   display_array.hdr.flags.arrays.mark = 1;
66   display_array.hdr.flags.arrays.length = 200;
67   display_array.hdr.flags.arrays.isAllocated = 1;
68   display_array.hdr.flags.arrays.type = T_INT;
69   display_array.hdr.monitorCount = 0;
70   display_array.hdr.threadId = 0;
71 }
72
73 static char *getSensorMode(byte code)
74 {
75   static char smBuffer[256];
76
77   strcpy(smBuffer, "mode = ");  
78   switch (code & 0xF0)
79   {
80     case 0x00: strcat(smBuffer, "RAW"); break;
81     case 0x20: strcat(smBuffer, "BOOLEAN"); break;
82     case 0x40: strcat(smBuffer, "EDGE"); break;
83     case 0x60: strcat(smBuffer, "PULSE"); break;
84     case 0x80: strcat(smBuffer, "PERCENT"); break;
85     case 0xA0: strcat(smBuffer, "DEGC"); break;
86     case 0xC0: strcat(smBuffer, "DEGF"); break;
87     case 0xE0: strcat(smBuffer, "ANGLE"); break;
88     default: sprintf(smBuffer, "mode = INVALID (0x%1X)", code & 0xF0); break;
89   }
90   
91   sprintf(&smBuffer[strlen(smBuffer)], ", slope = %d", code & 0x0F);
92   return smBuffer;
93 }
94
95 extern int      verbose;        /* If non-zero, generates verbose output. */
96 extern byte *region;
97
98 char *get_meaning(STACKWORD *);
99
100 void dump_flag(Object *obj)
101 {
102   if (is_allocated(obj))
103   {
104     if (is_gc(obj))
105     {
106       printf("Ready for the garbage\n");
107     }
108     else if (is_array(obj))
109     {
110       printf("Array, type=%d, length=%d\n", get_element_type(obj), get_array_length(obj));
111     }
112     else
113     {
114       printf("Class index = %d\n", get_na_class_index(obj));
115     }
116   }
117   else
118   {
119     printf ("Free block, length=%d\n", get_free_length(obj));
120   }
121   
122   /**
123    * Object/block flags.
124    * Free block:
125    *  -- bits 0-14: Size of free block in words.
126    *  -- bit 15   : Zero (not allocated).
127    * Objects:
128    *  -- bits 0-7 : Class index.
129    *  -- bits 8-12: Unused.
130    *  -- bit 13   : Garbage collection mark.
131    *  -- bit 14   : Zero (not an array).
132    *  -- bit 15   : One (allocated).
133    * Arrays:
134    *  -- bits 0-8 : Array length (0-527).
135    *  -- bits 9-12: Element type.
136    *  -- bit 13   : Garbage collection mark.
137    *  -- bit 14   : One (is an array).
138    *  -- bit 15   : One (allocated).
139    */
140
141 }
142 char* string2chp(String* s)
143 {
144   char *ret = "null";
145   if (s->characters)
146   {
147     int i;
148     Object *obj;
149     JCHAR *pA;
150     int length;
151     obj = word2obj(get_word_4_ns((byte*)(&(s->characters))));
152     pA = jchar_array(obj);
153     length = get_array_length(obj);
154     ret = malloc(length+1);
155     for (i=0; i<length; i++)
156     {
157       ret[i] = pA[i];
158     }
159     ret[i] = 0;
160   }
161
162   return ret;
163 }
164
165 boolean debug_uncaught_exception(Object * exception,
166                           const Thread * thread,
167                           const MethodRecord * methodRecord,
168                           const MethodRecord * rootMethod,
169                           byte * pc, int exceptionFrame)
170 {
171   return false;
172 }
173
174 /**
175  * NOTE: The technique is not the same as that used in TinyVM.
176  */
177 void dispatch_native (TWOBYTES signature, STACKWORD *paramBase)
178 {
179         ClassRecord     *classRecord;
180
181   switch (signature)
182   {
183     case wait_4_5V:
184       monitor_wait((Object*) word2ptr(paramBase[0]), 0);
185       return;
186     case wait_4J_5V:
187       monitor_wait((Object*) word2ptr(paramBase[0]), paramBase[2]);
188       return;
189     case notify_4_5V:
190       monitor_notify((Object*) word2ptr(paramBase[0]), false);
191       return;
192     case notifyAll_4_5V:
193       monitor_notify((Object*) word2ptr(paramBase[0]), true);
194       return;
195     case start_4_5V:
196       init_thread ((Thread *) word2ptr(paramBase[0]));
197       return;
198     case yield_4_5V:
199       schedule_request( REQUEST_SWITCH_THREAD);
200       return;
201     case sleep_4J_5V:
202       sleep_thread (paramBase[1]);
203       schedule_request( REQUEST_SWITCH_THREAD);
204       return;
205     case getPriority_4_5I:
206       push_word (get_thread_priority ((Thread*)word2ptr(paramBase[0])));
207       return;
208     case setPriority_4I_5V:
209       {
210         STACKWORD p = (STACKWORD)paramBase[1];
211         if (p > MAX_PRIORITY || p < MIN_PRIORITY)
212           throw_exception(illegalArgumentException);
213         else
214           set_thread_priority ((Thread*)word2ptr(paramBase[0]), p);
215       }
216       return;
217     case currentThread_4_5Ljava_3lang_3Thread_2:
218       push_ref(ptr2ref(currentThread));
219       return;
220     case interrupt_4_5V:
221       interrupt_thread((Thread*)word2ptr(paramBase[0]));
222       return;
223     case interrupted_4_5Z:
224       {
225         JBYTE i = currentThread->interruptState != INTERRUPT_CLEARED;
226         currentThread->interruptState = INTERRUPT_CLEARED;
227         push_word(i);
228       }
229       return;
230     case isInterrupted_4_5Z:
231       push_word(((Thread*)word2ptr(paramBase[0]))->interruptState
232                 != INTERRUPT_CLEARED);
233       return;
234     case setDaemon_4Z_5V:
235       ((Thread*)word2ptr(paramBase[0]))->daemon = (JBYTE)paramBase[1];
236       return;
237     case isDaemon_4_5Z:
238       push_word(((Thread*)word2ptr(paramBase[0]))->daemon);
239       return;
240     case join_4_5V:
241       join_thread((Thread*)word2ptr(paramBase[0]));
242       return;
243     case join_4J_5V:
244       join_thread((Thread*)word2obj(paramBase[0]));
245       return;
246     case exit_4I_5V:
247       schedule_request(REQUEST_EXIT);
248       return;
249     case currentTimeMillis_4_5J:
250       push_word (0);
251       push_word (get_sys_time());
252       return;
253     case setPoller_4_5V:
254       set_poller(word2ptr(paramBase[0]));
255       return;
256     case readSensorValue_4I_5I:
257       // Parameters: int portId
258       if (verbose)
259          printf("> ");
260       else
261          printf("& ");
262       printf("Reading sensor %d, returned value %d\n",paramBase[0], sensors[paramBase[0]].value);
263       push_word (sensors[paramBase[0]].value);
264       return;
265     case setADTypeById_4II_5V:
266       if (verbose)
267          printf("> ");
268       else
269          printf("& ");
270       printf("Setting sensor %d to AD type %d\n",paramBase[0], paramBase[1]);
271       return;
272     case setPowerTypeById_4II_5V:
273        if (verbose)
274          printf("> ");
275       else
276          printf("& ");
277       printf("Setting sensor %d to power type %d\n",paramBase[0], paramBase[1]);
278     return; 
279     case freeMemory_4_5J:
280       push_word (0);
281       push_word (getHeapFree());
282       return;
283     case totalMemory_4_5J:
284       push_word (0);
285       push_word (getHeapSize());
286       return;
287     case test_4Ljava_3lang_3String_2Z_5V:
288       if (!paramBase[1])
289       {
290         printf("%s\n",string2chp((String*)word2ptr(paramBase[0])));
291         throw_exception(error);
292       }
293       return;
294     case testEQ_4Ljava_3lang_3String_2II_5V:
295       if (paramBase[1] != paramBase[2])
296       {
297         printf("%s: expected %ld, got %ld\n",string2chp((String*)word2ptr(paramBase[0])), paramBase[1], paramBase[2]);
298         throw_exception(error);
299       }
300       return;
301     case floatToIntBits_4F_5I: // Fall through
302     case intBitsToFloat_4I_5F:
303       push_word (paramBase[0]);
304       return;
305     case drawString_4Ljava_3lang_3String_2II_5V:
306       {
307         byte *p = word2ptr(paramBase[0]);
308         int len, i;
309         //printf("displayString: pointer is %x\n",p);
310         //printf("Object size is %d\n",sizeof(Object));
311         Object *charArray = (Object *) word2ptr(get_word_4_ns(p + HEADER_SIZE));
312         //printf("Chars is %x\n",charArray);
313         len = charArray->flags.arrays.length;
314         //printf("length is %d\n",len);
315         {
316          char buff[len+1];
317          char *chars = ((char *) charArray) + HEADER_SIZE;
318          //printf("chars is %x\n",chars);
319          for(i=0;i<len;i++) buff[i] = chars[i+i];
320          buff[len] = 0;
321          if (verbose)
322            printf("> ");
323          else
324            printf("& ");
325          printf("drawString called with parameters %s, %d, %d\n",buff,paramBase[1],paramBase[2]);
326         }
327       }
328       return;
329     case drawInt_4III_5V:
330       if (verbose)
331          printf("> ");
332       else
333          printf("& ");
334       printf("drawInt called with parameters %d, %d, %d\n",paramBase[0],paramBase[1],paramBase[2]);
335       return;
336     case drawInt_4IIII_5V:
337       if (verbose)
338          printf("> ");
339       else
340          printf("& ");
341       printf("drawInt called with parameters %d, %d, %d, %d\n",paramBase[0],paramBase[1],paramBase[2],paramBase[3]);
342     return; 
343     case refresh_4_5V:
344       if (verbose)
345          printf("> ");
346       else
347          printf("& ");
348       printf("Displayed Refreshed\n");
349       return;
350     case clear_4_5V:
351       if (verbose)
352          printf("> ");
353       else
354          printf("& ");
355       printf("Display cleared\n");
356       return;
357     case setDisplay_4_1I_5V:
358       if (verbose)
359          printf("> ");
360       else
361          printf("& ");
362       printf("Display set\n");
363       return;  
364     case getDisplay_4_5_1B:
365       if (verbose)
366          printf("> ");
367       else
368          printf("& ");
369       printf("Get display\n");
370       display_init();
371       push_word((STACKWORD) ptr2word(&display_array));
372       return;
373     case setAutoRefresh_4I_5V:
374       if (verbose)
375          printf("> ");
376       else
377          printf("& ");
378       printf("Set autodisplay to %d\n", paramBase[0]);
379       return;
380     case bitBlt_4_1BIIII_1BIIIIIII_5V:
381       {
382         Object *src = word2ptr(paramBase[0]);
383         Object *dst = word2ptr(paramBase[5]);
384         if (verbose)
385           printf("> ");
386         else
387           printf("& ");
388         printf("bitBlt called\n");
389         return;
390       }
391     case getSystemFont_4_5_1B:
392       if (verbose)
393          printf("> ");
394       else
395          printf("& ");
396       printf("getSystemFont called\n");
397       push_word(0);
398       return;    
399     case getVoltageMilliVolt_4_5I:
400       if (verbose)
401          printf("> ");
402       else
403          printf("& ");
404       printf("getVoltageMillivolts returning 9999\n");
405       push_word(9999);
406       return;
407     case getButtons_4_5I:
408       if (verbose)
409       {
410          printf("> ");
411          printf("readButtons returning 0\n");
412       }     
413       push_word(0);
414       return;
415     case getTachoCountById_4I_5I:
416       if (verbose)
417          printf("> ");
418       else
419          printf("& ");
420       printf("getTachoCount on Motor %d returning 0\n", paramBase[0]);
421       push_word(0);
422       return;  
423     case controlMotorById_4III_5V:
424       if (verbose)
425          printf("> ");
426       else
427          printf("& ");
428       printf("controlMotor called with parameters %d, %d, %d\n",paramBase[0],paramBase[1],paramBase[2]);
429       return; 
430     case resetTachoCountById_4I_5V:
431       if (verbose)
432          printf("> ");
433       else
434          printf("& ");
435       printf("resetTachoCount on Motor %d \n", paramBase[0]);
436       return;  
437     case i2cEnableById_4I_5V:
438       if (verbose)
439          printf("> ");
440       else
441          printf("& ");
442       printf("i2cEnableById\n"); 
443       return;
444     case i2cDisableById_4I_5V:
445       if (verbose)
446          printf("> ");
447       else
448          printf("& ");
449       printf("i2cDisableById\n");
450       return;
451     case i2cBusyById_4I_5I:
452       if (verbose)
453          printf("> ");
454       else
455          printf("& ");
456       printf("i2cBusyById\n");
457       push_word(0);
458       return;
459     case i2cStartById_4IIII_1BII_5I:
460       {
461         Object *p = word2ptr(paramBase[4]);
462         byte *byteArray = (((byte *) p) + HEADER_SIZE);
463        if (verbose)
464          printf("> ");
465       else
466          printf("& ");
467       printf("i2cStart called with parameters %d, %d, %d, %d %x, %d, %d\n",
468                                         paramBase[0],
469                                         paramBase[1],
470                                         paramBase[2],
471                                         paramBase[3],
472                                         byteArray,
473                                         paramBase[5],
474                                         paramBase[6]);                      
475       }
476       push_word(0);
477       return; 
478     case playFreq_4III_5V:
479       if (verbose)
480          printf("> ");
481       else
482          printf("& ");
483       printf("playFreq with freq = %d, duration = %d, volume = %d\n", paramBase[0], paramBase[1], paramBase[2]);
484       return;
485     case btSend_4_1BI_5V:
486       {
487         Object *p = word2ptr(paramBase[0]);
488         byte *byteArray = (((byte *) p) + HEADER_SIZE);
489         if (verbose)
490           printf("> ");
491         else
492           printf("& "); 
493           printf("btSend called with parameters %x, %d\n", byteArray, paramBase[1]);                       
494       }
495       return;
496     case btReceive_4_1B_5V:
497       {
498         Object *p = word2ptr(paramBase[0]);
499         byte *byteArray = (((byte *) p) + HEADER_SIZE);
500         if (verbose)
501           printf("> ");
502         else
503           printf("& "); 
504         printf("btReceive called with parameter %x\n", byteArray);                                           
505       }
506       return;
507     case btGetBC4CmdMode_4_5I:
508       if (verbose)
509          printf("> ");
510       else
511          printf("& ");
512          printf("btGetBC4CmdMode returning 1\n");
513       push_word(1);
514       return;
515     case btSetArmCmdMode_4I_5V:
516       if (verbose)
517          printf("> ");
518       else
519          printf("& ");
520       printf("btSetArmCmdMode\n");
521       return;
522     case btStartADConverter_4_5V:
523       if (verbose)
524          printf("> ");
525       else
526          printf("& ");
527       printf("btStartAdConverter\n");
528       return;
529     case btSetResetLow_4_5V:
530       if (verbose)
531          printf("> ");
532       else
533          printf("& ");
534       printf("btSetResetLow\n");
535       return;
536     case btSetResetHigh_4_5V:
537       if (verbose)
538          printf("> ");
539       else
540          printf("& ");
541       printf("btSetResetHigh\n");
542     return;
543     case btWrite_4_1BII_5I:
544       {
545         Object *p = word2ptr(paramBase[0]);
546         byte *byteArray = (((byte *) p) + HEADER_SIZE);
547         if (verbose)
548           printf("> ");
549         else
550           printf("& "); 
551         printf("btWrite called with parameters %x, %d, %d\n", byteArray,paramBase[1],paramBase[2]);                                           
552       }
553       return;
554     case btRead_4_1BII_5I:
555       {
556         Object *p = word2ptr(paramBase[0]);
557         byte *byteArray = (((byte *) p) + HEADER_SIZE);
558         if (verbose)
559           printf("> ");
560         else
561           printf("& "); 
562         printf("btRead called with parameters %x, %d, %d\n", byteArray,paramBase[1],paramBase[2]);                                                               
563       }
564       return;
565     case btPending_4_5I:
566       if (verbose) 
567       {
568         printf("> ");
569         printf("btPending called\n");                                           
570       }
571       push_word(0);
572       return;
573     case usbRead_4_1BII_5I:
574       {
575         Object *p = word2ptr(paramBase[0]);
576         byte *byteArray = (((byte *) p) + HEADER_SIZE);
577         if (verbose) 
578         {
579           printf("> ");
580           printf("usbReceive called with parameters %x, %d\n", byteArray, paramBase[1]);                                           
581         }
582         push_word(0);                      
583       } 
584       return;
585     case usbWrite_4_1BII_5I:
586       {
587         Object *p = word2ptr(paramBase[0]);
588         byte *byteArray = (((byte *) p) + HEADER_SIZE);
589         if (verbose) 
590         {
591           printf("> ");
592           printf("usbWrite called with parameters %x, %d\n", byteArray, paramBase[1]);                                           
593         }                     
594       }
595       return; 
596     case usbStatus_4_5I:
597       {
598         push_word(0);
599       }
600       return;
601     case usbEnable_4I_5V:
602       {
603         if (verbose) 
604         {
605           printf("> ");
606           printf("usbEnable called\n");;                                           
607         }
608       }
609       return;
610     case usbDisable_4_5V:
611       {
612         if (verbose) 
613         {
614           printf("> ");
615           printf("usbDisable called\n");;                                           
616         }
617       }
618       return;
619     case usbReset_4_5V :
620       if (verbose) 
621       {
622         printf("> ");
623         printf("udpReset called\n");                                           
624       }
625       return;
626     case usbSetSerialNo_4Ljava_3lang_3String_2_5V: 
627       {
628         byte *p = word2ptr(paramBase[0]);
629         int len;
630         Object *charArray = (Object *) word2ptr(get_word_4_ns(fields_start(p)));
631
632         len = get_array_length(charArray);
633         if (verbose) 
634         {
635           printf("> ");
636           printf("udpSetSerial called\n");                                           
637         }
638       }
639       return;
640     case usbSetName_4Ljava_3lang_3String_2_5V:
641       {
642         byte *p = word2ptr(paramBase[0]);
643         int len;
644         Object *charArray = (Object *) word2ptr(get_word_4_ns(fields_start(p)));
645
646         len = get_array_length(charArray);
647         if (verbose) 
648         {
649           printf("> ");
650           printf("udpSetName called\n");
651         }                                            
652       }
653       return;
654     case writePage_4_1BI_5V:
655       {
656         Object *p = word2ptr(paramBase[0]);
657         unsigned long *intArray = (unsigned long *) (((byte *) p) + HEADER_SIZE);
658         if (verbose) 
659         {
660           printf("> ");
661           printf("writePage called with parameters %x, %d\n", intArray, paramBase[1]);                                           
662         }                       
663       }
664       return;
665     case readPage_4_1BI_5V:
666       {
667         int i;
668         Object *p = word2ptr(paramBase[0]);
669         unsigned long *intArray = (unsigned long *) (((byte *) p) + HEADER_SIZE);
670         if (verbose) 
671         {
672           printf("> ");
673           printf("readPage called with parameters %x, %d\n", intArray, paramBase[1]);                                           
674         }                       
675       }
676       return;
677     case exec_4II_5V:
678       if (verbose) 
679       {
680         printf("> ");
681         printf("exec called\n");                                           
682       }
683       return;
684     case playSample_4IIIII_5V:
685       if (verbose)
686          printf("> ");
687       else
688          printf("& ");
689       printf("Playing sound sample\n");
690       return;
691     case getTime_4_5I:
692       if (verbose)
693          printf("> ");
694       else
695          printf("& ");
696       printf("Sound getTime called\n");
697       push_word(0);
698       return;   
699     case getDataAddress_4Ljava_3lang_3Object_2_5I:
700       if (verbose)
701          printf("> ");
702       else
703          printf("& ");
704       printf("Data address is %x\n",ptr2word (((byte *) word2ptr (paramBase[0])) + HEADER_SIZE));
705       return;
706     case gc_4_5V:
707       if (verbose)
708          printf("> ");
709       else
710          printf("& ");
711       printf("Collecting garbage\n");
712       return;
713     case diagn_4II_5I:
714       push_word (sys_diagn(paramBase[0], paramBase[1]));
715       return;
716     case shutDown_4_5V:
717       if (verbose)
718          printf("> ");
719       else
720          printf("& ");
721       printf("Shutting down\n");
722       exit(0);
723     case arraycopy_4Ljava_3lang_3Object_2ILjava_3lang_3Object_2II_5V:
724       {
725         Object *p1 = word2ptr(paramBase[0]);
726         Object *p2 = word2ptr(paramBase[2]);
727         arraycopy(p1, paramBase[1], p2, paramBase[3], paramBase[4]);
728       }
729       return;
730     case executeProgram_4I_5V:
731       {
732         MethodRecord *mRec;
733         ClassRecord *classRecord;
734         classRecord = get_class_record (get_entry_class (paramBase[0]));
735         // Initialize top word with fake parameter for main():
736         set_top_ref_cur (JNULL);
737         // Push stack frame for main method:
738         mRec= find_method (classRecord, main_4_1Ljava_3lang_3String_2_5V);
739         dispatch_special (mRec, curPc);
740         dispatch_static_initializer (classRecord, curPc);
741       }
742       return;
743     case setDebug_4_5V:
744       if (verbose)
745          printf("> ");
746       else
747          printf("& ");
748       printf("Set debug\n");
749       return;
750     case peekWord_4I_5I:
751       push_word(*((unsigned long *)(paramBase[0])));
752       return;
753     case eventOptions_4II_5I:
754       {
755         if (verbose)
756           printf("> ");
757         else
758           printf("& ");
759         printf("Debug event options\n");
760         push_word(0);
761       }
762       return;
763     case suspendThread_4Ljava_3lang_3Object_2_5V:
764       suspend_thread(ref2ptr(paramBase[0]));
765       return;
766     case resumeThread_4Ljava_3lang_3Object_2_5V:
767       resume_thread(ref2ptr(paramBase[0]));
768       return;
769     case getProgramExecutionsCount_4_5I:
770       push_word(gProgramExecutions);
771       return;
772     case getFirmwareRevision_4_5I:
773       push_word(0);
774       return;
775     case getFirmwareMajorVersion_4_5I:
776       push_word((STACKWORD) MAJOR_VERSION);
777       return;
778     case getFirmwareMinorVersion_4_5I:
779       push_word((STACKWORD) MINOR_VERSION); 
780       return;
781     default:
782 #ifdef DEBUG_METHODS
783       printf("Received bad native method code: %d\n", signature);
784 #endif
785       throw_exception (noSuchMethodError);
786   }
787