int pce_f (st_ucon64_nfo_t *rominfo) /* Region protection codes are found in (American) TurboGrafx-16 games. It prevents those games from running on a PC-Engine. One search pattern seems sufficient to fix/crack all TG-16 games. In addition to that, the protection code appears to be always somewhere in the first 32 kB. */ { char src_name[FILENAME_MAX], dest_name[FILENAME_MAX], buffer[32 * 1024]; int bytesread, n; puts ("Attempting to fix region protection code..."); strcpy (src_name, ucon64.fname); strcpy (dest_name, ucon64.fname); ucon64_file_handler (dest_name, src_name, 0); fcopy (src_name, 0, ucon64.file_size, dest_name, "wb"); // no copy if one file if ((bytesread = ucon64_fread (buffer, rominfo->backup_header_len, 32 * 1024, src_name)) <= 0) return -1; // '!' == ASCII 33 (\x21), '*' == 42 (\x2a) if (rominfo->interleaved) n = change_mem (buffer, bytesread, "\x94\x02\x0f", 3, '*', '!', "\x01", 1, 0); else n = change_mem (buffer, bytesread, "\x29\x40\xf0", 3, '*', '!', "\x80", 1, 0); ucon64_fwrite (buffer, rominfo->backup_header_len, 32 * 1024, dest_name, "r+b"); printf ("Found %d pattern%s\n", n, n != 1 ? "s" : ""); printf (ucon64_msg[WROTE], dest_name); remove_temp_file (); return n; }
page_table() { #if (EDITFLAG*TEMFLAG) register int i,j; register long n,ctrlptr; register long *longptr; register EBDTLINK *ptabptr; long currpageptr,maxntable,dummlong; int type,nvals,ebdtindex,ebdt_i; CTRLHEADER ctrlheader; VAL_INFO *val[MAXNVALS]; /* build page address offset table */ if (!change_mem(addrmem,4L*curr_nctrl)) return 1; longptr= (long*)(heap[addrmem].start); ctrlptr= heap[curr_mem].start; for (i=0; i<curr_nctrl; i++,longptr++) { *longptr = i ? longptr[-1]+j : 0L ; j= ((CTRLHEADER*)(ctrlptr))->length; ctrlptr += j; } /* build linked list of ebdt/valinfo -- */ /* -- allocate largest possible table */ fill_mem(ptabmem); ptabptr= (EBDTLINK*)(heap[ptabmem].start); maxntable= heap[ptabmem].nbytes / sizeof(*ptabptr) ; /* -- first part of table is for the ebdt itself */ n= n_of_ebdt(&dummlong); if (n>maxntable) n= maxntable= 0; /* loops skipped, returns error */ for (i=0; i<n; i++) { ptabptr[i].next= i; ptabptr[i].ctrl_i= -1; /* means ebdt */ } /* -- rest of table is for ctrl valinfo's */ longptr= (long*)(heap[addrmem].start); currpageptr= heap[curr_mem].start; for (i=0; (i<curr_nctrl)&&(n<maxntable); i++) { ctrlptr= currpageptr + longptr[i] ; type= ((CTRLHEADER*)(ctrlptr))->type; if (type>=0) /* visible */ { nvals= find_vals(type,ctrlptr+sizeof(ctrlheader),val); for (j=0; (j<nvals)&&(n<maxntable); j++) { find_e_m(i,val[j],&ebdt_i,&dummy); if (ebdt_i>=0) { ctrlptr= currpageptr + longptr[ebdt_i]; ebdtindex= ( (CTRL_EBDT*)(ctrlptr+sizeof(ctrlheader)) )->index; ptabptr[n].ctrl_i= i; ptabptr[n].val_i= j; ptabptr[n].next= ptabptr[ebdtindex].next; ptabptr[ebdtindex].next= n; n++; } } } } if (n==maxntable) { form_alert(1,BADMEM2); n=0; } change_mem(ptabmem,n*sizeof(*ptabptr)); return (n==maxntable)||(!maxntable); #endif } /* end page_table() */