int chs_biosdisk(int cmd, int drive, int head, int track,int sector, int nsects, void *buf) { unsigned tries, err; struct SREGS sregs; union REGS regs; /* set up registers for INT 13h AH=02/03h */ sregs.es = FP_SEG(buf); regs.h.dh = head; regs.h.dl = drive; regs.h.ch = track; regs.h.cl = ((track >> 2) & 0xC0) | sector; regs.x.bx = FP_OFF(buf); /* make 3 attempts */ for(tries = 1; tries != 0; tries--) { if(cmd == _DISK_RESET) regs.h.ah = 0x00; else if(cmd == _DISK_STATUS) regs.h.ah = 0x01; else if(cmd == _DISK_READ) regs.h.ah = 0x02; else if(cmd == _DISK_WRITE) regs.h.ah = 0x03; else if(cmd == _DISK_VERIFY) regs.h.ah = 0x04; else if(cmd == _DISK_FORMAT) regs.h.ah = 0x05; else return 1; /* invalid command */ regs.h.al = nsects; int86x(0x13, ®s, ®s, &sregs); err = regs.h.ah; if(err == 0) return 0; /* reset disk */ regs.h.ah = 0; int86x(0x13,®s,®s,&sregs); } hxc_printf(0,"chs_biosdisk: error 0x%02X\n", err); return err; }
void trackseek(unsigned char drive,unsigned char track,unsigned char head) { unsigned char byte,ret; do { intflag=0; #ifdef DBGMODE hxc_printf(0,"Seek drive %d to track %d head %d... ",drive,track,head); #endif outp(FDC_DOR, DORsel[drive&3] | 0xC); wrfdc(FDC_CMD_SEEK); byte = drive & 3; if(head) { byte = byte | 0x4; } wrfdc(byte); wrfdc(track); ret = waitirq(); fd_result(1); }while(!ret); #ifdef DBGMODE hxc_printf(0,"done\n"); #endif }
int format_track(int drive,unsigned char density,int track,int head,int nbsector,int sectorsize,int interleave,unsigned char formatvalue,unsigned char precomp,int rate,int gap3) { unsigned char byte,ret,i; #ifdef DBGMODE hxc_printf(0,"Format track %d head %d drive %d ...\n",track); #endif intflag=0; if(((precomp&7)==5) && rate==500) precomp=6; for( i = 0 ; i < nbsector ; i++ ) { bufwr[(i*4) + 0] = track; bufwr[(i*4) + 1] = head; bufwr[(i*4) + 2] = i+1; bufwr[(i*4) + 3] = getsizecode(sectorsize); } outp(FDC_DRS,((precomp&7)<<2) | getratecode(rate)); // Program data rate outp(FDC_CCR, getratecode(rate)); outp(FDC_DOR, DORsel[drive&3] | 0xC); initdma(FD_MODE_WRITE, nbsector * 4); byte = FDC_CMD_FORMAT; if(density) byte = byte | 0x40; wrfdc(byte); // CMD byte = drive & 3; if( head ) byte = byte | 0x4; wrfdc(byte); // Drive wrfdc(getsizecode(sectorsize)); // N wrfdc(nbsector); // Nbsector wrfdc(gap3); // gap3 wrfdc(formatvalue); // Format value ret = waitirq(); //if(ret) fd_result(1); if((status[0] & 0xC0) || !ret) { hxc_printf(0,"Format failed : ST0:0x%.2x, ST1:0x%.2x, ST2:0x%.2x\n",status[0],status[1],status[2]); return 1; } #ifdef DBGMODE hxc_printf(0,"done\n"); #endif return 0; }
/* * Read a sector from the disk */ int read_sector(unsigned char deleted,unsigned index,unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char nbsector,unsigned int size,unsigned char density,int rate,int gap3) { unsigned char byte,ret; #ifdef DBGMODE hxc_printf(0,"Read Sector %d track %d head %d drive %d...\n",sector,track,head,drive); #endif intflag=0; // Program data rate 500K/s) outp(FDC_DRS,getratecode(rate)); outp(FDC_CCR,getratecode(rate)); outp(FDC_DOR, DORsel[drive&3] | 0xC); initdma(FD_MODE_READ, size * nbsector); if(deleted) byte = FDC_CMD_READDELETEDDATA; else byte = FDC_CMD_READ; byte = byte | 0xA0; if(density) byte = byte | 0x40; wrfdc(byte); byte = drive & 3; if( head ) byte = byte | 0x4; wrfdc(byte); wrfdc(track); // Cylinder wrfdc(head); // Head wrfdc(index); // Sector wrfdc(getsizecode(size)); // N wrfdc(index + (nbsector-1)); // EOT wrfdc(gap3); // GL wrfdc(0xFF); ret = waitirq(); //if(ret) fd_result(1); if((status[0] & 0xC0) || !ret) { hxc_printf(0,"Read failed : ST0:0x%.2x, ST1:0x%.2x, ST2:0x%.2x\n",status[0],status[1],status[2]); return 1; } #ifdef DBGMODE hxc_printf(0,"done\n"); #endif return 0; }
void init_buffer() { int i; display_sprite(screen_buffer_aligned, bitmap_hxc2001logo_bmp,(SCREEN_XRESOL-bitmap_hxc2001logo_bmp->Xsize), (SCREEN_YRESOL-bitmap_hxc2001logo_bmp->Ysize)); display_sprite(screen_buffer_aligned, bitmap_sdhxcfelogo_bmp,(SCREEN_XRESOL-bitmap_sdhxcfelogo_bmp->Xsize)/2, (SCREEN_YRESOL-bitmap_sdhxcfelogo_bmp->Ysize)); h_line(SCREEN_YRESOL-34,0xFFFF) ; h_line(SCREEN_YRESOL-((48+(3*8))+2),0xFFFF) ; h_line(8,0xFFFF) ; hxc_printf(0,0,SCREEN_YRESOL-(8*1),"Ver %s",VERSIONCODE); hxc_printf(1,0,0,"SDCard HxC Floppy Emulator Manager for Atari ST"); h_line(SCREEN_YRESOL-(48+20)+24-2,0xFFFF) ; hxc_printf(1,0,SCREEN_YRESOL-(48+20)+24,">>>Press HELP key for the function key list<<<"); i=1; hxc_printf(1,0,HELP_Y_POS+(i*8), "SDCard HxC Floppy Emulator file selector for Atari ST"); i++; hxc_printf(1,0,HELP_Y_POS+(i*8), "(c) 2006-2011 HxC2001 / Jean-Francois DEL NERO"); i++; hxc_printf(1,0,HELP_Y_POS+(i*8), "Check for updates on :"); i++; hxc_printf(1,0,HELP_Y_POS+(i*8), "http://hxc2001.free.fr/floppy_drive_emulator/"); i++; hxc_printf(1,0,HELP_Y_POS+(i*8), "Email : [email protected]"); i++; hxc_printf(1,0,HELP_Y_POS+(i*8), "V%s - %s",VERSIONCODE,DATECODE); }
void init_display_buffer(ui_context * ctx) { int i; font_type * font; font = font_list[ctx->font_id]; ctx->screen_txt_xsize = ctx->SCREEN_XRESOL / font->char_x_size; ctx->screen_txt_ysize = (ctx->SCREEN_YRESOL / font->char_y_size); ctx->NUMBER_OF_ENTRIES_ON_DISPLAY = ctx->screen_txt_ysize - 2; // (Display size minus top + bottom) ctx->NUMBER_OF_FILE_ON_DISPLAY = ctx->NUMBER_OF_ENTRIES_ON_DISPLAY - 1; // (Display size minus top + bottom + tittle) chg_video_conf(ctx); // Clear all lines. for(i=0;i<ctx->screen_txt_ysize;i++) { clear_line(ctx, i, 0 ); } // Footprint : Current software / firmware version and title clear_line(ctx, ctx->screen_txt_ysize - 1, INVERTED); hxc_printf(ctx,LEFT_ALIGNED | INVERTED,0, ctx->screen_txt_ysize - 1,"FW %s",ctx->FIRMWAREVERSION); hxc_print(ctx,CENTER_ALIGNED | INVERTED,0,ctx->screen_txt_ysize - 1,(char*)title_msg); hxc_print(ctx,RIGHT_ALIGNED | INVERTED,0,ctx->screen_txt_ysize - 1,(char*)copyright_msg); // Top header : current folder path clear_line(ctx, 0, INVERTED); hxc_print(ctx,LEFT_ALIGNED|INVERTED,0,0, (char*)cur_folder_msg); }
UBYTE _search(UWORD pagenumber, UWORD selectorpos) { int cmp, len; UWORD curFile; struct fs_dir_ent dir_entry; gfl_setCachedPage(pagenumber); len = strlen(_searchString); #ifdef IJ_DEBUG hxc_printf(0, 0, 8*(debug_line++), "searching for %s from position pagenumber %d, %d", _searchString, pagenumber, selectorpos); #endif while(1) { curFile = gfl_cachedPage[selectorpos]; if (!fli_getDirEntryMSB(curFile, &dir_entry)) { break; } strlwr(dir_entry.filename); cmp = strncmp(dir_entry.filename, _searchString, len); if (0 == cmp) { // found #ifdef IJ_DEBUG hxc_printf(0, 0, 8*(debug_line++), "Found at page %d, %d", pagenumber, selectorpos); get_char(); #endif // gfl_setCachedPage(pagenumber); (not needed) gfl_selectorPos = selectorpos; return 1; } selectorpos++; if (selectorpos >= NUMBER_OF_FILE_ON_DISPLAY) { if (gfl_isLastPage) { break; } selectorpos = 0; pagenumber++; gfl_setCachedPage(pagenumber); } } return 0; }
void print_hex_buffer(ui_context * ctx,unsigned char * buffer, int size) { int c,i; int x,y; c=0; x=0; y=0; for(i=0;i<size;i++) { x = ( (c & 0xF) * 3 ); hxc_printf(ctx,LEFT_ALIGNED,x,y,"%.2X ", buffer[i]); c++; if( !( c & 0xF ) ) { y++; } } c=0; x=0; y=0; for(i=0;i<size;i++) { x=((c & 0xF)*8)+384+8; if( (buffer[i]>='a' && buffer[i]<='z') || (buffer[i]>='A' && buffer[i]<='Z') || (buffer[i]>='0' && buffer[i]<='9') ) { hxc_printf(ctx,LEFT_ALIGNED,x,y,"%c", buffer[i]); } else { hxc_print(ctx,LEFT_ALIGNED,x,y,"."); } c++; if(!(c&0xF)) { y++; } } }
void calibratedrive(unsigned char drive) { intflag=0; #ifdef DBGMODE hxc_printf(0,"Calibrate drive %d ... ",drive); #endif outp(FDC_DOR, DORsel[drive&3] | 0xC ); wrfdc(FDC_CMD_RECAL); wrfdc(drive&3); waitirq(); fd_result(1); #ifdef DBGMODE hxc_printf(0,"done\n"); #endif }
/** * If a key was stroke within a short time, add that key to the current search * otherwise, initiate an other instajump. */ void ij_keyEvent(signed char key) { unsigned long time; int len; UWORD oldPageNumber, oldSelectorPos; UWORD res; len = strlen(_searchString); time = get_hz200(); if ( (time - _lastTime) < (IJ_TIMEOUT / 5) ) { } else { // init a new search len = 0; #ifdef IJ_DEBUG debug_line = 6; #endif } if ( (len < IJ_MAXLEN)) { _searchString[len++] = tolower(key); // lower case _searchString[len] = '\000'; } oldPageNumber = gfl_cachedPageNumber; oldSelectorPos = gfl_selectorPos; res = _search(oldPageNumber, oldSelectorPos); if (!res && len>1) { // remove the last character and restart the search at the next file _searchString[len-1] = '\000'; if (oldSelectorPos+1 >= NUMBER_OF_FILE_ON_DISPLAY) { res = _search(oldPageNumber+1, 0); } else { res = _search(oldPageNumber, oldSelectorPos+1); } } if (!res) { // still not found #ifdef IJ_DEBUG hxc_printf(0, 0, 8*(debug_line++), "Not found"); get_char(); #endif gfl_setCachedPage(oldPageNumber); // gfl_selectorPos = oldSelectorPos; // not needed: search only update the gfl_selectorpos when found } // reset the last with the time at the end of the search _lastTime = get_hz200(); }
/* * Wait for interrupt from the FDC * Last byte of command is sent here so that we can enable * interrupt before commands begins. */ unsigned char waitirq() { ticktimer = 0; do { }while( (!intflag) && (ticktimer<(18*8)) ); if(ticktimer>=(18*8)) { hxc_printf(0,"Waitirq Timeout\n"); return 0; } return 1; }
void init_floppyio(void) { int status; ticktimer = 0x00; intflag = 0x00; time_tick_count = 0x00; memset(§or_buf,0,512); status = chs_biosdisk(_DISK_RESET,0, 0, 255,0, 1, §or_buf); if(status) hxc_printf(0,"FDC Reset error : Return value %d\n",status); prev_floppy_int = _dos_getvect( 8+0x6 ); _dos_setvect( 8+0x6, floppy_interrupt_handler ); prev_timer_int = _dos_getvect( 8+0x0 ); _dos_setvect( 8+0x0, timer_interrupt_handler ); if(_dos_allocmem( 32768/16, &dmabuf_seg_rd )) { hxc_printf(0,"Alloc Error !\n"); for(;;); } bufrd = (unsigned char *)MK_FP(dmabuf_seg_rd, 0); if(_dos_allocmem( 32768/16, &dmabuf_seg_wr )) { hxc_printf(0,"Alloc Error !\n"); for(;;); } bufwr = (unsigned char *)MK_FP(dmabuf_seg_wr, 0); reset_drive(0); }
int media_init() { int ret; unsigned char sector[512]; direct_access_status_sector * dass; int i,count; #ifdef DEBUG dbg_printf("media_init\n"); #endif last_setlbabase=0xFFFFF000; ret = readsector(0,(unsigned char*)§or,1); g_ui_ctx.firmware_type = INVALID_FIRMWARE; if(ret == ERR_NO_ERROR) { dass = (direct_access_status_sector *)sector; if(!strcmp(dass->DAHEADERSIGNATURE,HXC_FW_ID)) { g_ui_ctx.firmware_type = HXC_LEGACY_FIRMWARE; i = 0; count = 0; if(dass->FIRMWAREVERSION[0] != 'v' && dass->FIRMWAREVERSION[0] != 'V') { g_ui_ctx.firmware_type = HXC_CLONE_FIRMWARE; } while(dass->FIRMWAREVERSION[i] && i < sizeof(dass->FIRMWAREVERSION)) { if(dass->FIRMWAREVERSION[i] == '.') count++; i++; } if(count != 3) g_ui_ctx.firmware_type = HXC_CLONE_FIRMWARE; } #ifdef CORTEX_FW_SUPPORT if(!strncmp(dass->DAHEADERSIGNATURE,CORTEX_FW_ID,strlen(CORTEX_FW_ID))) { g_ui_ctx.firmware_type = CORTEX_FIRMWARE; } #endif if( g_ui_ctx.firmware_type != INVALID_FIRMWARE ) { strncpy(g_ui_ctx.FIRMWAREVERSION,dass->FIRMWAREVERSION,sizeof(g_ui_ctx.FIRMWAREVERSION)); hxc_printf(&g_ui_ctx,LEFT_ALIGNED|INVERTED,0, g_ui_ctx.screen_txt_ysize - 1,"FW %s",g_ui_ctx.FIRMWAREVERSION); ret = test_floppy_if(); if( ret != ERR_NO_ERROR) return ret; dass = (direct_access_status_sector *)sector; last_setlbabase=0; ret = setlbabase(last_setlbabase); if( ret != ERR_NO_ERROR ) return ret; #ifdef DEBUG dbg_printf("media_init : HxC FE Found\n"); #endif return ERR_NO_ERROR; } #ifdef DEBUG dbg_printf("media_init : HxC FE not detected\n"); #endif return -ERR_BAD_DRIVE_ID; } #ifdef DEBUG dbg_printf("media_init : Media access error\n"); #endif return ret; }