void list_dir(void *arg) { terminal_clear(); printf("%s\n", path); printf("%s", arg); int files, fd, i, j, k; for(i = 0; i < 8; i++) { dir[i][0] = 0; } uint8_t stat; struct FATDirList list[8]; char *buf, *tmp; for(files = 0; (i = fat_dirlist(path, list, 8, files)); files += i) { for (j = i - 1; j >= 0; j--) { if(list[j].filename[0]) { stat = list[j].attrib; //skip volume labels if(stat & 0x8) continue; if(list[j].filename[0] == '.') continue; buf = dir[j]; for(k = 5; k != ~0; k--) { if(stat & (0x1 << k)) *buf++ = attribs[k]; else *buf++ = '-'; } if(stat & 0x10) { *buf++ = '\t'; *buf++ = '\t'; } else { pathcat((char *) pathbuf, path, list[j].filename); fd = fat_open(pathbuf, O_RDONLY); *buf++ = '\t'; //print_filesize(fat_fsize(fd)); *buf++ = '0'; *buf++ = '\t'; fat_close(fd); } tmp = list[j].filename; while(*tmp) { *buf++ = *tmp++; } *buf = 0; } } } }
bool init_screen() { terminal_initialize(); terminal_setcolor(make_color(FGCOLOR, BGCOLOR)); terminal_clear(); terminal_printf("Welcome to "); terminal_setcolor(make_color(COLOR_MAGENTA, BGCOLOR)); terminal_printf("%s", __KERNEL_NAME); terminal_setcolor(make_color(FGCOLOR, BGCOLOR)); terminal_printf(" multiboot32 => kernel loader\n"); return true; }
static void execute_elf(void *arg) { int fd, size, i, j; void *entry; //extern void *end; void *elf_begin = ((void *)(&end)) + 4*1024; uint8_t *tmp = elf_begin; printf("Load file to RAM\n"); fd = fat_open(path, O_RDONLY); size = fat_fsize(fd); for(j = 512; j < size; j += 512) { fat_read_sect(fd); for(i = 0; i < 512; i++) { *tmp++ = fat_buf[i]; } } fat_read_sect(fd); for(i = 0; i < j - size; i++) { *tmp++ = fat_buf[i]; } fat_close(fd); printf("File loaded\n"); printf("Highest addr used is 0x%X\n", tmp); //input_poll(); mmu040_init(); terminal_clear(); printf("MMU Init\n"); if(!(entry = elf_load(elf_begin, do_debug))) { printf("Failed to load ELF\n"); input_poll(); return; } printf("ELF load successful, entry is 0x%X, press any key\n", entry); //input_poll(); //printf("Here we have 0x%X\n", *((uint32_t *) entry)); //input_poll(); mmu_disable(); if(do_debug) { char *argv[] = {"debug"}; mmu_enable_and_jump(entry, 1, argv); } else { mmu_enable_and_jump(entry, 0, NULL); } }
void draw_logo(void) { char c, *data; terminal_clear(); data = logo; while ((c = *data++) != '\0' ) { switch (c) { case '_': terminal_setcolor(0x08); // Dark Grey terminal_putchar('_'); break; case '/': terminal_setcolor(0x0A); // Green terminal_putchar('/'); break; case 'X': terminal_setcolor(0x0A); // Green terminal_putchar('\\'); break; case ' ': terminal_putchar(' '); break; case 'n': terminal_putchar('\n'); break; } } terminal_setcolor(0x07); // Light Grey printf("===============================================================================\n"); terminal_setcolor(0x0F); printf(" ## BYOK: Forth machine, version: %s ##\n", VERSION); terminal_setcolor(0x07); printf(" This program (c) 2015 Richard Hull, published under the MIT License\n"); printf(" To read the licence, type LICENSE <enter>. For help, type HELP <enter>\n"); printf("===============================================================================\n"); }
void dbg_update_display() { debug_called++; if(!is_debugging) { return; } if(!redraw_screen) { for(int i = 0; i!=80; i++) { video_printcoloredchar(i,0,' ',0xE0); } printf_at_cc(0,0,0xE0,"Debug Mode | Screen %d %-10s | Command: %c |",current_screen,current_screen_name,last_command); } if(redraw_screen) { terminal_clear(); video_printstring(74,24,"DEBUG"); //Title for(int i = 0; i!=80; i++) { video_printcoloredchar(i,0,' ',0xE0); } printf_at_cc(0,0,0xE0,"Debug Mode | Screen %d %-10s | Command: %c | !",current_screen,current_screen_name,last_command); switch(current_screen) { case 0: dbg_screen_0(); break; case 1: dbg_screen_1(); break; case 2: dbg_screen_2(); break; } } }
/* * terminal_write * DESCRIPTION: Writes nbytes from buf to the terminal. * INPUTS: buf - buffer to read from * nbytes - number of bytes to write * OUTPUTS: none * RETURN VALUE: number of bytes actually written * SIDE EFFECTS: Bytes written to screen */ int32_t terminal_write(const void* buf, int32_t nbytes){ cli(); terminal_clear(); int i; for(i=0; i<nbytes; i++){ int8_t cur_char = ((char *)buf)[i]; //end of string to write if(cur_char == '\0'){ return i; } //prevent read overflow if (*isReading == 1) { if (*t_pos >= 1024) break; terminal_buffer[*t_pos] = cur_char; dbufarray[cur_terminal-1][dposarray[cur_terminal-1]] = cur_char; dposarray[cur_terminal-1] += 1; *t_pos= *t_pos+1; } else{ //write character to screen if(cur_terminal == cur_pcb -> terminal_id){ putc(cur_char); } } } sti(); sti(); return i; }
/* * terminal_read * DESCRIPTION: Reads nbytes from the terminal and enters them into buf. Reads up to nbytes or new line or null character. * INPUTS: buf - buffer to fill * nbytes - number of bytes to read * OUTPUTS: none * RETURN VALUE: number of bytes actually read, -1 on error * SIDE EFFECTS: Modifies buf */ int32_t terminal_read(void* buf, int32_t nbytes){ sti(); //Check for valid buf if(buf == 0x0) { return -1; } //Clear the read buffer *t_pos = 0; int i; for (i = 0; i < 1024; i++) { terminal_buffer[i] = '\0'; } //Read until enter is pressed *enter_pressed = 0; *isReading = 1; while(!(*enter_pressed)) { //Wait for enter to be pressed terminal_clear(); } *isReading = 0; //Fill buf with the terminal's read buffer int j = 0; for(i=0; i<nbytes; i++){ j++; if(terminal_buffer[i] == '\n'){ //found new line i++; break; } if(terminal_buffer[i] == '\0'){ j--; } ((char *)buf)[i] = terminal_buffer[i]; if (j >= 72) { if (j == 72) increment_row(); else if ((j-72)%80 == 0) increment_row(); } } ((char *)buf)[i] = '\0'; //terminating string character *t_pos = 0; for (i = 0; i < 1024; i++) { terminal_buffer[i] = '\0'; } increment_row(); //Return the number of bytes put into buf return i+1; }
/** * \brief getting-started Application entry point. * * \return Unused (ANSI-C compatibility). */ int main(void) { struct port_config pin; unsigned char c; system_init(); //Configure UART console. configure_console(); configure_usart_callbacks(); usart_enable_rx_interrupt(&cdc_uart_module,&c); usart_enable(&cdc_uart_module); //Configures TC driver configure_tc(); //Configures TC callback configure_tc_callbacks(); //Initialize the delay driver delay_init(); //Enable system interrupt system_interrupt_enable_global(); //Configures PORT for LED0 port_get_config_defaults(&pin); pin.direction = PORT_PIN_DIR_OUTPUT; port_pin_set_config(LED0_PIN, &pin); port_pin_set_output_level(LED0_PIN, LED0_INACTIVE); port_pin_set_output_level(LED0_PIN, LED0_INACTIVE); /*main loop*/ while(1) { if (is_running) { //Handle user's input // if (uart_getc(&c)) // { switch (c) { case 'w': case ' ': //ROTATE tetris_rotate(); break; case 's': //DOWN tetris_gravity(); break; case 'd': //RIGHT tetris_move_right(); break; case 'a': //LEFT tetris_move_left(); break; default: break; } c=0; // } // was here if(!iterate_game) if(iterate_game) { //Update game iterate_game = false; tetris_gravity(); tetris_check_lines(); terminal_cursor_home(); tetris_print(); if (tetris_is_game_over()) { is_running = false; } } } else { // if (uart_getc(&c)) // { if (c == 'n') { c=0; //Seed random function so we do not get same start condition //for each new game. In essence we will not start a new game //exactly at the same time. srand(tick); //New Game is_running = true; terminal_cursor_off(); terminal_clear(); tetris_init(); tetris_new_block(); terminal_cursor_home(); tetris_print(); } // } } } }
void TestExtendedInterlayer() { // Setup terminal_set("window.title='Omni: extended output / interlayer animation'"); terminal_composition(TK_ON); int map_left = terminal_state(TK_WIDTH)/2 - map_width/2; int map_top = terminal_state(TK_HEIGHT)/2 - map_height/2; std::srand(std::time(nullptr)); auto map = PrepareMap(); PlaceFoe(); auto Attack = [&] { int damage = 1+std::rand()%10; foe_hp -= damage; int x = foe_x, y = foe_y; if (foe_hp <= 0) { map[foe_y*map_width+foe_x] = 1; PlaceFoe(); terminal_clear(); DrawMap(map_left, map_top, map); } AnimateDamage(map_left+x, map_top+y, -damage); }; auto Step = [&](int dx, int dy) { if (player_x+dx == foe_x && player_y+dy == foe_y) { Attack(); } else if (map[(player_y+dy)*map_width+player_x+dx] <= 1) { player_x += dx; player_y += dy; } }; for (bool proceed=true; proceed;) { terminal_clear(); DrawMap(map_left, map_top, map); terminal_refresh(); do { int key = terminal_read(); if (key == TK_CLOSE || key == TK_ESCAPE) { proceed = false; } else if (key == TK_LEFT) { Step(-1, 0); } else if (key == TK_UP) { Step(0, -1); } else if (key == TK_RIGHT) { Step(1, 0); } else if (key == TK_DOWN) { Step(0, 1); } } while (proceed && terminal_has_input()); } // Clean up terminal_composition(TK_OFF); terminal_clear(); terminal_layer(0); }
/* Check if MAGIC is valid and print the Multiboot information structure pointed by ADDR. */ void entry(unsigned long magic, unsigned long addr) { multiboot_info_t *mbi; uint32_t filesys_start_addr; /* Clear the screen. */ vga_text_clear(); /* Am I booted by a Multiboot-compliant boot loader? */ if(magic != MULTIBOOT_BOOTLOADER_MAGIC) { printf("Invalid magic number: 0x%#x\n", (unsigned)magic); return; } /* Set MBI to the address of the Multiboot information structure. */ mbi = (multiboot_info_t *)addr; /* Print out the flags. */ printf("flags = 0x%#x\n", (unsigned)mbi->flags); /* Are mem_* valid? */ if(CHECK_FLAG(mbi->flags, 0)) printf("mem_lower = %uKB, mem_upper = %uKB\n", (unsigned)mbi->mem_lower, (unsigned)mbi->mem_upper); /* Is boot_device valid? */ if(CHECK_FLAG(mbi->flags, 1)) printf("boot_device = 0x%#x\n", (unsigned)mbi->boot_device); /* Is the command line passed? */ if(CHECK_FLAG(mbi->flags, 2)) printf("cmdline = %s\n", (char *)mbi->cmdline); if(CHECK_FLAG(mbi->flags, 3)) { int mod_count = 0; int i; module_t* mod = (module_t*)mbi->mods_addr; filesys_start_addr = (uint32_t)mod->mod_start; while(mod_count < mbi->mods_count) { printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start); printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end); printf("First few bytes of module:\n"); for(i = 0; i < 16; i++) { printf("0x%x ", *((char*)(mod->mod_start+i))); } printf("\n"); mod_count++; } } /* Bits 4 and 5 are mutually exclusive! */ if(CHECK_FLAG(mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)) { printf("Both bits 4 and 5 are set.\n"); return; } /* Is the section header table of ELF valid? */ if(CHECK_FLAG(mbi->flags, 5)) { elf_section_header_table_t *elf_sec = &(mbi->elf_sec); printf("elf_sec: num = %u, size = 0x%#x," " addr = 0x%#x, shndx = 0x%#x\n", (unsigned)elf_sec->num, (unsigned)elf_sec->size, (unsigned)elf_sec->addr, (unsigned)elf_sec->shndx); } /* Are mmap_* valid? */ if(CHECK_FLAG(mbi->flags, 6)) { memory_map_t *mmap; printf("mmap_addr = 0x%#x, mmap_length = 0x%x\n", (unsigned)mbi->mmap_addr, (unsigned)mbi->mmap_length); for(mmap = (memory_map_t *)mbi->mmap_addr; (unsigned long)mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (memory_map_t *)((unsigned long)mmap + mmap->size + sizeof(mmap->size))) printf(" size = 0x%x, base_addr = 0x%#x%#x\n" " type = 0x%x, length = 0x%#x%#x\n", (unsigned)mmap->size, (unsigned)mmap->base_addr_high, (unsigned)mmap->base_addr_low, (unsigned)mmap->type, (unsigned)mmap->length_high, (unsigned)mmap->length_low); } /* Construct an LDT entry in the GDT */ { seg_desc_t the_ldt_desc; the_ldt_desc.granularity = 0; the_ldt_desc.opsize = 1; the_ldt_desc.reserved = 0; the_ldt_desc.avail = 0; the_ldt_desc.present = 1; the_ldt_desc.dpl = 0x0; the_ldt_desc.sys = 0; the_ldt_desc.type = 0x2; SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size); ldt_desc_ptr = the_ldt_desc; lldt(KERNEL_LDT); } /* Construct a TSS entry in the GDT */ { seg_desc_t the_tss_desc; the_tss_desc.granularity = 0; the_tss_desc.opsize = 0; the_tss_desc.reserved = 0; the_tss_desc.avail = 0; the_tss_desc.seg_lim_19_16 = TSS_SIZE & 0x000F0000; the_tss_desc.present = 1; the_tss_desc.dpl = 0x0; the_tss_desc.sys = 0; the_tss_desc.type = 0x9; the_tss_desc.seg_lim_15_00 = TSS_SIZE & 0x0000FFFF; SET_TSS_PARAMS(the_tss_desc, &tss, tss_size); tss_desc_ptr = the_tss_desc; tss.ldt_segment_selector = KERNEL_LDT; tss.ss0 = KERNEL_DS; tss.esp0 = 0x800000; ltr(KERNEL_TSS); } /* If kernel got to here, that means everything should be fine with the boot. * Now we should initialize IDT, PIC, Syscall, paging, devices, filesystem, * and any other initialization stuff... terminal_init() should be called at * the very end of the initializations (after sti). */ /* But first, let's clear the screen */ vga_text_clear(); /* Init the IDT */ idt_init(); /* Init the PIC */ i8259_init(); /* Init Syscall */ syscall_init(); /* Init Paging */ paging_init(); /* Init file system */ filesys_init(filesys_start_addr); /* Init the Keyboard */ keyboard_init(); /* Init the RTC */ rtc_init(); /* Enable interrupts */ sti(); /* booting screen in mode X */ start_up = 3; set_mode_x(); load_bmp((uint8_t*)"boot", LOAD_FLAG_BOOT); while(start_up == 3); set_text_mode(); /* Init the good looking terminal */ terminal_init(); /* wait for a key press to clear the start up screen */ while(start_up == 2); vga_text_clear(); welcome_and_credit(); while(start_up == 1); /* Init the status bar for that terminal */ terminal_stat_bar_init(); terminal_clear(); /* Init the PIT */ pit_init(); /* Execute the first program "shell" */ pid_now = 1; pid_running[0] = 1; root_shell_flag = 1; execute((uint8_t*)"shell"); /* Spin (nicely, so we don't chew up cycles) */ asm volatile(".1: hlt; jmp .1;"); }
void TestTilesets() { terminal_set("window.title='Omni: tilesets'"); terminal_composition(TK_ON); // Load tilesets terminal_set("U+E100: ../Media/Runic.png, size=8x16"); terminal_set("U+E200: ../Media/Tiles.png, size=32x32, align=top-left"); terminal_set("U+E300: ../Media/fontawesome-webfont.ttf, size=24x24, spacing=3x2, codepage=../Media/fontawesome-codepage.txt"); terminal_set("zodiac font: ../Media/Zodiac-S.ttf, size=24x36, spacing=3x3, codepage=437"); terminal_clear(); terminal_color("white"); terminal_print(2, 1, "[color=orange]1.[/color] Of course, there is default font tileset."); terminal_print(2, 3, "[color=orange]2.[/color] You can load some arbitrary tiles and use them as glyphs:"); terminal_print ( 2+3, 4, "Fire rune ([color=red][U+E102][/color]), " "water rune ([color=lighter blue][U+E103][/color]), " "earth rune ([color=darker green][U+E104][/color])" ); terminal_print(2, 6, "[color=orange]3.[/color] Tiles are not required to be of the same size as font symbols:"); terminal_put(2+3+0, 7, 0xE200+7); terminal_put(2+3+5, 7, 0xE200+8); terminal_put(2+3+10, 7, 0xE200+9); terminal_print(2, 10, "[color=orange]4.[/color] Like font characters, tiles may be freely colored and combined:"); terminal_put(2+3+0, 11, 0xE200+8); terminal_color("lighter orange"); terminal_put(2+3+5, 11, 0xE200+8); terminal_color("orange"); terminal_put(2+3+10, 11, 0xE200+8); terminal_color("dark orange"); terminal_put(2+3+15, 11, 0xE200+8); terminal_color("white"); std::vector<int> order = {11, 10, 14, 12, 13}; for (int i=0; i<order.size(); i++) { terminal_put(2+3+25+i*4, 11, 0xE200+order[i]); terminal_put(2+3+25+(order.size()+1)*4, 11, 0xE200+order[i]); } terminal_put(2+3+25+order.size()*4, 11, 0xE200+15); terminal_print(2, 14, "[color=orange]5.[/color] And tiles can even come from TrueType fonts like this:"); for (int i=0; i<6; i++) { terminal_put(2+3+i*5, 15, 0xE300+i); } terminal_print(2+3, 18, "...or like this:\n[font=zodiac]D F G S C"); terminal_refresh(); for (int key=0; key!=TK_CLOSE && key!=TK_ESCAPE; key=terminal_read()); // Clean up terminal_set("U+E100: none; U+E200: none; U+E300: none; zodiac font: none"); terminal_composition(TK_OFF); }
void BasicOutput() { terminal_options("title=BearLibTerminal demo: output facilities"); terminal_options("font.name=default; font.supplement=Media/Omni/supplement-runic.png"); terminal_blending(BLENDING_ADDITIVE); terminal_color(COLOR_WHITE); terminal_clear(); // Simple output with postformatting terminal_printf(1, 1, "[color=gray]1. Most basic:[/color] ABC abc"); // Wide color range int n = terminal_printf(1, 3, "[color=gray]2. Colors: "); const char long_word[] = "Antidisestablishmentarianism"; const size_t long_word_length = sizeof(long_word)-1; for ( size_t i = 0; i < long_word_length; i++ ) { float factor = float(i)/long_word_length; int red = (1.0f - factor) * 255; int green = factor * 255; terminal_color(color_from_argb(255, red, green, 0)); terminal_put(n+1+i, 3, long_word[i]); } terminal_color(color_from_name("white")); // Tile backgrounds terminal_printf(1, 5, "[color=gray]3. Backgrounds: [color=black][bkcolor=gray] grey [/bkcolor] [bkcolor=red] red "); // Simple unicode output terminal_printf(1, 7, "[color=gray]4. Unicode:[/color] Latin Русский Ελληνικά"); // Composite (overlay) tiles n = terminal_printf(1, 9, "[color=gray]5. Tile overlay: "); terminal_printf(n+1, 9, "a+ = a, a+ = a, a vs. [color=red]ä"); terminal_printf(n+1, 9, "[color=red] / / ▔ ▔ [/color]a"); // Unicode Box Drawing characters terminal_printf(1, 11, "[color=gray]6. Box drawing:"); const char* box_lines[] = { " ┌──┬───┐ ╔═════╗ ", " ┌───┬─┘ │ ├──┐ ╟──┐ ║ ", " └─┐ └─┐ ├───┘ │ ║ └──╢ ", " └───┴──┴──────┘ ╚═════╝ " }; for ( size_t i = 0; i < sizeof(box_lines)/sizeof(box_lines[i]); i++ ) { terminal_printf(1, 12+i, "%s", box_lines[i]); } // Box drawing + overlay application terminal_printf(1, 17, "[color=gray]7. Box drawing + overlay:"); terminal_color(0xFF006000); for ( int y = 0; y < 6; y++ ) { for ( int x = 0; x < 19; x++ ) { terminal_put(1+x, 18+y, 'A'+(x+y)%26); } } DrawOverlayRectangle(3, 19, 15, 4, 0xFFFFFFFF, 0xA0909090); terminal_printf(4, 20, "[color=white]Itym:\nHeavy draggon"); terminal_printf(40, 17, "[color=gray]8. Font supplement:"); terminal_printf(40, 19, "fire ([color=red][uE001][/color]) - water ([color=lighter blue][uE004][/color]) - earth ([color=dark green][uE00F][/color])"); terminal_printf(40, 20, "\uE001\uE002\uE003, \uE004\uE005\uE006\uE007\uE008! \uE009\uE00A\uE00B \uE00C \uE00D\uE00E\uE00F\uE010."); terminal_refresh(); int key = 0; do { key = terminal_get(); } while ( key != VK_CLOSE && key != VK_ESCAPE ); }
void terminal_bluescreen(){ terminal_color = make_color(COLOR_WHITE, COLOR_BLUE); terminal_clear(); }
void panic(char* message){ terminal_clear(); terminal_writestringwithcolor("Kernel panic:\n", COLOR_RED, COLOR_BLACK); terminal_writestringwithcolor(message, COLOR_RED, COLOR_BLACK); }
void select_file_action(void *arg) { int selected = *((int *) arg); int i, j, k, fd, size; volatile uint8_t *tmp; switch(selected) { case 0: fd = fat_open(path, O_RDONLY); size = fat_fsize(fd); for(j = 0; j < size; j += 512) { terminal_clear(); fat_read_sect(fd); for(i = 0; i < 512; i++) { if(fat_buf[i] < 32 || fat_buf[i] > 126) printf("?"); else printf("%c", fat_buf[i]); } input_poll(); } fat_close(fd); break; case 1: fd = fat_open(path, O_RDONLY); size = fat_fsize(fd); for(j = 0; j < size; j += 512) { terminal_clear(); printf("\nSector %u\n", j >> 9); fat_read_sect(fd); for(i = 0; i < 256; i+=16) { tmp =((uint8_t *) fat_buf) + i; printf("%04x\t%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\t\t", j + i, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14], tmp[15] ); for(k = 0; k < 16; k++) { if(tmp[k] < 32 || tmp[k] > 126) printf("."); else printf("%c", tmp[k]); } printf("\n"); } input_poll(); terminal_clear(); printf("\nSector %u\n", j >> 9); for(i = 256; i < 512; i+=16) { tmp =((uint8_t *) fat_buf) + i; printf("%04x\t%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\t\t", j + i, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14], tmp[15] ); for(k = 0; k < 16; k++) { if(tmp[k] < 32 || tmp[k] > 126) printf("."); else printf("%c", tmp[k]); } printf("\n"); } input_poll(); } fat_close(fd); break; case 2: { void *addr, *entry; fd = fat_open(path, O_RDONLY); if(hexload(get_byte, fd, hexload_write_byte, NULL, &entry) < 0) { printf("Invalid hex file"); fat_close(fd); input_poll(); break; } fat_close(fd); fd = fat_open(path, O_RDONLY); if(hexload(get_byte, fd, hexload_verify_byte, NULL, &addr) < 0) { printf("Hexload validate error at 0x%X\n", addr); fat_close(fd); input_poll(); break; } __asm__ __volatile__ ("cpusha %dc\n"); goto *addr; fat_close(fd); input_poll(); } break; case 4: fd = fat_open(path, O_RDONLY); size = fat_fsize(fd); tmp = MEM_VGA_RAM; for(j = 512; j < size; j += 512) { fat_read_sect(fd); for(i = 0; i < 512; i++) { *tmp++ = fat_buf[i]; } } fat_read_sect(fd); for(i = 0; i < j - size; i++) { *tmp++ = fat_buf[i]; } fat_close(fd); input_poll(); terminal_clear(); break; case 5: load_hex_to_rom(path); input_poll(); break; case 6: terminal_clear(); printf("Loading WAV to RAM\n"); fd = fat_open(path, O_RDONLY); size = fat_fsize(fd); tmp = (volatile uint8_t *) SDRAM_BASE; printf("0/%u kB", size >> 10); for(j = 0; j < size; j += 512) { fat_read_sect(fd); for(i = 0; i < 512; i++) { *tmp++ = fat_buf[i]; } printf("\r%u/%u kB", j >> 10, size >> 10); } fat_close(fd); printf("\n"); wav_play((uint8_t *) SDRAM_BASE); printf("Press any key\n"); input_poll(); terminal_clear(); } }
static void clear_and_print_filename(void *arg) { terminal_clear(); printf("%s\n%s", path, arg); }