diff --git a/README.md b/README.md index 7c07f7b76..f6ba5eacf 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,19 @@ Keep in touch with the 86Box community: [![Visit our IRC channel](https://kiwiirc.com/buttons/irc.rol.im/softhistory.png)](https://kiwiirc.com/client/irc.rol.im/?nick=86box|?#softhistory) [![Visit our Discord server](https://discordapp.com/api/guilds/262614059009048590/embed.png)](https://discord.gg/Es3TnUH) + +--- +# Compilation +In order to compile 86Box from this repository, please follow this step-by-step guide: +1) Download the development environment from http://tinyurl.com/pcemude. Afterwards, extract it to your desired location. Of course, also clone the repository in your desired location. Downloading ZIPs is not recommended, as it makes it more inconvenient to keep the code up-to-date. To avoid issues, make sure neither path has spaces in it. +2) In the extracted environment folder, you will find a script called **mingw32_shell.bat**. Launch it. There are other shell launching scripts in there, but you should not use them. +3) Once launched, run **pacman -Syuu** in order to update the environment. Depending on the state of the downloaded DE, you may need to run it twice (once initially, and then again after re-entering the environment). Make sure to keep the enviroment up-to-date by re-running the command periodically. +4) Once the environment is fully updated, **cd** into your cloned **86box\src** directory. +5) Run **make -j*N* -fmakefile.mingw** to start the actual compilation process. Substitute *N* with the number of threads you want to use for the compilation process. The optimal number depends entirely on your processor, and it is up to you to determine the optimal number. A good starting point is the total number of threads (AKA Logical Processors) you have available. +6) If the compilation succeeded (which it almost always should), you will find **86Box.exe** in the src directory. +7) In order to test your fresh build, replace the **86Box.exe** in your current 86Box enviroment with your freshly built one. If you do not have a pre-existing 86Box environment, download the latest successful build from http://ci.86box.net, and the ROM set from http://tinyurl.com/roms2017. +8) Enjoy using and testing the emulator! :) + +If you encounter issues at any step or have additional questions, please join the IRC channel and wait patiently for someone to help you. + + diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index 49cf3358a..33a3397bf 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -45,6 +45,7 @@ static int old_overscan_color = 0; int update_overscan = 0; +#ifdef JEGA uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */ uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */ @@ -146,6 +147,7 @@ void ega_jega_read_font(ega_t *ega) ega->font_index++; ega->RSTAT |= 0x02; } +#endif void ega_out(uint16_t addr, uint8_t val, void *p) { @@ -259,7 +261,11 @@ void ega_out(uint16_t addr, uint8_t val, void *p) return; case 0x3d1: case 0x3d5: +#ifdef JEGA if ((ega->crtcreg < 0xb9) || !ega->is_jega) +#else + if (ega->crtcreg < 0xb9) +#endif { crtcreg = ega->crtcreg & 0x1f; if (crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; @@ -274,6 +280,7 @@ void ega_out(uint16_t addr, uint8_t val, void *p) } } } +#ifdef JEGA else { switch(ega->crtcreg) @@ -331,6 +338,7 @@ void ega_out(uint16_t addr, uint8_t val, void *p) break; } } +#endif break; } } @@ -391,11 +399,16 @@ uint8_t ega_in(uint16_t addr, void *p) return ega->crtcreg; case 0x3d1: case 0x3d5: +#ifdef JEGA if ((ega->crtcreg < 0xb9) || !ega->is_jega) +#else + if (ega->crtcreg < 0xb9) +#endif { crtcreg = ega->crtcreg & 0x1f; return ega->crtc[crtcreg]; } +#ifdef JEGA else { switch(ega->crtcreg) @@ -434,6 +447,8 @@ uint8_t ega_in(uint16_t addr, void *p) return 0x00; } } +#endif + return 0xff; case 0x3da: ega->attrff = 0; ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ @@ -534,6 +549,7 @@ void ega_poll(void *p) { if (fullchange) { +#ifdef JEGA if (ega_jega_enabled(ega)) { ega_render_text_jega(ega, drawcursor); @@ -542,6 +558,9 @@ void ega_poll(void *p) { ega_render_text_standard(ega, drawcursor); } +#else + ega_render_text_standard(ega, drawcursor); +#endif } } else @@ -1016,7 +1035,9 @@ void ega_common_defaults(ega_t *ega) update_overscan = 0; +#ifdef JEGA ega->is_jega = 0; +#endif } void *ega_standalone_init() @@ -1138,6 +1159,7 @@ void *sega_standalone_init() return ega; } +#ifdef JEGA uint16_t chrtosht(FILE *fp) { uint16_t i, j; @@ -1243,6 +1265,7 @@ void *jega_standalone_init() return ega; } +#endif static int ega_standalone_available() { @@ -1337,6 +1360,7 @@ device_t sega_device = ega_config }; +#ifdef JEGA device_t jega_device = { "AX JEGA", @@ -1349,3 +1373,4 @@ device_t jega_device = NULL, ega_config }; +#endif diff --git a/src/VIDEO/vid_ega.h b/src/VIDEO/vid_ega.h index e7b30b32b..e9835d1fb 100644 --- a/src/VIDEO/vid_ega.h +++ b/src/VIDEO/vid_ega.h @@ -91,11 +91,13 @@ typedef struct ega_t int video_res_x, video_res_y, video_bpp; +#ifdef JEGA uint8_t RMOD1, RMOD2, RDAGS, RDFFB, RDFSB, RDFAP, RPESL, RPULP, RPSSC, RPSSU, RPSSL; uint8_t RPPAJ; uint8_t RCMOD, RCCLH, RCCLL, RCCSL, RCCEL, RCSKW, ROMSL, RSTAT; int is_jega, font_index; int chr_left, chr_wide; +#endif } ega_t; extern int update_overscan; @@ -113,6 +115,7 @@ extern device_t ega_device; extern device_t cpqega_device; extern device_t sega_device; +#ifdef JEGA #define SBCS 0 #define DBCS 1 #define ID_LEN 6 @@ -122,3 +125,4 @@ extern device_t sega_device; extern uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */ extern uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */ +#endif diff --git a/src/VIDEO/vid_ega_render.c b/src/VIDEO/vid_ega_render.c index 66c3f2f65..50ef6139e 100644 --- a/src/VIDEO/vid_ega_render.c +++ b/src/VIDEO/vid_ega_render.c @@ -146,6 +146,7 @@ void ega_render_text_standard(ega_t *ega, int drawcursor) } } +#ifdef JEGA static __inline int is_kanji1(uint8_t chr) { return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc); @@ -374,6 +375,7 @@ void ega_render_text_jega(ega_t *ega, int drawcursor) } } } +#endif void ega_render_2bpp_lowres(ega_t *ega) { diff --git a/src/VIDEO/vid_ega_render.h b/src/VIDEO/vid_ega_render.h index b833128a9..3ff9a5412 100644 --- a/src/VIDEO/vid_ega_render.h +++ b/src/VIDEO/vid_ega_render.h @@ -29,7 +29,9 @@ extern uint8_t edatlookup[4][4]; void ega_render_blank(ega_t *ega); void ega_render_text_standard(ega_t *ega, int drawcursor); +#ifdef JEGA void ega_render_text_jega(ega_t *ega, int drawcursor); +#endif void ega_render_2bpp_lowres(ega_t *ega); void ega_render_2bpp_highres(ega_t *ega); diff --git a/src/WIN/win.c b/src/WIN/win.c index 66c20625c..d34465997 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -793,7 +793,7 @@ void create_floppy_tip(int part) } else { - _swprintf(tempTip, win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); + _swprintf(tempTip, win_language_get_string_from_id(IDS_2158), drive + 1, wtext, discfns[drive]); } if (sbTips[part] != NULL) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 32c7016b4..781a73e23 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -2500,7 +2500,6 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W char *big_buf; int b = 0; uint64_t r = 0; - int j = 0; switch (message) { @@ -2828,7 +2827,7 @@ hdd_add_file_open_error: } else { - for (j = 0; j < 16; j++) + for (i = 5; i < 16; i++) { if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19))) { @@ -3777,21 +3776,21 @@ static void cdrom_add_locations(HWND hdlg) h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); for (i = 0; i < 16; i++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4098), i); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4098), i); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4097), i >> 1, i & 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } diff --git a/src/config.c b/src/config.c index d7e62004f..bc3d84ba2 100644 --- a/src/config.c +++ b/src/config.c @@ -1,5 +1,23 @@ -/* Copyright holders: Sarah Walker - * see COPYING for more details +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Configuration file handler. + * + * Version: @(#)config.c 1.0.0 2017/07/26 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Overdoze, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. + * Copyright 2017-2017 Overdoze. * * NOTE: Forcing config files to be in Unicode encoding breaks it on * Windows XP, and possibly also Vista. Use -DANSI_CFG for use @@ -81,6 +99,18 @@ typedef struct entry_t (new)->next = NULL; \ } +#define list_delete(old, head) \ + { \ + struct list_t *next = head; \ + \ + while ((next)->next != old) \ + { \ + next = (next)->next; \ + } \ + \ + (next)->next = (old)->next; \ + } + void config_dump(void) { @@ -471,8 +501,8 @@ void config_delete_var(char *head, char *name) if (!entry) return; - /* memset(entry->name, 0, strlen(entry->name)); */ - entry->name[0] = 0; + list_delete(&entry->list, §ion->entry_head); + free(entry); return; } @@ -489,8 +519,8 @@ void config_delete_section_if_empty(char *head) if (entries_num(section) == 0) { - /* memset(section->name, 0, strlen(section->name)); */ - section->name[0] = 0; + list_delete(§ion->list, &config_head); + free(section); } return; diff --git a/src/config.h b/src/config.h index 8d1db0b7b..a7c15383f 100644 --- a/src/config.h +++ b/src/config.h @@ -1,8 +1,24 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ - - +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Configuration file handler header. + * + * Version: @(#)config.h 1.0.0 2017/07/26 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Overdoze, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. + * Copyright 2017-2017 Overdoze. + */ extern wchar_t config_file_default[256]; diff --git a/src/disc.c b/src/disc.c index 1a0321f39..bc6a7977e 100644 --- a/src/disc.c +++ b/src/disc.c @@ -194,11 +194,6 @@ double disc_byteperiod(int drive) if (drives[drive].byteperiod) { - if (fdd_get_turbo(drive)) - { - return 1.0; - } - return drives[drive].byteperiod(drive); } else @@ -217,7 +212,12 @@ double disc_real_period(int drive) dusec = (double) TIMER_USEC; /* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */ - if ((romset == ROM_MRTHOR) && !fdd_get_turbo(drive)) + if (fdd_get_turbo(drive)) + { + return (32.0 * dusec); + } + + if (romset == ROM_MRTHOR) { return (ddbp * dusec) / 4.0; } diff --git a/src/disc.h b/src/disc.h index eb5c7a1bd..b6f5f7c43 100644 --- a/src/disc.h +++ b/src/disc.h @@ -231,5 +231,10 @@ typedef union sector_id_fields_t id; } sector_id_t; +void d86f_set_version(int drive, uint16_t version); + +void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n); +void d86f_zero_bit_field(int drive, int side); + #endif /*EMU_DISC_H*/ diff --git a/src/disc_86f.c b/src/disc_86f.c index 9eb713365..95a03e86d 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -35,8 +35,6 @@ #include "fdd.h" #include "ibm.h" -#define D86FVER 0x020B - #define CHUNK 16384 uint64_t poly = 0x42F0E1EBA9EA3693ll; /* ECMA normal */ @@ -252,6 +250,8 @@ struct __attribute__((__packed__)) uint8_t *filebuf; uint8_t *outbuf; uint32_t dma_over; + int turbo_pos; + uint16_t sector_id_bit_field[2][256][256][256]; } d86f[FDD_NUM]; #ifdef __MSC__ # pragma pack(pop) @@ -273,6 +273,28 @@ void d86f_log(const char *format, ...) #endif } +void d86f_zero_bit_field(int drive, int side) +{ + int i = 0; + int j = 0; + int k = 0; + int l = 0; + + for (i = 0; i < side; i++) + { + for (j = 0; j < 256; j++) + { + for (k = 0; k < 256; k++) + { + for (l = 0; l < 256; l++) + { + d86f[drive].sector_id_bit_field[i][j][k][l] = 0; + } + } + } + } +} + static void d86f_setupcrc(uint16_t poly) { int c = 256, bc; @@ -490,6 +512,11 @@ uint32_t common_get_raw_size(int drive, int side) return ((((uint32_t) size) >> 4) << 4) + d86f_handler[drive].extra_bit_cells(drive, side); } +void d86f_set_version(int drive, uint16_t version) +{ + d86f[drive].version = version; +} + void d86f_unregister(int drive) { d86f_handler[drive].disk_flags = null_disk_flags; @@ -1793,6 +1820,20 @@ void d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_ fdc_sector_finishread(); } +void d86f_format_turbo_finish(int drive, int side, int do_write) +{ + d86f[drive].state = STATE_IDLE; + + if (do_write) + { + d86f_handler[drive].writeback(drive); + } + + d86f[drive].error_condition = 0; + d86f[drive].datac = 0; + fdc_sector_finishread(); +} + void d86f_format_track(int drive, int side, int do_write) { int data; @@ -2001,6 +2042,267 @@ void d86f_format_track_nop(int drive, int side) d86f_format_track(drive, side, 0); } +void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n) +{ + d86f[drive].last_sector.id.c = c; + d86f[drive].last_sector.id.h = h; + d86f[drive].last_sector.id.r = r; + d86f[drive].last_sector.id.n = n; +} + +void d86f_turbo_read(int drive, int side) +{ + uint8_t dat = 0; + + int recv_data = 0; + int read_status = 0; + + dat = d86f_handler[drive].read_data(drive, side, d86f[drive].turbo_pos); + d86f[drive].turbo_pos++; + + if (d86f[drive].state == STATE_11_SCAN_DATA) + { + /* Scan/compare command. */ + recv_data = d86f_get_data(drive, 0); + d86f_compare_byte(drive, recv_data, dat); + } + else + { + if (d86f[drive].data_find.bytes_obtained < (128 << d86f[drive].last_sector.id.n)) + { + if (d86f[drive].state != STATE_16_VERIFY_DATA) + { + read_status = fdc_data(dat); + if (read_status == -1) + { + d86f[drive].dma_over++; + } + } + } + } + + if (d86f[drive].dma_over > 1) + { + d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; + d86f[drive].error_condition = 0; + d86f[drive].state = STATE_IDLE; + fdc_finishread(); + fdc_overrun(); + return; + } + + if (d86f[drive].turbo_pos >= (128 << d86f[drive].last_sector.id.n)) + { + /* CRC is valid. */ + d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; + d86f[drive].error_condition = 0; + if (d86f[drive].state == STATE_11_SCAN_DATA) + { + d86f[drive].state = STATE_IDLE; + fdc_sector_finishcompare((d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0); + } + else + { + d86f[drive].state = STATE_IDLE; + fdc_sector_finishread(); + } + } +} + +void d86f_turbo_write(int drive, int side) +{ + uint8_t dat = 0; + + dat = d86f_get_data(drive, 1); + d86f_handler[drive].write_data(drive, side, d86f[drive].turbo_pos, dat); + + d86f[drive].turbo_pos++; + + if (d86f[drive].turbo_pos >= (128 << d86f[drive].last_sector.id.n)) + { + /* We've written the data. */ + d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; + d86f[drive].error_condition = 0; + d86f[drive].state = STATE_IDLE; + d86f_handler[drive].writeback(drive); + fdc_sector_finishread(); + return; + } +} + +void d86f_turbo_format(int drive, int side, int nop) +{ + int dat; + int i = 0; + + uint16_t sc = 0; + uint16_t dtl = 0; + + sc = fdc_get_format_sectors(); + dtl = 128 << fdc_get_format_n(); + + if (d86f[drive].datac <= 3) + { + dat = fdc_getdata(0); + if (dat != -1) + { + dat &= 0xff; + } + if ((dat == -1) && (d86f[drive].datac < 3)) + { + dat = 0; + } + d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = dat & 0xff; + if (d86f[drive].datac == 3) + { + fdc_stop_id_request(); + d86f_handler[drive].set_sector(drive, side, d86f[drive].format_sector_id.id.c, d86f[drive].format_sector_id.id.h, d86f[drive].format_sector_id.id.r, d86f[drive].format_sector_id.id.n); + } + } + else if (d86f[drive].datac == 4) + { + if (!nop) + { + for (i = 0; i < dtl; i++) + { + d86f_handler[drive].write_data(drive, side, i, d86f[drive].fill); + } + } + + d86f[drive].sector_count++; + } + + d86f[drive].datac++; + + if (d86f[drive].datac == 6) + { + d86f[drive].datac = 0; + + if (d86f[drive].sector_count < sc) + { + /* Sector within allotted amount. */ + fdc_request_next_sector_id(); + } + else + { + d86f[drive].state = STATE_IDLE; + d86f_format_turbo_finish(drive, side, nop); + } + } +} + +void d86f_turbo_poll(int drive, int side) +{ + if ((d86f[drive].state != STATE_IDLE) && (d86f[drive].state != STATE_SECTOR_NOT_FOUND) && ((d86f[drive].state & 0xF8) != 0xE8)) + { + if (!d86f_can_read_address(drive)) + { + /* if (fdc_get_bitcell_period() != d86f_get_bitcell_period(drive)) d86f_log("[%i, %i] Bitcell period mismatch (%i != %i)\n", drive, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive)); + if (!fdd_can_read_medium(real_drive(drive))) d86f_log("[%i, %i] Drive can not read medium (hole = %01X)\n", drive, side, d86f_hole(drive)); + if (fdc_is_mfm() != d86f_is_mfm(drive)) d86f_log("[%i, %i] Encoding mismatch\n", drive, side); + if (d86f_get_encoding(drive) > 1) d86f_log("[%i, %i] Image encoding (%s) not FM or MFM\n", drive, side, (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */ + + d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0; + fdc_noidam(); + d86f[drive].state = STATE_IDLE; + return; + } + } + + switch(d86f[drive].state) + { + case STATE_0D_SPIN_TO_INDEX: + case STATE_0D_NOP_SPIN_TO_INDEX: + d86f[drive].sector_count = 0; + d86f[drive].datac = 5; + case STATE_02_SPIN_TO_INDEX: + d86f[drive].state++; + return; + case STATE_02_FIND_ID: + if (!(d86f[drive].sector_id_bit_field[side][fdc_get_read_track_sector().id.c][fdc_get_read_track_sector().id.h][fdc_get_read_track_sector().id.r] & (1 << fdc_get_read_track_sector().id.n))) + { + d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0; + fdc_nosector(); + d86f[drive].state = STATE_IDLE; + return; + } + d86f[drive].last_sector.id.c = fdc_get_read_track_sector().id.c; + d86f[drive].last_sector.id.h = fdc_get_read_track_sector().id.h; + d86f[drive].last_sector.id.r = fdc_get_read_track_sector().id.r; + d86f[drive].last_sector.id.n = fdc_get_read_track_sector().id.n; + d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n); + d86f[drive].turbo_pos = 0; + d86f[drive].state++; + return; + case STATE_05_FIND_ID: + case STATE_09_FIND_ID: + case STATE_06_FIND_ID: + case STATE_0C_FIND_ID: + case STATE_11_FIND_ID: + case STATE_16_FIND_ID: + if (!(d86f[drive].sector_id_bit_field[side][d86f[drive].req_sector.id.c][d86f[drive].req_sector.id.h][d86f[drive].req_sector.id.r] & (1 << d86f[drive].req_sector.id.n))) + { + d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0; + fdc_nosector(); + d86f[drive].state = STATE_IDLE; + return; + } + d86f[drive].last_sector.id.c = d86f[drive].req_sector.id.c; + d86f[drive].last_sector.id.h = d86f[drive].req_sector.id.h; + d86f[drive].last_sector.id.r = d86f[drive].req_sector.id.r; + d86f[drive].last_sector.id.n = d86f[drive].req_sector.id.n; + d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n); + case STATE_0A_FIND_ID: + d86f[drive].turbo_pos = 0; + d86f[drive].state++; + return; + case STATE_0A_READ_ID: + d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0; + fdc_sectorid(d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0); + d86f[drive].state = STATE_IDLE; + break; + case STATE_02_READ_ID: + case STATE_05_READ_ID: + case STATE_09_READ_ID: + case STATE_06_READ_ID: + case STATE_0C_READ_ID: + case STATE_11_READ_ID: + case STATE_16_READ_ID: + d86f[drive].state++; + break; + case STATE_02_FIND_DATA: + case STATE_06_FIND_DATA: + case STATE_11_FIND_DATA: + case STATE_16_FIND_DATA: + case STATE_05_FIND_DATA: + case STATE_09_FIND_DATA: + case STATE_0C_FIND_DATA: + d86f[drive].state++; + break; + case STATE_02_READ_DATA: + case STATE_06_READ_DATA: + case STATE_0C_READ_DATA: + case STATE_11_SCAN_DATA: + case STATE_16_VERIFY_DATA: + d86f_turbo_read(drive, side); + break; + case STATE_05_WRITE_DATA: + case STATE_09_WRITE_DATA: + d86f_turbo_write(drive, side); + break; + case STATE_0D_FORMAT_TRACK: + d86f_turbo_format(drive, side, 0); + return; + case STATE_0D_NOP_FORMAT_TRACK: + d86f_turbo_format(drive, side, 1); + return; + case STATE_IDLE: + case STATE_SECTOR_NOT_FOUND: + default: + break; + } +} + void d86f_poll(int drive) { int side = 0; @@ -2022,6 +2324,12 @@ void d86f_poll(int drive) } } + if (fdd_get_turbo(drive) && (d86f[drive].version == 0x0063)) + { + d86f_turbo_poll(drive, side); + return; + } + if ((d86f[drive].state != STATE_IDLE) && (d86f[drive].state != STATE_SECTOR_NOT_FOUND) && ((d86f[drive].state & 0xF8) != 0xE8)) { if (!d86f_can_read_address(drive)) @@ -2337,6 +2645,8 @@ uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint16_t dataam_mfm = 0x4555; uint16_t datadam_mfm = 0x4A55; + d86f[drive].sector_id_bit_field[side][id_buf[0]][id_buf[1]][id_buf[2]] |= (1 << id_buf[3]); + mfm = d86f_is_mfm(drive); gap_fill = mfm ? 0x4E : 0xFF; @@ -3080,6 +3390,7 @@ void d86f_load(int drive, wchar_t *fn) { /* File is WAY too small, abort. */ fclose(d86f[drive].f); + d86f[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3089,6 +3400,7 @@ void d86f_load(int drive, wchar_t *fn) /* File is not of the valid format, abort. */ d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); fclose(d86f[drive].f); + d86f[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3111,6 +3423,7 @@ void d86f_load(int drive, wchar_t *fn) d86f_log("86F: Unrecognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); } fclose(d86f[drive].f); + d86f[drive].f = NULL; update_status_bar_icon_state(drive, 1); return; } @@ -3127,6 +3440,7 @@ void d86f_load(int drive, wchar_t *fn) { /* File too small, abort. */ fclose(d86f[drive].f); + d86f[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3149,6 +3463,7 @@ void d86f_load(int drive, wchar_t *fn) { d86f_log("86F: CRC64 error\n"); fclose(d86f[drive].f); + d86f[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3160,6 +3475,7 @@ void d86f_load(int drive, wchar_t *fn) memcpy(d86f[drive].original_file_name, fn, (wcslen(fn) << 1) + 2); fclose(d86f[drive].f); + d86f[drive].f = NULL; d86f[drive].f = _wfopen(temp_file_name, L"wb"); if (!d86f[drive].f) @@ -3190,6 +3506,7 @@ void d86f_load(int drive, wchar_t *fn) fclose(tf); fclose(d86f[drive].f); + d86f[drive].f = NULL; if (!temp) { @@ -3207,6 +3524,7 @@ void d86f_load(int drive, wchar_t *fn) /* Zoned disk. */ d86f_log("86F: Disk is zoned (Apple or Sony)\n"); fclose(d86f[drive].f); + d86f[drive].f = NULL; if (d86f[drive].is_compressed) { _wremove(temp_file_name); @@ -3220,6 +3538,7 @@ void d86f_load(int drive, wchar_t *fn) /* Zone type is not 0 but the disk is fixed-RPM. */ d86f_log("86F: Disk is fixed-RPM but zone type is not 0\n"); fclose(d86f[drive].f); + d86f[drive].f = NULL; if (d86f[drive].is_compressed) { _wremove(temp_file_name); @@ -3237,6 +3556,7 @@ void d86f_load(int drive, wchar_t *fn) if (writeprot[drive]) { fclose(d86f[drive].f); + d86f[drive].f = NULL; if (d86f[drive].is_compressed) { @@ -3257,6 +3577,7 @@ void d86f_load(int drive, wchar_t *fn) /* File has no track 0 side 0, abort. */ d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); + d86f[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3266,6 +3587,7 @@ void d86f_load(int drive, wchar_t *fn) /* File is 2-sided but has no track 0 side 1, abort. */ d86f_log("86F: No Track 0 side 1\n"); fclose(d86f[drive].f); + d86f[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3347,7 +3669,10 @@ void d86f_close(int drive) memcpy(temp_file_name, drive ? nvr_concat(L"TEMP$$$1.$$$") : nvr_concat(L"TEMP$$$0.$$$"), 26); if (d86f[drive].f) + { fclose(d86f[drive].f); + d86f[drive].f = NULL; + } if (d86f[drive].is_compressed) _wremove(temp_file_name); } diff --git a/src/disc_86f.h b/src/disc_86f.h index ec7e83c1e..bea967108 100644 --- a/src/disc_86f.h +++ b/src/disc_86f.h @@ -33,6 +33,7 @@ void d86f_readaddress(int drive, int side, int density); void d86f_format(int drive, int side, int density, uint8_t fill); void d86f_prepare_track_layout(int drive, int side); +void d86f_set_version(int drive, uint16_t version); #define length_gap0 80 #define length_gap1 50 @@ -59,3 +60,8 @@ extern int gap2_size[2]; extern int gap3_size[2]; extern int gap4_size[2]; #endif + +#define D86FVER 0x020B + +void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n); +void d86f_zero_bit_field(int drive, int side); diff --git a/src/disc_fdi.c b/src/disc_fdi.c index af192b76f..e23862d65 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -22,6 +22,7 @@ #include #include "ibm.h" #include "disc.h" +#include "disc_86f.h" #include "disc_img.h" #include "disc_fdi.h" #include "fdc.h" @@ -254,6 +255,7 @@ void d86f_register_fdi(int drive) d86f_handler[drive].index_hole_pos = fdi_index_hole_pos; d86f_handler[drive].get_raw_size = fdi_get_raw_size; d86f_handler[drive].check_crc = 1; + d86f_set_version(drive, D86FVER); } void fdi_load(int drive, wchar_t *fn) @@ -278,6 +280,7 @@ void fdi_load(int drive, wchar_t *fn) /* This is a Japanese FDI file. */ pclog("fdi_load(): Japanese FDI file detected, redirecting to IMG loader\n"); fclose(fdi[drive].f); + fdi[drive].f = NULL; img_load(drive, fn); return; } @@ -301,7 +304,10 @@ void fdi_close(int drive) if (fdi[drive].h) fdi2raw_header_free(fdi[drive].h); if (fdi[drive].f) + { fclose(fdi[drive].f); + fdi[drive].f = NULL; + } } void fdi_seek(int drive, int track) diff --git a/src/disc_imd.c b/src/disc_imd.c index d511dd46d..2017d1e96 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -110,6 +110,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: Not a valid ImageDisk image\n"); fclose(imd[drive].f); + imd[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -131,6 +132,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: No ASCII EOF character\n"); fclose(imd[drive].f); + imd[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -144,6 +146,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: File ends after ASCII EOF character\n"); fclose(imd[drive].f); + imd[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -263,6 +266,7 @@ void imd_load(int drive, wchar_t *fn) /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); fclose(imd[drive].f); + imd[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -301,6 +305,7 @@ void imd_close(int drive) memset(&(imd[drive].tracks[i][1]), 0, sizeof(imd_track_t)); } fclose(imd[drive].f); + imd[drive].f = NULL; } } @@ -531,6 +536,9 @@ void imd_seek(int drive, int track) d86f_reset_index_hole_pos(drive, 0); d86f_reset_index_hole_pos(drive, 1); + d86f_zero_bit_field(drive, 0); + d86f_zero_bit_field(drive, 1); + for (side = 0; side < imd[drive].sides; side++) { track_rate = imd[drive].current_side_flags[side] & 7; @@ -601,6 +609,11 @@ void imd_seek(int drive, int track) imd_sector_to_buffer(drive, track, side, data, actual_sector, ssize); current_pos = d86f_prepare_sector(drive, side, current_pos, id, data, ssize, 22, track_gap3, deleted, bad_crc); track_buf_pos[side] += ssize; + + if (sector == 0) + { + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } } } else @@ -635,6 +648,11 @@ void imd_seek(int drive, int track) } track_buf_pos[side] += ssize; + + if (sector == 0) + { + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } } } } @@ -746,6 +764,16 @@ void imd_writeback(int drive) } } +uint8_t imd_poll_read_data(int drive, int side, uint16_t pos) +{ + int type = imd[drive].current_data[side][0]; + if (!(type & 1)) + { + return 0xf6; /* Should never happen. */ + } + return imd[drive].current_data[side][pos + 1]; +} + void imd_poll_write_data(int drive, int side, uint16_t pos, uint8_t data) { int type = imd[drive].current_data[side][0]; @@ -777,6 +805,7 @@ void d86f_register_imd(int drive) d86f_handler[drive].side_flags = imd_side_flags; d86f_handler[drive].writeback = imd_writeback; d86f_handler[drive].set_sector = imd_set_sector; + d86f_handler[drive].read_data = imd_poll_read_data; d86f_handler[drive].write_data = imd_poll_write_data; d86f_handler[drive].format_conditions = imd_format_conditions; d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; @@ -785,4 +814,5 @@ void d86f_register_imd(int drive) d86f_handler[drive].index_hole_pos = null_index_hole_pos; d86f_handler[drive].get_raw_size = common_get_raw_size; d86f_handler[drive].check_crc = 1; + d86f_set_version(drive, 0x0063); } diff --git a/src/disc_img.c b/src/disc_img.c index 4220e5af0..8c78a5180 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -752,6 +752,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); + img[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -814,6 +815,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); + img[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -831,6 +833,7 @@ jump_if_fdf: { pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); fclose(img[drive].f); + img[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -863,7 +866,10 @@ void img_close(int drive) { d86f_unregister(drive); if (img[drive].f) + { fclose(img[drive].f); + img[drive].f = NULL; + } if (img[drive].disk_data) free(img[drive].disk_data); } @@ -938,6 +944,9 @@ void img_seek(int drive, int track) d86f_reset_index_hole_pos(drive, 0); d86f_reset_index_hole_pos(drive, 1); + d86f_zero_bit_field(drive, 0); + d86f_zero_bit_field(drive, 1); + if (!img[drive].xdf_type || img[drive].is_cqm) { for (side = 0; side < img[drive].sides; side++) @@ -980,6 +989,11 @@ void img_seek(int drive, int track) img[drive].sector_pos_side[side][sr] = side; img[drive].sector_pos[side][sr] = (sr - 1) * ssize; current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[side][(sr - 1) * ssize], ssize, img[drive].gap2_size, img[drive].gap3_size, 0, 0); + + if (sector == 0) + { + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } } } } @@ -1039,6 +1053,11 @@ void img_seek(int drive, int track) ssize = (128 << id[3]); current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &img[drive].track_data[buf_side][buf_pos], ssize, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0); } + + if (sector == 0) + { + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } } } } @@ -1108,6 +1127,7 @@ void d86f_register_img(int drive) d86f_handler[drive].side_flags = img_side_flags; d86f_handler[drive].writeback = img_writeback; d86f_handler[drive].set_sector = img_set_sector; + d86f_handler[drive].read_data = img_poll_read_data; d86f_handler[drive].write_data = img_poll_write_data; d86f_handler[drive].format_conditions = img_format_conditions; d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; @@ -1116,4 +1136,5 @@ void d86f_register_img(int drive) d86f_handler[drive].index_hole_pos = null_index_hole_pos; d86f_handler[drive].get_raw_size = common_get_raw_size; d86f_handler[drive].check_crc = 1; + d86f_set_version(drive, 0x0063); } diff --git a/src/disc_td0.c b/src/disc_td0.c index ac2cd9a6b..af9963e40 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -545,6 +545,7 @@ void td0_load(int drive, wchar_t *fn) { pclog("TD0: Not a valid Teledisk image\n"); fclose(td0[drive].f); + td0[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -560,6 +561,7 @@ void td0_load(int drive, wchar_t *fn) { pclog("TD0: Failed to initialize\n"); fclose(td0[drive].f); + td0[drive].f = NULL; memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -607,7 +609,10 @@ void td0_close(int drive) } if (td0[drive].f) + { fclose(td0[drive].f); + td0[drive].f = NULL; + } } uint32_t td0_get_raw_tsize(int side_flags, int slower_rpm) @@ -1103,6 +1108,9 @@ void td0_seek(int drive, int track) d86f_reset_index_hole_pos(drive, 0); d86f_reset_index_hole_pos(drive, 1); + d86f_zero_bit_field(drive, 0); + d86f_zero_bit_field(drive, 1); + for (side = 0; side < td0[drive].sides; side++) { track_rate = td0[drive].current_side_flags[side] & 7; @@ -1141,6 +1149,11 @@ void td0_seek(int drive, int track) id[3] = td0[drive].sects[track][side][actual_sector].size; ssize = 128 << ((uint32_t) td0[drive].sects[track][side][actual_sector].size); current_pos = d86f_prepare_sector(drive, side, current_pos, id, td0[drive].sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, td0[drive].sects[track][side][actual_sector].deleted, td0[drive].sects[track][side][actual_sector].bad_crc); + + if (sector == 0) + { + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } } } else @@ -1164,6 +1177,11 @@ void td0_seek(int drive, int track) { current_pos = d86f_prepare_sector(drive, side, current_pos, id, td0[drive].sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], td0[drive].sects[track][side][ordered_pos].deleted, td0[drive].sects[track][side][ordered_pos].bad_crc); } + + if (sector == 0) + { + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } } } } @@ -1201,12 +1219,18 @@ void td0_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_ return; } +uint8_t td0_poll_read_data(int drive, int side, uint16_t pos) +{ + return td0[drive].sects[td0[drive].track][side][td0[drive].current_sector_index[side]].data[pos]; +} + void d86f_register_td0(int drive) { d86f_handler[drive].disk_flags = td0_disk_flags; d86f_handler[drive].side_flags = td0_side_flags; d86f_handler[drive].writeback = null_writeback; d86f_handler[drive].set_sector = td0_set_sector; + d86f_handler[drive].read_data = td0_poll_read_data; d86f_handler[drive].write_data = null_write_data; d86f_handler[drive].format_conditions = null_format_conditions; d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; @@ -1215,4 +1239,5 @@ void d86f_register_td0(int drive) d86f_handler[drive].index_hole_pos = null_index_hole_pos; d86f_handler[drive].get_raw_size = common_get_raw_size; d86f_handler[drive].check_crc = 1; + d86f_set_version(drive, 0x0063); } diff --git a/src/fdd.c b/src/fdd.c index dd6649ee2..1fb1e50ec 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -189,6 +189,11 @@ int fdd_track0(int drive) return !fdd[drive].track; } +int fdd_track(int drive) +{ + return fdd[drive].track; +} + void fdd_set_densel(int densel) { int i = 0; diff --git a/src/fdd.h b/src/fdd.h index e8de9db96..6a28743f4 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -49,3 +49,5 @@ char *fdd_getname(int type); char *fdd_get_internal_name(int type); int fdd_get_from_internal_name(char *s); + +int fdd_track(int drive); diff --git a/src/mouse_bus.c b/src/mouse_bus.c index a47287c24..5d20f2f31 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -389,11 +389,7 @@ static uint8_t busmouse_poll(int x, int y, int z, int b, void *priv) busmouse->mouse_buttons_last = busmouse->mouse_buttons; } - /* if interrupts are on, fire the interrupt */ - if (busmouse->interrupts) - { - picint(1 << busmouse->irq); - } + picint(1 << busmouse->irq); return(0); } diff --git a/src/serial_old.c b/src/serial_old.c index c6bc83e4c..7dbb3e928 100644 --- a/src/serial_old.c +++ b/src/serial_old.c @@ -264,7 +264,7 @@ void serial_remove(int port) return; } - pclog("Removing serial port %i at %04X...\n", port, base_address[port - 1]); + /* pclog("Removing serial port %i at %04X...\n", port, base_address[port - 1]); */ switch(port) { @@ -281,7 +281,7 @@ void serial_remove(int port) void serial_setup(int port, uint16_t addr, int irq) { - pclog("Adding serial port %i at %04X...\n", port, addr); + /* pclog("Adding serial port %i at %04X...\n", port, addr); */ switch(port) { @@ -322,7 +322,7 @@ void serial_init(void) if (serial_enabled[0]) { - pclog("Adding serial port 1...\n"); + /* pclog("Adding serial port 1...\n"); */ memset(&serial1, 0, sizeof(serial1)); io_sethandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); serial1.irq = 4; @@ -331,7 +331,7 @@ void serial_init(void) } if (serial_enabled[1]) { - pclog("Adding serial port 2...\n"); + /* pclog("Adding serial port 2...\n"); */ memset(&serial2, 0, sizeof(serial2)); io_sethandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); serial2.irq = 3;