void emit_goto_test(Seq_T stream) { int patch_L = Seq_length(stream); emit(stream, loadval(r7, 0)); /* will be patched to 'r7 := L' */ emit(stream, loadprogram(r0, r7)); /* should goto label L */ emit_out_string(stream, "GOTO failed.\n", r1); emit(stream, halt()); /* define 'L' to be here */ add_label(stream, patch_L, Seq_length(stream)); emit_out_string(stream, "GOTO passed.\n", r1); emit(stream, halt()); }
/*execute program finds an available process table entry and puts the program in the appropriate segment*/ void executeprogram(char* filebuffer, int length, int foreground) { char* programbuffer; int i,j; short seg; /*set the current data segment to the kernel so we can read the process list*/ setdatasegkernel(); /*find an empty space for a process*/ for (i=0; i<MAXPROCESSES; i++) if (process_table[i].active==0) break; /*if the memory is full, we can't execute*/ if (i==MAXPROCESSES) { restoredataseg(); return; } /*set the process entry to active, set the stack pointer*/ seg=process_table[i].segment; process_table[i].active=1; process_table[i].sp=0xff00; /*get the id of the process that called execute*/ procid=getprocessid(); /*if the new process is to occupy the foreground, make the caller sleep*/ if (foreground==1) { process_table[procid].active=2; process_table[procid].waiton=i; } /*set the data segment back to the caller's segment*/ restoredataseg(); /*load the new process into memory*/ loadprogram(seg,filebuffer,length); }
int main(void) { __Set(BEEP_VOLUME, 0); // USART1 8N1 115200bps debug port RCC->APB2ENR |= RCC_APB2ENR_USART1EN; USART1->BRR = 72000000 / 115200; USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; gpio_usart1_tx_mode(GPIO_AFOUT_10); gpio_usart1_rx_mode(GPIO_HIGHZ_INPUT); printf("\nBoot!\n"); // Reduce the wait states of the FPGA & LCD interface // It works for me, hopefully it works for you too :) FSMC_BTR1 = 0x10100110; FSMC_BTR2 = 0x10100110; __Set(ADC_CTRL, EN); __Set(ADC_MODE, SEPARATE); alterbios_init(); int status = alterbios_check(); if (status < 0) { char buf[100]; snprintf(buf, sizeof(buf), "AlterBIOS not found or too old: %d\n" "Please install it from https://github.com/PetteriAimonen/AlterBIOS", status); while (1) show_msgbox("AlterBIOS is required", buf); } get_keys(ALL_KEYS); // Clear key buffer while (true) { select_file(amx_filename); get_keys(ANY_KEY); __Clear_Screen(0); char error[50] = {0}; int status = loadprogram(amx_filename, error, sizeof(error)); if (status != 0) { char buffer[200]; snprintf(buffer, sizeof(buffer), "Loading of program %s failed:\n\n" "Error %d: %s\n\n" "%s\n", amx_filename, status, my_aux_StrError(status), error); printf(buffer); printf(amx_filename); show_msgbox("Program load failed", buffer); } else { int idle_func = -1; if (amx_FindPublic(&amx, "@idle", &idle_func) != 0) idle_func = -1; cell ret; status = amx_Exec(&amx, &ret, AMX_EXEC_MAIN); while (status == AMX_ERR_SLEEP) { AMX nested_amx = amx; uint32_t end = get_time() + amx.pri; do { status = doevents(&nested_amx); } while (get_time() < end && status == 0); if (status == 0) status = amx_Exec(&amx, &ret, AMX_EXEC_CONT); else amx = nested_amx; // Report errors properly } if (status == 0 && idle_func != -1) { // Main() exited, keep running idle function. do { status = doevents(&amx); if (status == 0) status = amx_Exec(&amx, &ret, idle_func); } while (status == 0 && ret != 0); } amxcleanup_wavein(&amx); amxcleanup_file(&amx); if (status == AMX_ERR_EXIT && ret == 0) status = 0; // Ignore exit(0), but inform about e.g. exit(1) if (status != 0) { show_pawn_traceback(amx_filename, &amx, status); } else { draw_menubar("Close", "", "", ""); while (!get_keys(BUTTON1)); } } } return 0; }
void* ELFLoadObject( const char* objname ) { struct ElfObject *elfobj = NULL; /* allocate ElfObject structure */ elfobj = alloc32( sizeof( struct ElfObject ) ); if( elfobj != NULL ) { memset(elfobj,0,sizeof(struct ElfObject)); elfobj->header = alloc32( sizeof( struct Elf32_Ehdr ) ); if( elfobj->header != NULL ) { /* open ELF stream for reading */ elfobj->handle = opstream( elfobj, objname ); if( elfobj->handle != NULL ) { /* read and identify ELF 32bit PowerPC BigEndian header */ if( rdstream( elfobj, elfobj->header, sizeof(struct Elf32_Ehdr) ) ) { struct Elf32_Ehdr *hdr = elfobj->header; if (!strncmp(hdr->e_ident,ELFid,4) && hdr->e_ident[EI_CLASS]==ELFCLASS32 && hdr->e_ident[EI_DATA]==ELFDATA2MSB && hdr->e_ident[EI_VERSION]==1 && hdr->e_version==1 && (hdr->e_machine==EM_PPC || hdr->e_machine==EM_PPC_OLD || hdr->e_machine==EM_CYGNUS_POWERPC) && hdr->e_type==ET_REL) { struct Elf32_Shdr *shdrs; ULONG shdrsize = (ULONG) hdr->e_shnum * (ULONG) hdr->e_shentsize; // kprintf("elf32ppcbe format recognized\n"); shdrs = alloc32( shdrsize ); if( shdrs != NULL ) { /* read section header table and parse rest of object */ if( prstream( elfobj, hdr->e_shoff, shdrs, shdrsize ) ) { if( loadelf32( elfobj, shdrs ) ) { void* start; // kprintf("ELF object loaded (0x%08lx)\n", elfobj ); start = loadprogram( elfobj ); // kprintf("Start of PPC code: 0x%08lx\n", start ); free32( shdrs ); return (elfobj); } } free32( shdrs ); } } else kprintf( "Not an ELF32-PPC-BE\nrelocatable object."); } } freeelfobj(elfobj); } } return (NULL); }