⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmu.c

📁 DC的SEGA_GG模拟器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* vmu.c
 *   thanks to Ken Friece for this code
 *
 */
#include <kos.h>
#include "vmu.h"

void dc_print (char *fmt, ...);
void print_uint32 (uint32 val);

uint8 init_vmu() {
        return(maple_first_vmu());
}

void novmu() {
                printf("No VMU present!\r\n");
/* must add a "no vmu found" screen here */
}

uint16 calcCRC(const unsigned char *buf, int size) {
        int i, c, n = 0;
        for (i = 0; i < size; i++) {
                n ^= (buf[i]<<8);
                for (c = 0; c < 8; c++)
                        if (n & 0x8000)
                                n = (n << 1) ^ 4129;
                        else
                                n = (n << 1);
        }
        return (n & 0xffff);
}

uint16 get_next_block_from_fat (uint16 block_number) {
	
        uint8 addr = maple_first_vmu();
	uint16 fatblock;
	
	uint8 buf[512];
	uint16 *buf16 = (uint16*)buf;

        //uint8 free_blocks = 0;

	if (vmu_block_read(addr, 255, buf)) {
		return 0;
	}
        thd_sleep(30);
	
	fatblock = buf16[0x46/2];

	if (vmu_block_read(addr, fatblock, buf) != 0) {
		return 0;
	}
        thd_sleep(30);

	return buf16[block_number];

}

uint16 check_vmu_for_game (const char* game_name) {
	
	int i, n;
        uint8 addr = maple_first_vmu(), *ent;
	uint8 buf[512];
        uint16 *buf16 = (uint16*)buf, dirblock, dirlength;//, *ent16;
        //uint16 icondata = 0;
	char *rom_name = (char *)malloc(12);
	uint8 filename_size = strlen (game_name);
	int number = 0;

        /* Make sure we have a VMU */
	if (!addr) {
                novmu();
                free(rom_name);
		return 0;
	}

	for (i=0; i<11; i++) {
		if (i < filename_size) 
			rom_name[i] = game_name[i];
		else 
			rom_name[i] = ' ';
	}
	rom_name[11] = '&';

        /* Read the root block and find out where the directory is located */
	if (vmu_block_read(addr, 255, buf)) {
              printf("Can't read VMU root block\r\n");
	//	return 0;
	}
        thd_sleep(30);

	dirblock = buf16[0x4a/2]; dirlength = buf16[0x4c/2];

        /* Draw entries and look for the ICONDATA.VMS entry */
	for (n=dirlength; n>0; n--) {
                /* Read one dir block */
		if (vmu_block_read(addr, dirblock, buf) != 0) {
                        printf("Can't read VMU block %d\r\n", dirblock);
                        free(rom_name);
			return 0;
		}
                thd_sleep(30);

                /* Each block has 16 entries */
		for (i=0; i<16; i++) {
			dirent_vmu *vmu_val = (dirent_vmu *)ent;
                        int ii;

                        ent = buf+i*32;

			//dc_print (testing->filename);
                        //thd_sleep (1000);
			if (!*ent) {	
				continue;
			}

			number = 0;
                        for (ii=0; ii<12; ii++) {
				if (ent[ii+4] == rom_name[ii]) {
					number++;
				}
			}
			if (number == 12) {
				
				uint8 buf2[512];
				file_hdr_vmu *hdr_ptr = (file_hdr_vmu *)buf2;

				if (vmu_block_read(addr, vmu_val->firstblk, buf2)) {
                                        printf("Can't read VMU root block\r\n");
				}
                                thd_sleep(30);

				if ((strcmp (hdr_ptr->desc_short, game_name) == 0) && (strcmp (hdr_ptr->app_id, "***NesterDC***") == 0)) {
                                        free(rom_name);
					return vmu_val->firstblk;
				}
			}

		}
		dirblock--;
	}

        free(rom_name);
	return 0;
}

void update_fat (uint8 *free_mem, uint8 blocks_left) {
        uint8 addr = maple_first_vmu();
	uint16 fatblock;
	uint8 buf[512];
	uint16 *buf16 = (uint16*)buf;
	uint16 this_block = 0;
	//uint16 blocks_left = 18;
	uint8 max_block = blocks_left;
        int i;

	if (vmu_block_read(addr, 255, buf)) {
		return;
	}
        thd_sleep (30);
	
	fatblock = buf16[0x46/2];

	if (vmu_block_read(addr, fatblock, buf) != 0) {
		return;
	}
        thd_sleep (30);

        for (i=0; i<200; i++) {
		if (free_mem[199-i] == 1) {
                        /* first file block */
			if (blocks_left == max_block) {
				this_block = 199 - i;
			}
                        /* need the next one */
			if (blocks_left < max_block) {

				buf16[this_block] = 199 - i;
				this_block = 199 - i;
			}

			blocks_left--; 
		}
                /* last file block */
		if (blocks_left == 0) { 
			
			buf16[this_block] = 0xfffa;
			break;
		}
	}
	if (vmu_block_write (addr, fatblock, (uint8 *)buf16) != 0) {
                dc_print("there was an error updating the fat");
	}
        thd_sleep (30);
}

