int cdc_context_save(uint8 *state) { uint8 tmp8; int bufferptr = 0; if (cdc.dma_w == pcm_ram_dma_w) { tmp8 = 1; } else if (cdc.dma_w == prg_ram_dma_w) { tmp8 = 2; } else if (cdc.dma_w == word_ram_0_dma_w) { tmp8 = 3; } else if (cdc.dma_w == word_ram_1_dma_w) { tmp8 = 4; } else if (cdc.dma_w == word_ram_2M_dma_w) { tmp8 = 5; } else { tmp8 = 0; } save_param(&cdc, sizeof(cdc)); save_param(&tmp8, 1); return bufferptr; }
int sound_context_save(uint8 *state) { int bufferptr = 0; if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { bufferptr = YM2612SaveContext(state); } else { save_param(YM2413GetContextPtr(),YM2413GetContextSize()); } save_param(SN76489_GetContextPtr(),SN76489_GetContextSize()); save_param(&fm_cycles_start,sizeof(fm_cycles_start)); return bufferptr; }
int psg_context_save(uint8 *state) { int bufferptr = 0; save_param(&psg.clocks,sizeof(psg.clocks)); save_param(&psg.latch,sizeof(psg.latch)); save_param(&psg.noiseShiftValue,sizeof(psg.noiseShiftValue)); save_param(psg.regs,sizeof(psg.regs)); save_param(psg.freqInc,sizeof(psg.freqInc)); save_param(psg.freqCounter,sizeof(psg.freqCounter)); save_param(psg.polarity,sizeof(psg.polarity)); save_param(psg.chanOut,sizeof(psg.chanOut)); return bufferptr; }
int cdd_context_save(uint8 *state) { int bufferptr = 0; save_param(&cdd.cycles, sizeof(cdd.cycles)); save_param(&cdd.latency, sizeof(cdd.latency)); save_param(&cdd.index, sizeof(cdd.index)); save_param(&cdd.lba, sizeof(cdd.lba)); save_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); save_param(&cdd.volume, sizeof(cdd.volume)); save_param(&cdd.status, sizeof(cdd.status)); return bufferptr; }
int pcm_context_save(uint8 *state) { uint8 tmp8; int bufferptr = 0; tmp8 = (pcm.bank - pcm.ram) >> 12; save_param(pcm.chan, sizeof(pcm.chan)); save_param(pcm.out, sizeof(pcm.out)); save_param(&tmp8, 1); save_param(&pcm.enabled, sizeof(pcm.enabled)); save_param(&pcm.status, sizeof(pcm.status)); save_param(&pcm.index, sizeof(pcm.index)); save_param(pcm.ram, sizeof(pcm.ram)); return bufferptr; }
static void mouseEvent(int button, int state, int x, int y) { unsigned char *p, *p1; int ssx, ssy, eex, eey; int i, j, k; if( button == GLUT_RIGHT_BUTTON && state == GLUT_UP ) { if( status == 0 ) { arVideoCapStop(); arVideoClose(); if( patt.loop_num > 0 ) { calc_distortion( &patt, xsize, ysize, dist_factor ); printf("--------------\n"); printf("Center X: %f\n", dist_factor[0]); printf(" Y: %f\n", dist_factor[1]); printf("Dist Factor: %f\n", dist_factor[2]); printf("Size Adjust: %f\n", dist_factor[3]); printf("--------------\n"); status = 2; check_num = 0; print_comment(5); } else { glutDestroyWindow( win ); exit(0); } } else if( status == 1 ) { if( patt.loop_num == 0 ) {printf("error!!\n"); exit(0);} patt.loop_num--; free( patt.point[patt.loop_num] ); free( patt.savedImage[patt.loop_num] ); status = 0; point_num = 0; arVideoCapStart(); if( patt.loop_num == 0 ) print_comment(0); else print_comment(4); } } if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) { if( status == 1 && point_num < patt.h_num*patt.v_num ) { sx = ex = x; sy = ey = y; p = &(patt.savedImage[patt.loop_num-1][(y*xsize+x)*AR_PIX_SIZE]); p1 = &(clipImage[0]); #ifdef AR_PIX_FORMAT_BGRA k = (255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3; if( k < thresh ) k = 0; else k = 255; *(p1+0) = *(p1+1) = *(p1+2) = k; #endif #ifdef AR_PIX_FORMAT_ABGR k = (255*3 - (*(p+1) + *(p+2) + *(p+3))) / 3; if( k < thresh ) k = 0; else k = 255; *(p1+1) = *(p1+2) = *(p1+3) = k; #endif #ifdef AR_PIX_FORMAT_BGR k = (255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3; if( k < thresh ) k = 0; else k = 255; *(p1+0) = *(p1+1) = *(p1+2) = k; #endif #ifdef AR_PIX_FORMAT_RGBA k = (255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3; if( k < thresh ) k = 0; else k = 255; *(p1+0) = *(p1+1) = *(p1+2) = k; #endif #ifdef AR_PIX_FORMAT_RGB k = (255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3; if( k < thresh ) k = 0; else k = 255; *(p1+0) = *(p1+1) = *(p1+2) = k; #endif } } if( button == GLUT_LEFT_BUTTON && state == GLUT_UP ) { if( status == 0 && patt.loop_num < LOOP_MAX ) { while( (p = (unsigned char *)arVideoGetImage()) == NULL ) { arUtilSleep(2); } #ifdef USE_TEXMAP patt.savedImage[patt.loop_num] = (unsigned char *)malloc( xsize*tex1Ysize*AR_PIX_SIZE ); #else patt.savedImage[patt.loop_num] = (unsigned char *)malloc( xsize*ysize*AR_PIX_SIZE ); #endif if( patt.savedImage[patt.loop_num] == NULL ) exit(0); p1 = patt.savedImage[patt.loop_num]; for(i=0;i<xsize*ysize*AR_PIX_SIZE;i++) *(p1++) = *(p++); arVideoCapStop(); patt.point[patt.loop_num] = (CALIB_COORD_T *)malloc( sizeof(CALIB_COORD_T)*patt.h_num*patt.v_num ); if( patt.point[patt.loop_num] == NULL ) exit(0); patt.loop_num++; status = 1; sx = sy = ex= ey = -1; print_comment(1); } else if( status == 1 && point_num == patt.h_num*patt.v_num ) { status = 0; point_num = 0; arVideoCapStart(); printf("### No.%d ###\n", patt.loop_num); for( j = 0; j < patt.v_num; j++ ) { for( i = 0; i < patt.h_num; i++ ) { printf("%2d, %2d: %6.2f, %6.2f\n", i+1, j+1, patt.point[patt.loop_num-1][j*patt.h_num+i].x_coord, patt.point[patt.loop_num-1][j*patt.h_num+i].y_coord); } } printf("\n\n"); if( patt.loop_num < LOOP_MAX ) print_comment(4); else print_comment(6); } else if( status == 1 ) { if( sx < ex ) { ssx = sx; eex = ex; } else { ssx = ex; eex = sx; } if( sy < ey ) { ssy = sy; eey = ey; } else { ssy = ey; eey = sy; } patt.point[patt.loop_num-1][point_num].x_coord = 0.0; patt.point[patt.loop_num-1][point_num].y_coord = 0.0; p = clipImage; k = 0; for( j = 0; j < (eey-ssy+1); j++ ) { for( i = 0; i < (eex-ssx+1); i++ ) { patt.point[patt.loop_num-1][point_num].x_coord += i * *(p+1); patt.point[patt.loop_num-1][point_num].y_coord += j * *(p+1); k += *(p+1); p += AR_PIX_SIZE; } } if( k != 0 ) { patt.point[patt.loop_num-1][point_num].x_coord /= k; patt.point[patt.loop_num-1][point_num].y_coord /= k; patt.point[patt.loop_num-1][point_num].x_coord += ssx; patt.point[patt.loop_num-1][point_num].y_coord += ssy; point_num++; } sx = sy = ex= ey = -1; printf(" # %d/%d\n", point_num, patt.h_num*patt.v_num); if( point_num == patt.h_num*patt.v_num ) print_comment(2); } else if( status == 2 ) { check_num++; if( check_num == patt.loop_num ) { if(patt.loop_num >= 2) { if( calc_inp(&patt, dist_factor, xsize, ysize, mat) < 0 ) { printf("Calibration failed.\n"); exit(0); } save_param(); } glutDestroyWindow( win ); exit(0); } if( check_num+1 == patt.loop_num ) { printf("\nLeft Mouse Button: Next Step.\n"); } else { printf(" %d/%d.\n", check_num+1, patt.loop_num); } } } }
static void mouseEvent(int button, int state, int x, int y) { AR2VideoBufferT *buff; unsigned char *p, *p1; int ssx, ssy, eex, eey; int i, j, k; char line[256]; if( x < 0 ) x = 0; if( x >= xsize ) x = xsize-1; if( y < 0 ) y = 0; if( y >= ysize ) y = ysize-1; x *= SCALE; y *= SCALE; if( button == GLUT_RIGHT_BUTTON && state == GLUT_UP ) { if( status == 0 ) { arVideoCapStop(); arVideoClose(); if( patt.loop_num > 0 ) { calc_distortion( &patt, xsize, ysize, aspect_ratio, dist_factor, dist_function_version ); ARLOG("--------------\n"); if (dist_function_version == 3) { ARLOG("Center X: %f\n", dist_factor[0]); ARLOG(" Y: %f\n", dist_factor[1]); ARLOG("Size Adjust: %f\n", dist_factor[2]); ARLOG("Aspect Ratio: %f\n", dist_factor[3]); ARLOG("Dist Factor1: %f\n", dist_factor[4]); ARLOG("Dist Factor2: %f\n", dist_factor[5]); } else if (dist_function_version == 2) { ARLOG("Center X: %f\n", dist_factor[0]); ARLOG(" Y: %f\n", dist_factor[1]); ARLOG("Size Adjust: %f\n", dist_factor[2]); ARLOG("Dist Factor1: %f\n", dist_factor[3]); ARLOG("Dist Factor2: %f\n", dist_factor[4]); } else if (dist_function_version == 1) { ARLOG("Center X: %f\n", dist_factor[0]); ARLOG(" Y: %f\n", dist_factor[1]); ARLOG("Size Adjust: %f\n", dist_factor[2]); ARLOG("Dist Factor: %f\n", dist_factor[3]); } ARLOG("--------------\n"); status = 2; check_num = 0; print_comment(5); } else { exit(0); } } else if( status == 1 ) { if( patt.loop_num == 0 ) {ARLOGe("error!!\n"); exit(0);} patt.loop_num--; free( patt.point[patt.loop_num] ); free( patt.savedImage[patt.loop_num] ); status = 0; point_num = 0; arVideoCapStart(); if( patt.loop_num == 0 ) print_comment(0); else print_comment(4); } } if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) { if( status == 1 && point_num < patt.h_num*patt.v_num ) { sx = ex = x; sy = ey = y; p = &(patt.savedImage[patt.loop_num-1][(y*xsize+x)*pixelSize]); p1 = &(clipImage[0]); if (pixelFormat == AR_PIXEL_FORMAT_BGRA || pixelFormat == AR_PIXEL_FORMAT_RGBA) { k = (255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3; if( k < thresh ) k = 0; else k = 255; *(p1+0) = *(p1+1) = *(p1+2) = k; } else if (pixelFormat == AR_PIXEL_FORMAT_ARGB || pixelFormat == AR_PIXEL_FORMAT_ABGR) { k = (255*3 - (*(p+1) + *(p+2) + *(p+3))) / 3; if( k < thresh ) k = 0; else k = 255; *(p1+1) = *(p1+2) = *(p1+3) = k; } else if (pixelFormat == AR_PIXEL_FORMAT_BGR || pixelFormat == AR_PIXEL_FORMAT_RGB) { k = (255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3; if( k < thresh ) k = 0; else k = 255; *(p1+0) = *(p1+1) = *(p1+2) = k; } else if (pixelFormat == AR_PIXEL_FORMAT_MONO || pixelFormat == AR_PIXEL_FORMAT_420v || pixelFormat == AR_PIXEL_FORMAT_420f) { k = 255 - *p; if( k < thresh ) k = 0; else k = 255; *p1 = k; } else if (pixelFormat == AR_PIXEL_FORMAT_2vuy) { k = 255 - *(p+1); if( k < thresh ) k = 0; else k = 255; *(p1+1) = k; } else if (pixelFormat == AR_PIXEL_FORMAT_yuvs) { k = 255 - *p; if( k < thresh ) k = 0; else k = 255; *p1 = k; } } } if( button == GLUT_LEFT_BUTTON && state == GLUT_UP ) { if( status == 0 && patt.loop_num < LOOP_MAX ) { while (!(buff = arVideoGetImage()) || !buff->fillFlag) arUtilSleep(2); p = buff->buff; patt.savedImage[patt.loop_num] = (unsigned char *)malloc( xsize*ysize*pixelSize ); if( patt.savedImage[patt.loop_num] == NULL ) exit(0); p1 = patt.savedImage[patt.loop_num]; for(i=0;i<xsize*ysize*pixelSize;i++) *(p1++) = *(p++); arVideoCapStop(); patt.point[patt.loop_num] = (CALIB_COORD_T *)malloc( sizeof(CALIB_COORD_T)*patt.h_num*patt.v_num ); if( patt.point[patt.loop_num] == NULL ) exit(0); patt.loop_num++; status = 1; sx = sy = ex= ey = -1; print_comment(1); } else if( status == 1 && point_num == patt.h_num*patt.v_num ) { status = 0; point_num = 0; arVideoCapStart(); ARLOG("### No.%d ###\n", patt.loop_num); for( j = 0; j < patt.v_num; j++ ) { for( i = 0; i < patt.h_num; i++ ) { ARLOG("%2d, %2d: %6.2f, %6.2f\n", i+1, j+1, patt.point[patt.loop_num-1][j*patt.h_num+i].x_coord, patt.point[patt.loop_num-1][j*patt.h_num+i].y_coord); } } ARLOG("\n\n"); if( patt.loop_num < LOOP_MAX ) print_comment(4); else print_comment(6); } else if( status == 1 ) { if( sx < ex ) { ssx = sx; eex = ex; } else { ssx = ex; eex = sx; } if( sy < ey ) { ssy = sy; eey = ey; } else { ssy = ey; eey = sy; } patt.point[patt.loop_num-1][point_num].x_coord = 0.0; patt.point[patt.loop_num-1][point_num].y_coord = 0.0; p = clipImage; k = 0; for( j = 0; j < (eey-ssy+1); j++ ) { for( i = 0; i < (eex-ssx+1); i++ ) { if( pixelSize == 1 ) { patt.point[patt.loop_num-1][point_num].x_coord += i * *p; patt.point[patt.loop_num-1][point_num].y_coord += j * *p; k += *p; } else { patt.point[patt.loop_num-1][point_num].x_coord += i * *(p+1); patt.point[patt.loop_num-1][point_num].y_coord += j * *(p+1); k += *(p+1); } p += pixelSize; } } if( k != 0 ) { patt.point[patt.loop_num-1][point_num].x_coord /= k; patt.point[patt.loop_num-1][point_num].y_coord /= k; patt.point[patt.loop_num-1][point_num].x_coord += ssx; patt.point[patt.loop_num-1][point_num].y_coord += ssy; point_num++; } sx = sy = ex= ey = -1; ARLOG(" # %d/%d\n", point_num, patt.h_num*patt.v_num); if( point_num == patt.h_num*patt.v_num ) print_comment(2); } else if( status == 2 ) { check_num++; if( check_num == patt.loop_num ) { if(patt.loop_num >= 2) { if( calc_inp(&patt, dist_factor, xsize, ysize, mat, dist_function_version) < 0 ) { ARLOGe("Calibration failed.\n"); exit(0); } save_param(); if (dist_function_version == 3) { printf("Do you want to repeat again?"); scanf("%s", line); if( line[0] == 'y' ) { aspect_ratio *= mat[0][0] / mat[1][1]; ARLOG("New aspect ratio = %f\n", aspect_ratio); calc_distortion( &patt, xsize, ysize, aspect_ratio, dist_factor, dist_function_version ); ARLOG("--------------\n"); ARLOG("Center X: %f\n", dist_factor[0]); ARLOG(" Y: %f\n", dist_factor[1]); ARLOG("Size Adjust: %f\n", dist_factor[2]); ARLOG("Aspect Ratio: %f\n", dist_factor[3]); ARLOG("Dist Factor1: %f\n", dist_factor[4]); ARLOG("Dist Factor2: %f\n", dist_factor[5]); ARLOG("--------------\n"); status = 2; check_num = 0; print_comment(5); return; } } } exit(0); } if( check_num+1 == patt.loop_num ) { ARLOG("\nLeft Mouse Button: Next Step.\n"); } else { ARLOG(" %d/%d.\n", check_num+1, patt.loop_num); } } } return; }
int state_save(unsigned char *buffer) { /* buffer size */ int bufferptr = 0; /* version string */ char version[16]; strncpy(version,STATE_VERSION,16); save_param(version, 16); // GENESIS save_param(work_ram, sizeof(work_ram)); save_param(zram, sizeof(zram)); save_param(&zbusreq, sizeof(zbusreq)); save_param(&zreset, sizeof(zreset)); save_param(&zbank, sizeof(zbank)); // IO save_param(io_reg, sizeof(io_reg)); // VDP save_param(sat, sizeof(sat)); save_param(vram, sizeof(vram)); save_param(cram, sizeof(cram)); save_param(vsram, sizeof(vsram)); save_param(reg, sizeof(reg)); save_param(&addr, sizeof(addr)); save_param(&addr_latch, sizeof(addr_latch)); save_param(&code, sizeof(code)); save_param(&pending, sizeof(pending)); save_param(&status, sizeof(status)); save_param(&dmafill, sizeof(dmafill)); save_param(&hint_pending, sizeof(hint_pending)); save_param(&vint_pending, sizeof(vint_pending)); save_param(&irq_status, sizeof(irq_status)); // FM save_param(YM2612GetContextPtr(),YM2612GetContextSize()); // PSG save_param(SN76489_GetContextPtr(),SN76489_GetContextSize()); // 68000 uint16 tmp16; uint32 tmp32; tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D5); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D6); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D7); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A0); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A1); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A2); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A3); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A4); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A5); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A6); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4); tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2); tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4); // Z80 save_param(&Z80, sizeof(Z80_Regs)); /* compress state file */ unsigned long inbytes = bufferptr; unsigned long outbytes = STATE_SIZE; compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9); memcpy(buffer, &outbytes, 4); /* return total size */ return (outbytes + 4); }
int state_save(unsigned char *buffer) { /* buffer size */ int bufferptr = 0; /* first allocate state buffer */ unsigned char *state = (unsigned char *)malloc(STATE_SIZE); if (!state) return 0; /* version string */ char version[16]; strncpy(version,STATE_VERSION,16); save_param(version, 16); // GENESIS if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { save_param(work_ram, sizeof(work_ram)); save_param(zram, sizeof(zram)); save_param(&zstate, sizeof(zstate)); save_param(&zbank, sizeof(zbank)); } else { save_param(work_ram, 0x2000); } save_param(&mcycles_68k, sizeof(mcycles_68k)); save_param(&mcycles_z80, sizeof(mcycles_z80)); // IO if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { save_param(io_reg, sizeof(io_reg)); } else { save_param(&io_reg[0x0F], 1); } // VDP bufferptr += vdp_context_save(&state[bufferptr]); // SOUND bufferptr += sound_context_save(&state[bufferptr]); // 68000 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { uint16 tmp16; uint32 tmp32; tmp32 = m68k_get_reg(M68K_REG_D0); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_D1); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_D2); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_D3); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_D4); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_D5); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_D6); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_D7); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_A0); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_A1); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_A2); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_A3); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_A4); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_A5); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_A6); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_A7); save_param(&tmp32, 4); tmp32 = m68k_get_reg(M68K_REG_PC); save_param(&tmp32, 4); tmp16 = m68k_get_reg(M68K_REG_SR); save_param(&tmp16, 2); tmp32 = m68k_get_reg(M68K_REG_USP); save_param(&tmp32, 4); } // Z80 save_param(&Z80, sizeof(Z80_Regs)); // Cartridge HW if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { bufferptr += md_cart_context_save(&state[bufferptr]); } else { bufferptr += sms_cart_context_save(&state[bufferptr]); } /* compress state file */ unsigned long inbytes = bufferptr; unsigned long outbytes = STATE_SIZE; compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9); memcpy(buffer, &outbytes, 4); free(state); /* return total size */ return (outbytes + 4); }
chd_error mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int current_cylinder, int current_head) { if (TRACE_RWTRACK) osd_printf_verbose("%s: write back (c=%d,h=%d) to CHD\n", tag(), current_cylinder, current_head); uint8_t buffer[16384]; // for header or sector content int bytepos = 0; int state = SEARCH_A1; int count = 0; int pos = 0; uint16_t crc = 0; uint8_t byte; bool search_header = true; int ident = 0; int cylinder = 0; int head = 0; int sector = 0; int size = 0; int headerpos = 0; int interleave = 0; int interleave_prec = -1; bool check_interleave = true; bool check_skew = true; int gap1 = 0; int ecctype = 0; // if (current_cylinder==0 && current_head==0) showtrack(trackimage, tracksize); // If we want to detect gaps, we only do it on cylinder 0, head 0 // This makes it safer to detect the header length // (There is indeed some chance that we falsely assume a header length of 4 // because the two bytes behind happen to be a valid CRC value) if (save_param(MFMHD_GAP1) && current_cylinder==0 && current_head==0) { m_param.gap1 = 0; m_param.gap2 = 0; m_param.gap3 = 0; m_param.sync = 0; // 4-byte headers are used for the IBM-AT format // 5-byte headers are used in other formats m_param.headerlen = 4; m_param.ecctype = 0; } // AT format implies 512 bytes per sector int sector_length = 512; // Only check once bool countgap1 = (m_param.gap1==0); bool countgap2 = false; bool countgap3 = false; bool countsync = false; chd_error chdstate = CHDERR_NONE; if (TRACE_IMAGE) { for (int i=0; i < tracksize; i++) { if ((i % 16)==0) osd_printf_verbose("\n%04x: ", i); osd_printf_verbose("%02x ", (m_param.encoding==MFM_BITS || m_param.encoding==MFM_BYTE)? mfm_decode(trackimage[i]) : (trackimage[i]&0xff)); } osd_printf_verbose("\n"); } // We have to go through the bytes of the track and save a sector as soon as one shows up while (bytepos < tracksize) { // Decode the next 16 bits if (m_param.encoding==MFM_BITS || m_param.encoding==MFM_BYTE) { byte = mfm_decode(trackimage[bytepos]); } else byte = (trackimage[bytepos] & 0xff); switch (state) { case SEARCH_A1: // Counting gaps and sync if (countgap2) { if (byte == 0x4e) m_param.gap2++; else if (byte == 0) { countsync = true; countgap2 = false; } } if (countsync) { if (byte == 0) m_param.sync++; else countsync = false; } if (countgap3) { if (byte != 0x00 || m_param.gap3 < 4) m_param.gap3++; else countgap3 = false; } if (((m_param.encoding==MFM_BITS || m_param.encoding==MFM_BYTE) && trackimage[bytepos]==0x4489) || (m_param.encoding==SEPARATED && trackimage[bytepos]==0x0aa1) || (m_param.encoding==SEPARATED_SIMPLE && trackimage[bytepos]==0xffa1)) { state = FOUND_A1; count = (search_header? m_param.headerlen : (sector_length+1)) + 2; crc = 0x443b; // init value with a1 pos = 0; } bytepos++; break; case FOUND_A1: crc = ccitt_crc16_one(crc, byte); // osd_printf_verbose("%s: MFM HD: Byte = %02x, CRC=%04x\n", tag(), byte, crc); // Put byte into buffer // but not the data mark and the CRC if (search_header || (count > 2 && count < sector_length+3)) buffer[pos++] = byte; // Stop counting gap1 if (search_header && countgap1) { gap1 = bytepos-1; countgap1 = false; } if (--count == 0) { if (crc==0) { if (search_header) { // Found a header ident = buffer[0]; cylinder = buffer[1]; // For non-PC-AT formats, highest three bits are in the head field if (m_param.headerlen == 5) cylinder |= ((buffer[2]&0x70)<<4); else { osd_printf_verbose("%s: Unexpected header size: %d, cylinder=%d, position=%04x\n", tag(), m_param.headerlen, cylinder, bytepos); showtrack(trackimage, tracksize); } head = buffer[2] & 0x0f; sector = buffer[3]; int identexp = cylinder_to_ident(cylinder); if (identexp != ident) { osd_printf_verbose("%s: Field error; ident = %02x (expected %02x) for sector chs=(%d,%d,%d)\n", tag(), ident, identexp, cylinder, head, sector); } if (cylinder != current_cylinder) { osd_printf_verbose("%s: Sector header of sector %d defines cylinder = %02x (should be %02x)\n", tag(), sector, cylinder, current_cylinder); } if (head != current_head) { osd_printf_verbose("%s: Sector header of sector %d defines head = %02x (should be %02x)\n", tag(), sector, head, current_head); } // Check skew // We compare the beginning of this track with the track on the next head and the track on the next cylinder if (check_skew && cylinder < 2 && head < 2) { m_secnumber[cylinder*2 + head] = sector; check_skew=false; } // Count the sectors for the interleave if (check_interleave) { if (interleave_prec == -1) interleave_prec = sector; else { if (sector == interleave_prec+1) check_interleave = false; interleave++; } } if (interleave == 0) interleave = sector - buffer[3]; // When we have 4-byte headers, the sector length is 512 bytes if (m_param.headerlen == 5) { size = buffer[4]; sector_length = 128 << (size&0x07); ecctype = (size&0xf0)>>4; } search_header = false; if (TRACE_DETAIL) osd_printf_verbose("%s: Found sector chs=(%d,%d,%d)\n", tag(), cylinder, head, sector); headerpos = pos; // Start the GAP2 counter (if not already determined) if (m_param.gap2==0) countgap2 = true; } else { // Sector contents // Write the sectors to the CHD int lbaposition = chs_to_lba(cylinder, head, sector); if (lbaposition>=0) { if (TRACE_DETAIL) osd_printf_verbose("%s: Writing sector chs=(%d,%d,%d) to CHD\n", tag(), current_cylinder, current_head, sector); chdstate = chdfile->write_units(chs_to_lba(current_cylinder, current_head, sector), buffer); if (chdstate != CHDERR_NONE) { osd_printf_verbose("%s: Write error while writing sector chs=(%d,%d,%d)\n", tag(), cylinder, head, sector); } } else { osd_printf_verbose("%s: Invalid CHS data in track image: (%d,%d,%d); not saving to CHD\n", tag(), cylinder, head, sector); } if (m_param.gap3==0) countgap3 = true; search_header = true; } } else { // Let's test for a 5-byte header if (search_header && m_param.headerlen==4 && current_cylinder==0 && current_head==0) { if (TRACE_DETAIL) osd_printf_verbose("%s: CRC error for 4-byte header; trying 5 bytes\n", tag()); m_param.headerlen=5; count = 1; bytepos++; break; } else { osd_printf_verbose("%s: CRC error in %s of (%d,%d,%d)\n", tag(), search_header? "header" : "data", cylinder, head, sector); search_header = true; } } // search next A1 state = SEARCH_A1; if (!search_header && (pos - headerpos) > 30) { osd_printf_verbose("%s: Error; missing DAM; searching next header\n", tag()); search_header = true; } }