diff --git a/Makefile b/Makefile index f6c4524..b50f376 100644 --- a/Makefile +++ b/Makefile @@ -32,8 +32,8 @@ ifdef USE_YAML CFLAGS += -DUSE_YAML LIBS += -lyaml else -LIBS += -laltra64 endif +LIBS += -laltra64 LINK_FLAGS = -O1 -L$(ROOTDIR)/lib -L$(ROOTDIR)/mips64-elf/lib -L$(RUST_FULL_TARGET_DIR) -ldragon -lmad $(LIBS) -lc -lm -ldragonsys -lnosys -Tn64ld.x PROG_NAME = $(BINDIR)/OS64P diff --git a/rust/cbindgen.toml b/rust/cbindgen.toml index c629512..e847552 100644 --- a/rust/cbindgen.toml +++ b/rust/cbindgen.toml @@ -16,4 +16,4 @@ autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't mod include_version = false [export] -exclude = ["strtoul"] +exclude = ["strtoul", "screen_text", "test_c_print", "screen_text_num", "screen_text_ptr"] diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 58f6233..f408170 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![allow(dead_code,unused_variables)] use core::slice; use core::iter::Iterator; @@ -111,6 +112,8 @@ impl SliceSubsequence for &[T] { } } +/* +// for some reason, passing actual pointers like this freezes the n64 #[no_mangle] pub extern "C" fn parse_cheats_ffi( cheat_file: *mut u8, cheat_file_len: usize, @@ -123,16 +126,53 @@ pub extern "C" fn parse_cheats_ffi( parse_cheats(cheat_file, boot_cheats, in_game_cheats) } +*/ + +// in C world, usize is actually u32, no idea why but that's a problem for another day... +// but if we put u32 here it crashes, can only send usize +#[no_mangle] +pub extern "C" fn parse_cheats_ffi( + cheat_file: usize, cheat_file_len: usize, + boot_cheats: usize, boot_cheats_len: usize, + in_game_cheats: usize, in_game_cheats_len: usize, +) -> u8 { + +/* + unsafe { + let cheat_file = cheat_file as *mut u8; + let cheat_file = slice::from_raw_parts_mut(cheat_file, 4); + cheat_file[1] = b'a'; + 0 + } +*/ + //unsafe { screen_text_ptr(b"from rust woot" as *const u8 as u32); } + + //let cheat_file = unsafe { slice::from_raw_parts(cheat_file as *const u8, cheat_file_len as usize) }; + let cheat_file = unsafe { slice::from_raw_parts_mut(cheat_file as *mut u8, cheat_file_len as usize) }; + let boot_cheats = unsafe { slice::from_raw_parts_mut(boot_cheats as *mut u32, boot_cheats_len as usize) }; + let in_game_cheats = unsafe { slice::from_raw_parts_mut(in_game_cheats as *mut u32, in_game_cheats_len as usize) }; + + dbg(100); + + //cheat_file[1] = b'a'; + + //0 + + parse_cheats(cheat_file, boot_cheats, in_game_cheats) +} const SUCCESS: u8 = 0; const INVALID_CODE_LINE: u8 = 1; const INVALID_LINE: u8 = 2; pub fn parse_cheats(cheat_file: &[u8], boot_cheats: &mut [u32], in_game_cheats: &mut [u32]) -> u8 { + dbg(101); let mut repeater = false; let mut boot_cheats_idx = 0; let mut in_game_cheats_idx = 0; + dbg(102); for line in cheat_file.lines(b"\n") { + dbg(200); let line = line.trim(WHITESPACE); if line.is_empty() || line.starts_with(b"#") || line == b"---" { continue; // empty or comment or whatever the starting thing is @@ -233,6 +273,7 @@ pub fn parse_cheats(cheat_file: &[u8], boot_cheats: &mut [u32], in_game_cheats: return INVALID_LINE; } } + dbg(103); SUCCESS } @@ -248,8 +289,53 @@ fn hex_to_u32(str: &[u8]) -> u32 { unsafe { strtoul(str.as_ptr(), null_mut(), 16) } } +#[no_mangle] +pub extern "C" fn test_rust_print() { + //unsafe { test_c_print(); } + //unsafe { screen_text_num(9); } + // sent 18446744073709551515 = 4294967195 = FFFF_FF9B + // sent 0xffff_ffff_ffff_ffff = 4294967295 = FFFF_FFFF + unsafe { screen_text_num(0xffff_ffff_ffff_ffff); } + //unsafe { screen_text(b"rust test\0".as_ptr()); } +} + +#[no_mangle] +pub extern "C" fn rust_call_test(num: usize) { + unsafe { screen_text_num(num); } +} + +#[no_mangle] +pub extern "C" fn rust_call_test_ptr(num: usize) -> u8 { + unsafe { + let cheat_file = num as *mut u8; + let cheat_file = slice::from_raw_parts_mut(cheat_file, 4); + cheat_file[1] = b'a'; + //screen_text_num(cheat_file[0].into()); + 0 + } +} + +fn dbg(num: usize) { + #[cfg(not(test))] + unsafe { screen_text_num(num); } + #[cfg(test)] + println!("dbg: {}", num); +} + +/* +#[no_mangle] +pub extern "C" fn rust_call_test_bla() { + //rust_call_test(b"c rust test\0".as_ptr()); + rust_call_test([99, 32, 114, 117, 115, 116, 32, 116, 101, 115, 116, 0].as_ptr()); +} +*/ + extern "C" { fn strtoul(s: *const u8, endp: *mut *mut u8, base: i32) -> u32; // todo: is base i32 ? + fn screen_text(msg: *const u8); + fn screen_text_num(num: usize); + fn screen_text_ptr(ptr: u32); + fn test_c_print(); } #[cfg(test)] @@ -258,6 +344,7 @@ mod tests { #[test] fn test_hex_to_u32() { + println!("i: {:?}", b"c rust test\0"); assert_eq!(hex_to_u32(b"0x09"), 9); } @@ -353,5 +440,14 @@ In Health (ASM): assert_eq!(ok, SUCCESS); assert_eq!(boot_cheats, [0xF10004E4, 0x2400, 0xEE000000, 0x0000, 0, 0]); assert_eq!(in_game_cheats, [0x8138EDA0, 0x2400, 0, 0, 0, 0]); + + let cheats_file = &b"wootwootwootwootwootwootwootwoot\0"[..]; + let cheats_file = &b"wootwootwootwootwootwootwootwoot"[..]; + let mut boot_cheats = [0u32; 6]; + let mut in_game_cheats = [0u32; 6]; + let ok = parse_cheats(cheats_file, &mut boot_cheats, &mut in_game_cheats); + assert_eq!(ok, INVALID_LINE); + assert_eq!(boot_cheats, [0, 0, 0, 0, 0, 0]); + assert_eq!(in_game_cheats, [0, 0, 0, 0, 0, 0]); } } diff --git a/src/main.c b/src/main.c index 5966e48..1f0c0f2 100644 --- a/src/main.c +++ b/src/main.c @@ -41,9 +41,9 @@ // YAML parser #include #else -#include #endif /* USE_YAML */ +#include #include "constants.h" #include "debug.h" @@ -258,6 +258,50 @@ int page = 0; int cursor = 0; direntry_t *list; +display_context_t global_disp_ctx; + +void screen_text(u8 *msg) { + printText(msg, 3, -1, global_disp_ctx); + display_show(global_disp_ctx); + sleep(1000); +} + +void screen_text_num(size_t num) { + char num_str[64]; + + sprintf(num_str, "dbg: %u", num); + screen_text(num_str); +} + +void screen_text_ptr(size_t ptr) { + u8 *msg = (u8*)ptr; + screen_text(msg); +} + +void call_test(size_t num) { + screen_text_num(num); +} +/* +00006644 : + 6644: 27bdffd8 addiu sp,sp,-40 + 6648: ffbf0020 sd ra,32(sp) + 664c: 0c000000 jal 0 + 6650: 00000000 nop + 6654: dfbf0020 ld ra,32(sp) + 6658: 03e00008 jr ra + 665c: 27bd0028 addiu sp,sp,40 +*/ + +void call_test_bla() { + call_test(5); +} + +void test_c_print() { + screen_text("c rust test"); + screen_text_num(5); + screen_text("c rust test2"); +} + int filesize(FILE *pFile) { fseek(pFile, 0, SEEK_END); @@ -2191,6 +2235,11 @@ int readCheatFile(TCHAR *filename, u32 *cheat_lists[2]) FIL file; UINT bytesread; result = f_open(&file, filename, FA_READ); + + screen_text("in readCheatFile"); + screen_text_num(0xffffffffffffffff); + test_rust_print(); + screen_text("called rust"); if (result == FR_OK) { @@ -2238,7 +2287,7 @@ int readCheatFile(TCHAR *filename, u32 *cheat_lists[2]) #else // use rust size_t list1_size = both_list_sizes - list2_size; - repeater = parse_cheats_ffi(cheatfile, fsize, list1, list1_size, list2, list2_size); + repeater = parse_cheats_ffi((size_t)cheatfile, fsize, (size_t)list1, list1_size, (size_t)list2, list2_size); #endif /* USE_YAML */ free(cheatfile); @@ -2272,10 +2321,12 @@ void bootRom(display_context_t disp, int silent) char cheat_filename[64]; sprintf(cheat_filename, "/"ED64_FIRMWARE_PATH"/CHEATS/%s.yml", rom_filename); + global_disp_ctx = disp; int ok = readCheatFile(cheat_filename, cheat_lists); if (ok == 0) { printText("cheats found...", 3, -1, disp); + sleep(10000); } else { @@ -4589,6 +4640,59 @@ int main(void) drawBg(disp); //new drawBoxNumber(disp, 1); //new + + + + /* + */ + global_disp_ctx = disp; + screen_text("in MAIN"); + screen_text_num(SIZE_MAX); + screen_text("in MAIN2"); + screen_text_num((size_t)-1); + screen_text("in MAIN3"); + screen_text_num(0xffffffffffffffff); + test_rust_print(); + screen_text_ptr((size_t)"called rust"); + rust_call_test(SIZE_MAX); + screen_text_ptr((size_t)"called rust2"); + char* woot = "wootwootwootwootwootwootwootwoot"; + size_t fsize = 32; + + //u8 repeater = rust_call_test_ptr((size_t) woot); + + /* + */ + u32 *list1; + u32 *list2; + size_t both_list_sizes = fsize + 2 * sizeof(u32); + list1 = calloc(1, both_list_sizes); // Plus 2 words to be safe + if (!list1) + { + screen_text("oom"); + while(true) { sleep(1000); } + } + size_t list2_size = fsize / sizeof(u32) / 2; + list2 = &list1[list2_size]; + //cheat_lists[0] = list1; + //cheat_lists[1] = list2; + + size_t list1_size = both_list_sizes - list2_size; + + screen_text_num(list1_size); + screen_text_num(list2_size); + screen_text_ptr((size_t)"called rust2.5"); + + u8 repeater = parse_cheats_ffi((size_t)woot, fsize + , (size_t)list1, list1_size + , (size_t)list2, list2_size + ); + + + screen_text("called rust3"); + screen_text(woot); + screen_text("called rust4"); + while(true) { sleep(1000); } uint32_t *buffer = (uint32_t *)__get_buffer(disp); //fg disp = 2