void upload_vmu_data (uint8 *vmu_file, uint8 *free_mem, uint8 blocks_left) {
        uint8 addr = maple_first_vmu();
	//uint8 blocks_left = 18;
	uint8 *temp_ptr = vmu_file;
	uint8 *temp_p = (uint8 *)malloc(512);
        int i;

        for (i=0; i<200; i++) {

		if (free_mem[199-i] == 1) {

			if (vmu_block_read (addr, 199-i, temp_p) != 0) {
				dc_print ("there was an error reading data");
				print_uint32 ((uint32)blocks_left);
			}

                        thd_sleep(30);

			if (vmu_block_write (addr, 199-i, temp_ptr) != 0) {
				dc_print ("there was an error writing data");
				print_uint32 ((uint32)blocks_left);
			}
			blocks_left--;
			temp_ptr += 512;
                        thd_sleep (30);

		}
		if (blocks_left == 0) break;
	}
        free(temp_p);
}

void upload_data_by_block (uint8 *vmu_file, uint16 block_number, uint8 blocks_left) {
        uint8 addr = maple_first_vmu();
	uint8 *temp_p = (uint8 *)malloc(512);
	uint8 *temp_ptr = vmu_file;
	uint16 block_copy = block_number;
        int i;

        for (i=0; i<blocks_left; i++) {

		//dc_print ("the block number we are on is");
		//print_uint32 ((uint32)block_number);
                //thd_sleep (2000);

		block_copy = block_number;
		if (vmu_block_read (addr, block_copy, temp_p) != 0) {
			dc_print ("there was an error reading data");
			print_uint32 ((uint32)block_number);
                        thd_sleep(2000);
		}
                thd_sleep (30);

		block_copy = block_number;
		if (vmu_block_write (addr, block_copy, temp_ptr) != 0) {
			dc_print ("there was an error writing data");
			print_uint32 ((uint32)block_number);
                        thd_sleep(2000);
		}
                thd_sleep (30);
	
		temp_ptr += 512;

		block_number = get_next_block_from_fat (block_number);
	}
        free(temp_p);
}

void update_vmu_dir (uint16 block, const char *filename, uint8 blocks) {
        int i, ii, n;//, drawn = 0;
        uint8 addr = maple_first_vmu(), *ent;
	uint8 buf[512];
        //uint8 *buf_ptr = buf;
        uint16 *buf16 = (uint16*)buf, dirblock, dirlength;//, *ent16;
        //uint16 icondata = 0;
        dirent_vmu *dir_entry;

	if (!addr) {
                novmu();
                printf("No VMU present!\r\n");
		return;
	}

        /* Read the root block and find out where the directory is located */
	if (vmu_block_read(addr, 255, buf)) {
                dc_print("There was an error reading the root block");
                printf("Can't read VMU root block\r\n");
	}
        thd_sleep (30);

	dirblock = buf16[0x4a/2]; dirlength = buf16[0x4c/2];

        dir_entry = (dirent_vmu *)malloc(1);
	//uint8 *dir_entry = (uint8*)malloc(32);

	create_dir_vmu (dir_entry, filename, block, blocks); 

        /* Draw entries and look for the ICONDATA.VMS entry */
	for (n=dirlength; n>0; n--) {
                /* Read one dir block */
		if (vmu_block_read(addr, dirblock, buf) != 0) {
                        dc_print ("There was an error reading the dirblock");
                        printf("Can't read VMU block %d\r\n", dirblock);
                        free(dir_entry);
			return;
		}
                thd_sleep(30);

                /* Each block has 16 entries */
		for (i=0; i<16; i++) {
			ent = buf+i*32;
			if (!*ent) {	
				uint8 *temp_ptr = (uint8 *)dir_entry;

                                for (ii=0; ii<32; ii++) {
                                        ent[ii] = temp_ptr[ii];
				}
				if (vmu_block_write(addr, dirblock, buf) != 0) {
                                        dc_print("There was an error updating the directory");
				}
				vmu_block_read(addr, dirblock, buf);
                                thd_sleep(30);
                                free(dir_entry);
				return;
			}
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -