diff --git a/AltairZ80/altairz80_sio.c b/AltairZ80/altairz80_sio.c index 9e8263ac..786a2184 100644 --- a/AltairZ80/altairz80_sio.c +++ b/AltairZ80/altairz80_sio.c @@ -651,6 +651,8 @@ static SIO_PORT_INFO port_table[PORT_TABLE_SIZE] = { {0x01, 0, 0, 0, 0, FALSE, 0, FALSE, TRUE }, {0x02, 0, VGSIO_CAN_READ, 0, VGSIO_CAN_WRITE, FALSE, 0, TRUE, TRUE }, {0x03, 0, VGSIO_CAN_READ, 0, VGSIO_CAN_WRITE, FALSE, 0, FALSE, TRUE }, + {0x04, 0, VGSIO_CAN_READ, 0, VGSIO_CAN_WRITE, FALSE, 0, TRUE, TRUE }, + {0x05, 0, VGSIO_CAN_READ, 0, VGSIO_CAN_WRITE, FALSE, 0, FALSE, TRUE }, {0x10, 0, SIO_CAN_READ, 0, SIO_CAN_WRITE, TRUE, SIO_RESET, FALSE, TRUE }, {0x11, 0, SIO_CAN_READ, 0, SIO_CAN_WRITE, TRUE, SIO_RESET, TRUE, TRUE }, {0x14, 1, SIO_CAN_READ, 0, SIO_CAN_WRITE, TRUE, SIO_RESET, FALSE, TRUE }, @@ -1634,7 +1636,9 @@ void do_SIMH_sleep(void) { Otherwise there is the possibility that such interrupts are skipped. */ if ((simh_unit.flags & UNIT_SIMH_TIMERON) && rtc_avail && (sim_os_msec() + 1 >= timeOfNextInterrupt)) return; - if (SIMHSleep && !sio_unit.u4) /* time to sleep and SIO not attached to a file */ + if (SIMHSleep && !sio_unit.u4) + /* time to sleep and SIO not attached to a file. + Use 'D SLEEP 0' to disable this functionality when not needed. */ sim_os_ms_sleep(SIMHSleep); } diff --git a/AltairZ80/mfdc.c b/AltairZ80/mfdc.c index 98e1cef3..fa24da3b 100644 --- a/AltairZ80/mfdc.c +++ b/AltairZ80/mfdc.c @@ -235,7 +235,7 @@ static t_stat mfdc_attach(UNIT *uptr, CONST char *cptr) int32 i = 0; r = attach_unit(uptr, cptr); /* attach unit */ - if ( r != SCPE_OK) /* error? */ + if (r != SCPE_OK) /* error? */ return r; /* Determine length of this disk */ @@ -290,7 +290,6 @@ static t_stat mfdc_attach(UNIT *uptr, CONST char *cptr) /* Detach routine */ static t_stat mfdc_detach(UNIT *uptr) { - t_stat r; int8 i; for(i = 0; i < MFDC_MAX_DRIVES; i++) { @@ -307,8 +306,7 @@ static t_stat mfdc_detach(UNIT *uptr) diskClose(&mfdc_info->drive[i].imd); } - r = detach_unit(uptr); /* detach unit */ - return r; + return detach_unit(uptr); /* detach unit */ } diff --git a/AltairZ80/s100_2sio.c b/AltairZ80/s100_2sio.c index fe336079..4725d714 100644 --- a/AltairZ80/s100_2sio.c +++ b/AltairZ80/s100_2sio.c @@ -747,12 +747,12 @@ static int32 m2sio_stat(DEVICE *dptr, int32 io, int32 data) switch (data & M2SIO_RTSMSK) { case M2SIO_RTSLTIE: case M2SIO_RTSLTID: - r = m2sio_config_rts(dptr, 0); /* enable RTS */ + m2sio_config_rts(dptr, 0); /* enable RTS */ break; case M2SIO_RTSHTID: case M2SIO_RTSHTBR: - r = m2sio_config_rts(dptr, 1); /* disable RTS */ + m2sio_config_rts(dptr, 1); /* disable RTS */ break; default: diff --git a/AltairZ80/s100_dj2d.c b/AltairZ80/s100_dj2d.c index fbc04a38..057a1683 100644 --- a/AltairZ80/s100_dj2d.c +++ b/AltairZ80/s100_dj2d.c @@ -23,12 +23,11 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Patrick Linstruth. - *************************************************************************** - ** This device simulates the DISK JOCKEY 2D Model B, not the original 2D ** - ** ** - ** If I can find PROMs and CP/M images for the original 2D, I will add ** - ** support. ** - *************************************************************************** + These functions support the original Morrow DISK JOCKEY 2D (Model A) and + Model B disk controllers. + + The model is selected using the "SET DJ2D MODEL={A|B}" command. The default + is the Model B. DJ2D units: @@ -77,6 +76,7 @@ extern void setClockFrequency(const uint32 Value); enum { FMT_SD, FMT_256, FMT_512, FMT_1024, FMT_UNKNOWN }; static uint32 dj2d_image_size[] = {256256, 509184, 587008, 625920, 0}; +static uint32 dj2d_2s_image_size[] = {512512, 1021696, 1178368, 1256704, 0}; static uint16 dj2d_sector_len[] = {128, 256, 512, 1024, 0}; static uint16 dj2d_spt[] = {26, 26, 15, 8, 0}; static uint16 dj2d_track_len[] = {5000, 9800, 10300, 9700, 0}; @@ -93,9 +93,271 @@ static uint16 dj2d_track_len[] = {5000, 9800, 10300, 9700, 0}; static uint8 dj2d_mem[DJ2D_MEM_SIZE]; -/* DJ2D PROM is 1018 bytes following by 8 memory-mapped I/O bytes */ +/* DJ2D PROM is 1016 bytes following by 8 memory-mapped I/O bytes */ -static uint8 dj2d_prom_e000[DJ2D_PROM_SIZE] = { +static uint8 dj2d_proma_e000[DJ2D_PROM_SIZE] = { + 0xc3, 0x61, 0xe0, 0xc3, 0xff, 0xe0, 0xc3, 0xf0, + 0xe0, 0xc3, 0x6f, 0xe1, 0xc3, 0xa0, 0xe1, 0xc3, + 0x93, 0xe1, 0xc3, 0x56, 0xe1, 0xc3, 0xa9, 0xe1, + 0xc3, 0xfc, 0xe1, 0xc3, 0x4b, 0xe1, 0xc3, 0x0e, + 0xe1, 0xc3, 0x19, 0xe1, 0xc3, 0x43, 0xe1, 0xc3, + 0x1f, 0xe1, 0xc3, 0xdb, 0xe0, 0xc3, 0xbf, 0xe3, + 0xc3, 0xde, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x31, 0xfa, 0xe6, 0x21, 0xe1, 0xe6, 0x11, + 0xeb, 0xe2, 0x06, 0x04, 0x1a, 0xbe, 0xc2, 0x7a, + 0xe0, 0x23, 0x13, 0x05, 0xc2, 0x6c, 0xe0, 0xc3, + 0x7d, 0xe0, 0xcd, 0xe9, 0xe3, 0x21, 0x01, 0x00, + 0xe5, 0x2e, 0x03, 0xe5, 0x26, 0xff, 0xe5, 0xe5, + 0xe5, 0xe5, 0x21, 0x00, 0x00, 0xe5, 0x33, 0x26, + 0x08, 0xe5, 0x26, 0xfe, 0xe5, 0x26, 0xe7, 0xe5, + 0x26, 0x18, 0xe5, 0x3e, 0x03, 0x32, 0xfa, 0xe3, + 0x3e, 0xd0, 0x32, 0xfc, 0xe3, 0xaf, 0xcd, 0x25, + 0xe3, 0xd2, 0xb7, 0xe0, 0x3e, 0x1e, 0x32, 0xea, + 0xe6, 0xcd, 0xe9, 0xe3, 0xc3, 0xa5, 0xe0, 0x3e, + 0x3e, 0x32, 0xea, 0xe6, 0x36, 0x03, 0xe1, 0xcd, + 0xa2, 0xe3, 0xc1, 0xc5, 0xd5, 0x2a, 0xed, 0xe2, + 0xe5, 0x2a, 0xeb, 0xe2, 0xe5, 0x00, 0xc5, 0x06, + 0x0a, 0xc5, 0xcd, 0xa9, 0xe1, 0xc1, 0xd0, 0x05, + 0xc2, 0xd1, 0xe0, 0x0e, 0x3f, 0x11, 0xc3, 0xa2, + 0x1b, 0x7a, 0xb3, 0xc2, 0xe0, 0xe0, 0x3e, 0x20, + 0xa9, 0x32, 0xf9, 0xe3, 0x4f, 0xc3, 0xdd, 0xe0, + 0x3a, 0xf9, 0xe3, 0xe6, 0x08, 0xc2, 0xf0, 0xe0, + 0x79, 0x2f, 0x32, 0xf8, 0xe3, 0x2f, 0xc9, 0x3a, + 0xf9, 0xe3, 0xe6, 0x04, 0xc2, 0xff, 0xe0, 0x3a, + 0xf8, 0xe3, 0x2f, 0xe6, 0x7f, 0xc9, 0x3a, 0xf9, + 0xe3, 0xe6, 0x04, 0xc0, 0xcd, 0xff, 0xe0, 0xb9, + 0xc9, 0x3a, 0xf9, 0xe3, 0xe6, 0x04, 0xc9, 0x3a, + 0xfe, 0xe3, 0x47, 0x3a, 0xfd, 0xe3, 0x4f, 0x3a, + 0xf6, 0xe6, 0x2f, 0xe6, 0x01, 0x0f, 0x57, 0x3a, + 0xf7, 0xe6, 0x07, 0x07, 0x07, 0x82, 0x57, 0x3a, + 0xfd, 0xe6, 0x17, 0x17, 0x82, 0x57, 0x3a, 0xec, + 0xe6, 0x82, 0xc9, 0xe5, 0x2a, 0xe7, 0xe6, 0x44, + 0x4d, 0xe1, 0xc9, 0x3e, 0xfc, 0x81, 0x3e, 0x10, + 0xd8, 0x79, 0x32, 0xeb, 0xe6, 0xc9, 0x21, 0x08, + 0x20, 0x09, 0xd2, 0x68, 0xe1, 0x21, 0x00, 0x1c, + 0x09, 0xda, 0x68, 0xe1, 0x37, 0x3e, 0x10, 0xc9, + 0x60, 0x69, 0x22, 0xe7, 0xe6, 0xaf, 0xc9, 0xcd, + 0x7b, 0xe1, 0xf5, 0x9f, 0x32, 0xf9, 0xe6, 0xf1, + 0xc3, 0x2a, 0xe2, 0xcd, 0xef, 0xe2, 0xd8, 0xaf, + 0x32, 0xed, 0xe6, 0x32, 0xe9, 0xe6, 0x21, 0x00, + 0x00, 0x3e, 0x09, 0xcd, 0x6c, 0xe3, 0xe6, 0x04, + 0xc0, 0x37, 0xc9, 0xaf, 0xb1, 0x37, 0xc8, 0x79, + 0xfe, 0x1b, 0x3f, 0xd8, 0x32, 0xf8, 0xe6, 0xc9, + 0x79, 0xfe, 0x4d, 0x3f, 0xd8, 0x32, 0xf9, 0xe6, + 0xc9, 0xcd, 0x35, 0xe2, 0xe1, 0x3e, 0x40, 0xbb, + 0xca, 0xe8, 0xe1, 0xe5, 0x19, 0x19, 0xe5, 0xf9, + 0x1b, 0x21, 0xff, 0xe3, 0x3e, 0x80, 0x32, 0xfc, + 0xe3, 0x46, 0x4e, 0xc5, 0x46, 0x1d, 0xc2, 0xc2, + 0xe1, 0x15, 0xf2, 0xc2, 0xe1, 0x4e, 0xc5, 0x31, + 0xc6, 0xe6, 0xe1, 0xd1, 0x2b, 0x46, 0x1a, 0x77, + 0x78, 0x12, 0x13, 0x7d, 0xbb, 0xc2, 0xd4, 0xe1, + 0x7c, 0xba, 0xc2, 0xd4, 0xe1, 0xc3, 0x18, 0xe2, + 0x07, 0x4f, 0x11, 0xff, 0xe3, 0x3e, 0x80, 0x32, + 0xfc, 0xe3, 0x1a, 0x77, 0x23, 0x0d, 0xc2, 0xf2, + 0xe1, 0xc3, 0x18, 0xe2, 0xcd, 0x35, 0xe2, 0xe1, + 0xf9, 0x1b, 0x21, 0xff, 0xe3, 0x3e, 0xa0, 0x32, + 0xfc, 0xe3, 0xc1, 0x71, 0x70, 0xc1, 0x71, 0x1d, + 0xc2, 0x0c, 0xe2, 0x15, 0xf2, 0x0c, 0xe2, 0x70, + 0x3a, 0xfc, 0xe3, 0x1f, 0xda, 0x18, 0xe2, 0x17, + 0xe6, 0xdf, 0xca, 0x26, 0xe2, 0x37, 0x2a, 0xca, + 0xe6, 0xf9, 0xf5, 0x3a, 0xf6, 0xe6, 0xee, 0x10, + 0x32, 0xfa, 0xe3, 0xf1, 0xc9, 0xd1, 0x21, 0x00, + 0x00, 0x39, 0x31, 0xcc, 0xe6, 0xe5, 0x2a, 0xe7, + 0xe6, 0xe5, 0xd5, 0x21, 0x26, 0xe2, 0xe5, 0xcd, + 0xef, 0xe2, 0xd8, 0x3a, 0xfd, 0xe3, 0x3c, 0xcc, + 0x7b, 0xe1, 0xda, 0x9f, 0xe2, 0x21, 0xfd, 0xe3, + 0x3a, 0xf9, 0xe6, 0xbe, 0x23, 0x23, 0x77, 0x79, + 0x32, 0xfa, 0xe3, 0xca, 0x7d, 0xe2, 0xaf, 0x32, + 0xe9, 0xe6, 0x3a, 0xfa, 0xe3, 0xe6, 0x08, 0x7f, + 0x1f, 0x1f, 0xc6, 0x18, 0x21, 0x00, 0x00, 0xcd, + 0x6c, 0xe3, 0xda, 0x9f, 0xe2, 0x3a, 0xe9, 0xe6, + 0xb7, 0xc2, 0xc9, 0xe2, 0x06, 0x02, 0x3e, 0x1d, + 0xcd, 0x67, 0xe3, 0xe6, 0x99, 0xca, 0xa5, 0xe2, + 0x3a, 0xf6, 0xe6, 0xee, 0x01, 0x32, 0xf6, 0xe6, + 0x32, 0xfa, 0xe3, 0x05, 0xc2, 0x86, 0xe2, 0xcd, + 0x6f, 0xe1, 0xc3, 0x9e, 0xe3, 0x06, 0x0a, 0x11, + 0xff, 0xe3, 0x21, 0xfa, 0xe6, 0x3e, 0xc4, 0x32, + 0xfc, 0xe3, 0x1a, 0x77, 0x2c, 0xc2, 0xb2, 0xe2, + 0x21, 0xfc, 0xe3, 0xcd, 0x7e, 0xe3, 0xb7, 0xca, + 0xc9, 0xe2, 0x05, 0xc2, 0xa7, 0xe2, 0xc3, 0x9f, + 0xe2, 0x3a, 0xfd, 0xe6, 0x4f, 0x06, 0x00, 0x21, + 0xeb, 0xe2, 0x09, 0x3a, 0xf8, 0xe6, 0x47, 0x86, + 0x3e, 0x10, 0xd8, 0xe1, 0x78, 0x32, 0xfe, 0xe3, + 0x21, 0x40, 0x00, 0x0d, 0x54, 0x5d, 0xf8, 0x29, + 0xc3, 0xe3, 0xe2, 0xe5, 0xe5, 0xf0, 0xf7, 0x21, + 0xeb, 0xe6, 0x4e, 0x23, 0x5e, 0x71, 0x23, 0x7b, + 0xb9, 0x7e, 0x36, 0x04, 0x23, 0xca, 0x25, 0xe3, + 0xe5, 0x16, 0x00, 0x42, 0x19, 0x19, 0x3a, 0xf6, + 0xe6, 0x77, 0x23, 0x11, 0xfd, 0xe3, 0x1a, 0x77, + 0xe1, 0x09, 0x09, 0x7e, 0x32, 0xf6, 0xe6, 0x23, + 0x7e, 0x12, 0x3e, 0x7f, 0x07, 0x0d, 0xf2, 0x1c, + 0xe3, 0x32, 0xea, 0xe6, 0xaf, 0x21, 0xfa, 0xe3, + 0xa6, 0x32, 0xe9, 0xe6, 0xf5, 0x3a, 0xea, 0xe6, + 0x4f, 0x3a, 0xf7, 0xe6, 0x2f, 0xa1, 0x32, 0xf9, + 0xe3, 0x3a, 0xf6, 0xe6, 0x4f, 0x3a, 0xf9, 0xe6, + 0xd6, 0x01, 0x9f, 0x3d, 0x2f, 0xb1, 0x77, 0xee, + 0x02, 0x4f, 0xf1, 0xc2, 0x59, 0xe3, 0xe5, 0x2a, + 0xe5, 0xe6, 0x2b, 0x7c, 0xb5, 0xc2, 0x52, 0xe3, + 0xe1, 0x7e, 0xe6, 0x20, 0xc8, 0x3a, 0xf6, 0xe6, + 0xf6, 0x18, 0x77, 0x3e, 0x80, 0x37, 0xc9, 0x2a, + 0xe5, 0xe6, 0x29, 0x29, 0xeb, 0x21, 0xfc, 0xe3, + 0xc3, 0x76, 0xe3, 0xc3, 0xef, 0xe2, 0x00, 0x00, + 0x77, 0x7e, 0x1f, 0xd2, 0x79, 0xe3, 0x7e, 0x1f, + 0x7e, 0xd0, 0x1b, 0x7a, 0xb3, 0xc2, 0x7e, 0xe3, + 0xe5, 0x23, 0x56, 0x3a, 0xf6, 0xe6, 0xee, 0x04, + 0x32, 0xfa, 0xe3, 0xee, 0x04, 0xe3, 0x32, 0xfa, + 0xe3, 0x36, 0xd0, 0xe3, 0x72, 0xe1, 0x3e, 0x11, + 0x37, 0xc9, 0x11, 0x00, 0x00, 0x21, 0xfa, 0xe3, + 0x0e, 0x10, 0x7e, 0xa1, 0xc2, 0xaa, 0xe3, 0x7e, + 0xa1, 0xca, 0xaf, 0xe3, 0x13, 0xe3, 0xe3, 0xe3, + 0xe3, 0x7e, 0xa1, 0xc2, 0xb4, 0xe3, 0xc9, 0x79, + 0xe6, 0x01, 0x2f, 0x47, 0x21, 0xeb, 0xe6, 0x5e, + 0x16, 0x00, 0x23, 0x7e, 0xab, 0xf5, 0x23, 0x23, + 0x19, 0x19, 0x7e, 0xf6, 0x01, 0xa0, 0x77, 0xf1, + 0xc0, 0x7e, 0x32, 0xf6, 0xe6, 0xc9, 0x79, 0xe6, + 0x01, 0x17, 0x17, 0x17, 0x17, 0x32, 0xf7, 0xe6, + 0xc9, 0x21, 0x00, 0x00, 0x2b, 0x7c, 0xb5, 0xe3, + 0xe3, 0xc2, 0xec, 0xe3, 0xc9, 0xe0, 0x00, 0xc3, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + +static uint8 dj2d_proma_f800[DJ2D_PROM_SIZE] = { + 0xc3, 0x61, 0xf8, 0xc3, 0xff, 0xf8, 0xc3, 0xf0, + 0xf8, 0xc3, 0x6f, 0xf9, 0xc3, 0xa0, 0xf9, 0xc3, + 0x93, 0xf9, 0xc3, 0x56, 0xf9, 0xc3, 0xa9, 0xf9, + 0xc3, 0xfc, 0xf9, 0xc3, 0x4b, 0xf9, 0xc3, 0x0e, + 0xf9, 0xc3, 0x19, 0xf9, 0xc3, 0x43, 0xf9, 0xc3, + 0x1f, 0xf9, 0xc3, 0xdb, 0xf8, 0xc3, 0xbf, 0xfb, + 0xc3, 0xde, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x31, 0xfa, 0xfe, 0x21, 0xe1, 0xfe, 0x11, + 0xeb, 0xfa, 0x06, 0x04, 0x1a, 0xbe, 0xc2, 0x7a, + 0xf8, 0x23, 0x13, 0x05, 0xc2, 0x6c, 0xf8, 0xc3, + 0x7d, 0xf8, 0xcd, 0xe9, 0xfb, 0x21, 0x01, 0x00, + 0xe5, 0x2e, 0x03, 0xe5, 0x26, 0xff, 0xe5, 0xe5, + 0xe5, 0xe5, 0x21, 0x00, 0x00, 0xe5, 0x33, 0x26, + 0x08, 0xe5, 0x26, 0xfe, 0xe5, 0x26, 0xff, 0xe5, + 0x26, 0x18, 0xe5, 0x3e, 0x03, 0x32, 0xfa, 0xfb, + 0x3e, 0xd0, 0x32, 0xfc, 0xfb, 0xaf, 0xcd, 0x25, + 0xfb, 0xd2, 0xb7, 0xf8, 0x3e, 0x1e, 0x32, 0xea, + 0xfe, 0xcd, 0xe9, 0xfb, 0xc3, 0xa5, 0xf8, 0x3e, + 0x3e, 0x32, 0xea, 0xfe, 0x36, 0x03, 0xe1, 0xcd, + 0xa2, 0xfb, 0xc1, 0xc5, 0xd5, 0x2a, 0xed, 0xfa, + 0xe5, 0x2a, 0xeb, 0xfa, 0xe5, 0x00, 0xc5, 0x06, + 0x0a, 0xc5, 0xcd, 0xa9, 0xf9, 0xc1, 0xd0, 0x05, + 0xc2, 0xd1, 0xf8, 0x0e, 0x3f, 0x11, 0xc3, 0xa2, + 0x1b, 0x7a, 0xb3, 0xc2, 0xe0, 0xf8, 0x3e, 0x20, + 0xa9, 0x32, 0xf9, 0xfb, 0x4f, 0xc3, 0xdd, 0xf8, + 0x3a, 0xf9, 0xfb, 0xe6, 0x08, 0xc2, 0xf0, 0xf8, + 0x79, 0x2f, 0x32, 0xf8, 0xfb, 0x2f, 0xc9, 0x3a, + 0xf9, 0xfb, 0xe6, 0x04, 0xc2, 0xff, 0xf8, 0x3a, + 0xf8, 0xfb, 0x2f, 0xe6, 0x7f, 0xc9, 0x3a, 0xf9, + 0xfb, 0xe6, 0x04, 0xc0, 0xcd, 0xff, 0xf8, 0xb9, + 0xc9, 0x3a, 0xf9, 0xfb, 0xe6, 0x04, 0xc9, 0x3a, + 0xfe, 0xfb, 0x47, 0x3a, 0xfd, 0xfb, 0x4f, 0x3a, + 0xf6, 0xfe, 0x2f, 0xe6, 0x01, 0x0f, 0x57, 0x3a, + 0xf7, 0xfe, 0x07, 0x07, 0x07, 0x82, 0x57, 0x3a, + 0xfd, 0xfe, 0x17, 0x17, 0x82, 0x57, 0x3a, 0xec, + 0xfe, 0x82, 0xc9, 0xe5, 0x2a, 0xe7, 0xfe, 0x44, + 0x4d, 0xe1, 0xc9, 0x3e, 0xfc, 0x81, 0x3e, 0x10, + 0xd8, 0x79, 0x32, 0xeb, 0xfe, 0xc9, 0x21, 0x08, + 0x08, 0x09, 0xd2, 0x68, 0xf9, 0x21, 0x00, 0x04, + 0x09, 0xda, 0x68, 0xf9, 0x37, 0x3e, 0x10, 0xc9, + 0x60, 0x69, 0x22, 0xe7, 0xfe, 0xaf, 0xc9, 0xcd, + 0x7b, 0xf9, 0xf5, 0x9f, 0x32, 0xf9, 0xfe, 0xf1, + 0xc3, 0x2a, 0xfa, 0xcd, 0xef, 0xfa, 0xd8, 0xaf, + 0x32, 0xed, 0xfe, 0x32, 0xe9, 0xfe, 0x21, 0x00, + 0x00, 0x3e, 0x09, 0xcd, 0x6c, 0xfb, 0xe6, 0x04, + 0xc0, 0x37, 0xc9, 0xaf, 0xb1, 0x37, 0xc8, 0x79, + 0xfe, 0x1b, 0x3f, 0xd8, 0x32, 0xf8, 0xfe, 0xc9, + 0x79, 0xfe, 0x4d, 0x3f, 0xd8, 0x32, 0xf9, 0xfe, + 0xc9, 0xcd, 0x35, 0xfa, 0xe1, 0x3e, 0x40, 0xbb, + 0xca, 0xe8, 0xf9, 0xe5, 0x19, 0x19, 0xe5, 0xf9, + 0x1b, 0x21, 0xff, 0xfb, 0x3e, 0x80, 0x32, 0xfc, + 0xfb, 0x46, 0x4e, 0xc5, 0x46, 0x1d, 0xc2, 0xc2, + 0xf9, 0x15, 0xf2, 0xc2, 0xf9, 0x4e, 0xc5, 0x31, + 0xc6, 0xfe, 0xe1, 0xd1, 0x2b, 0x46, 0x1a, 0x77, + 0x78, 0x12, 0x13, 0x7d, 0xbb, 0xc2, 0xd4, 0xf9, + 0x7c, 0xba, 0xc2, 0xd4, 0xf9, 0xc3, 0x18, 0xfa, + 0x07, 0x4f, 0x11, 0xff, 0xfb, 0x3e, 0x80, 0x32, + 0xfc, 0xfb, 0x1a, 0x77, 0x23, 0x0d, 0xc2, 0xf2, + 0xf9, 0xc3, 0x18, 0xfa, 0xcd, 0x35, 0xfa, 0xe1, + 0xf9, 0x1b, 0x21, 0xff, 0xfb, 0x3e, 0xa0, 0x32, + 0xfc, 0xfb, 0xc1, 0x71, 0x70, 0xc1, 0x71, 0x1d, + 0xc2, 0x0c, 0xfa, 0x15, 0xf2, 0x0c, 0xfa, 0x70, + 0x3a, 0xfc, 0xfb, 0x1f, 0xda, 0x18, 0xfa, 0x17, + 0xe6, 0xdf, 0xca, 0x26, 0xfa, 0x37, 0x2a, 0xca, + 0xfe, 0xf9, 0xf5, 0x3a, 0xf6, 0xfe, 0xee, 0x10, + 0x32, 0xfa, 0xfb, 0xf1, 0xc9, 0xd1, 0x21, 0x00, + 0x00, 0x39, 0x31, 0xcc, 0xfe, 0xe5, 0x2a, 0xe7, + 0xfe, 0xe5, 0xd5, 0x21, 0x26, 0xfa, 0xe5, 0xcd, + 0xef, 0xfa, 0xd8, 0x3a, 0xfd, 0xfb, 0x3c, 0xcc, + 0x7b, 0xf9, 0xda, 0x9f, 0xfa, 0x21, 0xfd, 0xfb, + 0x3a, 0xf9, 0xfe, 0xbe, 0x23, 0x23, 0x77, 0x79, + 0x32, 0xfa, 0xfb, 0xca, 0x7d, 0xfa, 0xaf, 0x32, + 0xe9, 0xfe, 0x3a, 0xfa, 0xfb, 0xe6, 0x08, 0x7f, + 0x1f, 0x1f, 0xc6, 0x18, 0x21, 0x00, 0x00, 0xcd, + 0x6c, 0xfb, 0xda, 0x9f, 0xfa, 0x3a, 0xe9, 0xfe, + 0xb7, 0xc2, 0xc9, 0xfa, 0x06, 0x02, 0x3e, 0x1d, + 0xcd, 0x67, 0xfb, 0xe6, 0x99, 0xca, 0xa5, 0xfa, + 0x3a, 0xf6, 0xfe, 0xee, 0x01, 0x32, 0xf6, 0xfe, + 0x32, 0xfa, 0xfb, 0x05, 0xc2, 0x86, 0xfa, 0xcd, + 0x6f, 0xf9, 0xc3, 0x9e, 0xfb, 0x06, 0x0a, 0x11, + 0xff, 0xfb, 0x21, 0xfa, 0xfe, 0x3e, 0xc4, 0x32, + 0xfc, 0xfb, 0x1a, 0x77, 0x2c, 0xc2, 0xb2, 0xfa, + 0x21, 0xfc, 0xfb, 0xcd, 0x7e, 0xfb, 0xb7, 0xca, + 0xc9, 0xfa, 0x05, 0xc2, 0xa7, 0xfa, 0xc3, 0x9f, + 0xfa, 0x3a, 0xfd, 0xfe, 0x4f, 0x06, 0x00, 0x21, + 0xeb, 0xfa, 0x09, 0x3a, 0xf8, 0xfe, 0x47, 0x86, + 0x3e, 0x10, 0xd8, 0xe1, 0x78, 0x32, 0xfe, 0xfb, + 0x21, 0x40, 0x00, 0x0d, 0x54, 0x5d, 0xf8, 0x29, + 0xc3, 0xe3, 0xfa, 0xe5, 0xe5, 0xf0, 0xf7, 0x21, + 0xeb, 0xfe, 0x4e, 0x23, 0x5e, 0x71, 0x23, 0x7b, + 0xb9, 0x7e, 0x36, 0x04, 0x23, 0xca, 0x25, 0xfb, + 0xe5, 0x16, 0x00, 0x42, 0x19, 0x19, 0x3a, 0xf6, + 0xfe, 0x77, 0x23, 0x11, 0xfd, 0xfb, 0x1a, 0x77, + 0xe1, 0x09, 0x09, 0x7e, 0x32, 0xf6, 0xfe, 0x23, + 0x7e, 0x12, 0x3e, 0x7f, 0x07, 0x0d, 0xf2, 0x1c, + 0xfb, 0x32, 0xea, 0xfe, 0xaf, 0x21, 0xfa, 0xfb, + 0xa6, 0x32, 0xe9, 0xfe, 0xf5, 0x3a, 0xea, 0xfe, + 0x4f, 0x3a, 0xf7, 0xfe, 0x2f, 0xa1, 0x32, 0xf9, + 0xfb, 0x3a, 0xf6, 0xfe, 0x4f, 0x3a, 0xf9, 0xfe, + 0xd6, 0x01, 0x9f, 0x3d, 0x2f, 0xb1, 0x77, 0xee, + 0x02, 0x4f, 0xf1, 0xc2, 0x59, 0xfb, 0xe5, 0x2a, + 0xe5, 0xfe, 0x2b, 0x7c, 0xb5, 0xc2, 0x52, 0xfb, + 0xe1, 0x7e, 0xe6, 0x20, 0xc8, 0x3a, 0xf6, 0xfe, + 0xf6, 0x18, 0x77, 0x3e, 0x80, 0x37, 0xc9, 0x2a, + 0xe5, 0xfe, 0x29, 0x29, 0xeb, 0x21, 0xfc, 0xfb, + 0xc3, 0x76, 0xfb, 0xc3, 0xef, 0xfa, 0x00, 0x00, + 0x77, 0x7e, 0x1f, 0xd2, 0x79, 0xfb, 0x7e, 0x1f, + 0x7e, 0xd0, 0x1b, 0x7a, 0xb3, 0xc2, 0x7e, 0xfb, + 0xe5, 0x23, 0x56, 0x3a, 0xf6, 0xfe, 0xee, 0x04, + 0x32, 0xfa, 0xfb, 0xee, 0x04, 0xe3, 0x32, 0xfa, + 0xfb, 0x36, 0xd0, 0xe3, 0x72, 0xe1, 0x3e, 0x11, + 0x37, 0xc9, 0x11, 0x00, 0x00, 0x21, 0xfa, 0xfb, + 0x0e, 0x10, 0x7e, 0xa1, 0xc2, 0xaa, 0xfb, 0x7e, + 0xa1, 0xca, 0xaf, 0xfb, 0x13, 0xe3, 0xe3, 0xe3, + 0xe3, 0x7e, 0xa1, 0xc2, 0xb4, 0xfb, 0xc9, 0x79, + 0xe6, 0x01, 0x2f, 0x47, 0x21, 0xeb, 0xfe, 0x5e, + 0x16, 0x00, 0x23, 0x7e, 0xab, 0xf5, 0x23, 0x23, + 0x19, 0x19, 0x7e, 0xf6, 0x01, 0xa0, 0x77, 0xf1, + 0xc0, 0x7e, 0x32, 0xf6, 0xfe, 0xc9, 0x79, 0xe6, + 0x01, 0x17, 0x17, 0x17, 0x17, 0x32, 0xf7, 0xfe, + 0xc9, 0x21, 0x00, 0x00, 0x2b, 0x7c, 0xb5, 0xe3, + 0xe3, 0xc2, 0xec, 0xfb, 0xc9, 0xf8, 0x00, 0xc3, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + +static uint8 dj2d_promb_e000[DJ2D_PROM_SIZE] = { 0xc3, 0x69, 0xe0, 0xc3, 0xe9, 0xe0, 0xc3, 0xda, 0xe0, 0xc3, 0x5a, 0xe1, 0xc3, 0x8b, 0xe1, 0xc3, 0x81, 0xe1, 0xc3, 0x43, 0xe1, 0xc3, 0xdd, 0xe1, @@ -226,7 +488,7 @@ static uint8 dj2d_prom_e000[DJ2D_PROM_SIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -static uint8 dj2d_prom_f800[DJ2D_PROM_SIZE] = { +static uint8 dj2d_promb_f800[DJ2D_PROM_SIZE] = { 0xc3, 0x69, 0xf8, 0xc3, 0xe9, 0xf8, 0xc3, 0xda, 0xf8, 0xc3, 0x5a, 0xf9, 0xc3, 0x8b, 0xf9, 0xc3, 0x81, 0xf9, 0xc3, 0x43, 0xf9, 0xc3, 0xdd, 0xf9, @@ -358,7 +620,7 @@ static uint8 dj2d_prom_f800[DJ2D_PROM_SIZE] = { }; /* PROM selection (default E000) */ -uint8 *dj2d_prom = dj2d_prom_e000; +uint8 *dj2d_prom = dj2d_promb_e000; /* ** Western Digital WD1791 Registers and Interface Controls @@ -396,6 +658,7 @@ typedef struct { uint8 status; /* Disk Jockey status register */ uint8 control; /* Disk Jockey control register */ uint8 function; /* Disk Jockey function register */ + uint8 led; /* Disk Jockey LED status */ } DJ2D_REG; #define WD1791_STAT_NOTREADY 0x80 @@ -436,20 +699,22 @@ typedef struct { int32 conn; /* Connected Status */ TMLN *tmln; /* TMLN pointer */ TMXR *tmxr; /* TMXR pointer */ + uint8 modelB; /* Model B? */ + uint8 promEnabled; /* PROM is enabled */ uint32 ticks; /* Timer ticks */ uint32 sioticks; /* SIO Timer ticks */ uint16 headTimeout; /* Head unload timer tick value */ uint16 indexTimeout; /* Index timer tick value */ uint16 busyTimeout; /* Busy timer tick value */ - uint8 promEnabled; /* PROM is enabled */ uint8 writeProtect; /* Write Protect is enabled */ uint8 currentDrive; /* currently selected drive */ uint8 secsPerTrack; /* sectors per track */ uint16 bytesPerTrack; /* bytes per track */ + uint8 sides2[DJ2D_MAX_DRIVES]; /* double sided flag */ uint8 headLoaded[DJ2D_MAX_DRIVES]; /* Head Loaded */ uint8 format[DJ2D_MAX_DRIVES]; /* Attached disk format */ uint16 sectorLen[DJ2D_MAX_DRIVES]; /* Attached disk sector length */ - uint8 side[DJ2D_MAX_DRIVES]; /* side 0 or side 1 */ + uint8 side[DJ2D_MAX_DRIVES]; /* side 0 or 1 */ WD1791_REG WD1791; /* WD1791 Registers and Data */ DJ2D_REG DJ2D; /* DJ2D Registers and Data */ UNIT *uptr[DJ2D_UNITS]; @@ -460,7 +725,9 @@ static DJ2D_INFO dj2d_info_data = { DJ2D_MEM_BASE, DJ2D_MEM_SIZE, DJ2D_PROM_BASE, DJ2D_PROM_SIZE, 0, dj2d_tmln, &dj2d_tmxr, - 0, 0, 0 + TRUE, TRUE, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + {0, 0, 0, 0} }; static DJ2D_INFO *dj2d_info = &dj2d_info_data; @@ -480,6 +747,14 @@ static uint8 sdata[1024]; /* Sector data buffer */ #define DJ2D_REG_1791_SECTOR 0x06 /* Register 6 */ #define DJ2D_REG_1791_DATA 0x07 /* Register 7 */ +/* DJ2D MODEL A/B */ +#define DJ2D_STAT_PE 0x01 /* Parity Error */ +#define DJ2D_STAT_OE 0x02 /* Overrun Error */ +#define DJ2D_STAT_DR 0x04 /* Data Ready */ +#define DJ2D_STAT_TBRE 0x08 /* TBRE */ +#define DJ2D_STAT_FE 0x10 /* Framing Error */ + +/* DJ2D MODEL B */ #define DJ2D_STAT_HEAD 0x01 /* HEAD */ #define DJ2D_STAT_DATARQ 0x02 /* DATARQ */ #define DJ2D_STAT_INTRQ 0x04 /* INTRQ */ @@ -487,12 +762,6 @@ static uint8 sdata[1024]; /* Sector data buffer */ #define DJ2D_STAT_INDEX 0x10 /* INDEX */ #define DJ2D_STAT_READY 0x80 /* READY */ -#define DJ2D_STAT_PE 0x01 /* Parity Error */ -#define DJ2D_STAT_OE 0x02 /* Overrun Error */ -#define DJ2D_STAT_DR 0x04 /* Data Ready */ -#define DJ2D_STAT_TBRE 0x08 /* TBRE */ -#define DJ2D_STAT_FE 0x10 /* Framing Error */ - #define DJ2D_CTRL_DSEL 0x0f /* Drive Select Mask */ #define DJ2D_CTRL_SIDE0 0x10 /* Side 0 Select */ #define DJ2D_CTRL_INTDSBL 0x20 /* Interrupt Disable */ @@ -504,9 +773,28 @@ static uint8 sdata[1024]; /* Sector data buffer */ #define DJ2D_FUNC_HDLOAD 0x00 /* Head Loaded */ #define DJ2D_FUNC_HDUNLD 0x06 /* Head Unloaded */ #define DJ2D_FUNC_LEDOFF 0x08 /* LED Off */ -#define DJ2D_FUNC_VCOFF 0x20 /* VCO Off */ -/* DJ2D Commands */ +/* DJ2D MODEL A */ +#define DJ2DA_STAT_INTRQ 0x01 /* INTRQ */ +#define DJ2DA_STAT_DATARQ 0x02 /* DATARQ */ +#define DJ2DA_STAT_HEAD 0x04 /* HEAD */ +#define DJ2DA_STAT_N2SIDED 0x08 /* NOT 2 SIDED */ +#define DJ2DA_STAT_NINDEX 0x10 /* NOT INDEX */ +#define DJ2DA_STAT_NREADY 0x20 /* NOT READY */ + +#define DJ2DA_CTRL_DSEL 0x0f /* Drive Select Mask */ +#define DJ2DA_CTRL_SIDE0 0x10 /* Side 0 Select */ +#define DJ2DA_CTRL_LEDOFF 0x20 /* LED Off */ + +#define DJ2DA_FUNC_SINGLE 0x01 /* Single Density */ +#define DJ2DA_FUNC_AENBL 0x02 /* AENBL */ +#define DJ2DA_FUNC_CLRFDC 0x04 /* Reset 1791 */ +#define DJ2DA_FUNC_HDMASK 0x18 /* Head Mask */ +#define DJ2DA_FUNC_HDLOAD 0x00 /* Head Loaded */ +#define DJ2DA_FUNC_HDUNLD 0x18 /* Head Unloaded */ +#define DJ2DA_FUNC_VCOFF 0x20 /* VCOFF */ + +/* WD1791 Commands */ #define WD1791_CMD_RESTORE 0x00 #define WD1791_CMD_SEEK 0x10 #define WD1791_CMD_STEP 0x20 @@ -562,16 +850,21 @@ static t_stat dj2d_detach(UNIT *uptr); static t_stat dj2d_boot(int32 unitno, DEVICE *dptr); static t_stat dj2d_set_prombase(UNIT *uptr, int32 val, CONST char *cptr, void *desc); static t_stat dj2d_show_prombase(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +static t_stat dj2d_set_model(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +static t_stat dj2d_show_model(FILE *st, UNIT *uptr, int32 val, CONST void *desc); static t_stat dj2d_set_prom(UNIT *uptr, int32 val, CONST char *cptr, void *desc); static t_stat dj2d_show_prom(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +static t_stat dj2d_set_sides(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +static t_stat dj2d_show_sides(FILE *st, UNIT *uptr, int32 val, CONST void *desc); static t_stat dj2d_set_baud(UNIT *uptr, int32 value, const char *cptr, void *desc); static t_stat dj2d_show_baud(FILE *st, UNIT *uptr, int32 value, const void *desc); static t_stat dj2d_config_line(void); static uint16 sector_len(uint8 drive, uint8 track); static uint32 secs_per_track(uint8 track); static uint32 bytes_per_track(uint8 track); -static uint32 calculate_dj2d_sec_offset(uint8 track, uint8 sector); +static t_offset calculate_dj2d_sec_offset(uint8 track, uint8 sector); static void DJ2D_HeadLoad(UNIT *uptr, WD1791_REG *pWD1791, uint8 load); +static void DJ2D_LED(DJ2D_REG *pDJ2D, int status); static uint8 DJ2D_Read(uint32 Addr); static uint8 DJ2D_Write(uint32 Addr, int32 data); static const char * DJ2D_CommandString(uint8 command); @@ -625,6 +918,7 @@ static REG dj2d_reg[] = { { HRDATAD (UTXP, dj2d_info_data.DJ2D.uart_txp, 8, "UART TX data pending"), }, { HRDATAD (USTAT, dj2d_info_data.DJ2D.uart_status, 8, "UART status register"), }, { DRDATAD (BAUD, dj2d_info_data.DJ2D.uart_baud, 16, "UART baud rate"), }, + { FLDATAD (LED, dj2d_info_data.DJ2D.led, 0, "LED status"), }, { NULL } }; @@ -645,6 +939,10 @@ static MTAB dj2d_mod[] = { &dj2d_set_prom, &dj2d_show_prom, NULL, "Set/Show PROM enabled/disabled status"}, { MTAB_XTD|MTAB_VDV, 0, "PROMBASE", "PROMBASE", &dj2d_set_prombase, &dj2d_show_prombase, NULL, "Sets PROM base address" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "MODEL", "MODEL={A|B}", + &dj2d_set_model, &dj2d_show_model, NULL, "Set/Show the current controller model" }, + { MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "SIDES", "SIDES={1|2}", + &dj2d_set_sides, &dj2d_show_sides, NULL, "Set/Show the current drive sides" }, { UNIT_DJ2D_WPROTECT, 0, "WRTENB", "WRTENB", NULL, NULL, NULL, "Enables " DJ2D_SNAME "n for writing" }, { UNIT_DJ2D_WPROTECT, UNIT_DJ2D_WPROTECT, "WRTPROT", "WRTPROT", NULL, NULL, NULL, @@ -744,6 +1042,7 @@ static t_stat dj2d_reset(DEVICE *dptr) pInfo->DJ2D.uart_status = DJ2D_STAT_TBRE; pInfo->DJ2D.uart_txp = FALSE; pInfo->DJ2D.uart_baud = DJ2D_BAUD; + pInfo->DJ2D.led = FALSE; pInfo->WD1791.track = 0; pInfo->WD1791.sector = 1; @@ -931,9 +1230,17 @@ static t_stat dj2d_set_prombase(UNIT *uptr, int32 val, CONST char *cptr, void *d } if (newba == 0xe000) { - dj2d_prom = dj2d_prom_e000; + if (dj2d_info->modelB) { + dj2d_prom = dj2d_promb_e000; + } else { + dj2d_prom = dj2d_proma_e000; + } } else { - dj2d_prom = dj2d_prom_f800; + if (dj2d_info->modelB) { + dj2d_prom = dj2d_promb_f800; + } else { + dj2d_prom = dj2d_proma_f800; + } } return dj2d_reset(&dj2d_dev); @@ -962,6 +1269,77 @@ t_stat dj2d_show_prombase(FILE *st, UNIT *uptr, int32 val, CONST void *desc) return SCPE_OK; } +static t_stat dj2d_set_model(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + char base[5]; + + if (!cptr) return SCPE_IERR; + + /* this assumes that the parameter has already been upcased */ + if (!strcmp(cptr, "B")) { + dj2d_info->modelB = TRUE; + } else if (!strcmp(cptr, "A")) { + dj2d_info->modelB = FALSE; + } else { + return SCPE_ARG; + } + + sprintf(base, "%04x", dj2d_info->prom_base); + + dj2d_set_prombase(uptr, dj2d_info->prom_base, base, "PROMBASE"); + + return SCPE_OK; +} + +static t_stat dj2d_show_model(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + fprintf(st, "MODEL=%s", (dj2d_info->modelB) ? "B" : "A"); + + return SCPE_OK; +} + +static t_stat dj2d_set_sides(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int i; + + if (!cptr) return SCPE_IERR; + + for (i = 0; i < DJ2D_MAX_DRIVES; i++) { + if (dj2d_info->uptr[i] == uptr) { + break; + } + } + + /* this assumes that the parameter has already been upcased */ + if (i < DJ2D_MAX_DRIVES) { + if (!strcmp(cptr, "1")) { + dj2d_info->sides2[i] = FALSE; + } else if (!strcmp(cptr, "2")) { + dj2d_info->sides2[i] = TRUE; + } else { + return SCPE_ARG; + } + + return SCPE_OK; + } + + return SCPE_ARG; +} + +static t_stat dj2d_show_sides(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + int i; + + for (i = 0; i < DJ2D_MAX_DRIVES; i++) { + if (dj2d_info->uptr[i] == uptr) { + fprintf(st, "SIDES=%d", (dj2d_info->sides2[i]) ? 2 : 1); + break; + } + } + + return SCPE_OK; +} + /* Attach routine */ static t_stat dj2d_attach(UNIT *uptr, CONST char *cptr) { @@ -1001,15 +1379,21 @@ static t_stat dj2d_attach(UNIT *uptr, CONST char *cptr) /* Default is 1024 byte sectors */ dj2d_info->format[i] = FMT_1024; dj2d_info->sectorLen[i] = dj2d_sector_len[FMT_1024]; + dj2d_info->sides2[i] = FALSE; for (f = 0; f < FMT_UNKNOWN; f++) { if (uptr->capac == dj2d_image_size[f]) { dj2d_info->format[i] = f; dj2d_info->sectorLen[i] = dj2d_sector_len[f]; + dj2d_info->sides2[i] = FALSE; + } else if (uptr->capac == dj2d_2s_image_size[f]) { + dj2d_info->format[i] = f; + dj2d_info->sectorLen[i] = dj2d_sector_len[f]; + dj2d_info->sides2[i] = TRUE; } } - sim_debug(DEBUG_MSG, &dj2d_dev, DJ2D_SNAME ": ATTACH drive=%d uptr->capac=%d format=%d sectorLen=%d\n", i, uptr->capac, dj2d_info->format[i], dj2d_info->sectorLen[i]); + sim_debug(DEBUG_MSG, &dj2d_dev, DJ2D_SNAME ": ATTACH drive=%d uptr->capac=%d format=%d sectorLen=%d 2sided=%d\n", i, uptr->capac, dj2d_info->format[i], dj2d_info->sectorLen[i], dj2d_info->sides2[i]); /* Default for new file is DSK */ uptr->u3 = IMAGE_TYPE_DSK; @@ -1176,7 +1560,11 @@ static void showdata(int32 isRead) { sim_debug(isRead ? RD_DATA_DETAIL_MSG : WR_DATA_DETAIL_MSG, &dj2d_dev, "\n\t"); } } - sim_debug(RD_DATA_DETAIL_MSG|WR_DATA_DETAIL_MSG, &dj2d_dev, "\n"); + if (isRead) { + sim_debug(RD_DATA_DETAIL_MSG, &dj2d_dev, "\n"); + } else { + sim_debug(WR_DATA_DETAIL_MSG, &dj2d_dev, "\n"); + } } static uint16 sector_len(uint8 drive, uint8 track) @@ -1214,9 +1602,9 @@ static uint32 bytes_per_track(uint8 track) return dj2d_info->bytesPerTrack; } -static uint32 calculate_dj2d_sec_offset(uint8 track, uint8 sector) +static t_offset calculate_dj2d_sec_offset(uint8 track, uint8 sector) { - uint32 offset; + t_offset offset; uint8 ds; uint8 format; @@ -1247,7 +1635,7 @@ static uint32 calculate_dj2d_sec_offset(uint8 track, uint8 sector) */ offset += (sector-1) * dj2d_sector_len[format]; - sim_debug(DEBUG_MSG, &dj2d_dev, DJ2D_SNAME ": OFFSET=%d drive=%d side=%d format=%d track=%03d sector=%03d\r\n", offset, dj2d_info->currentDrive, ds, dj2d_info->format[dj2d_info->currentDrive], track, sector); + sim_debug(DEBUG_MSG, &dj2d_dev, DJ2D_SNAME ": OFFSET=%08llx drive=%d side=%d format=%d track=%03d sector=%03d\r\n", offset, dj2d_info->currentDrive, ds, dj2d_info->format[dj2d_info->currentDrive], track, sector); return (offset); } @@ -1278,6 +1666,15 @@ static void DJ2D_HeadLoad(UNIT *uptr, WD1791_REG *pWD1791, uint8 load) dj2d_info->headLoaded[dj2d_info->currentDrive] = load; } +static void DJ2D_LED(DJ2D_REG *pDJ2D, int status) +{ + if (pDJ2D->led != status) { + sim_debug(STATUS_MSG, &dj2d_dev, DJ2D_SNAME ": LED %s.\n", (status) ? "ON" : "OFF"); + } + + pDJ2D->led = status; +} + static uint8 DJ2D_Read(uint32 Addr) { uint8 cData; @@ -1306,12 +1703,21 @@ static uint8 DJ2D_Read(uint32 Addr) break; case DJ2D_REG_2D_STATUS: - cData = (pWD1791->intrq) ? DJ2D_STAT_INTRQ : 0; - cData |= (pWD1791->drq) ? DJ2D_STAT_DATARQ : 0; - cData |= (pWD1791->index) ? DJ2D_STAT_INDEX : 0; - cData |= (dj2d_info->headLoaded[dj2d_info->currentDrive]) ? DJ2D_STAT_HEAD : 0; - cData |= (pWD1791->status & WD1791_STAT_NOTREADY) ? 0 : DJ2D_STAT_READY; - cData |= DJ2D_STAT_N2SIDED; + if (dj2d_info->modelB) { + cData = (pWD1791->intrq) ? DJ2D_STAT_INTRQ : 0; + cData |= (pWD1791->drq) ? DJ2D_STAT_DATARQ : 0; + cData |= (pWD1791->index) ? DJ2D_STAT_INDEX : 0; + cData |= (dj2d_info->headLoaded[dj2d_info->currentDrive]) ? DJ2D_STAT_HEAD : 0; + cData |= (pWD1791->status & WD1791_STAT_NOTREADY) ? 0 : DJ2D_STAT_READY; + cData |= (dj2d_info->sides2[dj2d_info->currentDrive]) ? 0 : DJ2D_STAT_N2SIDED; + } else { + cData = (pWD1791->intrq) ? DJ2DA_STAT_INTRQ : 0; + cData |= (pWD1791->drq) ? DJ2DA_STAT_DATARQ : 0; + cData |= (pWD1791->index) ? 0 : DJ2DA_STAT_NINDEX; + cData |= (dj2d_info->headLoaded[dj2d_info->currentDrive]) ? DJ2DA_STAT_HEAD : 0; + cData |= (pWD1791->status & WD1791_STAT_NOTREADY) ? DJ2DA_STAT_NREADY : 0; + cData |= (dj2d_info->sides2[dj2d_info->currentDrive]) ? 0 : DJ2D_STAT_N2SIDED; + } pDJ2D->status = cData; break; @@ -1419,17 +1825,35 @@ static uint8 DJ2D_Write(uint32 Addr, int32 Data) case DJ2D_REG_2D_FUNCTION: pDJ2D->function = Data; - switch (Data & DJ2D_FUNC_HDMASK) { - case DJ2D_FUNC_HDLOAD: - DJ2D_HeadLoad(uptr, pWD1791, TRUE); - break; + if (dj2d_info->modelB) { + switch (Data & DJ2D_FUNC_HDMASK) { + case DJ2D_FUNC_HDLOAD: + DJ2D_HeadLoad(uptr, pWD1791, TRUE); + break; - case DJ2D_FUNC_HDUNLD: - DJ2D_HeadLoad(uptr, pWD1791, FALSE); - break; + case DJ2D_FUNC_HDUNLD: + DJ2D_HeadLoad(uptr, pWD1791, FALSE); + break; - default: - break; + default: + break; + } + + DJ2D_LED(pDJ2D, !(Data & DJ2D_FUNC_LEDOFF)); + + } else { + switch (Data & DJ2DA_FUNC_HDMASK) { + case DJ2DA_FUNC_HDLOAD: + DJ2D_HeadLoad(uptr, pWD1791, TRUE); + break; + + case DJ2DA_FUNC_HDUNLD: + DJ2D_HeadLoad(uptr, pWD1791, FALSE); + break; + + default: + break; + } } break; @@ -1479,6 +1903,8 @@ static uint8 DJ2D_Write(uint32 Addr, int32 Data) if (pWD1791->dataCount == sector_len(driveNum, pWD1791->track)) { pWD1791->status &= ~WD1791_STAT_WRITEFAULT; /* Clear Status Bit */ + showdata(FALSE); + rtn = DJ2D_WriteSector(uptr, pWD1791->track, pWD1791->sector, sdata); if (rtn != sector_len(driveNum, pWD1791->track)) { @@ -1489,17 +1915,17 @@ static uint8 DJ2D_Write(uint32 Addr, int32 Data) sim_debug(DEBUG_MSG, &dj2d_dev, DJ2D_SNAME ": WRITE TRACK drive=%d track=%03d sector=%03d trkcount=%d datacount=%d data=%02X status=%02X\n", driveNum, pWD1791->track, pWD1791->sector, pWD1791->trkCount, pWD1791->dataCount, pWD1791->data, pWD1791->status); pWD1791->dataCount = 0; - pWD1791->idAddrMrk = 0; - pWD1791->dataAddrMrk = 0; + pWD1791->idAddrMrk = FALSE; + pWD1791->dataAddrMrk = FALSE; if (pWD1791->sector < secs_per_track(pWD1791->track)) { pWD1791->sector++; } } } else if (pWD1791->data == 0xFE) { - pWD1791->idAddrMrk = 1; + pWD1791->idAddrMrk = TRUE; } else if (pWD1791->data == 0xFB) { - pWD1791->dataAddrMrk = 1; + pWD1791->dataAddrMrk = TRUE; } /* @@ -1513,12 +1939,6 @@ static uint8 DJ2D_Write(uint32 Addr, int32 Data) pWD1791->intrq = TRUE; pWD1791->writeTrkActive = FALSE; - /* - ** Last track, truncate file size in case it shrank - */ - if (pWD1791->track == 76) { - sim_set_fsize(uptr->fileref, (t_addr)sim_ftell(uptr->fileref)); - } sim_debug(WR_DATA_MSG, &dj2d_dev, DJ2D_SNAME ": WRITE TRACK COMPLETE track=%03d sector=%03d trkcount=%d datacount=%d data=%02X status=%02X\n", pWD1791->track, pWD1791->sector, pWD1791->trkCount, pWD1791->dataCount, pWD1791->data, pWD1791->status); } @@ -1555,7 +1975,11 @@ static uint8 DJ2D_Write(uint32 Addr, int32 Data) } /* Side */ - dj2d_info->side[cData] = (Data & DJ2D_CTRL_SIDE0) == 0x00; + if (dj2d_info->sides2[cData]) { + dj2d_info->side[cData] = (Data & DJ2D_CTRL_SIDE0) == 0x00; + } else { + dj2d_info->side[cData] = FALSE; + } if (dj2d_info->currentDrive != cData) { sim_debug(STATUS_MSG, &dj2d_dev, DJ2D_SNAME ": Current drive now %d side %d\n", cData, dj2d_info->side[cData]); @@ -1563,6 +1987,26 @@ static uint8 DJ2D_Write(uint32 Addr, int32 Data) dj2d_info->currentDrive = cData; + if (dj2d_info->modelB) { + if (Data & DJ2D_CTRL_RESET) { + /* Reset 1791 */ + pWD1791->status = 0x00; + pWD1791->track = 0; + pWD1791->dataCount = 0; + pWD1791->trkCount = 0; + pWD1791->readActive = FALSE; + pWD1791->readTrkActive = FALSE; + pWD1791->writeActive = FALSE; + pWD1791->writeTrkActive = FALSE; + pWD1791->addrActive = FALSE; + pWD1791->dataAddrMrk = FALSE; + pWD1791->idAddrMrk = FALSE; + pWD1791->drq = FALSE; + pWD1791->intrq = FALSE; + } + } else { + DJ2D_LED(pDJ2D, !(Data & DJ2DA_CTRL_LEDOFF)); + } break; default: @@ -1587,7 +2031,7 @@ static uint32 DJ2D_ReadSector(UNIT *uptr, uint8 track, uint8 sector, uint8 *buff return 0; } - sec_offset = calculate_dj2d_sec_offset(track, sector); + sec_offset = (uint32)calculate_dj2d_sec_offset(track, sector); len = sector_len(dj2d_info->currentDrive, track); @@ -1605,7 +2049,7 @@ static uint32 DJ2D_ReadSector(UNIT *uptr, uint8 track, uint8 sector, uint8 *buff static uint32 DJ2D_WriteSector(UNIT *uptr, uint8 track, uint8 sector, uint8 *buffer) { - uint32 sec_offset; + t_offset sec_offset; uint32 len; uint32 rtn = 0; @@ -1618,14 +2062,14 @@ static uint32 DJ2D_WriteSector(UNIT *uptr, uint8 track, uint8 sector, uint8 *buf len = sector_len(dj2d_info->currentDrive, track); - sim_debug(WR_DATA_MSG, &dj2d_dev, DJ2D_SNAME ": WRITESEC track %03d sector %03d at offset %04X len %d\n", track, sector, sec_offset, len); - - if (sim_fseek(uptr->fileref, sec_offset, SEEK_SET) != 0) { + if (sim_fseek(uptr->fileref, (t_addr)sec_offset, SEEK_SET) != 0) { sim_debug(ERROR_MSG, &dj2d_dev, DJ2D_SNAME ": WRITESEC sim_fseek error.\n"); return 0; } rtn = sim_fwrite(buffer, 1, len, uptr->fileref); + + sim_debug(WR_DATA_MSG, &dj2d_dev, DJ2D_SNAME ": WRITESEC track %03d sector %03d at offset %08llX len %d rtn=%d\n", track, sector, sec_offset, len, rtn); return rtn; } diff --git a/AltairZ80/s100_hayes.c b/AltairZ80/s100_hayes.c index 5467cf60..27c419f9 100644 --- a/AltairZ80/s100_hayes.c +++ b/AltairZ80/s100_hayes.c @@ -538,7 +538,7 @@ static t_stat hayes_set_dtr(UNIT *uptr, int32 flag) static int32 hayes_io(int32 addr, int32 io, int32 data) { - int32 r; + int32 r = 0; addr &= 0xff; data &= 0xff; diff --git a/AltairZ80/s100_hdc1001.c b/AltairZ80/s100_hdc1001.c index e4dffa2a..63b798b3 100644 --- a/AltairZ80/s100_hdc1001.c +++ b/AltairZ80/s100_hdc1001.c @@ -348,6 +348,8 @@ static t_stat hdc1001_unit_set_geometry(UNIT* uptr, int32 value, CONST char* cpt return SCPE_ARG; result = sscanf(cptr, "C:%hd/H:%hd/S:%hd/N:%hd", &newCyls, &newHeads, &newSPT, &newSecLen); + if (result != 4) + return SCPE_ARG; /* Validate Cyl, Heads, Sector, Length are valid for the HDC-1001 */ if (newCyls < 1 || newCyls > HDC1001_MAX_CYLS) { @@ -624,7 +626,6 @@ static t_stat HDC1001_doCommand(void) /* Fall through */ case HDC1001_CMD_READ_SECT: { - uint32 track_len; uint32 xfr_len; uint32 file_offset; uint8 rwopts; /* Options specified in the command: DMA, Multi-sector, long. */ @@ -632,8 +633,6 @@ static t_stat HDC1001_doCommand(void) /* Abort the read/write operation if C/H/S/N is not valid. */ if (HDC1001_Validate_CHSN(pDrive) != SCPE_OK) break; - track_len = pDrive->nsectors * pDrive->sectsize; - /* Calculate file offset */ file_offset = (pDrive->cur_cyl * pDrive->nheads * pDrive->nsectors); /* Full cylinders */ file_offset += (pDrive->cur_head * pDrive->nsectors); /* Add full heads */ diff --git a/AltairZ80/s100_icom.c b/AltairZ80/s100_icom.c index 6f1768f6..715775d2 100644 --- a/AltairZ80/s100_icom.c +++ b/AltairZ80/s100_icom.c @@ -1040,7 +1040,6 @@ static uint8 ICOM_Read(uint32 Addr) ICOM_REG *pICOM; UNIT *uptr; - cData = 0; driveNum = icom_info->currentDrive; uptr = icom_info->uptr[driveNum]; pICOM = &icom_info->ICOM; @@ -1250,7 +1249,6 @@ static uint8 ICOM_Command(UNIT *uptr, ICOM_REG *pICOM, int32 Data) { uint8 cData; uint8 newTrack; - uint8 drive; int32 rtn; cData = 0; @@ -1261,8 +1259,6 @@ static uint8 ICOM_Command(UNIT *uptr, ICOM_REG *pICOM, int32 Data) pICOM->command = Data; - drive = icom_info->currentDrive; - switch(pICOM->command) { case ICOM_CMD_STATUS: pICOM->rData = pICOM->status; diff --git a/AltairZ80/s100_pmmi.c b/AltairZ80/s100_pmmi.c index d3c74e6e..3fdba418 100644 --- a/AltairZ80/s100_pmmi.c +++ b/AltairZ80/s100_pmmi.c @@ -582,7 +582,7 @@ static t_stat pmmi_config_line(UNIT *uptr) static int32 pmmi_io(int32 addr, int32 io, int32 data) { - int32 r; + int32 r = 0; addr &= 0xff; data &= 0xff; diff --git a/doc/altairz80_doc.pdf b/doc/altairz80_doc.pdf index 31a04982..2094948a 100644 Binary files a/doc/altairz80_doc.pdf and b/doc/altairz80_doc.pdf differ