Example #1
0
LINK_ERR forceload_app(TilemCalc* calc, TIFILE_t *tifile) {
	u_char (*dest)[PAGE_SIZE_W] = (u_char (*)[PAGE_SIZE_W]) calc->mem;
	if (dest == NULL)
		return LERR_MODEL;

	if (tifile->flash == NULL)
		return LERR_FILE;

	int upper_flash_index = -1;

	int i;

	upages_t upages;
	state_userpages(calc, &upages);
	if (upages.start == -1)
		return LERR_MODEL;

	for (i = 0; i < calc->hw.nhwregs; i++) {
		if (!strcmp("port23", calc->hw.hwregnames[i])) {
			upper_flash_index = i;
			break;
		}
	}

	if (upper_flash_index < 0)
	{
		return LERR_MODEL;
	}

	u_int page;
	for (page = upages.start;
			page >= upages.end + tifile->flash->pages
					&& dest[page][0x00] == 0x80 && dest[page][0x01] == 0x0F;) {
		int page_size;
		//different size app need to send the long way
		if (!memcmp(&dest[page][0x12], &tifile->flash->data[0][0x12], 8)) {
			if (get_page_size(dest, page) != tifile->flash->pages) {
				//or we can force load it still ;D
				//there's probably some good reason Jim didn't write this code :|
				int pageDiff = tifile->flash->pages - get_page_size(dest, page);
				u_int currentPage = page - tifile->flash->pages;
				u_int end_page =
						pageDiff > 0 ? currentPage : currentPage + pageDiff;
				while (!check_flashpage_empty(dest, end_page, 1)
						&& end_page >= upages.end)
					end_page -= get_page_size(dest, end_page);
				if (end_page != currentPage) {
					if (pageDiff > 0) {
						if (end_page - pageDiff < upages.end)
							return LERR_MEM;
						memmove(dest[currentPage - pageDiff], dest[currentPage],
								PAGE_SIZE_W * (end_page - currentPage));
						/*	if (cpu->pio.model == TI_83P) {
						 //mark pages unprotected
						 for (i = end_page - 7; i <= end_page + pageDiff - 8; i++) {
						 cpu->mem_c->protected_page[i / 8] &= ~(1 << (i % 8));
						 }
						 }*/
					} else {
						//0xFF all extra pages
						for (i = tifile->flash->pages;
								i < tifile->flash->pages - pageDiff;
								i++, currentPage--) {
							memset(dest[currentPage], 0xFF, PAGE_SIZE_W);
						}
						/*
						 if (cpu->pio.model == TI_83P) {
						 //mark pages as protected
						 for (i = end_page - 7; i <= end_page - pageDiff - 8; i++) {
						 cpu->mem_c->protected_page[i / 8] |= 1 << (i % 8);
						 }
						 }*/
					}
				}
				//fix page execution permissions

				if (upper_flash_index >= 0)
					calc->hwregs[upper_flash_index] -= pageDiff;
				//cpu->mem_c->flash_upper -= pageDiff;
			}
			u_int i;
			for (i = 0; i < tifile->flash->pages; i++, page--) {
				memcpy(dest[page], tifile->flash->data[i], PAGE_SIZE_W);
			}
			//note that this does not fix the old marks, only ensures that
			//the new order of apps has the correct parts marked
			applist_t applist;
			state_build_applist(calc, &applist);
			for (i = 0; i < applist.count; i++) {
				fix_certificate(calc, applist.apps[i].page);
			}

			printf("Found already\n");
			return LERR_SUCCESS;
		}
		page_size = get_page_size(dest, page);
		page -= page_size;
	}

	if (page - tifile->flash->pages < upages.end)
		return LERR_MEM;

	//mark the app as non trial
	fix_certificate(calc, page);
	//force reset the app list says BrandonW. seems to work, apps show up (sometimes)
	//mem_write(calc->mem, 0x9C87, 0x00);
	(*calc->hw.z80_wrmem)(calc, 0x9C87, 0x00);

	//u_char *space = &dest[page][PAGE_SIZE - 1];
	// Make sure the subsequent pages are empty
	if (!check_flashpage_empty(dest, page, tifile->flash->pages))
		return LERR_MEM;
	for (i = 0; i < tifile->flash->pages; i++, page--) {
		memcpy(dest[page], tifile->flash->data[i], PAGE_SIZE_W);
	}

	if (upper_flash_index >= 0)
		calc->hwregs[upper_flash_index] -= tifile->flash->pages;

	/*
	 for (i = page - 7; i <= page + tifile->flash->pages - 8; i++) {
	 //-8 is for the start of user mem
	 cpu->mem_c->protected_page[i / 8] &= ~(1 << (i % 8));
	 }*/

	return LERR_SUCCESS;
}
static LINK_ERR SendFile(const LPCALC lpCalc, LPCTSTR lpszFileName, SEND_FLAG Destination)
{
	TIFILE_t *var = importvar(lpszFileName, FALSE);

	BOOL exec_vio_backup = break_on_exe_violation;
	break_on_exe_violation = false;
	LINK_ERR result;
	if (var != NULL) {
		switch(var->type)
		{
		case GROUP_TYPE:
		case VAR_TYPE:
		case FLASH_TYPE:
			{
				if (lpCalc->cpu.pio.link == NULL) {
					result = LERR_MODEL;
					//81 for now
					break;
				}

				lpCalc->cpu.pio.link->vlink_size = var->length;
				lpCalc->cpu.pio.link->vlink_send = 0;
				BOOL running_backup = lpCalc->running;
				// if we just started running, calc_turn_on may be running
				while (lpCalc->fake_running) { }
				lpCalc->fake_running = TRUE;

				result = link_send_var(&lpCalc->cpu, var, (SEND_FLAG) Destination);
				if (var->type == FLASH_TYPE)
				{
					if (var->flash->type == FLASH_TYPE_OS) {
						calc_reset(lpCalc);
						//calc_turn_on(lpCalc);
					} else {
						// Rebuild the app list
						applist_t applist;
						state_build_applist(&lpCalc->cpu, &applist);

						u_int i;
						for (i = 0; i < applist.count; i++) {
							if (_tcsncmp((TCHAR *) var->flash->name, applist.apps[i].name, 8) == 0) {
								lpCalc->last_transferred_app = applist.apps[i];
								break;
							}
						}
					}
				}

				lpCalc->fake_running = FALSE;
				lpCalc->running = running_backup;
				break;
			}
		case BACKUP_TYPE:
			lpCalc->cpu.pio.link->vlink_size = var->length;
			lpCalc->cpu.pio.link->vlink_send = 0;
			result = link_send_backup(&lpCalc->cpu, var);
			break;
		case ZIP_TYPE: {
			WIN32_FIND_DATA FindFileData;
			HANDLE hFind;
			TCHAR path[MAX_PATH];
			TCHAR search[MAX_PATH];
			GetStorageString(path, sizeof(path));
			StringCbCat(path, sizeof(path), _T("Zip\\"));
			StringCbCopy(search, sizeof(search), path);
			StringCbCat(search, sizeof(search), _T("*"));
			hFind = FindFirstFile(search, &FindFileData);
			if (hFind == INVALID_HANDLE_VALUE) {
				result = LERR_FILE;
				break;
			} else if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
				TCHAR filename[MAX_PATH];
				StringCbCopy(filename, sizeof(filename), path);
				StringCbCat(filename, sizeof(filename), FindFileData.cFileName);
				SendFileToCalc(NULL, lpCalc, filename, FALSE, Destination);
				SendFileToCalc(NULL, lpCalc, filename, FALSE, Destination);
			}
			while (FindNextFile(hFind, &FindFileData)) {
				if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
					TCHAR filename[MAX_PATH];
					StringCbCopy(filename, sizeof(filename), path);
					StringCbCat(filename, sizeof(filename), FindFileData.cFileName);
					SendFileToCalc(NULL, lpCalc, filename, FALSE, Destination);
					DeleteFile(filename);
				}
			}
			FindClose(hFind);
			DeleteFile(path);
			result = LERR_SUCCESS;
			break;
		}
		case ROM_TYPE:
		case SAV_TYPE: {
			if (rom_load(lpCalc, lpszFileName) == TRUE) {
				result = LERR_SUCCESS;
			} else {
				result = LERR_LINK;
			}

			FreeTiFile(var);
			var = NULL;
			break;
		}
		case LABEL_TYPE: {
			VoidLabels(lpCalc);
			labels_app_load(lpCalc, lpszFileName);
			result = LERR_SUCCESS;
			break;
		}
		case BREAKPOINT_TYPE:
			break;
		}
		if (var) {
			FreeTiFile(var);
		}
		break_on_exe_violation = exec_vio_backup;
		return result;
	}
	else
	{
		break_on_exe_violation = exec_vio_backup;
		return LERR_FILE;
	}
}