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

📄 vmuload.c

📁 DC记录卡读取程序
💻 C
字号:
/*   VMULoad 1.0   (c)2000 Dan Potter   Please see the file README for info about distribution and usage.   Thanks to Marcus Comstedt for this VMU format info.*/#include "dream.h"uint8 buf[512];uint8 fat[512];typedef struct {	uint16	first_block;	uint16	block_cnt;	char	fn[12];} vmufile_t;vmufile_t files[16] = {0};/* Routine to flush parts of cache.. thanks to the Linux-SH guys *//* This routine was taken from sh-stub.c which had a prominent   no-copyright notice at the top. Therefore, I'm including it now   under the copyright umbrella of KallistiOS. */#define L1_CACHE_BYTES 32#define CACHE_IC_ADDRESS_ARRAY	0xf0000000#define CACHE_IC_ENTRY_MASK	0x1fe0struct __large_struct { uint32 buf[100]; };#define __m(x) (*(struct __large_struct *)(x))/* end is really cnt */static void flush_icache_range(uint32 start, uint32 end) {	uint32 addr, data, v;	end += start;	start &= ~(L1_CACHE_BYTES-1);		for (v=start; v<end; v+=L1_CACHE_BYTES) {		/* Write back O Cache */		asm volatile("ocbwb %0"			: /* no output */			: "m" (__m(v)));		/* Invalidate I Cache */		//addr = CACHE_IC_ADDRESS_ARRAY |		//	(v & CACHE_IC_ENTRY_MASK) | 0x8	/* A-bit */;		addr = CACHE_IC_ADDRESS_ARRAY |			(v & CACHE_IC_ENTRY_MASK);		data = (v & 0xfffffc00);	/* Valid = 0 */		*((volatile uint32*)addr) = data;	}}/* Read the VMU's directory, looking for VMULoad files */int vmu_scan_card(uint8 addr) {	int i, n, curfile;	uint8 *ent;	uint16 *buf16 = (uint16*)buf, dirblock, dirlength, *ent16;	uint16 file_block = 0;	memset(files, 0, sizeof(files));	curfile = 0;	/* 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");	}	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);			return -1;		}		/* Each block has 16 entries */		for (i=0; i<16; i++) {			ent = buf+i*32;			if (!*ent) continue;			ent16 = (uint16*)ent;			files[curfile].first_block = ent16[1];			files[curfile].block_cnt = ent16[0x18/2];			memcpy(files[curfile].fn, ent+4, 12);						curfile++;			if (curfile >= 16) {				i = 16; n = 0; break;			}		}		dirblock--;	}	return 0;}/* Load the indexed file from the VMU */int vmu_load_file(uint8 addr, int idx, uint8 *buffer) {	uint16 *fat16 = (uint16*)fat;	uint16 blkcnt = 0;	uint16 file_block = files[idx].first_block;	/* Read the FAT */	if (vmu_block_read(addr, 254, fat) < 0) {		printf("Can't read VMU FAT\r\n");		return -1;	}	while (file_block != 0xfffa) {		printf("Loading block %d\r\n", file_block);		if (vmu_block_read(addr, file_block, buffer) < 0) {			printf("Failure to read block %d\r\n", file_block);			return -1;		}		if (blkcnt > 0)					buffer += 512;		file_block = fat16[file_block];		blkcnt++;				/* Sanity check */		if (blkcnt > 200) {			printf("More than 200 blocks: corrupted memory card?\r\n");			return -1;		}	}		printf("Load complete: loaded %d blocks\r\n", blkcnt);	flush_icache_range(0x8c010000, 512*blkcnt+512);		return 0;}/* VMU file menu */void draw_listing(int cur) {	uint16 *out = vram_s + 640*60+20;	int i;	char tmp[64];		/* Clear everything */	vid_clear(0,0,0);		/* Put a banner */	bfont_draw_str(vram_s+640*20+20, 640, "VMULoad v1.0 (c)2000 Dan Potter/Cryptic Allusion");		for (i=0; i<16; i++) {		if (files[i].block_cnt == 0) continue;				strncpy(tmp, files[i].fn, 12); tmp[12] = 0;		bfont_draw_str(out, 640, tmp);				sprintf(tmp, "(%d blocks @ %d)", files[i].block_cnt, files[i].first_block);		bfont_draw_str(out + 16*13, 640, tmp);		out += 640*24;	}	bfont_draw(vram_s+640*(60+24*cur)+8, 640, '>');}uint8 mcont=0, mvmu=0;int vmu_menu() {	cont_cond_t cond;	int cur = 0, cnt = 0, moved = 0;		/* Make sure we have a controller */	if (!mcont) {		mcont = maple_controller_addr();		if (!mcont) {			printf("Can't find a controller\r\n");			return -1;		}	}		/* Make sure we have a VMU */	if (!mvmu) {		mvmu = maple_vmu_addr();		if (!mvmu) {			printf("Can't find a VMU\r\n");			return -1;		}	}	/* Draw the memory card listing */	if (vmu_scan_card(mvmu) < 0) return -1;	draw_listing(cur);		/* Now let the user pick one */	while(1) {		/* Check status */		if (cont_get_cond(mcont, &cond) < 0) {			printf("Couldn't get controller status\r\n");			return -1;		}				/* File selection */		if (!(cond.buttons & CONT_A))			return cur;				/* Exit */		if (!(cond.buttons & CONT_START))			return -1;		/* Move selector */		if (!(cnt % 10) && !(cond.buttons & CONT_DPAD_UP)) {			moved = 1;			if (cur > 0) cur--;		}		if (!(cnt % 10) && !(cond.buttons & CONT_DPAD_DOWN)) {			moved = 1;			if (cur < 16) cur++;		}				if (moved) {			draw_listing(cur);			moved = 0;		}				/* Once in a while rescan maple to allow VMU switchout		   and memory bank swapping */		cnt++;		if (!(cnt % 25)) {			int scanned = 0;			maple_rescan_bus(1);			while (!maple_vmu_addr()) {				maple_rescan_bus(1);				timer_sleep(100);				scanned = 1;			}			if (scanned) {				mvmu = maple_vmu_addr();				if (vmu_scan_card(mvmu) < 0) {					printf("Error scanning card\r\n");					return -1;				}				draw_listing(0);				cur = 0;			}		}				timer_sleep(10);	}		return -1;}void call_prog() {	uint32 *mem = (uint32*)0x8c010000;	/* void (*m)() = (void (*)())(mem[0x38/4]); */	void (*m)() = (void (*)())mem;		m();}/* wow: cheap! =) */void disclaim() {	int y = 20;	bfont_draw_str(vram_s+640*(y+=24)+20, 640, "Despite the preceeding disclaimer,");	bfont_draw_str(vram_s+640*(y+=24)+20, 640, "this program is not produced by");	bfont_draw_str(vram_s+640*(y+=24)+20, 640, "or under license from Sega Enterprises, Ltd.,");	bfont_draw_str(vram_s+640*(y+=24)+20, 640, "but by a group of hobbyist developers.");	y+=24;	bfont_draw_str(vram_s+640*(y+=24)+20, 640, "\"Sega\" and \"Dreamcast\" are registered");	bfont_draw_str(vram_s+640*(y+=24)+20, 640, "trademarks of Sega Enterprises, Ltd.");	timer_sleep(8000);}int dc_main() {	/* Do initial setup */		serial_disable();	dc_setup(DM_640x480, PM_RGB565);	disclaim();	/* VMU File menu */	while (1) {		int cur;				if ( (cur=vmu_menu()) < 0)		//	return 0;			continue;		/* Load from VMU */		bfont_draw_str(vram_s+640*376+20, 640, "Loading program");		if (vmu_load_file(mvmu, cur, (uint8*)(0x8c010000)) < 0) {			bfont_draw_str(vram_s+640*400+20, 640, "Can't load file");			return 0;		}		/* Call program */		bfont_draw_str(vram_s+640*400+20, 640, "Executing program");		call_prog();	}	return 0;}

⌨️ 快捷键说明

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