u_int32 identify_hd ( ){ u_int16 hd_info_buf[256]; struct HD_MSG hd; hd.lba=0; hd.buf=hd_info_buf; hd.type=HD_IDENTIFY; make_msg(&msg_send,fs_pid,HD_DRIVER,HD_MSG_TYPE,BLOCK_NEED); msg_send.u.msg_hd=hd; u_int32 key=send(&msg_send,fs_pid); if(key==FALSE) return 0; else { memcpy8((u_int8*)(hd_info_buf+10),(u_int8*)hd_info.hd_no,20);//硬盘序列号 hd_info.hd_no[20]='\0'; hd_info.hd_type[40]='\0'; memcpy8((u_int8*)(hd_info_buf+27),(u_int8*)hd_info.hd_type,40);//型号 hd_info.sectorNum=*((u_int32*)(hd_info_buf+60)); hd_info.capabilities=*(hd_info_buf+49); hd_info.support_cmd=*(hd_info_buf+83); bmp_sect=((hd_info.sectorNum%4096)==0)?(hd_info.sectorNum/4096):(hd_info.sectorNum/4096+1); return TRUE; } }
void create_fs ( ){ /*进入此函数证明当前硬盘无任何操作系统,需要初始化superBlock,扇区位图,文件分配表*/ /*superBlock*/ memcpy8("TINY",superBlock.sign,5);/*文件系统标识*/ superBlock.n_sects=hd_info.sectorNum; superBlock.n_inode=MAX_FILE; /*扇区位图,注:前32个扇区存储文件系统的信息,一定处于使用状态*/ int i; for(i=0;i<DATA_START;i++) mask1(i); for(i=DATA_START;i<superBlock.n_sects;i++) mask0(i); /*文件分配表,初始时全部无效化*/ fat.size=0; for(i=0;i<MAX_FILE;i++) fat.i_node_arr[i].status=I_NODE_INVALID; /*将信息全部写入硬盘*/ u_int8 buf[512]; /*写superBlock*/ memcpy8((u_int8*)&superBlock,buf,SUPERBLOCK_SIZE); while(write_sector(SUPERBLOCK_START,buf)==FALSE); /*写位图*/ u_int32 bmp_sect=((superBlock.n_sects%4096)==0)?(superBlock.n_sects/4096):(superBlock.n_sects/4096+1); u_int32 pos=0; for(i=HD_BMP_START;i<HD_BMP_START+bmp_sect;i++,pos+=512) while(write_sector(i,hd_bmp+pos)==FALSE); /*写文件分配表*/ pos=0; for(i=FAT_START;i<FAT_START+MAX_FAT;i++,pos+=512) while(write_sector(i,((u_int8*)&fat+pos))==FALSE); }
u_int32 read_file (u_int32 handle,u_int32 buf_len,void*buf ,u_int32 send_pid){ /*patch:判断权限*/ int i; int8*buffer=(int8*)transTolinerAddr((u_int32)buf,send_pid,1); /*patch:判断handle的有效性*/ u_int32 size=fat.i_node_arr[handle].byte_size; /*请求长度超过了文件长度,只读取本文件*/ if(buf_len>size) buf_len=size; u_int32 read_sects=buf_len/512; u_int32 start=fat.i_node_arr[handle].startSector; u_int32 pos=0; for(i=start;i<start+read_sects;i++,pos+=512) while(read_sector(i,buffer+pos)==FALSE); if((buf_len%512)==0) { return buf_len; } else {/*否则对最后一个扇区特殊处理*/ int8 tempBuf[512]; while(read_sector(start+read_sects,tempBuf)==FALSE); memcpy8(tempBuf,buffer+read_sects*512,buf_len%512); return buf_len; } }
PUBLIC int32 addDes (u_int32 base,u_int32 limit,u_int32 attribute ){ u_int8 desc[8]; gen_normalDescriptor(desc,base,limit,attribute); memcpy8(desc,(u_int8*)(&(gdt.gdtDescriptor[gdt.gdtDescriptor_length])),8); gdt.gdtDescriptor_length++; return gdt.gdtDescriptor_length-1; }
u_int32 write_file (u_int32 handle,u_int32 buf_len,void*buf,u_int32 send_pid ){ /*patch:判断权限*/ int i; /*patch:判断handle的有效性*/ int8*buffer=(int8*)transTolinerAddr((u_int32)buf,send_pid,1); u_int32 write_sects=buf_len/512; /*patch:增加判断扇区超出文件拥有扇区*/ u_int32 start=fat.i_node_arr[handle].startSector; u_int32 pos=0; for(i=start;i<start+write_sects;i++,pos+=512) while(write_sector(i,buffer+pos)==FALSE); /*文件若变得更长,则需要更新信息*/ u_int32 size=fat.i_node_arr[handle].byte_size; if(buf_len>size) fat.i_node_arr[handle].byte_size=buf_len; if((buf_len%512)==0) { return TRUE; } else {/*否则对最后一个扇区特殊处理*/ int8 tempBuf[512]; while(read_sector(start+write_sects,tempBuf)==FALSE); memcpy8(buffer+write_sects*512,tempBuf,buf_len%512); while(write_sector(start+write_sects,tempBuf)==FALSE); return TRUE; } }
StringData* StringData::Make(const StringData* s1, const StringData* s2) { auto const len = s1->m_len + s2->m_len; // `memcpy8()' could overrun the buffer by at most 7 bytes, so we allocate 6 // more bytes here, which (together with the trailing 0) makes it safe. auto const sd = allocFlatForLenSmall(len + 6); sd->m_lenAndHash = len; // hash=0 auto const data = reinterpret_cast<char*>(sd + 1); auto const next = memcpy8(data, s1->m_data, s1->m_len); *memcpy8(next, s2->m_data, s2->m_len) = 0; assert(sd->getCount() == 1); assert(sd->isFlat()); assert(sd->checkSane()); return sd; }
static void assert_memcpy (uword iter) { u8 * s, * d; void * s_orig, * d_orig; uword i, j; uword size; for (i = 0; i < iter; i++) { void * avoid_warnings_s, * avoid_warnings_d; size = bounded_random_u32 (&g_seed, 0, g_bytes); get_random_pointer (size + 1, &avoid_warnings_d, &d_orig); get_random_pointer (size + 1, &avoid_warnings_s, &s_orig); s = avoid_warnings_s; d = avoid_warnings_d; memset (d, 0, size + 1); memset (s, 0xba, size + 1); d[size] = MAGIC_GUARD; memcpy8 (d, s, size); for (j = 0; j < size; j++) ASSERT (d[j] == s[j]); ASSERT (d[size] == MAGIC_GUARD); clib_mem_free_safe (d_orig); clib_mem_free_safe (s_orig); } fformat (stdout, "memcpy() validation successful!\n"); }
StringData* StringData::Make(const StringData* s, CopyStringMode) { auto const sd = allocFlatForLenSmall(s->m_len); sd->m_lenAndHash = s->m_lenAndHash; auto const data = static_cast<void*>(sd + 1); *memcpy8(data, s->data(), s->m_len) = 0; assert(sd->same(s)); return sd; }
u_int32 identify_fs ( ){ int8 buf[512]; u_int32 status=read_sector(SUPERBLOCK_START,buf); if(status==FALSE) return FALSE; else { memcpy8(buf,(u_int8*)&superBlock,SUPERBLOCK_SIZE); return TRUE; } }
void read_fat ( ){ int i; u_int8 buf[512]; u_int32 write_pos=0; for(i=FAT_START;i<FAT_START+MAX_FAT;i++) { while(read_sector(i,buf)==FALSE); /*注:由于最后一个扇区可能只有一部分是FAT的内容,为保证写入不越界*/ if(write_pos+512<=FAT_SIZE)/*如果当前读入的扇区全部是fat内容*/ { memcpy8(buf,(u_int8*)&fat+write_pos,512); write_pos+=512; } else/*否则当前buf只有FAT_SIZE-write_pos个字节属于fat*/ { memcpy8(buf,(u_int8*)&fat+write_pos,FAT_SIZE-write_pos); return; } } }
StringData* StringData::Make(const StringData* s, CopyStringMode) { auto const allocRet = allocFlatForLen(s->m_len); auto const sd = allocRet.first; auto const cc = allocRet.second; auto const data = reinterpret_cast<char*>(sd + 1); sd->m_data = data; sd->m_hdr.init(cc, HeaderKind::String, 1); sd->m_lenAndHash = s->m_lenAndHash; *memcpy8(data, s->m_data, s->m_len) = 0; assert(sd->same(s)); return sd; }
u_int32 read_hd_bmp ( ){ int8 buf[512]; u_int32 read_times=bmp_sect; assert(read_times<=MAX_BMP_SECTOR); u_int32 i; for(i=0;i<read_times;i++) { while(read_sector(HD_BMP_START+i,buf)==FALSE); memcpy8(buf,hd_bmp+(i<<9),512); } return TRUE; }
// State transition from Mode::Shared to Mode::Flat. StringData* StringData::escalate(size_t cap) { assert(isShared() && !isStatic() && cap >= m_len); auto const sd = allocFlatForLenSmall(cap); sd->m_lenAndHash = m_lenAndHash; auto const data = reinterpret_cast<char*>(sd + 1); *memcpy8(data, m_data, m_len) = 0; assert(sd->hasExactlyOneRef()); assert(sd->isFlat()); assert(sd->checkSane()); return sd; }
StringData* StringData::shrinkImpl(size_t len) { assert(!isImmutable() && !hasMultipleRefs()); assert(isFlat()); assert(len <= capacity()); auto const sd = Make(len); sd->m_len = len; auto const src = slice(); auto const dst = sd->mutableData(); *memcpy8(dst, src.ptr, len) = 0; assert(sd->checkSane()); return sd; }
StringData* StringData::shrinkImpl(size_t len) { assert(!isImmutable() && !hasMultipleRefs()); assert(isFlat()); assert(len <= capacity()); auto const sd = allocFlatForLenSmall(len); sd->m_lenAndHash = len; auto const src = static_cast<void*>(this + 1); auto const dst = static_cast<void*>(sd + 1); *memcpy8(dst, src, len) = 0; assert(sd->checkSane()); return sd; }
// State transition from Mode::Shared to Mode::Flat. StringData* StringData::escalate(size_t cap) { assert(isShared() && !isStatic() && cap >= m_len); auto const allocRet = allocFlatForLen(cap); auto const sd = allocRet.first; auto const cc = allocRet.second; auto const data = reinterpret_cast<char*>(sd + 1); sd->m_data = data; sd->m_hdr.init(cc, HeaderKind::String, 1); sd->m_lenAndHash = m_lenAndHash; *memcpy8(data, m_data, m_len) = 0; assert(sd->hasExactlyOneRef()); assert(sd->isFlat()); assert(sd->checkSane()); return sd; }
u_int32 create_file (int8* file_name,u_int32 send_pid ){ int8*ptr=transTolinerAddr((u_int32)file_name,send_pid,1); u_int32 i_node=get_valid_inode(); if(i_node==0) return FALSE; u_int32 len=strlen(ptr); if(len>=MAX_FILE_NAME) return 0; memcpy8(ptr,fat.i_node_arr[i_node].file_name,len); fat.i_node_arr[i_node].file_name[len]='\0'; /*分配文件的扇区,并设置位图*/ u_int32 valid_sector=get_valid_sector(); fat.i_node_arr[i_node].byte_size=0; fat.i_node_arr[i_node].startSector=valid_sector; fat.i_node_arr[i_node].sectorNum=ALLOC_FILE_LEN; fat.i_node_arr[i_node].status=I_NODE_VALID; int i; for(i=valid_sector;i<valid_sector+ALLOC_FILE_LEN;i++) mask1(i); fat.size++; return TRUE; }
inline void memcpy8( volatile void* dst, const void* src, u32 bytecount ) { memcpy8( (void*)dst, src, bytecount ); }
/*文件操作函数*/ u_int32 identify_file (u_int32 handle,struct I_NODE*inode,u_int32 send_pid ){ /*patch:判断handle的有效性*/ int8*temp=(int8*)transTolinerAddr((u_int32)inode,send_pid,1); memcpy8((u_int8*)&fat.i_node_arr[handle],temp,sizeof(struct I_NODE)); return TRUE; }
inline void arr_memcpy8( type* dst, const void* src, u32 num_elems ) { memcpy8( (void*)dst, src, num_elems * sizeof(type) / sizeof(u8) ); }
int main() { irq_init(); // This will eventually be used to identify whether save data has been // created. As of right now, there is no need for save data, but that // will change in the future. It is likely that 64 kiB of save data // will be more than enough. memcpy8( game_manager::sram_init_str, game_manager::sram_const_init_str, game_manager::sram_init_str_size ); //asm_comment("Before first show_debug_s32_group() call"); //show_debug_s32_group // ( fixedu12p4_packed::get_underlying_type_is_signed(), // fixeds12p4_packed::get_underlying_type_is_signed(), // fixeds8p8_packed::get_underlying_type_is_signed(), // sizeof(fixedu12p4_packed), // sizeof(fixeds12p4_packed), // sizeof(fixeds8p8_packed) ); // //asm_comment("Before second show_debug_s32_group() call"); //show_debug_s32_group( make_f24p8( -3, 5 ).data, // make_f8p8( -3, 5 ).data, // make_fu12p4_packed( 10, 12 ).data, // make_fs12p4_packed( -3, 5 ).data, // make_fs8p8_packed( 124, 200 ).data ); //arr_memfill8( (u8*)ewram_test_arr, '#', ewram_test_arr_size ); //memset( ewram_test_arr, '#', ewram_test_arr_size ); //memset( ewram_test_arr, '#', 4 ); //ewram_test_arr[0] = '9'; //memset( &ewram_test_arr[1], '3', 9 ); //memcpy( &ewram_test_arr[1], test_str, 5 ); //slower_memcpy( &ewram_test_arr[1], test_str, 5 ); //memcpy( &ewram_test_arr[1] //halt(); game_manager::title_screen_func(); // This function is called by game_manager::title_screen_func(). //game_manager::reinit_the_game(); for (;;) { gfx_manager::back_up_bgofs_mirror(); sprite& the_player = *sprite_manager::the_player; debug_arr_group::clear_debug_vars(); clear_oam_mirror(); // Key polling is done in game_manager::vblank_func() //key_poll(); if ( soft_reset_keys_down() ) { // Reset the game if A, B, Start, and Select are pressed //bios_do_hard_reset(); ////bios_do_soft_reset(); game_manager::reinit_the_game(); } sprite_manager::find_all_active_sprites(); // Despawn sprites that are too far offscreen. sprite_manager::despawn_sprites_if_needed (gfx_manager::bgofs_mirror[0].curr); sprite_manager::find_all_active_sprites(); sprite_manager::update_all_sprites ( active_level::get_curr_sublevel_ptr().get_size_2d(), gfx_manager::bgofs_mirror[0] ); // This is temporary if ( key_hit_or_held(key_l) ) { sprite_manager::spawn_a_sprite_basic( st_waffle, the_player.in_level_pos.curr, gfx_manager::bgofs_mirror[0], (bool)the_player.the_oam_entry.get_hflip_status() ); } //if ( key_hit(key_select) ) //{ // game_manager::fade_out_to_black(1); // // game_manager::wait_for_x_frames(60); // // game_manager::fade_in(1); //} sprite_manager::spawn_sprites_if_needed (gfx_manager::bgofs_mirror[0]); //if ( key_hit(key_l) ) //{ // --player_sprite_stuff::remaining_hp; //} //if ( key_hit(key_r) ) //{ // ++player_sprite_stuff::remaining_hp; //} // //active_level_manager::update_sublevel_in_screenblock_mirror_2d // ( active_level::bg0_screenblock_mirror_2d, // test_level.get_size_2d() ); active_level_manager::update_sublevel_in_screenblock_mirror_2d(); bios_wait_for_vblank(); //game_manager::vblank_func(); } return 0; }