- Timestamp:
- 12/23/09 02:10:17 (2 years ago)
- Location:
- trunk
- Files:
-
- 7 added
- 7 modified
-
CHDK/SCRIPTS/TEST/tstcallf.lua (added)
-
buildconf.inc (modified) (1 diff)
-
core/Makefile (modified) (2 diffs)
-
core/luascript.c (modified) (3 diffs)
-
include/lolevel.h (modified) (1 diff)
-
include/platform.h (modified) (1 diff)
-
lib/Makefile (modified) (1 diff)
-
lib/armutil (added)
-
lib/armutil/Makefile (added)
-
lib/armutil/README.TXT (added)
-
lib/armutil/callfunc.S (added)
-
lib/armutil/callfunc_test.c (added)
-
lib/armutil/reversebytes.S (added)
-
platform/generic/wrappers.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/buildconf.inc
r851 r864 12 12 OPT_EDGEOVERLAY=1 13 13 OPT_LUA_STRLIB=1 14 #allow Lua to call arbitrary ROM functions and eventprocs 15 # WARNING: This is DANGEROUS. e.g. call_event_proc("EraseSectorOfRom",...) 16 # NOTE: the interface for this may change in the future, to support better support buffers etc 17 #OPT_LUA_CALL_NATIVE=1 14 18 #OPT_MD_DEBUG=1 15 19 # needs proper fi2.inc in platform/ !!! see http://chdk.setepontos.com/index.php/topic,2995.0.html -
trunk/core/Makefile
r826 r864 53 53 CFLAGS+=-DOPT_MD_DEBUG 54 54 endif 55 ifdef OPT_LUA_CALL_NATIVE 56 CFLAGS+=-DOPT_LUA_CALL_NATIVE 57 endif 58 55 59 OBJS=entry.o nothumb.o main.o gui_draw.o gui_menu.o gui_palette.o gui_mbox.o \ 56 60 gui_fselect.o gui.o kbd.o conf.o \ … … 76 80 $(topdir)lib/font/libfont.a $(topdir)lib/math/libmath.a \ 77 81 $(topdir)lib/ubasic/libubasic.a $(topdir)lib/lang/liblang.a \ 78 $(topdir)lib/lua/liblua.a 82 $(topdir)lib/lua/liblua.a \ 83 $(topdir)lib/armutil/libarmutil.a 79 84 @echo \-\> $@ 80 85 $(CC) $(CFLAGS) -o $@ --start-group $^ $(LDLIBS) --end-group $(LDFLAGS) $(LDOPTS) -
trunk/core/luascript.c
r847 r864 725 725 } 726 726 727 /* 728 val=peek(address[,size]) 729 return the value found at address in memory, or nil if address or size is invalid 730 size is optional 1=byte 2=halfword 4=word. defaults is 4 731 */ 727 732 static int luaCB_peek( lua_State* L ) 728 733 { 729 int addr = (luaL_checknumber(L,1)); 730 // must be alligned 731 if (addr & 0x3) { 732 lua_pushnil(L); 734 unsigned addr = luaL_checknumber(L,1); 735 unsigned size = luaL_optnumber(L, 2, 4); 736 switch(size) { 737 case 1: 738 lua_pushnumber( L, *(unsigned char *)(addr) ); 739 break; 740 case 2: 741 if (addr & 0x1) { 742 lua_pushnil(L); 743 } 744 else { 745 lua_pushnumber( L, *(unsigned short *)(addr) ); 746 } 747 break; 748 case 4: 749 if (addr & 0x3) { 750 lua_pushnil(L); 751 } 752 else { 753 lua_pushnumber( L, *(unsigned *)(addr) ); 754 } 755 break; 756 default: 757 lua_pushnil(L); 758 759 } 760 return 1; 761 } 762 763 /* 764 status=poke(address,value[,size]) 765 writes value to address in memory 766 size is optional 1=byte 2=halfword 4=word. defaults is 4 767 returns true, or nil if address or size is invalid 768 */ 769 static int luaCB_poke( lua_State* L ) 770 { 771 unsigned addr = luaL_checknumber(L,1); 772 unsigned val = luaL_checknumber(L,2); 773 unsigned size = luaL_optnumber(L, 3, 4); 774 int status = 0; 775 switch(size) { 776 case 1: 777 *(unsigned char *)(addr) = (unsigned char)val; 778 lua_pushboolean(L,1); 779 status=1; 780 break; 781 case 2: 782 if (!(addr & 0x1)) { 783 *(unsigned short *)(addr) = (unsigned short)val; 784 status=1; 785 } 786 break; 787 case 4: 788 if (!(addr & 0x3)) { 789 *(unsigned *)(addr) = val; 790 status=1; 791 } 792 break; 793 } 794 if(status) { 795 lua_pushboolean(L,1); 733 796 } 734 797 else { 735 lua_pushnumber( L, *(unsigned *)(addr) ); 736 } 737 return 1; 738 } 739 740 static int luaCB_poke( lua_State* L ) 741 { 742 int addr = (luaL_checknumber(L,1)); 743 int val = (luaL_checknumber(L,2)); 744 if (addr & 0x3) { 745 lua_pushnil(L); 746 } 747 else { 748 *(unsigned *)(addr) = val; 749 lua_pushboolean(L,1); 798 lua_pushnil(L); 750 799 } 751 800 return 1; … … 1106 1155 return 0; 1107 1156 } 1157 1158 /* 1159 pack the lua args into a buffer to pass to the native code calling functions 1160 currently only handles strings/numbers 1161 start is the stack index of the first arg 1162 */ 1163 #ifdef OPT_LUA_CALL_NATIVE 1164 static int pack_native_args( lua_State* L, unsigned start, unsigned *argbuf) 1165 { 1166 unsigned i; 1167 unsigned end = lua_gettop(L); 1168 1169 for(i = start; i <= end; i++,argbuf++) { 1170 if (lua_type(L, i) == LUA_TSTRING) { 1171 *argbuf=(unsigned)lua_tostring( L, i); 1172 } 1173 else if (lua_type(L, i) == LUA_TNUMBER) { 1174 *argbuf=lua_tonumber( L, i); 1175 } 1176 else { 1177 return 0; 1178 } 1179 } 1180 return 1; 1181 } 1182 1183 /* 1184 Native function call interface. Can be used to call canon eventprocs or arbitrary 1185 pointers. 1186 1187 NOTE: this is preliminary, interface may change in later versions! 1188 All arguments must be strings or numbers. 1189 If the function expects to modify it's arguments via a pointer, 1190 then you must provide a number that is a valid pointer. 1191 1192 You can use the "AllocateMemory" eventproc to obtain buffers. 1193 1194 If the function tries to write to a string passed from lua, Bad Things may happen. 1195 1196 This is potentially dangerous, functions exist which can destroy the onboard firmware. 1197 */ 1198 1199 /* 1200 result=call_func_ptr(ptr,...) 1201 ptr: address of a valid ARM or Thumb function, which uses the normal C calling convention. 1202 result: R0 value after the call returns 1203 NOTE: 1204 lua does not correctly handle hex constants which would represent a negative number. 1205 You must use the signed decimal value instead. 1206 */ 1207 static int luaCB_call_func_ptr( lua_State* L) 1208 { 1209 unsigned *argbuf=NULL; 1210 unsigned i; 1211 unsigned n_args = lua_gettop(L)-1; 1212 void *fptr; 1213 1214 fptr=(void *)luaL_checknumber( L, 1 ); 1215 1216 if (n_args) { 1217 argbuf=malloc(n_args * 4); 1218 if(!argbuf) { 1219 return luaL_error( L, "malloc fail" ); 1220 } 1221 if(!pack_native_args(L, 2, argbuf)) { 1222 free(argbuf); 1223 return luaL_error( L, "expected string or number" ); 1224 } 1225 } 1226 1227 lua_pushnumber( L, call_func_ptr(fptr, argbuf, n_args) ); 1228 free(argbuf); 1229 return 1; 1230 } 1231 1232 /* 1233 Call an event procedure 1234 1235 result=call_event_proc("EventprocName",...) 1236 result is the value returned by ExecuteEventProcedure, which is -1 if the eventproc is not found, 1237 or the eventproc return value (which could also be -1) 1238 NOTE: 1239 Many eventprocs are not registered by default, but can be loaded by calling another event proc 1240 Some useful ones are 1241 SystemEventInit 1242 includes AllocateMemory, FreeMemory, sprintf, memcpy, Fut functions, log ... 1243 UI_RegistDebugEventProc 1244 includes capture mode functions, PTM_ functions and much more 1245 RegisterProductTestEvent 1246 includes PT_ functions 1247 1248 Others: 1249 RegisterShootSeqEvent 1250 RegisterNRTableEvent 1251 */ 1252 1253 // grab from lowlevel 1254 extern unsigned _ExecuteEventProcedure(const char *name,...); 1255 static int luaCB_call_event_proc( lua_State* L ) 1256 { 1257 const char *evpname; 1258 unsigned *argbuf; 1259 unsigned i; 1260 unsigned n_args = lua_gettop(L); 1261 1262 evpname=luaL_checkstring( L, 1 ); 1263 1264 argbuf=malloc(n_args * 4); 1265 if (!argbuf) { 1266 return luaL_error( L, "malloc fail" ); 1267 } 1268 1269 // event proc name is first arg 1270 *argbuf = (unsigned)evpname; 1271 1272 if(!pack_native_args(L,2,argbuf+1)) { 1273 free(argbuf); 1274 return luaL_error( L, "expected string or number" ); 1275 } 1276 1277 lua_pushnumber( L, call_func_ptr(_ExecuteEventProcedure,argbuf,n_args) ); 1278 free(argbuf); 1279 return 1; 1280 } 1281 1282 #endif // OPT_LUA_CALL_NATIVE 1108 1283 1109 1284 void register_lua_funcs( lua_State* L ) … … 1262 1437 1263 1438 FUNC(set_record); 1264 } 1439 1440 #ifdef OPT_LUA_CALL_NATIVE 1441 FUNC(call_event_proc); 1442 FUNC(call_func_ptr); 1443 #endif 1444 } -
trunk/include/lolevel.h
r838 r864 268 268 extern void _ScreenLock(); 269 269 extern void _SetCurrentCaptureModeType(); 270 extern unsigned _ExecuteEventProcedure(const char *name,...); 270 271 // known in CHDK as _RefreshPhysicalScreen 271 272 //extern void _ScreenUnLock(); -
trunk/include/platform.h
r847 r864 477 477 void SetScriptMode(unsigned mode); 478 478 479 /* 480 call C function with argument list created at runtime. 481 See lib/armutil/callfunc.S for documentation 482 */ 483 unsigned call_func_ptr(void *func, const unsigned *args, unsigned n_args); 484 479 485 #define started() debug_led(1) 480 486 #define finished() debug_led(0) -
trunk/lib/Makefile
r515 r864 2 2 include $(topdir)makefile.inc 3 3 4 SUBDIRS=font math ubasic lang lua 4 SUBDIRS=font math ubasic lang lua armutil 5 5 6 6 include $(topdir)bottom.inc -
trunk/platform/generic/wrappers.c
r847 r864 795 795 } 796 796 797 void reverse_bytes_order(char* start, int count){798 // note, we will go to count rounded up to the nearest 32799 asm volatile(800 "ldr r2, =0xFF00FF\n" // r2 = mask801 "add r1, r0, r1\n" // r1 = start + count802 "LOOP:\n"803 "ldm r0, {R4-R11}\n" // load 8 words804 805 // out = ((in>>8) & 0xFF00FF) | ((in&0xFF00FF) << 8);806 "mov r3, r4, lsr #8\n" // r3 = in >> 8807 "and r3, r3, r2\n" // r3 &= 0xFF00FF808 "and r4, r4, r2\n" // r4 = in & 0xFF00FF809 "orr r4, r3, r4, asl #8\n" // out = r3 | (r4 << 8)810 811 "mov r3, r5, lsr #8\n"812 "and r3, r3, r2\n"813 "and r5, r5, r2\n"814 "orr r5, r3, r5, asl #8\n"815 816 "mov r3, r6, lsr #8\n"817 "and r3, r3, r2\n"818 "and r6, r6, r2\n"819 "orr r6, r3, r6, asl #8\n"820 821 "mov r3, r7, lsr #8\n"822 "and r3, r3, r2\n"823 "and r7, r7, r2\n"824 "orr r7, r3, r7, asl #8\n"825 826 "mov r3, r8, lsr #8\n"827 "and r3, r3, r2\n"828 "and r8, r8, r2\n"829 "orr r8, r3, r8, asl #8\n"830 831 "mov r3, r9, lsr #8\n"832 "and r3, r3, r2\n"833 "and r9, r9, r2\n"834 "orr r9, r3, r9, asl #8\n"835 836 "mov r3, r10, lsr #8\n"837 "and r3, r3, r2\n"838 "and r10, r10, r2\n"839 "orr r10, r3, r10, asl #8\n"840 841 "mov r3, r11, lsr #8\n"842 "and r3, r3, r2\n"843 "and r11, r11, r2\n"844 "orr r11, r3, r11, asl #8\n"845 846 "stmia r0!, {r4-r11}\n" // store and increment847 848 "cmp r0, r1\n"849 "bcc LOOP\n"850 :::"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11"851 );852 }853 854 797 #if defined (DNG_EXT_FROM) 855 798