diff --git a/Intel-Systems/common/i8237.c.old b/Intel-Systems/common/i8237.c.old deleted file mode 100644 index c3c3853e..00000000 --- a/Intel-Systems/common/i8237.c.old +++ /dev/null @@ -1,866 +0,0 @@ -/* i8237.c: Intel 8237 DMA adapter - - Copyright (c) 2016, William A. Beech - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of William A. Beech shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from William A. Beech. - - MODIFICATIONS: - - 11 Jul 16 - Original file. - - NOTES: - - - Default is none. Since all channel registers in the i8237 are 16-bit, transfers - are done as two 8-bit operations, low- then high-byte. - - Port addressing is as follows (Port offset = 0): - - Port Mode Command Function - - 00 Write Load DMAC Channel 0 Base and Current Address Regsiters - Read Read DMAC Channel 0 Current Address Register - 01 Write Load DMAC Channel 0 Base and Current Word Count Registers - Read Read DMAC Channel 0 Current Word Count Register - 02 Write Load DMAC Channel 1 Base and Current Address Regsiters - Read Read DMAC Channel 1 Current Address Register - 03 Write Load DMAC Channel 1 Base and Current Word Count Registers - Read Read DMAC Channel 1 Current Word Count Register - 04 Write Load DMAC Channel 2 Base and Current Address Regsiters - Read Read DMAC Channel 2 Current Address Register - 05 Write Load DMAC Channel 2 Base and Current Word Count Registers - Read Read DMAC Channel 2 Current Word Count Register - 06 Write Load DMAC Channel 3 Base and Current Address Regsiters - Read Read DMAC Channel 3 Current Address Register - 07 Write Load DMAC Channel 3 Base and Current Word Count Registers - Read Read DMAC Channel 3 Current Word Count Register - 08 Write Load DMAC Command Register - Read Read DMAC Status Register - 09 Write Load DMAC Request Register - 0A Write Set/Reset DMAC Mask Register - 0B Write Load DMAC Mode Register - 0C Write Clear DMAC First/Last Flip-Flop - 0D Write DMAC Master Clear - 0F Write Load DMAC Mask Register - - Register usage is defined in the following paragraphs. - - Read/Write DMAC Address Registers - - Used to simultaneously load a channel's current-address register and base-address - register with the memory address of the first byte to be transferred. (The Channel - 0 current/base address register must be loaded prior to initiating a diskette read - or write operation.) Since each channel's address registers are 16 bits in length - (64K address range), two "write address register" commands must be executed in - order to load the complete current/base address registers for any channel. - - Read/Write DMAC Word Count Registers - - The Write DMAC Word Count Register command is used to simultaneously load a - channel's current and base word-count registers with the number of bytes - to be transferred during a subsequent DMA operation. Since the word-count - registers are 16-bits in length, two commands must be executed to load both - halves of the registers. - - Write DMAC Command Register - - The Write DMAC Command Register command loads an 8-bit byte into the - DMAC's command register to define the operating characteristics of the - DMAC. The functions of the individual bits in the command register are - defined in the following diagram. Note that only two bits within the - register are applicable to the controller; the remaining bits select - functions that are not supported and, accordingly, must always be set - to zero. - - 7 6 5 4 3 2 1 0 - +---+---+---+---+---+---+---+---+ - | 0 0 0 0 0 0 | - +---+---+---+---+---+---+---+---+ - | | - | +---------- 0 CONTROLLER ENABLE - | 1 CONTROLLER DISABLE - | - +------------------ 0 FIXED PRIORITY - 1 ROTATING PRIORITY - - Read DMAC Status Register Command - - The Read DMAC Status Register command accesses an 8-bit status byte that - identifies the DMA channels that have reached terminal count or that - have a pending DMA request. - - 7 6 5 4 3 2 1 0 - +---+---+---+---+---+---+---+---+ - | 0 0 | - +---+---+---+---+---+---+---+---+ - | | | | | | - | | | | | +-- CHANNEL 0 TC - | | | | +---------- CHANNEL 2 TC - | | | +-------------- CHANNEL 3 TC - | | +------------------ CHANNEL 0 DMA REQUEST - | +-------------------------- CHANNEL 2 DMA REQUEST - +------------------------------ CHANNEL 3 DMA REQUEST - - Write DMAC Request Register - - The data byte associated with the Write DMAC Request Register command - sets or resets a channel's associated request bit within the DMAC's - internal 4-bit request register. - - 7 6 5 4 3 2 1 0 - +---+---+---+---+---+---+---+---+ - | X X X X X | - +---+---+---+---+---+---+---+---+ - | | | - | +---+-- 00 SELECT CHANNEL 0 - | 01 SELECT CHANNEL 1 - | 10 SELECT CHANNEL 2 - | 11 SELECT CHANNEL 3 - | - +---------- 0 RESET REQUEST BIT - 1 SET REQUEST BIT - - Set/Reset DMAC Mask Register - - Prior to a DREQ-initiated DMA transfer, the channel's mask bit must - be reset to enable recognition of the DREQ input. When the transfer - is complete (terminal count reached or external EOP applied) and - the channel is not programmed to autoinitialize, the channel's - mask bit is automatically set (disabling DREQ) and must be reset - prior to a subsequent DMA transfer. All four bits of the mask - register are set (disabling the DREQ inputs) by a DMAC master - clear or controller reset. Additionally, all four bits can be - set/reset by a single Write DMAC Mask Register command. - - - 7 6 5 4 3 2 1 0 - +---+---+---+---+---+---+---+---+ - | X X X X X | - +---+---+---+---+---+---+---+---+ - | | | - | +---+-- 00 SELECT CHANNEL 0 - | 01 SELECT CHANNEL 1 - | 10 SELECT CHANNEL 2 - | 11 SELECT CHANNEL 3 - | - +---------- 0 RESET REQUEST BIT - 1 SET REQUEST BIT - - Write DMAC Mode Register - - The Write DMAC Mode Register command is used to define the - operating mode characteristics for each DMA channel. Each - channel has an internal 6-bit mode register; the high-order - six bits of the associated data byte are written into the - mode register addressed by the two low-order bits. - - - 7 6 5 4 3 2 1 0 - +---+---+---+---+---+---+---+---+ - | | - +---+---+---+---+---+---+---+---+ - | | | | | | | | - | | | | | | +---+-- 00 SELECT CHANNEL 0 - | | | | | | 01 SELECT CHANNEL 1 - | | | | | | 10 SELECT CHANNEL 2 - | | | | | | 11 SELECT CHANNEL 3 - | | | | | | - | | | | +---+---------- 00 VERIFY TRANSFER - | | | | 01 WRITE TRANSFER - | | | | 10 READ TRANSFER - | | | | - | | | +------------------ 0 AUTOINITIALIZE DISABLE - | | | 1 AUTOINITIALIZE ENABLE - | | | - | | +---------------------- 0 ADDRESS INCREMENT - | | 1 ADDRESS DECREMENT - | | - +---+-------------------------- 00 DEMAND MODE - 01 SINGLE MODE - 10 BLOCK MODE - - Clear DMAC First/Last Flip-Flop - - The Clear DMAC First/Last Flip-Flop command initializes - the DMAC's internal first/last flip-flop so that the - next byte written to or re~d from the 16-bit address - or word-count registers is the low-order byte. The - flip-flop is toggled with each register access so that - a second register read or write command accesses the - high-order byte. - - DMAC Master Clear - - The DMAC Master Clear command clears the DMAC's command, status, - request, and temporary registers to zero, initializes the - first/last flip-flop, and sets the four channel mask bits in - the mask register to disable all DMA requests (i.e., the DMAC - is placed in an idle state). - - Write DMAC Mask Register - - The Write DMAC Mask Register command allows all four bits of the - DMAC's mask register to be written with a single command. - - 7 6 5 4 3 2 1 0 - +---+---+---+---+---+---+---+---+ - | X X X X X | - +---+---+---+---+---+---+---+---+ - | | | - | | +-- 0 CLEAR CHANNEL 0 MASK BIT - | | 1 SET CHANNEL 0 MASK BIT - | | - | +---------- 0 CLEAR CHANNEL 2 MASK BIT - | 1 SET CHANNEL 2 MASK BIT - | - +-------------- 0 CLEAR CHANNEL 3 MASK BIT - 1 SET CHANNEL 3 MASK BIT - -*/ - -#include "system_defs.h" - -/* external globals */ - -extern uint16 port; //port called in dev_table[port] - -/* globals */ - -int32 i8237_devnum = 0; //actual number of 8253 instances + 1 -uint16 i8237_port[4]; //base port registered to each instance - -/* function prototypes */ - -t_stat i8237_svc(UNIT *uptr); -t_stat i8237_reset(DEVICE *dptr, uint16 base); -void i8237_reset1(int32 devnum); -t_stat i8237_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); -uint8 i8237_r0x(t_bool io, uint8 data); -uint8 i8237_r1x(t_bool io, uint8 data); -uint8 i8237_r2x(t_bool io, uint8 data); -uint8 i8237_r3x(t_bool io, uint8 data); -uint8 i8237_r4x(t_bool io, uint8 data); -uint8 i8237_r5x(t_bool io, uint8 data); -uint8 i8237_r6x(t_bool io, uint8 data); -uint8 i8237_r7x(t_bool io, uint8 data); -uint8 i8237_r8x(t_bool io, uint8 data); -uint8 i8237_r9x(t_bool io, uint8 data); -uint8 i8237_rAx(t_bool io, uint8 data); -uint8 i8237_rBx(t_bool io, uint8 data); -uint8 i8237_rCx(t_bool io, uint8 data); -uint8 i8237_rDx(t_bool io, uint8 data); -uint8 i8237_rEx(t_bool io, uint8 data); -uint8 i8237_rFx(t_bool io, uint8 data); - -/* external function prototypes */ - -extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16); - -/* 8237 physical register definitions */ - -uint16 i8237_r0[4]; // 8237 ch 0 address register -uint16 i8237_r1[4]; // 8237 ch 0 count register -uint16 i8237_r2[4]; // 8237 ch 1 address register -uint16 i8237_r3[4]; // 8237 ch 1 count register -uint16 i8237_r4[4]; // 8237 ch 2 address register -uint16 i8237_r5[4]; // 8237 ch 2 count register -uint16 i8237_r6[4]; // 8237 ch 3 address register -uint16 i8237_r7[4]; // 8237 ch 3 count register -uint8 i8237_r8[4]; // 8237 status register -uint8 i8237_r9[4]; // 8237 command register -uint8 i8237_rA[4]; // 8237 mode register -uint8 i8237_rB[4]; // 8237 mask register -uint8 i8237_rC[4]; // 8237 request register -uint8 i8237_rD[4]; // 8237 first/last ff -uint8 i8237_rE[4]; // 8237 -uint8 i8237_rF[4]; // 8237 - -/* i8237 physical register definitions */ - -uint16 i8237_sr[4]; // isbc-208 segment register -uint8 i8237_i[4]; // iSBC-208 interrupt register -uint8 i8237_a[4]; // iSBC-208 auxillary port register - -/* i8237 Standard SIMH Device Data Structures - 1 unit */ - -UNIT i8237_unit[] = { - { UDATA (0, 0, 0) ,20 }, /* i8237 0 */ - { UDATA (0, 0, 0) ,20 }, /* i8237 1 */ - { UDATA (0, 0, 0) ,20 }, /* i8237 2 */ - { UDATA (0, 0, 0) ,20 } /* i8237 3 */ -}; - - -REG i8237_reg[] = { - { HRDATA (CH0ADR, i8237_r0[devnum], 16) }, - { HRDATA (CH0CNT, i8237_r1[devnum], 16) }, - { HRDATA (CH1ADR, i8237_r2[devnum], 16) }, - { HRDATA (CH1CNT, i8237_r3, 16) }, - { HRDATA (CH2ADR, i8237_r4, 16) }, - { HRDATA (CH2CNT, i8237_r5, 16) }, - { HRDATA (CH3ADR, i8237_r6, 16) }, - { HRDATA (CH3CNT, i8237_r7, 16) }, - { HRDATA (STAT37, i8237_r8, 8) }, - { HRDATA (CMD37, i8237_r9, 8) }, - { HRDATA (MODE, i8237_rA, 8) }, - { HRDATA (MASK, i8237_rB, 8) }, - { HRDATA (REQ, i8237_rC, 8) }, - { HRDATA (FF, i8237_rD, 8) }, - { HRDATA (SEGREG, i8237_sr, 8) }, - { HRDATA (AUX, i8237_a, 8) }, - { HRDATA (INT, i8237_i, 8) }, - { NULL } -}; - -MTAB i8237_mod[] = { - { 0 } -}; - -DEBTAB i8237_debug[] = { - { "ALL", DEBUG_all }, - { "FLOW", DEBUG_flow }, - { "READ", DEBUG_read }, - { "WRITE", DEBUG_write }, - { "LEV1", DEBUG_level1 }, - { "LEV2", DEBUG_level2 }, - { "REG", DEBUG_reg }, - { NULL } -}; - -DEVICE i8237_dev = { - "I8237", //name - i8237_unit, //units - i8237_reg, //registers - i8237_mod, //modifiers - 1, //numunits - 16, //aradix - 32, //awidth - 1, //aincr - 16, //dradix - 8, //dwidth - NULL, //examine - NULL, //deposit -// &i8237_reset, //deposit - NULL, //reset - NULL, //boot - NULL, //attach - NULL, //detach - NULL, //ctxt - DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags - 0, //dctrl -// DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl - i8237_debug, //debflags - NULL, //msize - NULL //lname -}; - -/* Service routines to handle simulator functions */ - -/* service routine - actually does the simulated DMA */ - -t_stat i8237_svc(UNIT *uptr) -{ - sim_activate (&i8237_unit[uptr->u6], i8237_unit[uptr->u6].wait); - return SCPE_OK; -} - -/* Reset routine */ - -t_stat i8237_reset(DEVICE *dptr, uint16 base) -{ - if (i8237_devnum > I8237_NUM) { - sim_printf("i8237_reset: too many devices!\n"); - return SCPE_MEM; - } - sim_printf(" 8237 Reset\n"); - sim_printf(" 8237: Registered at %03X\n", base); - i8237_port[i8237_devnum] = reg_dev(i8237_r0x, base); - reg_dev(i8237_r1x, base + 1); - reg_dev(i8237_r2x, base + 2); - reg_dev(i8237_r3x, base + 3); - reg_dev(i8237_r4x, base + 4); - reg_dev(i8237_r5x, base + 5); - reg_dev(i8237_r6x, base + 6); - reg_dev(i8237_r7x, base + 7); - reg_dev(i8237_r8x, base + 8); - reg_dev(i8237_r9x, base + 9); - reg_dev(i8237_rAx, base + 10); - reg_dev(i8237_rBx, base + 11); - reg_dev(i8237_rCx, base + 12); - reg_dev(i8237_rDx, base + 13); - reg_dev(i8237_rEx, base + 14); - reg_dev(i8237_rFx, base + 15); - sim_printf(" 8237 Reset\n"); - sim_printf(" 8237: Registered at %03X\n", base); - sim_activate (&i8237_unit[i8237_devnum], i8237_unit[i8237_devnum].wait); /* activate unit */ - if ((i8237_dev.flags & DEV_DIS) == 0) - i8237_reset1(i8237_devnum); - i8237_devnum++; - return SCPE_OK; -} - -uint8 i8237_get_dn(void) -{ - int i; - - for (i=0; i=i8237_port[i] && port <= i8237_port[i] + 16) - return i; - sim_printf("i8237_get_dn: port %03X not in 8237 device table\n", port); - return 0xFF; -} - -void i8237_reset1(int32 devnum) -{ - int32 i; - UNIT *uptr; - - uptr = i8237_dev[devnum].units; - if (uptr->capac == 0) { /* if not configured */ - uptr->capac = 0; /* initialize unit */ - uptr->u3 = 0; - uptr->u4 = 0; - uptr->u5 = 0; - uptr->u6 = i; /* unit number - only set here! */ - sim_activate (&i8237_unit[devnum], i8237_unit[devnum].wait); - } - i8237_r8[devnum] = 0; /* status */ - i8237_r9[devnum] = 0; /* command */ - i8237_rB[devnum] = 0x0F; /* mask */ - i8237_rC[devnum] = 0; /* request */ - i8237_rD[devnum] = 0; /* first/last FF */ -} - - -/* i8237 set mode = 8- or 16-bit data bus */ -/* always 8-bit mode for current simulators */ - -t_stat i8237_set_mode(UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ - sim_debug (DEBUG_flow, &i8237_dev, " i8237_set_mode: Entered with val=%08XH uptr->flags=%08X\n", val, uptr->flags); - sim_debug (DEBUG_flow, &i8237_dev, " i8237_set_mode: Done\n"); - return SCPE_OK; -} - -/* I/O instruction handlers, called from the CPU module when an - IN or OUT instruction is issued. - - Each function is passed an 'io' flag, where 0 means a read from - the port, and 1 means a write to the port. On input, the actual - input is passed as the return value, on output, 'data' is written - to the device. -*/ - -uint8 i8237_r0x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read current address CH 0 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](H) read as %04X\n", devnum, i8237_r0[devnum]); - return (i8237_r0[devnum] >> 8); - } else { /* low byte */ - i8237_rD++; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](L) read as %04X\n", devnum, i8237_r0[devnum]); - return (i8237_r0[devnum] & 0xFF); - } - } else { /* write base & current address CH 0 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - i8237_r0[devnum] |= (data << 8); - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](H) set to %04X\n", devnum, i8237_r0[devnum]); - } else { /* low byte */ - i8237_rD++; - i8237_r0[devnum] = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](L) set to %04X\n"devnum, , i8237_r0[devnum]); - } - return 0; - } - } -} - -uint8 i8237_r1x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read current word count CH 0 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](H) read as %04X\n", devnum, i8237_r1[devnum]); - return (i8237_r1[devnum][devnum] >> 8); - } else { /* low byte */ - i8237_rD++; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](L) read as %04X\n", devnum, i8237_r1[devnum]); - return (i8237_r1[devnum] & 0xFF); - } - } else { /* write base & current address CH 0 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - i8237_r1[devnum] |= (data << 8); - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](H) set to %04X\n", devnum, i8237_r1[devnum]); - } else { /* low byte */ - i8237_rD++; - i8237_r1[devnum] = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](L) set to %04X\n", devnum, i8237_r1[devnum]); - } - return 0; - } - } -} - -uint8 i8237_r2x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read current address CH 1 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](H) read as %04X\n", devnum, i8237_r2[devnum]); - return (i8237_r2[devnum] >> 8); - } else { /* low byte */ - i8237_rD++; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](L) read as %04X\n", devnum, i8237_r2[devnum]); - return (i8237_r2[devnum] & 0xFF); - } - } else { /* write base & current address CH 1 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - i8237_r2[devnum] |= (data << 8); - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](H) set to %04X\n", devnum, i8237_r2[devnum]); - } else { /* low byte */ - i8237_rD++; - i8237_r2[devnum] = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](L) set to %04X\n", devnum, i8237_r2[devnum]); - } - return 0; - } - } -} - -uint8 i8237_r3x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read current word count CH 1 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(H) read as %04X\n", i8237_r3); - return (i8237_r3 >> 8); - } else { /* low byte */ - i8237_rD++; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(L) read as %04X\n", i8237_r3); - return (i8237_r3 & 0xFF); - } - } else { /* write base & current address CH 1 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - i8237_r3 |= (data << 8); - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(H) set to %04X\n", i8237_r3); - } else { /* low byte */ - i8237_rD++; - i8237_r3 = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(L) set to %04X\n", i8237_r3); - } - return 0; - } - } -} - -uint8 i8237_r4x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read current address CH 2 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(H) read as %04X\n", i8237_r4); - return (i8237_r4 >> 8); - } else { /* low byte */ - i8237_rD++; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(L) read as %04X\n", i8237_r4); - return (i8237_r4 & 0xFF); - } - } else { /* write base & current address CH 2 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - i8237_r4 |= (data << 8); - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(H) set to %04X\n", i8237_r4); - } else { /* low byte */ - i8237_rD++; - i8237_r4 = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(L) set to %04X\n", i8237_r4); - } - return 0; - } - } -} - -uint8 i8237_r5x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read current word count CH 2 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(H) read as %04X\n", i8237_r5); - return (i8237_r5 >> 8); - } else { /* low byte */ - i8237_rD++; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(L) read as %04X\n", i8237_r5); - return (i8237_r5 & 0xFF); - } - } else { /* write base & current address CH 2 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - i8237_r5 |= (data << 8); - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(H) set to %04X\n", i8237_r5); - } else { /* low byte */ - i8237_rD++; - i8237_r5 = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(L) set to %04X\n", i8237_r5); - } - return 0; - } - } -} - -uint8 i8237_r6x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read current address CH 3 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(H) read as %04X\n", i8237_r6); - return (i8237_r6 >> 8); - } else { /* low byte */ - i8237_rD++; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(L) read as %04X\n", i8237_r6); - return (i8237_r6 & 0xFF); - } - } else { /* write base & current address CH 3 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - i8237_r6 |= (data << 8); - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(H) set to %04X\n", i8237_r6); - } else { /* low byte */ - i8237_rD++; - i8237_r6 = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(L) set to %04X\n", i8237_r6); - } - return 0; - } - } -} - -uint8 i8237_r7x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read current word count CH 3 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(H) read as %04X\n", i8237_r7); - return (i8237_r7 >> 8); - } else { /* low byte */ - i8237_rD++; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(L) read as %04X\n", i8237_r7); - return (i8237_r7 & 0xFF); - } - } else { /* write base & current address CH 3 */ - if (i8237_rD) { /* high byte */ - i8237_rD = 0; - i8237_r7 |= (data << 8); - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(H) set to %04X\n", i8237_r7); - } else { /* low byte */ - i8237_rD++; - i8237_r7 = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(L) set to %04X\n", i8237_r7); - } - return 0; - } - } -} - -uint8 i8237_r8x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read status register */ - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r8 (status) read as %02X\n", i8237_r8); - return (i8237_r8); - } else { /* write command register */ - i8237_r9 = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_r9 (command) set to %02X\n", i8237_r9); - return 0; - } - } -} - -uint8 i8237_r9x(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { - sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_r9\n"); - return 0; - } else { /* write request register */ - i8237_rC = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_rC (request) set to %02X\n", i8237_rC); - return 0; - } - } -} - -uint8 i8237_rAx(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { - sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rA\n"); - return 0; - } else { /* write single mask register */ - switch(data & 0x03) { - case 0: - if (data & 0x04) - i8237_rB |= 1; - else - i8237_rB &= ~1; - break; - case 1: - if (data & 0x04) - i8237_rB |= 2; - else - i8237_rB &= ~2; - break; - case 2: - if (data & 0x04) - i8237_rB |= 4; - else - i8237_rB &= ~4; - break; - case 3: - if (data & 0x04) - i8237_rB |= 8; - else - i8237_rB &= ~8; - break; - } - sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) set to %02X\n", i8237_rB); - return 0; - } - } -} - -uint8 i8237_rBx(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { - sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rB\n"); - return 0; - } else { /* write mode register */ - i8237_rA = data & 0xFF; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_rA (mode) set to %02X\n", i8237_rA); - return 0; - } - } -} - -uint8 i8237_rCx(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { - sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rC\n"); - return 0; - } else { /* clear byte pointer FF */ - i8237_rD = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_rD (FF) cleared\n"); - return 0; - } - } -} - -uint8 i8237_rDx(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { /* read temporary register */ - sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rD\n"); - return 0; - } else { /* master clear */ - i8237_reset1(); - sim_debug (DEBUG_reg, &i8237_dev, "i8237 master clear\n"); - return 0; - } - } -} - -uint8 i8237_rEx(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { - sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rE\n"); - return 0; - } else { /* clear mask register */ - i8237_rB = 0; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) cleared\n"); - return 0; - } - } -} - -uint8 i8237_rFx(t_bool io, uint8 data) -{ - uint8 devnum; - - if ((devnum = i8237_get_dn()) != 0xFF) { - if (io == 0) { - sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rF\n"); - return 0; - } else { /* write all mask register bits */ - i8237_rB = data & 0x0F; - sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) set to %02X\n", i8237_rB); - return 0; - } - } -} - -/* end of i8237.c */ diff --git a/Intel-Systems/common/i8253.c b/Intel-Systems/common/i8253.c index 26c5fb47..37dcb12d 100644 --- a/Intel-Systems/common/i8253.c +++ b/Intel-Systems/common/i8253.c @@ -142,8 +142,8 @@ t_stat i8253_reset (DEVICE *dptr, uint16 baseport) sim_printf("i8253_reset: too many devices!\n"); return SCPE_MEM; } - sim_printf(" 8253-%d: Reset\n", i8253_devnum); - sim_printf(" 8253-%d: Registered at %04X\n", i8253_devnum, baseport); + sim_printf(" 8253-%d: Reset\n", i8253_devnum); + sim_printf(" 8253-%d: Registered at %04X\n", i8253_devnum, baseport); i8253_port[i8253_devnum] = baseport; reg_dev(i8253t0, baseport, i8253_devnum); reg_dev(i8253t1, baseport + 1, i8253_devnum); diff --git a/Intel-Systems/common/i8259.c b/Intel-Systems/common/i8259.c index d43c9890..2a1e4729 100644 --- a/Intel-Systems/common/i8259.c +++ b/Intel-Systems/common/i8259.c @@ -58,6 +58,12 @@ extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); int32 i8259_devnum = 0; //actual number of 8259 instances + 1 uint16 i8259_port[4]; //baseport port registered to each instance +/* these bytes represent the input and output to/from a port instance */ + +uint8 i8259_IR[4]; //interrupt inputs (bits 0-7) +uint8 i8259_CAS[4]; //interrupt cascade I/O (bits 0-2) +uint8 i8259_INT[4]; //interrupt output (bit 0) + uint8 i8259_base[I8259_NUM]; uint8 i8259_icw1[I8259_NUM]; uint8 i8259_icw2[I8259_NUM]; @@ -144,8 +150,8 @@ t_stat i8259_reset (DEVICE *dptr, uint16 baseport) sim_printf("i8255_reset: too many devices!\n"); return SCPE_MEM; } - sim_printf(" 8259-%d: Reset\n", i8259_devnum); - sim_printf(" 8259-%d: Registered at %04X\n", i8259_devnum, baseport); + sim_printf(" 8259-%d: Reset\n", i8259_devnum); + sim_printf(" 8259-%d: Registered at %04X\n", i8259_devnum, baseport); i8259_port[i8259_devnum] = baseport; reg_dev(i8259a, baseport, i8259_devnum); reg_dev(i8259b, baseport + 1, i8259_devnum); diff --git a/Intel-Systems/common/ieprom.c b/Intel-Systems/common/ieprom.c index 36f19ab4..0b570ebc 100644 --- a/Intel-Systems/common/ieprom.c +++ b/Intel-Systems/common/ieprom.c @@ -40,6 +40,8 @@ #include "system_defs.h" +#define DEBUG 0 + /* function prototypes */ t_stat EPROM_attach (UNIT *uptr, CONST char *cptr); @@ -48,13 +50,13 @@ uint8 EPROM_get_mbyte(uint16 addr); /* external function prototypes */ -extern uint8 i8255_C[4]; //port c byte I/O +//extern uint8 i8255_C[4]; //port c byte I/O extern uint8 xack; /* XACK signal */ /* SIMH EPROM Standard I/O Data Structures */ UNIT EPROM_unit = { - UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0), 0 + UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 0 }; DEBTAB EPROM_debug[] = { @@ -88,8 +90,7 @@ DEVICE EPROM_dev = { NULL, //detach NULL, //ctxt DEV_DEBUG, //flags - DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl -// 0, //dctrl + 0, //dctrl EPROM_debug, //debflags NULL, //msize NULL //lname @@ -99,54 +100,6 @@ DEVICE EPROM_dev = { /* EPROM functions */ -/* EPROM attach */ - -t_stat EPROM_attach (UNIT *uptr, CONST char *cptr) -{ - uint16 j; - int c; - FILE *fp; - t_stat r; - - sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: cptr=%s\n", cptr); - if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { - sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Error\n"); - return r; - } - sim_debug (DEBUG_read, &EPROM_dev, "\tAllocate buffer\n"); - if (EPROM_unit.filebuf == NULL) { /* no buffer allocated */ - EPROM_unit.filebuf = malloc(EPROM_unit.capac); /* allocate EPROM buffer */ - if (EPROM_unit.filebuf == NULL) { - sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Malloc error\n"); - return SCPE_MEM; - } - } - sim_debug (DEBUG_read, &EPROM_dev, "\tOpen file %s\n", EPROM_unit.filename); - fp = fopen(EPROM_unit.filename, "rb"); /* open EPROM file */ - if (fp == NULL) { - sim_printf("EPROM: Unable to open ROM file %s\n", EPROM_unit.filename); - sim_printf("\tNo ROM image loaded!!!\n"); - return SCPE_OK; - } - sim_debug (DEBUG_read, &EPROM_dev, "\tRead file\n"); - j = 0; /* load EPROM file */ - c = fgetc(fp); - while (c != EOF) { - *((uint8 *)EPROM_unit.filebuf + j++) = c & 0xFF; - c = fgetc(fp); - if (j >= EPROM_unit.capac) { - sim_printf("\tImage is too large - Load truncated!!!\n"); - break; - } - } - sim_debug (DEBUG_read, &EPROM_dev, "\tClose file\n"); - fclose(fp); - sim_printf(" EPROM: Configured %d bytes, Attached to %s\n", - EPROM_unit.capac, EPROM_unit.filename); - sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Done\n"); - return SCPE_OK; -} - /* EPROM reset */ t_stat EPROM_reset (DEVICE *dptr, uint16 size) @@ -164,6 +117,24 @@ t_stat EPROM_reset (DEVICE *dptr, uint16 size) return SCPE_OK; } +/* EPROM attach */ + +t_stat EPROM_attach (UNIT *uptr, CONST char *cptr) +{ + t_stat r; + + sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: cptr=%s\n", cptr); + if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { + sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Error\n"); + return r; + } + sim_debug (DEBUG_read, &EPROM_dev, "\tClose file\n"); + sim_printf(" EPROM: Configured %d bytes, Attached to %s\n", + EPROM_unit.capac, EPROM_unit.filename); + sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Done\n"); + return SCPE_OK; +} + /* get a byte from memory */ uint8 EPROM_get_mbyte(uint16 addr) diff --git a/Intel-Systems/common/ioc-cont.c b/Intel-Systems/common/ioc-cont.c index df75f1ed..46835588 100644 --- a/Intel-Systems/common/ioc-cont.c +++ b/Intel-Systems/common/ioc-cont.c @@ -140,8 +140,8 @@ DEVICE ioc_cont_dev = { t_stat ioc_cont_reset(DEVICE *dptr, uint16 baseport) { - sim_printf(" ioc_cont[%d]: Reset\n", 0); - sim_printf(" ioc_cont[%d]: Registered at %04X\n", 0, baseport); + sim_printf(" ioc_cont[%d]: Reset\n", 0); + sim_printf(" ioc_cont[%d]: Registered at %04X\n", 0, baseport); reg_dev(ioc_cont0, baseport, 0); reg_dev(ioc_cont1, baseport + 1, 0); dbb_stat = 0x00; /* clear DBB status */ diff --git a/Intel-Systems/common/ipc-cont.c b/Intel-Systems/common/ipc-cont.c index f467a2a8..82d22205 100644 --- a/Intel-Systems/common/ipc-cont.c +++ b/Intel-Systems/common/ipc-cont.c @@ -33,6 +33,8 @@ #include "system_defs.h" /* system header in system dir */ +#define DEBUG 0 + /* function prototypes */ uint8 ipc_cont(t_bool io, uint8 data); /* ipc_cont*/ @@ -96,8 +98,8 @@ DEVICE ipc_cont_dev = { t_stat ipc_cont_reset(DEVICE *dptr, uint16 baseport) { - sim_printf(" ipc_cont[%d]: Reset\n", 0); - sim_printf(" ipc_cont[%d]: Registered at %04X\n", 0, baseport); + sim_printf(" ipc_cont[%d]: Reset\n", 0); + sim_printf(" ipc_cont[%d]: Registered at %04X\n", 0, baseport); reg_dev(ipc_cont, baseport, 0); ipc_cont_unit[0].u3 = 0x00; /* ipc reset */ return SCPE_OK; @@ -112,8 +114,9 @@ t_stat ipc_cont_reset(DEVICE *dptr, uint16 baseport) uint8 ipc_cont(t_bool io, uint8 data) { if (io == 0) { /* read status port */ - sim_printf(" ipc_cont: read data=%02X ipc_cont_unit[%d].u3=%02X\n", - ipc_cont_unit[0].u3, 0, ipc_cont_unit[0].u3); + if (DEBUG) + sim_printf(" ipc_cont: read data=%02X ipc_cont_unit[%d].u3=%02X\n", + ipc_cont_unit[0].u3, 0, ipc_cont_unit[0].u3); return ipc_cont_unit[0].u3; } else { /* write control port */ //this simulates an 74LS259 register @@ -152,7 +155,8 @@ uint8 ipc_cont(t_bool io, uint8 data) default: break; } - sim_printf(" ipc_cont: write data=%02X ipc_cont_unit[%d].u3=%02X\n", data, 0, ipc_cont_unit[0].u3); + if (DEBUG) + sim_printf(" ipc_cont: write data=%02X ipc_cont_unit[%d].u3=%02X\n", data, 0, ipc_cont_unit[0].u3); } return 0; } diff --git a/Intel-Systems/common/ipceprom.c b/Intel-Systems/common/ipceprom.c deleted file mode 100644 index 7aab9159..00000000 --- a/Intel-Systems/common/ipceprom.c +++ /dev/null @@ -1,186 +0,0 @@ -/* ipcEPROM.c: Intel EPROM simulator for 8-bit SBCs - - Copyright (c) 2010, William A. Beech - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of William A. Beech shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from William A. Beech. - - MODIFICATIONS: - - ?? ??? 10 - Original file. - 16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size. - 24 Apr 15 -- Modified to use simh_debug - - NOTES: - - These functions support a simulated ROM devices on an iSBC-80/XX SBCs. - This allows the attachment of the device to a binary file containing the EPROM - code image. Unit will support a single 2708, 2716, 2732, or 2764 type EPROM. - These functions also support bit 1 of 8255 number 1, port B, to enable/ - disable the onboard ROM. -*/ - -#include "system_defs.h" - -/* function prototypes */ - -t_stat EPROM_attach (UNIT *uptr, CONST char *cptr); -t_stat EPROM_reset (DEVICE *dptr, uint16 size); -uint8 EPROM_get_mbyte(uint16 addr); - -/* external function prototypes */ - -extern uint8 xack; /* XACK signal */ -extern UNIT ipc_cont_unit[]; - -/* SIMH EPROM Standard I/O Data Structures */ - -UNIT EPROM_unit = { - UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0), 0 -}; - -DEBTAB EPROM_debug[] = { - { "ALL", DEBUG_all }, - { "FLOW", DEBUG_flow }, - { "READ", DEBUG_read }, - { "WRITE", DEBUG_write }, - { "XACK", DEBUG_xack }, - { "LEV1", DEBUG_level1 }, - { "LEV2", DEBUG_level2 }, - { NULL } -}; - -DEVICE EPROM_dev = { - "EPROM", //name - &EPROM_unit, //units - NULL, //registers - NULL, //modifiers - 1, //numunits - 16, //aradix - 16, //awidth - 1, //aincr - 16, //dradix - 8, //dwidth - NULL, //examine - NULL, //deposit -// &EPROM_reset, //reset - NULL, //reset - NULL, //boot - &EPROM_attach, //attach - NULL, //detach - NULL, //ctxt - DEV_DEBUG, //flags - 0, //dctrl - EPROM_debug, //debflags - NULL, //msize - NULL //lname -}; - -/* global variables */ - -/* EPROM functions */ - -/* EPROM attach */ - -t_stat EPROM_attach (UNIT *uptr, CONST char *cptr) -{ - uint16 j; - int c; - FILE *fp; - t_stat r; - - sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: cptr=%s\n", cptr); - if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { - sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Error\n"); - return r; - } - sim_debug (DEBUG_read, &EPROM_dev, "\tAllocate buffer\n"); - if (EPROM_unit.filebuf == NULL) { /* no buffer allocated */ - EPROM_unit.filebuf = malloc(EPROM_unit.capac); /* allocate EPROM buffer */ - if (EPROM_unit.filebuf == NULL) { - sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Malloc error\n"); - return SCPE_MEM; - } - } - sim_debug (DEBUG_read, &EPROM_dev, "\tOpen file %s\n", EPROM_unit.filename); - fp = fopen(EPROM_unit.filename, "rb"); /* open EPROM file */ - if (fp == NULL) { - sim_printf("EPROM: Unable to open ROM file %s\n", EPROM_unit.filename); - sim_printf("\tNo ROM image loaded!!!\n"); - return SCPE_OK; - } - sim_debug (DEBUG_read, &EPROM_dev, "\tRead file\n"); - j = 0; /* load EPROM file */ - c = fgetc(fp); - while (c != EOF) { - *((uint8 *)EPROM_unit.filebuf + j++) = c & 0xFF; - c = fgetc(fp); - if (j > EPROM_unit.capac) { - sim_printf("\tImage is too large - Load truncated!!!\n"); - break; - } - } - sim_printf("\tImage size=%04X unit_capac=%04X\n", j, EPROM_unit.capac); - sim_debug (DEBUG_read, &EPROM_dev, "\tClose file\n"); - fclose(fp); - sim_printf("EPROM: %d bytes of ROM image %s loaded\n", j, EPROM_unit.filename); - sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Done\n"); - return SCPE_OK; -} - -/* EPROM reset */ - -t_stat EPROM_reset (DEVICE *dptr, uint16 size) -{ -// sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=0000 size=%04X\n", size); - if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */ - EPROM_unit.capac = size; /* set EPROM size to 0 */ - sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n"); -// sim_printf(" EPROM: Available [%04X-%04XH]\n", -// 0, EPROM_unit.capac - 1); - return SCPE_OK; - } - if ((EPROM_unit.flags & UNIT_ATT) == 0) { - sim_printf("EPROM: No file attached\n"); - } - sim_debug (DEBUG_flow, &EPROM_dev, "Done2\n"); - return SCPE_OK; -} - -/* get a byte from memory */ - -uint8 EPROM_get_mbyte(uint16 addr) -{ - uint8 val; - - sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%04X\n", addr); - if (addr < EPROM_unit.capac) { - SET_XACK(1); /* good memory address */ - sim_debug (DEBUG_xack, &EPROM_dev, "EPROM_get_mbyte: Set XACK for %04X\n", addr); - val = *((uint8 *)EPROM_unit.filebuf + addr); - sim_debug (DEBUG_read, &EPROM_dev, " val=%04X\n", val); - return (val & 0xFF); - } - sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n"); - return 0xFF; -} - -/* end of ipcEPROM.c */ diff --git a/Intel-Systems/common/ipcmultibus.c b/Intel-Systems/common/ipcmultibus.c index e3a25939..93b1e55a 100644 --- a/Intel-Systems/common/ipcmultibus.c +++ b/Intel-Systems/common/ipcmultibus.c @@ -60,7 +60,6 @@ void multibus_put_mword(uint16 addr, uint16 val); extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */ extern void set_cpuint(int32 int_num); -extern UNIT zx200a_unit; extern t_stat zx200a_reset(DEVICE *dptr, uint16 base); extern t_stat isbc201_reset (DEVICE *dptr, uint16); extern t_stat isbc202_reset (DEVICE *dptr, uint16); @@ -150,8 +149,7 @@ t_stat multibus_reset(DEVICE *dptr) SBC_reset(NULL); sim_printf(" Multibus: Reset\n"); zx200a_fdcnum = 0; - zx200a_reset(NULL, ZX200A_BASE_DD); -// zx200a_reset(NULL, ZX200A_BASE_SD); + zx200a_reset(NULL, ZX200A_BASE); isbc201_fdcnum = 0; isbc201_reset(NULL, SBC201_BASE); isbc202_fdcnum = 0; @@ -258,9 +256,9 @@ uint8 nulldev(t_bool flag, uint8 data) uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port, uint8 devnum) { if (dev_table[port].routine != &nulldev) { /* port already assigned */ - sim_printf("Multibus: I/O Port %04X is already assigned\n", port); + sim_printf(" Multibus: I/O Port %04X is already assigned\n", port); } else { - sim_printf("Port %04X is assigned\n", port); + sim_printf(" Port %04X is assigned\n", port); dev_table[port].routine = routine; dev_table[port].devnum = devnum; } diff --git a/Intel-Systems/common/ipcram8.c b/Intel-Systems/common/ipcram8.c deleted file mode 100644 index b2697ef2..00000000 --- a/Intel-Systems/common/ipcram8.c +++ /dev/null @@ -1,145 +0,0 @@ -/* ipcRAM8.c: Intel RAM simulator for 8-bit SBCs - - Copyright (c) 2011, William A. Beech - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of William A. Beech shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from William A. Beech. - - MODIFICATIONS: - - ?? ??? 11 - Original file. - 16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size. - 24 Apr 15 -- Modified to use simh_debug - - NOTES: - - These functions support a simulated RAM devices on an iSBC-80/XX SBCs. - These functions also support bit 2 of 8255 number 1, port B, to enable/ - disable the onboard RAM. -*/ - -#include "system_defs.h" - -/* function prototypes */ - -t_stat RAM_svc (UNIT *uptr); -t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size); -uint8 RAM_get_mbyte(uint16 addr); -void RAM_put_mbyte(uint16 addr, uint8 val); - -/* external function prototypes */ - -extern uint8 xack; /* XACK signal */ - -/* SIMH RAM Standard I/O Data Structures */ - -UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0), KBD_POLL_WAIT }; - -DEBTAB RAM_debug[] = { - { "ALL", DEBUG_all }, - { "FLOW", DEBUG_flow }, - { "READ", DEBUG_read }, - { "WRITE", DEBUG_write }, - { "XACK", DEBUG_xack }, - { "LEV1", DEBUG_level1 }, - { "LEV2", DEBUG_level2 }, - { NULL } -}; - -DEVICE RAM_dev = { - "RAM", //name - &RAM_unit, //units - NULL, //registers - NULL, //modifiers - 1, //numunits - 16, //aradix - 16, //awidth - 1, //aincr - 16, //dradix - 8, //dwidth - NULL, //examine - NULL, //deposit -// &RAM_reset, //reset - NULL, //reset - NULL, //boot - NULL, //attach - NULL, //detach - NULL, //ctxt - DEV_DEBUG, //flags - 0, //dctrl - RAM_debug, //debflags - NULL, //msize - NULL //lname -}; - -/* global variables */ - -/* RAM functions */ - -/* RAM reset */ - -t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size) -{ - sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%04X size=%04X\n", base, size-1); - if (RAM_unit.capac == 0) { /* if undefined */ - RAM_unit.capac = size; - RAM_unit.u3 = base; - } - if (RAM_unit.filebuf == NULL) { /* no buffer allocated */ - RAM_unit.filebuf = malloc(RAM_unit.capac); - if (RAM_unit.filebuf == NULL) { - sim_debug (DEBUG_flow, &RAM_dev, "RAM_set_size: Malloc error\n"); - return SCPE_MEM; - } - } -// sim_printf(" RAM: Available [%04X-%04XH]\n", -// RAM_unit.u3, -// RAM_unit.u3 + RAM_unit.capac - 1); - sim_debug (DEBUG_flow, &RAM_dev, "RAM_reset: Done\n"); - return SCPE_OK; -} - -/* get a byte from memory */ - -uint8 RAM_get_mbyte(uint16 addr) -{ - uint8 val; - - sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr); - SET_XACK(1); /* good memory address */ - sim_debug (DEBUG_xack, &RAM_dev, "RAM_get_mbyte: Set XACK for %04X\n", addr); - val = *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)); - sim_debug (DEBUG_read, &RAM_dev, " val=%04X\n", val); - return (val & 0xFF); -} - -/* put a byte to memory */ - -void RAM_put_mbyte(uint16 addr, uint8 val) -{ - sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val); - SET_XACK(1); /* good memory address */ - sim_debug (DEBUG_xack, &RAM_dev, "RAM_put_mbyte: Set XACK for %04X\n", addr); - *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF; - sim_debug (DEBUG_write, &RAM_dev, "\n"); -} - -/* end of ipcRAM8.c */ diff --git a/Intel-Systems/common/iram8.c b/Intel-Systems/common/iram8.c index edb7bb38..5ae08a4c 100644 --- a/Intel-Systems/common/iram8.c +++ b/Intel-Systems/common/iram8.c @@ -38,6 +38,8 @@ #include "system_defs.h" +#define DEBUG 0 + /* function prototypes */ t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size); @@ -108,9 +110,10 @@ t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size) return SCPE_MEM; } } - sim_printf(" RAM: Available [%04X-%04XH]\n", - RAM_unit.u3, - RAM_unit.u3 + RAM_unit.capac - 1); + if (DEBUG) + sim_printf(" RAM: Available [%04X-%04XH]\n", + RAM_unit.u3, + RAM_unit.u3 + RAM_unit.capac - 1); sim_debug (DEBUG_flow, &RAM_dev, "RAM_reset: Done\n"); return SCPE_OK; } diff --git a/Intel-Systems/common/isbc201.c b/Intel-Systems/common/isbc201.c index b5766d31..5c5d605d 100644 --- a/Intel-Systems/common/isbc201.c +++ b/Intel-Systems/common/isbc201.c @@ -136,7 +136,7 @@ u3 - u4 - - u5 - fdc number. + u5 - fdc number (board instance number). u6 - fdd number. */ @@ -183,12 +183,16 @@ #define RB1RD0 0x40 //drive 0 ready #define RB1RD1 0x80 //drive 1 ready +//disk geometry values #define MDSSD 256256 //single density FDD size #define MDSDD 512512 //double density FDD size +#define MAXSECSD 26 //single density last sector +#define MAXSECDD 52 //double density last sector +#define MAXTRK 76 //last track /* external globals */ -extern uint16 port; //port called in dev_table[port] +extern uint16 port; //port called in dev_table[port] extern int32 PCX; /* external function prototypes */ @@ -218,11 +222,10 @@ void isbc201_diskio(uint8 fdcnum); //do actual disk i/o int32 isbc201_fdcnum = 0; //actual number of SBC-201 instances + 1 typedef struct { //FDD definition - uint8 *buf; int t0; int rdy; - uint8 maxsec; - uint8 maxcyl; + uint8 sec; + uint8 cyl; } FDDDEF; typedef struct { //FDC definition @@ -240,25 +243,33 @@ typedef struct { //FDC definition FDCDEF fdc201[4]; //indexed by the isbc-201 instance number UNIT isbc201_unit[] = { - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 } + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD), 20 } }; REG isbc201_reg[] = { - { HRDATA (STATUS0, isbc201_unit[0].u3, 8) }, /* isbc201 0 status */ - { HRDATA (RTYP0, isbc201_unit[0].u4, 8) }, /* isbc201 0 result type */ - { HRDATA (RBYT0, isbc201_unit[0].u5, 8) }, /* isbc201 0 result byte */ - { HRDATA (STATUS1, isbc201_unit[1].u3, 8) }, /* isbc201 1 status */ - { HRDATA (RTYP1, isbc201_unit[1].u4, 8) }, /* isbc201 0 result type */ - { HRDATA (RBYT1, isbc201_unit[1].u5, 8) }, /* isbc201 0 result byte */ - { HRDATA (STATUS2, isbc201_unit[2].u3, 8) }, /* isbc201 2 status */ - { HRDATA (RTYP2, isbc201_unit[0].u4, 8) }, /* isbc201 0 result type */ - { HRDATA (R$BYT2, isbc201_unit[2].u5, 8) }, /* isbc201 0 result byte */ - { HRDATA (STATUS3, isbc201_unit[3].u3, 8) }, /* isbc201 3 status */ - { HRDATA (RTYP3, isbc201_unit[3].u4, 8) }, /* isbc201 0 result type */ - { HRDATA (RBYT3, isbc201_unit[3].u5, 8) }, /* isbc201 0 result byte */ + { HRDATA (STAT0, fdc201[0].stat, 8) }, /* fdc201 0 status */ + { HRDATA (RTYP0, fdc201[0].rtype, 8) }, /* fdc201 0 result type */ + { HRDATA (RBYT0A, fdc201[0].rbyte0, 8) }, /* fdc201 0 result byte 0 */ + { HRDATA (RBYT0B, fdc201[0].rbyte1, 8) }, /* fdc201 0 result byte 1 */ + { HRDATA (INTFF0, fdc201[0].intff, 8) }, /* fdc201 0 interrupt f/f */ + { HRDATA (STAT1, fdc201[1].stat, 8) }, /* fdc201 1 status */ + { HRDATA (RTYP1, fdc201[1].rtype, 8) }, /* fdc201 1 result type */ + { HRDATA (RBYT1A, fdc201[1].rbyte0, 8) }, /* fdc201 1 result byte 0 */ + { HRDATA (RBYT1B, fdc201[1].rbyte1, 8) }, /* fdc201 1 result byte 1 */ + { HRDATA (INTFF1, fdc201[1].intff, 8) }, /* fdc201 1 interrupt f/f */ + { HRDATA (STAT2, fdc201[2].stat, 8) }, /* fdc201 2 status */ + { HRDATA (RTYP2, fdc201[2].rtype, 8) }, /* fdc201 2 result type */ + { HRDATA (RBYT2A, fdc201[2].rbyte0, 8) }, /* fdc201 2 result byte 0 */ + { HRDATA (RBYT2B, fdc201[2].rbyte1, 8) }, /* fdc201 2 result byte 1 */ + { HRDATA (INTFF2, fdc201[2].intff, 8) }, /* fdc201 2 interrupt f/f */ + { HRDATA (STAT3, fdc201[3].stat, 8) }, /* fdc201 3 status */ + { HRDATA (RTYP3, fdc201[3].rtype, 8) }, /* fdc201 3 result type */ + { HRDATA (RBYT3A, fdc201[3].rbyte0, 8) }, /* fdc201 3 result byte 0 */ + { HRDATA (RBYT3B, fdc201[3].rbyte1, 8) }, /* fdc201 3 result byte 1 */ + { HRDATA (INTFF3, fdc201[3].intff, 8) }, /* fdc201 3 interrupt f/f */ { NULL } }; @@ -310,17 +321,29 @@ DEVICE isbc201_dev = { t_stat isbc201_reset(DEVICE *dptr, uint16 base) { + int32 i; + UNIT *uptr; + sim_printf(" iSBC-201 FDC Board"); if (SBC201_NUM) { sim_printf(" - Found\n"); sim_printf(" isbc201-%d: Hardware Reset\n", isbc201_fdcnum); sim_printf(" isbc201-%d: Registered at %04X\n", isbc201_fdcnum, base); + //register base port address for this FDC instance fdc201[isbc201_fdcnum].baseport = base; + //register I/O port addresses for each function reg_dev(isbc2010, base, isbc201_fdcnum); //read status reg_dev(isbc2011, base + 1, isbc201_fdcnum); //read rslt type/write IOPB addr-l reg_dev(isbc2012, base + 2, isbc201_fdcnum); //write IOPB addr-h and start reg_dev(isbc2013, base + 3, isbc201_fdcnum); //read rstl byte - reg_dev(isbc2017, base + 7, isbc201_fdcnum); //write reset isbc202 + reg_dev(isbc2017, base + 7, isbc201_fdcnum); //write reset fdc201 + // one-time initialization for all FDDs for this FDC instance + for (i = 0; i < FDD_NUM; i++) { + uptr = isbc201_dev.units + i; + uptr->u5 = isbc201_fdcnum; //fdc device number + uptr->u6 = i; //fdd unit number + uptr->flags |= UNIT_WPMODE; //set WP in unit flags + } isbc201_reset1(isbc201_fdcnum); isbc201_fdcnum++; } else @@ -342,38 +365,30 @@ void isbc201_reset1(uint8 fdcnum) fdc201[fdcnum].stat |= FDCPRE; //set the FDC status fdc201[fdcnum].rtype = ROK; if (uptr->capac == 0) { /* if not configured */ - uptr->capac = 0; /* initialize unit */ - uptr->u5 = fdcnum; //fdc device number - uptr->u6 = i; //fdd unit number - uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */ sim_printf(" isbc201-%d: Configured, Status=%02X Not attached\n", i, fdc201[fdcnum].stat); } else { switch(i){ case 0: fdc201[fdcnum].stat |= RDY0; //set FDD 0 ready fdc201[fdcnum].rbyte1 |= RB1RD0; - fdc201[fdcnum].rdychg = 0; break; case 1: fdc201[fdcnum].stat |= RDY1; //set FDD 1 ready fdc201[fdcnum].rbyte1 |= RB1RD1; - fdc201[fdcnum].rdychg = 0; break; } + fdc201[fdcnum].rdychg = 0; sim_printf(" isbc201-%d: Configured, Status=%02X Attached to %s\n", i, fdc201[fdcnum].stat, uptr->filename); } } } -/* isbc202 attach - attach an .IMG file to a FDD */ +/* fdc201 attach - attach an .IMG file to a FDD */ t_stat isbc201_attach (UNIT *uptr, CONST char *cptr) { t_stat r; - FILE *fp; - int32 i, c = 0; - long flen; uint8 fdcnum, fddnum; sim_debug (DEBUG_flow, &isbc201_dev, " isbc201_attach: Entered with cptr=%s\n", cptr); @@ -383,60 +398,24 @@ t_stat isbc201_attach (UNIT *uptr, CONST char *cptr) } fdcnum = uptr->u5; fddnum = uptr->u6; - fp = fopen(uptr->filename, "rb"); - if (fp == NULL) { - sim_printf(" Unable to open disk image file %s\n", uptr->filename); - sim_printf(" No disk image loaded!!!\n"); - } else { - sim_printf("isbc202: Attach\n"); - fseek(fp, 0, SEEK_END); /* size disk image */ - flen = ftell(fp); - fseek(fp, 0, SEEK_SET); - if (flen == -1) { - sim_printf(" isbc201_attach: File error\n"); - fclose(fp); - return SCPE_IOERR; - } - if (fdc201[fdcnum].fdd[fddnum].buf == NULL) { /* no buffer allocated */ - fdc201[fdcnum].fdd[fddnum].buf = (uint8 *)malloc(flen); - if (fdc201[fdcnum].fdd[fddnum].buf == NULL) { - sim_printf(" isbc201_attach: Malloc error\n"); - fclose(fp); - return SCPE_MEM; - } - } - uptr->capac = flen; - i = 0; - c = fgetc(fp); // copy disk image into buffer - while (c != EOF) { - *(fdc201[fdcnum].fdd[fddnum].buf + i++) = c & 0xFF; - c = fgetc(fp); - } - fclose(fp); - switch(fddnum){ - case 0: - fdc201[fdcnum].stat |= RDY0; //set FDD 0 ready - fdc201[fdcnum].rtype = ROK; - fdc201[fdcnum].rbyte1 |= RB1RD0; - break; - case 1: - fdc201[fdcnum].stat |= RDY1; //set FDD 1 ready - fdc201[fdcnum].rtype = ROK; - fdc201[fdcnum].rbyte1 |= RB1RD1; - break; - } - if (flen == 256256) { /* 8" 256K SSSD */ - fdc201[fdcnum].fdd[fddnum].maxcyl = 77; - fdc201[fdcnum].fdd[fddnum].maxsec = 26; - } - sim_printf(" iSBC-201%d: Configured %d bytes, Attached to %s\n", - fdcnum, uptr->capac, uptr->filename); + switch(fddnum){ + case 0: + fdc201[fdcnum].stat |= RDY0; //set FDD 0 ready + fdc201[fdcnum].rbyte1 |= RB1RD0; + break; + case 1: + fdc201[fdcnum].stat |= RDY1; //set FDD 1 ready + fdc201[fdcnum].rbyte1 |= RB1RD1; + break; } + fdc201[fdcnum].rtype = ROK; + sim_printf(" iSBC-201%d: FDD %d Configured %d bytes, Attached to %s\n", + fdcnum, fddnum, uptr->capac, uptr->filename); sim_debug (DEBUG_flow, &isbc201_dev, " isbc201_attach: Done\n"); return SCPE_OK; } -/* isbc202 set mode = Write protect */ +/* fdc201 set mode = Write protect */ t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { @@ -458,7 +437,7 @@ uint8 isbc201_get_dn(void) for (i=0; i= fdc201[i].baseport && port <= fdc201[i].baseport + 7) return i; - sim_printf("isbc201_get_dn: port %04X not in isbc202 device table\n", port); + sim_printf("isbc201_get_dn: port %04X not in fdc201 device table\n", port); return 0xFF; } @@ -574,13 +553,13 @@ uint8 isbc2017(t_bool io, uint8 data) void isbc201_diskio(uint8 fdcnum) { - uint8 cw, di, nr, ta, sa, bn, data, nrptr, c; + uint8 cw, di, nr, ta, sa, bn, data, nrptr; uint16 ba, ni; uint32 dskoff; - uint8 fddnum; + uint8 fddnum, fmtb; uint32 i; UNIT *uptr; - FILE *fp; + uint8 *fbuf; //parse the IOPB cw = multibus_get_mbyte(fdc201[fdcnum].iopb); @@ -593,6 +572,7 @@ void isbc201_diskio(uint8 fdcnum) ni = multibus_get_mword(fdc201[fdcnum].iopb + 8); fddnum = (di & 0x30) >> 4; uptr = isbc201_dev.units + fddnum; + fbuf = (uint8 *) (isbc201_dev.units + fddnum)->filebuf; if (DEBUG) { sim_printf("\n isbc201-%d: isbc201_diskio IOPB=%04X FDD=%02X STAT=%02X", fdcnum, fdc201[fdcnum].iopb, fddnum, fdc201[fdcnum].stat); @@ -605,7 +585,7 @@ void isbc201_diskio(uint8 fdcnum) if ((fdc201[fdcnum].stat & RDY0) == 0) { fdc201[fdcnum].rtype = RERR; fdc201[fdcnum].rbyte0 = RB0NR; - fdc201[fdcnum].intff = 1; //set interrupt FF + fdc201[fdcnum].intff = 1; //set interrupt FF sim_printf("\n isbc201-%d: Ready error on drive %d", fdcnum, fddnum); return; } @@ -614,7 +594,7 @@ void isbc201_diskio(uint8 fdcnum) if ((fdc201[fdcnum].stat & RDY1) == 0) { fdc201[fdcnum].rtype = RERR; fdc201[fdcnum].rbyte0 = RB0NR; - fdc201[fdcnum].intff = 1; //set interrupt FF + fdc201[fdcnum].intff = 1; //set interrupt FF sim_printf("\n isbc201-%d: Ready error on drive %d", fdcnum, fddnum); return; } @@ -622,38 +602,68 @@ void isbc201_diskio(uint8 fdcnum) } //check for address error if ( - ((di & 0x07) != 0x03) || - (sa > fdc201[fdcnum].fdd[fddnum].maxsec) || - ((sa + nr) > (fdc201[fdcnum].fdd[fddnum].maxsec + 1)) || + ((di & 0x07) != DHOME) && ( + (sa > MAXSECSD) || + ((sa + nr) > (MAXSECSD + 1)) || (sa == 0) || - (ta > fdc201[fdcnum].fdd[fddnum].maxcyl) - ) { -// sim_printf("\n isbc201-%d: maxsec=%02X maxcyl=%02X", -// fdcnum, fdc201[fdcnum].fdd[fddnum].maxsec, fdc201[fdcnum].fdd[fddnum].maxcyl); - fdc201[fdcnum].rtype = RERR; - fdc201[fdcnum].rbyte0 = RB0ADR; - fdc201[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc201-%d: Address error on drive %d", fdcnum, fddnum); - return; + (ta > MAXTRK) + )) { + fdc201[fdcnum].rtype = RERR; + fdc201[fdcnum].rbyte0 = RB0ADR; + fdc201[fdcnum].intff = 1; //set interrupt FF + sim_printf("\n isbc201-%d: Address error on drive %d", fdcnum, fddnum); + return; } switch (di & 0x07) { case DNOP: + fdc201[fdcnum].rtype = ROK; + fdc201[fdcnum].intff = 1; //set interrupt FF + break; case DSEEK: + fdc201[fdcnum].fdd[fddnum].sec = sa; + fdc201[fdcnum].fdd[fddnum].cyl = ta; + fdc201[fdcnum].rtype = ROK; + fdc201[fdcnum].intff = 1; //set interrupt FF + break; case DHOME: + fdc201[fdcnum].fdd[fddnum].sec = sa; + fdc201[fdcnum].fdd[fddnum].cyl = 0; + fdc201[fdcnum].rtype = ROK; + fdc201[fdcnum].intff = 1; //set interrupt FF + break; case DVCRC: fdc201[fdcnum].rtype = ROK; - fdc201[fdcnum].intff = 1; //set interrupt FF + fdc201[fdcnum].intff = 1; //set interrupt FF + break; + case DFMT: + //check for WP + if(uptr->flags & UNIT_WPMODE) { + fdc201[fdcnum].rtype = RERR; + fdc201[fdcnum].rbyte0 = RB0WP; + fdc201[fdcnum].intff = 1; //set interrupt FF + sim_printf("\n isbc202-%d: Write protect error 1 on drive %d", fdcnum, fddnum); + return; + } + fmtb = multibus_get_mbyte(ba); //get the format byte + //calculate offset into disk image + dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; + for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) { + *(fbuf + (dskoff + i)) = fmtb; + } + fdc201[fdcnum].rtype = ROK; + fdc201[fdcnum].intff = 1; //set interrupt FF break; case DREAD: nrptr = 0; while(nrptr < nr) { //calculate offset into disk image - dskoff = ((ta * fdc201[fdcnum].fdd[fddnum].maxsec) + (sa - 1)) * 128; + dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; if (DEBUG) - sim_printf("\n isbc201-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X bn=%02X ni=%04X dskoff=%06X", + sim_printf("\n isbc201-%d: DREAD cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X bn=%02X ni=%04X dskoff=%06X", fdcnum, cw, di, nr, ta, sa, ba, bn, ni, dskoff); - for (i=0; i<128; i++) { //copy sector from image to RAM - data = *(fdc201[fdcnum].fdd[fddnum].buf + (dskoff + i)); + //copy sector from image to RAM + for (i=0; i<128; i++) { + data = *(fbuf + (dskoff + i)); multibus_put_mbyte(ba + i, data); } sa++; @@ -661,41 +671,34 @@ void isbc201_diskio(uint8 fdcnum) nrptr++; } fdc201[fdcnum].rtype = ROK; - fdc201[fdcnum].intff = 1; //set interrupt FF + fdc201[fdcnum].intff = 1; //set interrupt FF break; case DWRITE: //check for WP if(uptr->flags & UNIT_WPMODE) { fdc201[fdcnum].rtype = RERR; fdc201[fdcnum].rbyte0 = RB0WP; - fdc201[fdcnum].intff = 1; //set interrupt FF + fdc201[fdcnum].intff = 1; //set interrupt FF sim_printf("\n isbc201-%d: Write protect error on drive %d", fdcnum, fddnum); return; } nrptr = 0; while(nrptr < nr) { //calculate offset into disk image - dskoff = ((ta * fdc201[fdcnum].fdd[fddnum].maxsec) + (sa - 1)) * 128; + dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; if (DEBUG) - sim_printf("\n isbc201-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X bn=%02X ni=%04X dskoff=%06X", + sim_printf("\n isbc201-%d: DWRITE cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X bn=%02X ni=%04X dskoff=%06X", fdcnum, cw, di, nr, ta, sa, ba, bn, ni, dskoff); - for (i=0; i<128; i++) { //copy sector from image to RAM + for (i=0; i<128; i++) { //copy sector from image to RAM data = multibus_get_mbyte(ba + i); - *(fdc201[fdcnum].fdd[fddnum].buf + (dskoff + i)) = data; + *(fbuf + (dskoff + i)) = data; } sa++; ba+=0x80; nrptr++; } - //*** quick fix. Needs more thought! - fp = fopen(uptr->filename, "wb"); // write out modified image - for (i=0; icapac; i++) { - c = *(fdc201[fdcnum].fdd[fddnum].buf + i); - fputc(c, fp); - } - fclose(fp); fdc201[fdcnum].rtype = ROK; - fdc201[fdcnum].intff = 1; //set interrupt FF + fdc201[fdcnum].intff = 1; //set interrupt FF break; default: sim_printf("\n isbc201-%d: isbc201_diskio bad di=%02X", fdcnum, di & 0x07); diff --git a/Intel-Systems/common/isbc202.c b/Intel-Systems/common/isbc202.c index 3ada6d07..042ac259 100644 --- a/Intel-Systems/common/isbc202.c +++ b/Intel-Systems/common/isbc202.c @@ -126,7 +126,7 @@ u3 - u4 - - u5 - fdc number. + u5 - fdc number (board instance number). u6 - fdd number. */ @@ -178,6 +178,13 @@ #define RB1RD0 0x40 //drive 0 ready #define RB1RD1 0x80 //drive 1 ready +//disk geometry values +#define MDSSD 256256 //single density FDD size +#define MDSDD 512512 //double density FDD size +#define MAXSECSD 26 //single density last sector +#define MAXSECDD 52 //double density last sector +#define MAXTRK 76 //last track + /* external globals */ extern uint16 port; //port called in dev_table[port] @@ -210,13 +217,10 @@ void isbc202_diskio(uint8 fdcnum); //do actual disk i/o int32 isbc202_fdcnum = 0; //actual number of SBC-202 instances + 1 typedef struct { //FDD definition - uint8 *buf; int t0; int rdy; uint8 sec; uint8 cyl; - uint8 maxsec; - uint8 maxcyl; } FDDDEF; typedef struct { //FDC definition @@ -234,10 +238,10 @@ typedef struct { //FDC definition FDCDEF fdc202[4]; //indexed by the isbc-202 instance number UNIT isbc202_unit[] = { - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 } + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 } }; REG isbc202_reg[] = { @@ -254,13 +258,13 @@ REG isbc202_reg[] = { { HRDATA (STAT2, fdc202[2].stat, 8) }, /* isbc202 2 status */ { HRDATA (RTYP2, fdc202[2].rtype, 8) }, /* isbc202 2 result type */ { HRDATA (RBYT2A, fdc202[2].rbyte0, 8) }, /* isbc202 2 result byte 0 */ - { HRDATA (RBYT2B, fdc202[0].rbyte1, 8) }, /* isbc202 2 result byte 1 */ + { HRDATA (RBYT2B, fdc202[2].rbyte1, 8) }, /* isbc202 2 result byte 1 */ { HRDATA (INTFF2, fdc202[2].intff, 8) }, /* isbc202 2 interrupt f/f */ { HRDATA (STAT3, fdc202[3].stat, 8) }, /* isbc202 3 status */ { HRDATA (RTYP3, fdc202[3].rtype, 8) }, /* isbc202 3 result type */ { HRDATA (RBYT3A, fdc202[3].rbyte0, 8) }, /* isbc202 3 result byte 0 */ { HRDATA (RBYT3B, fdc202[3].rbyte1, 8) }, /* isbc202 3 result byte 1 */ - { HRDATA (INTFF3, fdc202[0].intff, 8) }, /* isbc202 3 interrupt f/f */ + { HRDATA (INTFF3, fdc202[3].intff, 8) }, /* isbc202 3 interrupt f/f */ { NULL } }; @@ -312,17 +316,30 @@ DEVICE isbc202_dev = { t_stat isbc202_reset(DEVICE *dptr, uint16 base) { + int32 i; + UNIT *uptr; + sim_printf(" iSBC-202 FDC Board"); if (SBC202_NUM) { sim_printf(" - Found\n"); sim_printf(" isbc202-%d: Hardware Reset\n", isbc202_fdcnum); sim_printf(" isbc202-%d: Registered at %04X\n", isbc202_fdcnum, base); + //register base port address for this FDC instance fdc202[isbc202_fdcnum].baseport = base; + //register I/O port addresses for each function reg_dev(isbc2020, base, isbc202_fdcnum); //read status reg_dev(isbc2021, base + 1, isbc202_fdcnum); //read rslt type/write IOPB addr-l reg_dev(isbc2022, base + 2, isbc202_fdcnum); //write IOPB addr-h and start reg_dev(isbc2023, base + 3, isbc202_fdcnum); //read rstl byte reg_dev(isbc2027, base + 7, isbc202_fdcnum); //write reset isbc202 + // one-time initialization for all FDDs for this FDC instance + for (i = 0; i < FDD_NUM; i++) { + uptr = isbc202_dev.units + i; + uptr->u5 = isbc202_fdcnum; //fdc device number + uptr->u6 = i; //fdd unit number + uptr->flags |= UNIT_WPMODE; //set WP in unit flags + } + isbc202_reset1(isbc202_fdcnum); //software reset isbc202_reset1(isbc202_fdcnum); isbc202_fdcnum++; } else @@ -344,33 +361,27 @@ void isbc202_reset1(uint8 fdcnum) fdc202[fdcnum].stat |= FDCPRE | FDCDD; //set the FDC status fdc202[fdcnum].rtype = ROK; if (uptr->capac == 0) { /* if not configured */ - uptr->u5 = fdcnum; //fdc device number - uptr->u6 = i; //fdd unit number - uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */ sim_printf(" SBC202%d: Configured, Status=%02X Not attached\n", i, fdc202[fdcnum].stat); } else { switch(i){ case 0: fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready fdc202[fdcnum].rbyte1 |= RB1RD0; - fdc202[fdcnum].rdychg = 0; break; case 1: fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready fdc202[fdcnum].rbyte1 |= RB1RD1; - fdc202[fdcnum].rdychg = 0; break; case 2: fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready fdc202[fdcnum].rbyte1 |= RB1RD2; - fdc202[fdcnum].rdychg = 0; break; case 3: fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready fdc202[fdcnum].rbyte1 |= RB1RD3; - fdc202[fdcnum].rdychg = 0; break; } + fdc202[fdcnum].rdychg = 0; sim_printf(" SBC202%d: Configured, Status=%02X Attached to %s\n", i, fdc202[fdcnum].stat, uptr->filename); } @@ -382,80 +393,37 @@ void isbc202_reset1(uint8 fdcnum) t_stat isbc202_attach (UNIT *uptr, CONST char *cptr) { t_stat r; - FILE *fp; - int32 i, c = 0; - long flen; uint8 fdcnum, fddnum; sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_attach: Entered with cptr=%s\n", cptr); +// sim_printf(" isbc202_attach: Entered with cptr=%s\n", cptr); if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { sim_printf(" isbc202_attach: Attach error\n"); return r; } fdcnum = uptr->u5; fddnum = uptr->u6; - fp = fopen(uptr->filename, "rb"); - if (fp == NULL) { - sim_printf(" Unable to open disk image file %s\n", uptr->filename); - sim_printf(" No disk image loaded!!!\n"); - } else { - sim_printf("isbc202: Attach\n"); - fseek(fp, 0, SEEK_END); /* size disk image */ - flen = ftell(fp); - fseek(fp, 0, SEEK_SET); - if (flen == -1) { - sim_printf(" isbc202_attach: File error\n"); - fclose(fp); - return SCPE_IOERR; - } - if (fdc202[fdcnum].fdd[fddnum].buf == NULL) { /* no buffer allocated */ - fdc202[fdcnum].fdd[fddnum].buf = (uint8 *)malloc(flen); - if (fdc202[fdcnum].fdd[fddnum].buf == NULL) { - sim_printf(" isbc202_attach: Malloc error\n"); - fclose(fp); - return SCPE_MEM; - } - } - uptr->capac = flen; - i = 0; - c = fgetc(fp); // copy disk image into buffer - while (c != EOF) { - *(fdc202[fdcnum].fdd[fddnum].buf + i++) = c & 0xFF; - c = fgetc(fp); - } - fclose(fp); - switch(fddnum){ - case 0: - fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].rbyte1 |= RB1RD0; - break; - case 1: - fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].rbyte1 |= RB1RD1; - break; - case 2: - fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].rbyte1 |= RB1RD2; - break; - case 3: - fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].rbyte1 |= RB1RD3; - break; - } - if (flen == 512512) { /* 8" 512K SSDD */ - fdc202[fdcnum].fdd[fddnum].maxcyl = 77; - fdc202[fdcnum].fdd[fddnum].maxsec = 52; - fdc202[fdcnum].fdd[fddnum].sec = 1; - fdc202[fdcnum].fdd[fddnum].cyl = 0; - } else - sim_printf(" iSBC-202-%d: Not a DD disk image\n", fdcnum); - sim_printf(" iSBC-202%d: Configured %d bytes, Attached to %s\n", - fdcnum, uptr->capac, uptr->filename); + switch(fddnum){ + case 0: + fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready + fdc202[fdcnum].rbyte1 |= RB1RD0; + break; + case 1: + fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready + fdc202[fdcnum].rbyte1 |= RB1RD1; + break; + case 2: + fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready + fdc202[fdcnum].rbyte1 |= RB1RD2; + break; + case 3: + fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready + fdc202[fdcnum].rbyte1 |= RB1RD3; + break; } + fdc202[fdcnum].rtype = ROK; + sim_printf(" iSBC-202%d: FDD %d Configured %d bytes, Attached to %s\n", + fdcnum, fddnum, uptr->capac, uptr->filename); sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_attach: Done\n"); return SCPE_OK; } @@ -594,13 +562,14 @@ uint8 isbc2027(t_bool io, uint8 data) void isbc202_diskio(uint8 fdcnum) { - uint8 cw, di, nr, ta, sa, data, nrptr, c; + uint8 cw, di, nr, ta, sa, data, nrptr; uint16 ba; uint32 dskoff; uint8 fddnum, fmtb; uint32 i; UNIT *uptr; - FILE *fp; + uint8 *fbuf; + //parse the IOPB cw = multibus_get_mbyte(fdc202[fdcnum].iopb); di = multibus_get_mbyte(fdc202[fdcnum].iopb + 1); @@ -610,13 +579,12 @@ void isbc202_diskio(uint8 fdcnum) ba = multibus_get_mword(fdc202[fdcnum].iopb + 5); fddnum = (di & 0x30) >> 4; uptr = isbc202_dev.units + fddnum; + fbuf = (uint8 *) (isbc202_dev.units + fddnum)->filebuf; if (DEBUG) { sim_printf("\n isbc202-%d: isbc202_diskio IOPB=%04X FDD=%02X STAT=%02X", fdcnum, fdc202[fdcnum].iopb, fddnum, fdc202[fdcnum].stat); sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X", fdcnum, cw, di, nr, ta, sa, ba); -// sim_printf("\n isbc202-%d: maxsec=%02X maxcyl=%02X", -// fdcnum, fdc202[fdcnum].fdd[fddnum].maxsec, fdc202[fdcnum].fdd[fddnum].maxcyl); } //check for not ready switch(fddnum) { @@ -659,20 +627,17 @@ void isbc202_diskio(uint8 fdcnum) } //check for address error if ( - ((di & 0x07) != 0x03) && ( - (sa > fdc202[fdcnum].fdd[fddnum].maxsec) || - ((sa + nr) > (fdc202[fdcnum].fdd[fddnum].maxsec + 1)) || + ((di & 0x07) != DHOME) && ( + (sa > MAXSECDD) || + ((sa + nr) > (MAXSECDD + 1)) || (sa == 0) || - (ta > fdc202[fdcnum].fdd[fddnum].maxcyl) + (ta > MAXTRK) )) { - if (DEBUG) - sim_printf("\n isbc202-%d: maxsec=%02X maxcyl=%02X", - fdcnum, fdc202[fdcnum].fdd[fddnum].maxsec, fdc202[fdcnum].fdd[fddnum].maxcyl); - fdc202[fdcnum].rtype = RERR; - fdc202[fdcnum].rbyte0 = RB0ADR; - fdc202[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc202-%d: Address error on drive %d", fdcnum, fddnum); - return; + fdc202[fdcnum].rtype = RERR; + fdc202[fdcnum].rbyte0 = RB0ADR; + fdc202[fdcnum].intff = 1; //set interrupt FF + sim_printf("\n isbc202-%d: Address error on drive %d", fdcnum, fddnum); + return; } switch (di & 0x07) { case DNOP: @@ -706,17 +671,10 @@ void isbc202_diskio(uint8 fdcnum) } fmtb = multibus_get_mbyte(ba); //get the format byte //calculate offset into disk image - dskoff = ((ta * (uint32)(fdc202[fdcnum].fdd[fddnum].maxsec)) + (sa - 1)) * 128; - for(i=0; i<=((uint32)(fdc202[fdcnum].fdd[fddnum].maxsec) * 128); i++) { - *(fdc202[fdcnum].fdd[fddnum].buf + (dskoff + i)) = fmtb; + dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; + for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) { + *(fbuf + (dskoff + i)) = fmtb; } - //*** quick fix. Needs more thought! - fp = fopen(uptr->filename, "wb"); // write out modified image - for (i=0; icapac; i++) { - c = *(fdc202[fdcnum].fdd[fddnum].buf + i); - fputc(c, fp); - } - fclose(fp); fdc202[fdcnum].rtype = ROK; fdc202[fdcnum].intff = 1; //set interrupt FF break; @@ -724,11 +682,13 @@ void isbc202_diskio(uint8 fdcnum) nrptr = 0; while(nrptr < nr) { //calculate offset into disk image - dskoff = ((ta * fdc202[fdcnum].fdd[fddnum].maxsec) + (sa - 1)) * 128; -// sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", -// fdcnum, cw, di, nr, ta, sa, ba, dskoff); - for (i=0; i<128; i++) { //copy sector from image to RAM - data = *(fdc202[fdcnum].fdd[fddnum].buf + (dskoff + i)); + dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; + if (DEBUG) + sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", + fdcnum, cw, di, nr, ta, sa, ba, dskoff); + //copy sector from image to RAM + for (i=0; i<128; i++) { + data = *(fbuf + (dskoff + i)); multibus_put_mbyte(ba + i, data); } sa++; @@ -750,24 +710,18 @@ void isbc202_diskio(uint8 fdcnum) nrptr = 0; while(nrptr < nr) { //calculate offset into disk image - dskoff = ((ta * fdc202[fdcnum].fdd[fddnum].maxsec) + (sa - 1)) * 128; - // sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", - // fdcnum, cw, di, nr, ta, sa, ba, dskoff); - for (i=0; i<128; i++) { //copy sector from image to RAM + dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; + if (DEBUG) + sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", + fdcnum, cw, di, nr, ta, sa, ba, dskoff); + for (i=0; i<128; i++) { //copy sector from image to RAM data = multibus_get_mbyte(ba + i); - *(fdc202[fdcnum].fdd[fddnum].buf + (dskoff + i)) = data; + *(fbuf + (dskoff + i)) = data; } sa++; ba+=0x80; nrptr++; } - //*** quick fix. Needs more thought! - fp = fopen(uptr->filename, "wb"); // write out modified image - for (i=0; icapac; i++) { - c = *(fdc202[fdcnum].fdd[fddnum].buf + i); - fputc(c, fp); - } - fclose(fp); fdc202[fdcnum].rtype = ROK; fdc202[fdcnum].intff = 1; //set interrupt FF break; diff --git a/Intel-Systems/common/isbc202.c.new.c b/Intel-Systems/common/isbc202.c.new.c deleted file mode 100644 index 1a1dae37..00000000 --- a/Intel-Systems/common/isbc202.c.new.c +++ /dev/null @@ -1,736 +0,0 @@ -/* isbc202.c: Intel double density disk adapter adapter - - Copyright (c) 2010, William A. Beech - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of William A. Beech shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from William A. Beech. - - MODIFICATIONS: - - 27 Jun 16 - Original file. - - NOTES: - - This controller will mount 4 DD disk images on drives :F0: thru :F3: addressed - at ports 078H to 07FH. - - Registers: - - 078H - Read - Subsystem status - bit 0 - ready status of drive 0 - bit 1 - ready status of drive 1 - bit 2 - state of channel's interrupt FF - bit 3 - controller presence indicator - bit 4 - DD controller presence indicator - bit 5 - ready status of drive 2 - bit 6 - ready status of drive 3 - bit 7 - zero - - 079H - Read - Read result type (bits 2-7 are zero) - 00 - I/O complete with error - 01 - Reserved - 10 - Result byte contains diskette ready status - 11 - Reserved - 079H - Write - IOPB address low byte. - - 07AH - Write - IOPB address high byte and start operation. - - 07BH - Read - Read result byte - If result type is 00H - bit 0 - deleted record - bit 1 - CRC error - bit 2 - seek error - bit 3 - address error - bit 4 - data overrun/underrun - bit 5 - write protect - bit 6 - write error - bit 7 - not ready - If result type is 02H and ready has changed - bit 0 - zero - bit 1 - zero - bit 2 - zero - bit 3 - zero - bit 4 - drive 2 ready - bit 5 - drive 3 ready - bit 6 - drive 0 ready - bit 7 - drive 1 ready - else return 0 - - 07FH - Write - Reset diskette system. - - Operations: - NOP - 0x00 - Seek - 0x01 - Format Track - 0x02 - Recalibrate - 0x03 - Read Data - 0x04 - Verify CRC - 0x05 - Write Data - 0x06 - Write Deleted Data - 0x07 - - IOPB - I/O Parameter Block - Byte 0 - Channel Word - bit 3 - data word length (=8-bit, 1=16-bit) - bit 4-5 - interrupt control - 00 - I/O complete interrupt to be issued - 01 - I/O complete interrupts are disabled - 10 - illegal code - 11 - illegal code - bit 6- randon format sequence - - Byte 1 - Diskette Instruction - bit 0-2 - operation code - 000 - no operation - 001 - seek - 010 - format track - 011 - recalibrate - 100 - read data - 101 - verify CRC - 110 - write data - 111 - write deleted data - bit 3 - data word length ( same as byte-0, bit-3) - bit 4-5 - unit select - 00 - drive 0 - 01 - drive 1 - 10 - drive 2 - 11 - drive 3 - bit 6-7 - reserved (zero) - - Byte 2 - Number of Records - - Byte 4 - Track Address - - Byte 5 - Sector Address - - Byte 6 - Buffer Low Address - - Byte 7 - Buffer High Address - - u3 - - u4 - - u5 - fdc number (board instance number). - u6 - fdd number. - -*/ - -#include "system_defs.h" /* system header in system dir */ - -#define DEBUG 0 - -#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */ -#define UNIT_WPMODE (1 << UNIT_V_WPMODE) - -#define FDD_NUM 4 - -//disk controoler operations -#define DNOP 0x00 //disk no operation -#define DSEEK 0x01 //disk seek -#define DFMT 0x02 //disk format -#define DHOME 0x03 //disk home -#define DREAD 0x04 //disk read -#define DVCRC 0x05 //disk verify CRC -#define DWRITE 0x06 //disk write - -//status -#define RDY0 0x01 //FDD 0 ready -#define RDY1 0x02 //FDD 1 ready -#define FDCINT 0x04 //FDC interrupt flag -#define FDCPRE 0x08 //FDC board present -#define FDCDD 0x10 //fdc is DD -#define RDY2 0x20 //FDD 2 ready -#define RDY3 0x40 //FDD 3 ready - -//result type -#define RERR 0x00 //FDC returned error -#define ROK 0x02 //FDC returned ok - -// If result type is RERR then rbyte is -#define RB0DR 0x01 //deleted record -#define RB0CRC 0x02 //CRC error -#define RB0SEK 0x04 //seek error -#define RB0ADR 0x08 //address error -#define RB0OU 0x10 //data overrun/underrun -#define RB0WP 0x20 //write protect -#define RB0WE 0x40 //write error -#define RB0NR 0x80 //not ready - -// If result type is ROK then rbyte is -#define RB1RD2 0x10 //drive 2 ready -#define RB1RD3 0x20 //drive 3 ready -#define RB1RD0 0x40 //drive 0 ready -#define RB1RD1 0x80 //drive 1 ready - -#define MDSSD 256256 //single density FDD size -#define MDSDD 512512 //double density FDD size -#define MAXSECSD 26 //single density last sector -#define MAXSECDD 52 //double density last sector -#define MAXTRK 76 //last track - -/* external globals */ - -extern uint16 port; //port called in dev_table[port] -extern int32 PCX; - -/* external function prototypes */ - -extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); -extern uint8 multibus_get_mbyte(uint16 addr); -extern uint16 multibus_get_mword(uint16 addr); -extern void multibus_put_mbyte(uint16 addr, uint8 val); -extern uint8 multibus_put_mword(uint16 addr, uint16 val); - -/* function prototypes */ - -t_stat isbc202_reset(DEVICE *dptr, uint16 base); -void isbc202_reset1(uint8 fdcnum); -t_stat isbc202_attach (UNIT *uptr, CONST char *cptr); -t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); -uint8 isbc202_get_dn(void); -uint8 isbc2020(t_bool io, uint8 data); /* isbc202 0 */ -uint8 isbc2021(t_bool io, uint8 data); /* isbc202 1 */ -uint8 isbc2022(t_bool io, uint8 data); /* isbc202 2 */ -uint8 isbc2023(t_bool io, uint8 data); /* isbc202 3 */ -uint8 isbc2027(t_bool io, uint8 data); /* isbc202 7 */ -void isbc202_diskio(uint8 fdcnum); //do actual disk i/o - -/* globals */ - -int32 isbc202_fdcnum = 0; //actual number of SBC-202 instances + 1 - -typedef struct { //FDD definition - int t0; - int rdy; - uint8 sec; - uint8 cyl; - } FDDDEF; - -typedef struct { //FDC definition - uint16 baseport; //FDC base port - uint16 iopb; //FDC IOPB - uint8 stat; //FDC status - uint8 rdychg; //FDC ready change - uint8 rtype; //FDC result type - uint8 rbyte0; //FDC result byte for type 00 - uint8 rbyte1; //FDC result byte for type 10 - uint8 intff; //fdc interrupt FF - FDDDEF fdd[FDD_NUM]; //indexed by the FDD number - } FDCDEF; - -FDCDEF fdc202[4]; //indexed by the isbc-202 instance number - -UNIT isbc202_unit[] = { - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 20 } -}; - -REG isbc202_reg[] = { - { HRDATA (STAT0, fdc202[0].stat, 8) }, /* isbc202 0 status */ - { HRDATA (RTYP0, fdc202[0].rtype, 8) }, /* isbc202 0 result type */ - { HRDATA (RBYT0A, fdc202[0].rbyte0, 8) }, /* isbc202 0 result byte 0 */ - { HRDATA (RBYT0B, fdc202[0].rbyte1, 8) }, /* isbc202 0 result byte 1 */ - { HRDATA (INTFF0, fdc202[0].intff, 8) }, /* isbc202 0 interrupt f/f */ - { HRDATA (STAT1, fdc202[1].stat, 8) }, /* isbc202 1 status */ - { HRDATA (RTYP1, fdc202[1].rtype, 8) }, /* isbc202 1 result type */ - { HRDATA (RBYT1A, fdc202[1].rbyte0, 8) }, /* isbc202 1 result byte 0 */ - { HRDATA (RBYT1B, fdc202[1].rbyte1, 8) }, /* isbc202 1 result byte 1 */ - { HRDATA (INTFF1, fdc202[1].intff, 8) }, /* isbc202 1 interrupt f/f */ - { HRDATA (STAT2, fdc202[2].stat, 8) }, /* isbc202 2 status */ - { HRDATA (RTYP2, fdc202[2].rtype, 8) }, /* isbc202 2 result type */ - { HRDATA (RBYT2A, fdc202[2].rbyte0, 8) }, /* isbc202 2 result byte 0 */ - { HRDATA (RBYT2B, fdc202[2].rbyte1, 8) }, /* isbc202 2 result byte 1 */ - { HRDATA (INTFF2, fdc202[2].intff, 8) }, /* isbc202 2 interrupt f/f */ - { HRDATA (STAT3, fdc202[3].stat, 8) }, /* isbc202 3 status */ - { HRDATA (RTYP3, fdc202[3].rtype, 8) }, /* isbc202 3 result type */ - { HRDATA (RBYT3A, fdc202[3].rbyte0, 8) }, /* isbc202 3 result byte 0 */ - { HRDATA (RBYT3B, fdc202[3].rbyte1, 8) }, /* isbc202 3 result byte 1 */ - { HRDATA (INTFF3, fdc202[3].intff, 8) }, /* isbc202 3 interrupt f/f */ - { NULL } -}; - -MTAB isbc202_mod[] = { - { UNIT_WPMODE, 0, "RW", "RW", &isbc202_set_mode }, - { UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc202_set_mode }, - { 0 } -}; - -DEBTAB isbc202_debug[] = { - { "ALL", DEBUG_all }, - { "FLOW", DEBUG_flow }, - { "READ", DEBUG_read }, - { "WRITE", DEBUG_write }, - { "XACK", DEBUG_xack }, - { "LEV1", DEBUG_level1 }, - { "LEV2", DEBUG_level2 }, - { NULL } -}; - -/* address width is set to 16 bits to use devices in 8086/8088 implementations */ - -DEVICE isbc202_dev = { - "SBC202", //name - isbc202_unit, //units - isbc202_reg, //registers - isbc202_mod, //modifiers - FDD_NUM, //numunits - 16, //aradix - 16, //awidth - 1, //aincr - 16, //dradix - 8, //dwidth - NULL, //examine - NULL, //deposit - NULL, //reset - NULL, //boot - &isbc202_attach, //attach - NULL, //detach - NULL, //ctxt - DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags - DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl - isbc202_debug, //debflags - NULL, //msize - NULL //lname -}; - -/* Hardware reset routine */ - -t_stat isbc202_reset(DEVICE *dptr, uint16 base) -{ - int32 i; - UNIT *uptr; - - sim_printf(" iSBC-202 FDC Board"); - if (SBC202_NUM) { - sim_printf(" - Found\n"); - sim_printf(" isbc202-%d: Hardware Reset\n", isbc202_fdcnum); - sim_printf(" isbc202-%d: Registered at %04X\n", isbc202_fdcnum, base); - //register base port address for this FDC instance - fdc202[isbc202_fdcnum].baseport = base; - //register I/O port addresses for each function - reg_dev(isbc2020, base, isbc202_fdcnum); //read status - reg_dev(isbc2021, base + 1, isbc202_fdcnum); //read rslt type/write IOPB addr-l - reg_dev(isbc2022, base + 2, isbc202_fdcnum); //write IOPB addr-h and start - reg_dev(isbc2023, base + 3, isbc202_fdcnum); //read rstl byte - reg_dev(isbc2027, base + 7, isbc202_fdcnum); //write reset isbc202 - // one-time initialization for all FDDs for this FDC instance - for (i = 0; i < FDD_NUM; i++) { - uptr = isbc202_dev.units + i; - uptr->u5 = isbc202_fdcnum; //fdc device number - uptr->u6 = i; //fdd unit number - uptr->flags |= UNIT_WPMODE; //set WP in unit flags - } - isbc202_reset1(isbc202_fdcnum); //software reset - isbc202_fdcnum++; //next FDC instance - } else - sim_printf(" - Not Found\n"); - return SCPE_OK; -} - -/* Software reset routine */ - -void isbc202_reset1(uint8 fdcnum) -{ - int32 i; - UNIT *uptr; - - sim_printf(" isbc202-%d: Software Reset\n", fdcnum); - fdc202[fdcnum].stat = 0; //clear status - for (i = 0; i < FDD_NUM; i++) { /* handle all FDDs */ - uptr = isbc202_dev.units + i; - fdc202[fdcnum].stat |= FDCPRE | FDCDD; //set the FDC status - fdc202[fdcnum].rtype = ROK; -// sim_printf("FDD %d uptr->capac=%d\n", i, uptr->capac); - if (uptr->capac == 0) { /* if not configured */ - sim_printf(" SBC202%d: Configured, FDC Status=%02X Not attached\n", i, fdc202[fdcnum].stat); - } else { - switch(i){ - case 0: - fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready - fdc202[fdcnum].rbyte1 |= RB1RD0; - break; - case 1: - fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready - fdc202[fdcnum].rbyte1 |= RB1RD1; - break; - case 2: - fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready - fdc202[fdcnum].rbyte1 |= RB1RD2; - break; - case 3: - fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready - fdc202[fdcnum].rbyte1 |= RB1RD3; - break; - } - fdc202[fdcnum].rdychg = 0; - sim_printf(" SBC202%d: Configured, FDC Status=%02X Attached to %s\n", - i, fdc202[fdcnum].stat, uptr->filename); - } - } -} - -/* isbc202 attach - attach an .IMG file to a FDD */ - -t_stat isbc202_attach (UNIT *uptr, CONST char *cptr) -{ - t_stat r; - uint8 fdcnum, fddnum; - - sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_attach: Entered with cptr=%s\n", cptr); - if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { - sim_printf(" isbc202_attach: Attach error\n"); - return r; - } - fdcnum = uptr->u5; - fddnum = uptr->u6; - uptr->capac = MDSDD; - switch(fddnum){ - case 0: - fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready - fdc202[fdcnum].rbyte1 |= RB1RD0; - break; - case 1: - fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready - fdc202[fdcnum].rbyte1 |= RB1RD1; - break; - case 2: - fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready - fdc202[fdcnum].rbyte1 |= RB1RD2; - break; - case 3: - fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready - fdc202[fdcnum].rbyte1 |= RB1RD3; - break; - } - fdc202[fdcnum].rtype = ROK; - sim_printf(" iSBC-202%d: FDD: %d Configured %d bytes, Attached to %s\n", - fdcnum, fddnum, uptr->capac, uptr->filename); - sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_attach: Done\n"); - return SCPE_OK; -} - -/* isbc202 set mode = Write protect */ - -t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ - sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_set_mode: Entered with val=%08XH uptr->flags=%08X\n", - val, uptr->flags); - if (val & UNIT_WPMODE) { /* write protect */ - uptr->flags |= val; - } else { /* read write */ - uptr->flags &= ~val; - } - sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_set_mode: Done\n"); - return SCPE_OK; -} - -uint8 isbc202_get_dn(void) -{ - int i; - - for (i=0; i= fdc202[i].baseport && port <= fdc202[i].baseport + 7) - return i; - sim_printf("isbc202_get_dn: port %04X not in isbc202 device table\n", port); - return 0xFF; -} - -/* ISBC202 control port functions */ - -uint8 isbc2020(t_bool io, uint8 data) -{ - uint8 fdcnum; - - if ((fdcnum = isbc202_get_dn()) != 0xFF) { - if (io == 0) { /* read ststus*/ - if (DEBUG) - sim_printf("\n isbc202-%d: 0x78 returned status=%02X PCX=%04X", - fdcnum, fdc202[fdcnum].stat, PCX); - return fdc202[fdcnum].stat; - } - } - return 0; -} - -uint8 isbc2021(t_bool io, uint8 data) -{ - uint8 fdcnum; - - if ((fdcnum = isbc202_get_dn()) != 0xFF) { - if (io == 0) { /* read data port */ - fdc202[fdcnum].intff = 0; //clear interrupt FF - fdc202[fdcnum].stat &= ~FDCINT; - if (DEBUG) - sim_printf("\n isbc202-%d: 0x79 returned rtype=%02X intff=%02X status=%02X PCX=%04X", - fdcnum, fdc202[fdcnum].rtype, fdc202[fdcnum].intff, fdc202[fdcnum].stat, PCX); - return fdc202[fdcnum].rtype; - } else { /* write data port */ - fdc202[fdcnum].iopb = data; - if (DEBUG) - sim_printf("\n isbc202-%d: 0x79 IOPB low=%02X PCX=%04X", - fdcnum, data, PCX); - } - } - return 0; -} - -uint8 isbc2022(t_bool io, uint8 data) -{ - uint8 fdcnum; - int i; - - if ((fdcnum = isbc202_get_dn()) != 0xFF) { - if (io == 0) { /* read data port */ - ; - } else { /* write data port */ - fdc202[fdcnum].iopb |= (data << 8); -// if (DEBUG) - sim_printf("\n isbc202-%d: 0x7A IOPB=%04X PCX=%04X", - fdcnum, fdc202[fdcnum].iopb, PCX); - sim_printf("\nIOPB: "); - for (i=0; i<7; i++) - sim_printf("%02X ", multibus_get_mbyte(fdc202[fdcnum].iopb + i)); - sim_printf("\n"); - isbc202_diskio(fdcnum); - if (fdc202[fdcnum].intff) - fdc202[fdcnum].stat |= FDCINT; - } - } - return 0; -} - -uint8 isbc2023(t_bool io, uint8 data) -{ - uint8 fdcnum; - - if ((fdcnum = isbc202_get_dn()) != 0xFF) { - if (io == 0) { /* read data port */ - if (fdc202[fdcnum].rtype == 0) { - if (DEBUG) - sim_printf("\n isbc202-%d: 0x7B returned rbyte0=%02X PCX=%04X", - fdcnum, fdc202[fdcnum].rbyte0, PCX); - return fdc202[fdcnum].rbyte0; - } else { - if (fdc202[fdcnum].rdychg) { - if (DEBUG) - sim_printf("\n isbc202-%d: 0x7B returned rbyte1=%02X PCX=%04X", - fdcnum, fdc202[fdcnum].rbyte1, PCX); - return fdc202[fdcnum].rbyte1; - } else { - if (DEBUG) - sim_printf("\n isbc202-%d: 0x7B returned rbytex=%02X PCX=%04X", - fdcnum, 0, PCX); - return 0; - } - } - } else { /* write data port */ - ; //stop diskette operation - } - } - return 0; -} - -uint8 isbc2027(t_bool io, uint8 data) -{ - uint8 fdcnum; - - if ((fdcnum = isbc202_get_dn()) != 0xFF) { - if (io == 0) { /* read data port */ - ; - } else { /* write data port */ - isbc202_reset1(fdcnum); - } - } - return 0; -} - -// perform the actual disk I/O operation - -void isbc202_diskio(uint8 fdcnum) -{ - uint8 cw, di, nr, ta, sa, data, nrptr; - uint16 ba; - uint32 dskoff; - uint8 fddnum, fmtb; - uint32 i; - UNIT *uptr; - uint8 *fbuf = (uint8 *) (isbc202_dev.units + fddnum)->filebuf; - - //parse the IOPB - cw = multibus_get_mbyte(fdc202[fdcnum].iopb); - di = multibus_get_mbyte(fdc202[fdcnum].iopb + 1); - nr = multibus_get_mbyte(fdc202[fdcnum].iopb + 2); - ta = multibus_get_mbyte(fdc202[fdcnum].iopb + 3); - sa = multibus_get_mbyte(fdc202[fdcnum].iopb + 4); - ba = multibus_get_mword(fdc202[fdcnum].iopb + 5); - fddnum = (di & 0x30) >> 4; - uptr = isbc202_dev.units + fddnum; - if (DEBUG) { - sim_printf("\n isbc202-%d: isbc202_diskio IOPB=%04X FDD=%02X STAT=%02X", - fdcnum, fdc202[fdcnum].iopb, fddnum, fdc202[fdcnum].stat); - sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X", - fdcnum, cw, di, nr, ta, sa, ba); - } - //check for not ready - switch(fddnum) { - case 0: - if ((fdc202[fdcnum].stat & RDY0) == 0) { - fdc202[fdcnum].rtype = RERR; - fdc202[fdcnum].rbyte0 = RB0NR; - fdc202[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum); - return; - } - break; - case 1: - if ((fdc202[fdcnum].stat & RDY1) == 0) { - fdc202[fdcnum].rtype = RERR; - fdc202[fdcnum].rbyte0 = RB0NR; - fdc202[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum); - return; - } - break; - case 2: - if ((fdc202[fdcnum].stat & RDY2) == 0) { - fdc202[fdcnum].rtype = RERR; - fdc202[fdcnum].rbyte0 = RB0NR; - fdc202[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum); - return; - } - break; - case 3: - if ((fdc202[fdcnum].stat & RDY3) == 0) { - fdc202[fdcnum].rtype = RERR; - fdc202[fdcnum].rbyte0 = RB0NR; - fdc202[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum); - return; - } - break; - } - //check for address error - if ( - ((di & 0x07) != DHOME) && ( - (sa > MAXSECDD) || - ((sa + nr) > (MAXSECDD + 1)) || - (sa == 0) || - (ta > MAXTRK) - )) { - fdc202[fdcnum].rtype = RERR; - fdc202[fdcnum].rbyte0 = RB0ADR; - fdc202[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc202-%d: Address error on drive %d", fdcnum, fddnum); - return; - } - switch (di & 0x07) { //decode disk command - case DNOP: - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].intff = 1; //set interrupt FF - break; - case DSEEK: - fdc202[fdcnum].fdd[fddnum].sec = sa; - fdc202[fdcnum].fdd[fddnum].cyl = ta; - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].intff = 1; //set interrupt FF - break; - case DHOME: - fdc202[fdcnum].fdd[fddnum].sec = sa; - fdc202[fdcnum].fdd[fddnum].cyl = 0; - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].intff = 1; //set interrupt FF - break; - case DVCRC: - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].intff = 1; //set interrupt FF - break; - case DFMT: - //check for WP - if(uptr->flags & UNIT_WPMODE) { - fdc202[fdcnum].rtype = RERR; - fdc202[fdcnum].rbyte0 = RB0WP; - fdc202[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc202-%d: Write protect error 1 on drive %d", fdcnum, fddnum); - return; - } - fmtb = multibus_get_mbyte(ba); //get the format byte - //calculate offset into disk image - dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; - for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) { - *(fbuf + (dskoff + i)) = fmtb; - } - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].intff = 1; //set interrupt FF - break; - case DREAD: - nrptr = 0; - while(nrptr < nr) { - //calculate offset into disk image - dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; -// if (DEBUG) - sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", - fdcnum, cw, di, nr, ta, sa, ba, dskoff); - for (i=0; i<128; i++) { //copy sector from image to RAM - data = *(fbuf + (dskoff + i)); - multibus_put_mbyte(ba + i, data); - } - sa++; - ba+=0x80; - nrptr++; - } - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].intff = 1; //set interrupt FF - break; - case DWRITE: - //check for WP - if(uptr->flags & UNIT_WPMODE) { - fdc202[fdcnum].rtype = RERR; - fdc202[fdcnum].rbyte0 = RB0WP; - fdc202[fdcnum].intff = 1; //set interrupt FF - sim_printf("\n isbc202-%d: Write protect error 2 on drive %d", fdcnum, fddnum); - return; - } - nrptr = 0; - while(nrptr < nr) { - //calculate offset into disk image - dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; - // if (DEBUG) - // sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", - // fdcnum, cw, di, nr, ta, sa, ba, dskoff); - for (i=0; i<128; i++) { //copy sector from image to RAM - data = multibus_get_mbyte(ba + i); - *(fbuf + (dskoff + i)) = data; - } - sa++; - ba+=0x80; - nrptr++; - } - fdc202[fdcnum].rtype = ROK; - fdc202[fdcnum].intff = 1; //set interrupt FF - break; - default: - sim_printf("\n isbc202-%d: isbc202_diskio bad di=%02X", fdcnum, di & 0x07); - break; - } -} - -/* end of isbc202.c */ diff --git a/Intel-Systems/common/multibus.c b/Intel-Systems/common/multibus.c index 23bb66eb..40c5ef76 100644 --- a/Intel-Systems/common/multibus.c +++ b/Intel-Systems/common/multibus.c @@ -143,7 +143,7 @@ t_stat multibus_svc(UNIT *uptr) t_stat multibus_reset(DEVICE *dptr) { SBC_reset(NULL); - sim_printf("Initializing The Multibus\n Multibus Boards:\n"); + sim_printf(" Multibus: Reset\n"); isbc064_reset(NULL); isbc201_fdcnum = 0; isbc201_reset(NULL, SBC201_BASE); diff --git a/Intel-Systems/common/zx200a.c b/Intel-Systems/common/zx200a.c index f6154a46..3a6722bf 100644 --- a/Intel-Systems/common/zx200a.c +++ b/Intel-Systems/common/zx200a.c @@ -127,7 +127,7 @@ u3 - u4 - - u5 - fdc number. + u5 - fdc number (board instance number). u6 - fdd number. The ZX-200A appears to the multibus system as if there were an iSBC-201 @@ -184,6 +184,13 @@ #define RB1RD0 0x40 //drive 0 ready #define RB1RD1 0x80 //drive 1 ready +//disk geometry values +#define MDSSD 256256 //single density FDD size +#define MDSDD 512512 //double density FDD size +#define MAXSECSD 26 //single density last sector +#define MAXSECDD 52 //double density last sector +#define MAXTRK 76 //last track + /* external function prototypes */ extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); @@ -215,13 +222,14 @@ void zx200a_diskio(uint8 fdcnum); int32 zx200a_fdcnum = 0; //actual number of ZX-200A instances + 1 typedef struct { //FDD definition - uint8 *buf; +// uint8 *buf; int t0; int rdy; uint8 sec; uint8 cyl; - uint8 maxsec; - uint8 maxcyl; + uint8 dd; +// uint8 maxsec; +// uint8 maxcyl; } FDDDEF; typedef struct { //FDC definition @@ -236,13 +244,13 @@ typedef struct { //FDC definition FDDDEF fdd[FDD_NUM]; //indexed by the FDD number } FDCDEF; -FDCDEF zx200a[4]; //indexed by the isbc-202 instance number +FDCDEF zx200a[4]; //indexed by the zx200a instance number UNIT zx200a_unit[] = { - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }, - { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 } + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, + { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 } }; REG zx200a_reg[] = { @@ -259,13 +267,13 @@ REG zx200a_reg[] = { { HRDATA (STAT2, zx200a[2].stat, 8) }, /* zx200a 2 status */ { HRDATA (RTYP2, zx200a[2].rtype, 8) }, /* zx200a 2 result type */ { HRDATA (RBYT2A, zx200a[2].rbyte0, 8) }, /* zx200a 2 result byte 0 */ - { HRDATA (RBYT2B, zx200a[0].rbyte1, 8) }, /* zx200a 2 result byte 1 */ + { HRDATA (RBYT2B, zx200a[2].rbyte1, 8) }, /* zx200a 2 result byte 1 */ { HRDATA (INTFF2, zx200a[2].intff, 8) }, /* zx200a 2 interrupt f/f */ { HRDATA (STAT3, zx200a[3].stat, 8) }, /* zx200a 3 status */ { HRDATA (RTYP3, zx200a[3].rtype, 8) }, /* zx200a 3 result type */ { HRDATA (RBYT3A, zx200a[3].rbyte0, 8) }, /* zx200a 3 result byte 0 */ { HRDATA (RBYT3B, zx200a[3].rbyte1, 8) }, /* zx200a 3 result byte 1 */ - { HRDATA (INTFF3, zx200a[0].intff, 8) }, /* zx200a 3 interrupt f/f */ + { HRDATA (INTFF3, zx200a[3].intff, 8) }, /* zx200a 3 interrupt f/f */ { NULL } }; @@ -323,12 +331,17 @@ DEVICE zx200a_dev = { t_stat zx200a_reset(DEVICE *dptr, uint16 base) { + int32 i; + UNIT *uptr; + sim_printf(" ZX-200A FDC Board"); if (ZX200A_NUM) { sim_printf(" - Found on Port %02X\n", base); sim_printf(" ZX200A-%d: Hardware Reset\n", zx200a_fdcnum); sim_printf(" ZX200A-%d: Registered at %04X\n", zx200a_fdcnum, base); + //register base port address for this FDC instance zx200a[zx200a_fdcnum].baseport = base; + //register I/O port addresses for each function reg_dev(zx200a0, base, zx200a_fdcnum); reg_dev(zx200a1, base + 1, zx200a_fdcnum); reg_dev(zx200a2, base + 2, zx200a_fdcnum); @@ -339,10 +352,17 @@ t_stat zx200a_reset(DEVICE *dptr, uint16 base) reg_dev(zx200a2, base+16 + 2, zx200a_fdcnum); reg_dev(zx200a3, base+16 + 3, zx200a_fdcnum); reg_dev(zx200a7, base+16 + 7, zx200a_fdcnum); + // one-time initialization for all FDDs for this FDC instance + for (i = 0; i < FDD_NUM; i++) { + uptr = zx200a_dev.units + i; + uptr->u5 = zx200a_fdcnum; //fdc device number + uptr->u6 = i; //fdd unit number + uptr->flags |= UNIT_WPMODE; //set WP in unit flags + } zx200a_reset1(zx200a_fdcnum); zx200a_fdcnum++; } else - sim_printf(" - Not Found on Port %02X\n", base); + sim_printf(" - Not Found\n"); return SCPE_OK; } /* Software reset routine */ @@ -359,33 +379,27 @@ void zx200a_reset1(uint8 fdcnum) zx200a[fdcnum].stat |= FDCPRE | FDCDD; //set the FDC status zx200a[fdcnum].rtype = ROK; if (uptr->capac == 0) { /* if not configured */ - uptr->u5 = fdcnum; //fdc device number - uptr->u6 = i; /* unit number - only set here! */ - uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */ sim_printf(" ZX-200A%d: Configured, Status=%02X Not attached\n", i, zx200a[fdcnum].stat); } else { switch(i){ case 0: zx200a[fdcnum].stat |= RDY0; //set FDD 0 ready zx200a[fdcnum].rbyte1 |= RB1RD0; - zx200a[fdcnum].rdychg = 0; break; case 1: zx200a[fdcnum].stat |= RDY1; //set FDD 1 ready zx200a[fdcnum].rbyte1 |= RB1RD1; - zx200a[fdcnum].rdychg = 0; break; case 2: zx200a[fdcnum].stat |= RDY2; //set FDD 2 ready zx200a[fdcnum].rbyte1 |= RB1RD2; - zx200a[fdcnum].rdychg = 0; break; case 3: zx200a[fdcnum].stat |= RDY3; //set FDD 3 ready zx200a[fdcnum].rbyte1 |= RB1RD3; - zx200a[fdcnum].rdychg = 0; break; } + zx200a[fdcnum].rdychg = 0; sim_printf(" ZX-200A%d: Configured, Status=%02X Attached to %s\n", i, zx200a[fdcnum].stat, uptr->filename); } @@ -397,9 +411,6 @@ void zx200a_reset1(uint8 fdcnum) t_stat zx200a_attach (UNIT *uptr, CONST char *cptr) { t_stat r; - FILE *fp; - int32 i, c = 0; - long flen; uint8 fdcnum, fddnum; sim_debug (DEBUG_flow, &zx200a_dev, " zx200a_attach: Entered with cptr=%s\n", cptr); @@ -409,74 +420,42 @@ t_stat zx200a_attach (UNIT *uptr, CONST char *cptr) } fdcnum = uptr->u5; fddnum = uptr->u6; - fp = fopen(uptr->filename, "rb"); - if (fp == NULL) { - sim_printf(" Unable to open disk image file %s\n", uptr->filename); - sim_printf(" No disk image loaded!!!\n"); - } else { - sim_printf("zx200a: Attach\n"); - fseek(fp, 0, SEEK_END); /* size disk image */ - flen = ftell(fp); - fseek(fp, 0, SEEK_SET); - if (flen == -1) { - sim_printf(" zx200a_attach: File error\n"); - fclose(fp); - return SCPE_IOERR; - } - if (zx200a[fdcnum].fdd[fddnum].buf == NULL) { /* no buffer allocated */ - zx200a[fdcnum].fdd[fddnum].buf = (uint8 *)malloc(flen); - if (zx200a[fdcnum].fdd[fddnum].buf == NULL) { - sim_printf(" zx200a_attach: Malloc error\n"); - fclose(fp); - return SCPE_MEM; - } + switch(fddnum){ + case 0: + zx200a[fdcnum].stat |= RDY0; //set FDD 0 ready + zx200a[fdcnum].rbyte1 |= RB1RD0; + break; + case 1: + zx200a[fdcnum].stat |= RDY1; //set FDD 1 ready + zx200a[fdcnum].rbyte1 |= RB1RD1; + break; + case 2: + zx200a[fdcnum].stat |= RDY2; //set FDD 2 ready + zx200a[fdcnum].rbyte1 |= RB1RD2; + break; + case 3: + zx200a[fdcnum].stat |= RDY3; //set FDD 3 ready + zx200a[fdcnum].rbyte1 |= RB1RD3; + break; } - uptr->capac = flen; - i = 0; - c = fgetc(fp); // copy disk image into buffer - while (c != EOF) { - *(zx200a[fdcnum].fdd[fddnum].buf + i++) = c & 0xFF; - c = fgetc(fp); - } - fclose(fp); - switch(fddnum){ - case 0: - zx200a[fdcnum].stat |= RDY0; //set FDD 0 ready - zx200a[fdcnum].rtype = ROK; - zx200a[fdcnum].rbyte1 |= RB1RD0; - break; - case 1: - zx200a[fdcnum].stat |= RDY1; //set FDD 1 ready - zx200a[fdcnum].rtype = ROK; - zx200a[fdcnum].rbyte1 |= RB1RD1; - break; - case 2: - zx200a[fdcnum].stat |= RDY2; //set FDD 2 ready - zx200a[fdcnum].rtype = ROK; - zx200a[fdcnum].rbyte1 |= RB1RD2; - break; - case 3: - zx200a[fdcnum].stat |= RDY3; //set FDD 3 ready - zx200a[fdcnum].rtype = ROK; - zx200a[fdcnum].rbyte1 |= RB1RD3; - break; - } - if (flen == 256256) { /* 8" 256K SSSD */ - zx200a[fdcnum].fdd[fddnum].maxcyl = 77; - zx200a[fdcnum].fdd[fddnum].maxsec = 26; - zx200a[fdcnum].fdd[fddnum].sec = 1; - zx200a[fdcnum].fdd[fddnum].cyl = 0; - } - else if (flen == 512512) { /* 8" 512K SSDD */ - zx200a[fdcnum].fdd[fddnum].maxcyl = 77; - zx200a[fdcnum].fdd[fddnum].maxsec = 52; - zx200a[fdcnum].fdd[fddnum].sec = 1; - zx200a[fdcnum].fdd[fddnum].cyl = 0; - } else - sim_printf(" ZX-200A-%d: Not a known disk image\n", fdcnum); - sim_printf(" ZX-200A-%d: Configured %d bytes, Attached to %s\n", - fdcnum, uptr->capac, uptr->filename); + zx200a[fdcnum].rtype = ROK; + if (uptr->capac == 256256 && (fddnum == 2 || fddnum == 3)) { /* 8" 256K SSSD */ + zx200a[fdcnum].fdd[fddnum].dd = 0; +// zx200a[fdcnum].fdd[fddnum].maxcyl = 77; +// zx200a[fdcnum].fdd[fddnum].maxsec = 26; + zx200a[fdcnum].fdd[fddnum].sec = 1; + zx200a[fdcnum].fdd[fddnum].cyl = 0; } + else if (uptr->capac == 512512) { /* 8" 512K SSDD */ + zx200a[fdcnum].fdd[fddnum].dd = 1; +// zx200a[fdcnum].fdd[fddnum].maxcyl = 77; +// zx200a[fdcnum].fdd[fddnum].maxsec = 52; + zx200a[fdcnum].fdd[fddnum].sec = 1; + zx200a[fdcnum].fdd[fddnum].cyl = 0; + } else + sim_printf(" ZX-200A-%d: Invalid disk image or SD on drive 0 or 1\n", fdcnum); + sim_printf(" ZX-200A-%d: Configured %d bytes, Attached to %s\n", + fdcnum, uptr->capac, uptr->filename); sim_debug (DEBUG_flow, &zx200a_dev, " ZX-200A_attach: Done\n"); return SCPE_OK; } @@ -621,13 +600,14 @@ uint8 zx200a7(t_bool io, uint8 data) void zx200a_diskio(uint8 fdcnum) { - uint8 cw, di, nr, ta, sa, data, nrptr, c; + uint8 cw, di, nr, ta, sa, data, nrptr; uint16 ba; uint32 dskoff; uint8 fddnum, fmtb; uint32 i; UNIT *uptr; - FILE *fp; + uint8 *fbuf; + //parse the IOPB cw = multibus_get_mbyte(zx200a[fdcnum].iopb); di = multibus_get_mbyte(zx200a[fdcnum].iopb + 1); @@ -637,13 +617,12 @@ void zx200a_diskio(uint8 fdcnum) ba = multibus_get_mword(zx200a[fdcnum].iopb + 5); fddnum = (di & 0x30) >> 4; uptr = zx200a_dev.units + fddnum; + fbuf = (uint8 *) (zx200a_dev.units + fddnum)->filebuf; if (DEBUG) { sim_printf("\n zx200a-%d: zx200a_diskio IOPB=%04X FDD=%02X STAT=%02X", fdcnum, zx200a[fdcnum].iopb, fddnum, zx200a[fdcnum].stat); sim_printf("\n zx200a-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X", fdcnum, cw, di, nr, ta, sa, ba); -// sim_printf("\n zx200a-%d: maxsec=%02X maxcyl=%02X", -// fdcnum, zx200a[fdcnum].fdd[fddnum].maxsec, zx200a[fdcnum].fdd[fddnum].maxcyl); } //check for not ready switch(fddnum) { @@ -685,26 +664,52 @@ void zx200a_diskio(uint8 fdcnum) break; } //check for address error - if ( - ((di & 0x07) != 0x03) && ( - (sa > zx200a[fdcnum].fdd[fddnum].maxsec) || - ((sa + nr) > (zx200a[fdcnum].fdd[fddnum].maxsec + 1)) || - (sa == 0) || - (ta > zx200a[fdcnum].fdd[fddnum].maxcyl) - )) { - if (DEBUG) - sim_printf("\n zx200a-%d: maxsec=%02X maxcyl=%02X", - fdcnum, zx200a[fdcnum].fdd[fddnum].maxsec, zx200a[fdcnum].fdd[fddnum].maxcyl); + if (zx200a[fdcnum].fdd[fddnum].dd == 1) { + if ( + ((di & 0x07) != DHOME) && ( + (sa > MAXSECDD) || + ((sa + nr) > (MAXSECDD + 1)) || + (sa == 0) || + (ta > MAXTRK) + )) { zx200a[fdcnum].rtype = RERR; zx200a[fdcnum].rbyte0 = RB0ADR; zx200a[fdcnum].intff = 1; //set interrupt FF sim_printf("\n zx200a-%d: Address error on drive %d", fdcnum, fddnum); return; + } + } else if (zx200a[fdcnum].fdd[fddnum].dd == 0) { + if ( + ((di & 0x07) != DHOME) && ( + (sa > MAXSECSD) || + ((sa + nr) > (MAXSECSD + 1)) || + (sa == 0) || + (ta > MAXTRK) + )) { + zx200a[fdcnum].rtype = RERR; + zx200a[fdcnum].rbyte0 = RB0ADR; + zx200a[fdcnum].intff = 1; //set interrupt FF + sim_printf("\n zx200a-%d: Address error on drive %d", fdcnum, fddnum); + return; + } } switch (di & 0x07) { case DNOP: + zx200a[fdcnum].rtype = ROK; + zx200a[fdcnum].intff = 1; //set interrupt FF + break; case DSEEK: + zx200a[fdcnum].fdd[fddnum].sec = sa; + zx200a[fdcnum].fdd[fddnum].cyl = ta; + zx200a[fdcnum].rtype = ROK; + zx200a[fdcnum].intff = 1; //set interrupt FF + break; case DHOME: + zx200a[fdcnum].fdd[fddnum].sec = sa; + zx200a[fdcnum].fdd[fddnum].cyl = 0; + zx200a[fdcnum].rtype = ROK; + zx200a[fdcnum].intff = 1; //set interrupt FF + break; case DVCRC: zx200a[fdcnum].rtype = ROK; zx200a[fdcnum].intff = 1; //set interrupt FF @@ -719,18 +724,19 @@ void zx200a_diskio(uint8 fdcnum) return; } fmtb = multibus_get_mbyte(ba); //get the format byte - //calculate offset into disk image - dskoff = ((ta * (uint32)(zx200a[fdcnum].fdd[fddnum].maxsec)) + (sa - 1)) * 128; - for(i=0; i<=((uint32)(zx200a[fdcnum].fdd[fddnum].maxsec) * 128); i++) { - *(zx200a[fdcnum].fdd[fddnum].buf + (dskoff + i)) = fmtb; + if (zx200a[fdcnum].fdd[fddnum].dd == 1) { + //calculate offset into DD disk image + dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; + for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) { + *(fbuf + (dskoff + i)) = fmtb; + } + } else { + //calculate offset into SD disk image + dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; + for(i=0; i<=((uint32)(MAXSECSD) * 128); i++) { + *(fbuf + (dskoff + i)) = fmtb; + } } - //*** quick fix. Needs more thought! - fp = fopen(uptr->filename, "wb"); // write out modified image - for (i=0; icapac; i++) { - c = *(zx200a[fdcnum].fdd[fddnum].buf + i); - fputc(c, fp); - } - fclose(fp); zx200a[fdcnum].rtype = ROK; zx200a[fdcnum].intff = 1; //set interrupt FF break; @@ -738,11 +744,17 @@ void zx200a_diskio(uint8 fdcnum) nrptr = 0; while(nrptr < nr) { //calculate offset into disk image - dskoff = ((ta * zx200a[fdcnum].fdd[fddnum].maxsec) + (sa - 1)) * 128; -// sim_printf("\n zx200a-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", -// fdcnum, cw, di, nr, ta, sa, ba, dskoff); - for (i=0; i<128; i++) { //copy sector from image to RAM - data = *(zx200a[fdcnum].fdd[fddnum].buf + (dskoff + i)); + if (zx200a[fdcnum].fdd[fddnum].dd == 1) { + dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; + } else { + dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; + } + if (DEBUG) + sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", + fdcnum, cw, di, nr, ta, sa, ba, dskoff); + //copy sector from image to RAM + for (i=0; i<128; i++) { + data = *(fbuf + (dskoff + i)); multibus_put_mbyte(ba + i, data); } sa++; @@ -764,24 +776,22 @@ void zx200a_diskio(uint8 fdcnum) nrptr = 0; while(nrptr < nr) { //calculate offset into disk image - dskoff = ((ta * zx200a[fdcnum].fdd[fddnum].maxsec) + (sa - 1)) * 128; - // sim_printf("\n zx200a-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", - // fdcnum, cw, di, nr, ta, sa, ba, dskoff); - for (i=0; i<128; i++) { //copy sector from image to RAM + if (zx200a[fdcnum].fdd[fddnum].dd == 1) { + dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; + } else { + dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; + } + if (DEBUG) + sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", + fdcnum, cw, di, nr, ta, sa, ba, dskoff); + for (i=0; i<128; i++) { //copy sector from image to RAM data = multibus_get_mbyte(ba + i); - *(zx200a[fdcnum].fdd[fddnum].buf + (dskoff + i)) = data; + *(fbuf + (dskoff + i)) = data; } sa++; ba+=0x80; nrptr++; } - //*** quick fix. Needs more thought! - fp = fopen(uptr->filename, "wb"); // write out modified image - for (i=0; icapac; i++) { - c = *(zx200a[fdcnum].fdd[fddnum].buf + i); - fputc(c, fp); - } - fclose(fp); zx200a[fdcnum].rtype = ROK; zx200a[fdcnum].intff = 1; //set interrupt FF break; diff --git a/Intel-Systems/imds-225/ipc.c b/Intel-Systems/imds-225/ipc.c index b20a1b3e..79d82199 100644 --- a/Intel-Systems/imds-225/ipc.c +++ b/Intel-Systems/imds-225/ipc.c @@ -31,6 +31,8 @@ #include "system_defs.h" +#define DEBUG 0 + /* function prototypes */ uint8 get_mbyte(uint16 addr); @@ -123,15 +125,18 @@ uint16 get_mword(uint16 addr) void put_mbyte(uint16 addr, uint8 val) { if (addr >= 0xF800) { //monitor ROM - always there - sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX); + if (DEBUG) + sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX); return; } if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup - sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX); + if (DEBUG) + sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX); return; } if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM - sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX); + if (DEBUG) + sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX); return; } RAM_put_mbyte(addr, val); diff --git a/Intel-Systems/imds-225/system_defs.h b/Intel-Systems/imds-225/system_defs.h index 4ca3cf22..f7483e63 100644 --- a/Intel-Systems/imds-225/system_defs.h +++ b/Intel-Systems/imds-225/system_defs.h @@ -69,7 +69,7 @@ //board definitions for the multibus /* set the base I/O address for the iSBC 201 */ -#define SBC201_BASE 0x88 +#define SBC201_BASE 0x78 #define SBC201_INT INT_1 #define SBC201_NUM 0 @@ -84,8 +84,7 @@ #define SBC208_NUM 0 /* set the base for the zx-200a disk controller */ -#define ZX200A_BASE_DD 0x78 -#define ZX200A_BASE_SD 0x88 +#define ZX200A_BASE 0x78 #define ZX200A_NUM 0 /* set INTR for CPU */ diff --git a/Intel-Systems/isys8010/system_defs.h b/Intel-Systems/isys8010/system_defs.h index c143e10d..ad982e89 100644 --- a/Intel-Systems/isys8010/system_defs.h +++ b/Intel-Systems/isys8010/system_defs.h @@ -33,7 +33,7 @@ #define SET_XACK(VAL) (xack = VAL) //chip definitions for the iSBC-80/10 -/* set the base I/O address and device count for the 8251s */ +/* set the base I/O address and device count for the 8251s */ #define I8251_BASE 0xEC #define I8251_NUM 1 @@ -59,7 +59,7 @@ /* set the base I/O address for the iSBC 201 */ #define SBC201_BASE 0x88 #define SBC201_INT INT_1 -#define SBC201_NUM 1 +#define SBC201_NUM 0 /* set the base I/O address for the iSBC 202 */ #define SBC202_BASE 0x78 diff --git a/Intel-Systems/isys8030/system_defs.h b/Intel-Systems/isys8030/system_defs.h index 957edc4a..717477d6 100644 --- a/Intel-Systems/isys8030/system_defs.h +++ b/Intel-Systems/isys8030/system_defs.h @@ -37,7 +37,7 @@ #define I8041_BASE 0xDC #define I8041_NUM 1 -/* set the base I/O address and device count for the 8251s */ +/* set the base I/O address and device count for the 8251s */ #define I8251_BASE 0xEC #define I8251_NUM 1 diff --git a/Visual Studio Projects/imds-225.vcproj b/Visual Studio Projects/imds-225.vcproj index e69cae89..08baa5ae 100644 --- a/Visual Studio Projects/imds-225.vcproj +++ b/Visual Studio Projects/imds-225.vcproj @@ -208,6 +208,10 @@ RelativePath="..\Intel-Systems\common\i8259.c" > + + @@ -224,16 +228,12 @@ RelativePath="..\Intel-Systems\imds-225\ipc.c" > - -