mirror of
https://github.com/simh/simh.git
synced 2026-01-25 11:46:37 +00:00
IBMPC, IBMPCXT, isys80xx: Restructure directories to eliminate redundant files
This commit is contained in:
4875
Intel-Systems/common/i8088.c
Normal file
4875
Intel-Systems/common/i8088.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -41,10 +41,6 @@
|
||||
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
|
||||
@@ -248,11 +244,11 @@ extern uint16 port; //port called in dev_table[port]
|
||||
int32 i8237_devnum = 0; //actual number of 8253 instances + 1
|
||||
uint16 i8237_port[4]; //base port registered to each instance
|
||||
|
||||
/* function prototypes */
|
||||
/* internal function prototypes */
|
||||
|
||||
t_stat i8237_svc(UNIT *uptr);
|
||||
t_stat i8237_reset(DEVICE *dptr, uint16 base);
|
||||
void i8237_reset1(int32 devnum);
|
||||
t_stat i8237_svc (UNIT *uptr);
|
||||
t_stat i8237_reset (DEVICE *dptr, uint16 base);
|
||||
void i8237_reset1 (void);
|
||||
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);
|
||||
@@ -277,28 +273,28 @@ 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
|
||||
uint16 i8237_r0; // 8237 ch 0 address register
|
||||
uint16 i8237_r1; // 8237 ch 0 count register
|
||||
uint16 i8237_r2; // 8237 ch 1 address register
|
||||
uint16 i8237_r3; // 8237 ch 1 count register
|
||||
uint16 i8237_r4; // 8237 ch 2 address register
|
||||
uint16 i8237_r5; // 8237 ch 2 count register
|
||||
uint16 i8237_r6; // 8237 ch 3 address register
|
||||
uint16 i8237_r7; // 8237 ch 3 count register
|
||||
uint8 i8237_r8; // 8237 status register
|
||||
uint8 i8237_r9; // 8237 command register
|
||||
uint8 i8237_rA; // 8237 mode register
|
||||
uint8 i8237_rB; // 8237 mask register
|
||||
uint8 i8237_rC; // 8237 request register
|
||||
uint8 i8237_rD; // 8237 first/last ff
|
||||
uint8 i8237_rE; // 8237
|
||||
uint8 i8237_rF; // 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
|
||||
uint16 i8237_sr; // isbc-208 segment register
|
||||
uint8 i8237_i; // iSBC-208 interrupt register
|
||||
uint8 i8237_a; // iSBC-208 auxillary port register
|
||||
|
||||
/* i8237 Standard SIMH Device Data Structures - 1 unit */
|
||||
|
||||
@@ -311,9 +307,9 @@ UNIT i8237_unit[] = {
|
||||
|
||||
|
||||
REG i8237_reg[] = {
|
||||
{ HRDATA (CH0ADR, i8237_r0[devnum], 16) },
|
||||
{ HRDATA (CH0CNT, i8237_r1[devnum], 16) },
|
||||
{ HRDATA (CH1ADR, i8237_r2[devnum], 16) },
|
||||
{ HRDATA (CH0ADR, i8237_r0, 16) },
|
||||
{ HRDATA (CH0CNT, i8237_r1, 16) },
|
||||
{ HRDATA (CH1ADR, i8237_r2, 16) },
|
||||
{ HRDATA (CH1CNT, i8237_r3, 16) },
|
||||
{ HRDATA (CH2ADR, i8237_r4, 16) },
|
||||
{ HRDATA (CH2CNT, i8237_r5, 16) },
|
||||
@@ -347,7 +343,7 @@ DEBTAB i8237_debug[] = {
|
||||
};
|
||||
|
||||
DEVICE i8237_dev = {
|
||||
"I8237", //name
|
||||
"8237", //name
|
||||
i8237_unit, //units
|
||||
i8237_reg, //registers
|
||||
i8237_mod, //modifiers
|
||||
@@ -391,8 +387,6 @@ t_stat i8237_reset(DEVICE *dptr, uint16 base)
|
||||
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);
|
||||
@@ -413,7 +407,7 @@ t_stat i8237_reset(DEVICE *dptr, uint16 base)
|
||||
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_reset1();
|
||||
i8237_devnum++;
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -429,25 +423,36 @@ uint8 i8237_get_dn(void)
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void i8237_reset1(int32 devnum)
|
||||
void i8237_reset1(void)
|
||||
{
|
||||
int32 i;
|
||||
UNIT *uptr;
|
||||
static int flag = 1;
|
||||
|
||||
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);
|
||||
for (i = 0; i < 1; i++) { /* handle all units */
|
||||
uptr = i8237_dev.units + i;
|
||||
if (uptr->capac == 0) { /* if not configured */
|
||||
// sim_printf(" SBC208%d: Not configured\n", i);
|
||||
// if (flag) {
|
||||
// sim_printf(" ALL: \"set isbc208 en\"\n");
|
||||
// sim_printf(" EPROM: \"att isbc2080 <filename>\"\n");
|
||||
// flag = 0;
|
||||
// }
|
||||
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[uptr->u6], i8237_unit[uptr->u6].wait);
|
||||
} else {
|
||||
// sim_printf(" SBC208%d: Configured, Attached to %s\n", i, uptr->filename);
|
||||
}
|
||||
}
|
||||
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_r8 = 0; /* status */
|
||||
i8237_r9 = 0; /* command */
|
||||
i8237_rB = 0x0F; /* mask */
|
||||
i8237_rC = 0; /* request */
|
||||
i8237_rD = 0; /* first/last FF */
|
||||
}
|
||||
|
||||
|
||||
@@ -478,26 +483,27 @@ uint8 i8237_r0x(t_bool io, uint8 data)
|
||||
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);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(H) read as %04X\n", i8237_r0);
|
||||
return (i8237_r0 >> 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);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(L) read as %04X\n", i8237_r0);
|
||||
return (i8237_r0 & 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]);
|
||||
i8237_r0 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(H) set to %04X\n", i8237_r0);
|
||||
} 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]);
|
||||
i8237_r0 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(L) set to %04X\n", i8237_r0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r1x(t_bool io, uint8 data)
|
||||
@@ -508,26 +514,27 @@ uint8 i8237_r1x(t_bool io, uint8 data)
|
||||
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);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(H) read as %04X\n", i8237_r1);
|
||||
return (i8237_r1 >> 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);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(L) read as %04X\n", i8237_r1);
|
||||
return (i8237_r1 & 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]);
|
||||
i8237_r1 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(H) set to %04X\n", i8237_r1);
|
||||
} 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]);
|
||||
i8237_r1 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(L) set to %04X\n", i8237_r1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r2x(t_bool io, uint8 data)
|
||||
@@ -538,26 +545,27 @@ uint8 i8237_r2x(t_bool io, uint8 data)
|
||||
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);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(H) read as %04X\n", i8237_r2);
|
||||
return (i8237_r2 >> 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);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(L) read as %04X\n", i8237_r2);
|
||||
return (i8237_r2 & 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]);
|
||||
i8237_r2 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(H) set to %04X\n", i8237_r2);
|
||||
} 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]);
|
||||
i8237_r2 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(L) set to %04X\n", i8237_r2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r3x(t_bool io, uint8 data)
|
||||
@@ -588,6 +596,7 @@ uint8 i8237_r3x(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r4x(t_bool io, uint8 data)
|
||||
@@ -618,6 +627,7 @@ uint8 i8237_r4x(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r5x(t_bool io, uint8 data)
|
||||
@@ -648,6 +658,7 @@ uint8 i8237_r5x(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r6x(t_bool io, uint8 data)
|
||||
@@ -678,6 +689,7 @@ uint8 i8237_r6x(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r7x(t_bool io, uint8 data)
|
||||
@@ -708,6 +720,7 @@ uint8 i8237_r7x(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r8x(t_bool io, uint8 data)
|
||||
@@ -724,6 +737,7 @@ uint8 i8237_r8x(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_r9x(t_bool io, uint8 data)
|
||||
@@ -740,6 +754,7 @@ uint8 i8237_r9x(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_rAx(t_bool io, uint8 data)
|
||||
@@ -781,6 +796,7 @@ uint8 i8237_rAx(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_rBx(t_bool io, uint8 data)
|
||||
@@ -797,6 +813,7 @@ uint8 i8237_rBx(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_rCx(t_bool io, uint8 data)
|
||||
@@ -813,6 +830,7 @@ uint8 i8237_rCx(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_rDx(t_bool io, uint8 data)
|
||||
@@ -829,6 +847,7 @@ uint8 i8237_rDx(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_rEx(t_bool io, uint8 data)
|
||||
@@ -845,6 +864,7 @@ uint8 i8237_rEx(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8237_rFx(t_bool io, uint8 data)
|
||||
@@ -861,6 +881,7 @@ uint8 i8237_rFx(t_bool io, uint8 data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* end of i8237.c */
|
||||
|
||||
866
Intel-Systems/common/i8237.c.old
Normal file
866
Intel-Systems/common/i8237.c.old
Normal file
@@ -0,0 +1,866 @@
|
||||
/* 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_NUM; i++)
|
||||
if (port >=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 */
|
||||
@@ -28,7 +28,7 @@
|
||||
This software was written by Bill Beech, 24 Jan 13, to allow emulation of
|
||||
more complex Multibus Computer Systems.
|
||||
|
||||
This program simulates up to 2 i8259 devices. It handles 1 i8259
|
||||
This program simulates up to 4 i8259 devices. It handles 1 i8259
|
||||
device on the iSBC 80/20 and iSBC 80/30 SBCs. Other devices could be on
|
||||
other multibus boards in the simulated system.
|
||||
*/
|
||||
@@ -69,7 +69,7 @@ uint8 i8259_ocw3[I8259_NUM];
|
||||
uint8 icw_num0 = 1, icw_num1 = 1;
|
||||
|
||||
/* i8259 Standard I/O Data Structures */
|
||||
/* up to 2 i8259 devices */
|
||||
/* up to 4 i8259 devices */
|
||||
|
||||
UNIT i8259_unit[] = {
|
||||
{ UDATA (0, 0, 0) }, /* i8259 0 */
|
||||
@@ -99,7 +99,6 @@ DEBTAB i8259_debug[] = {
|
||||
{ "FLOW", DEBUG_flow },
|
||||
{ "READ", DEBUG_read },
|
||||
{ "WRITE", DEBUG_write },
|
||||
{ "XACK", DEBUG_xack },
|
||||
{ "LEV1", DEBUG_level1 },
|
||||
{ "LEV2", DEBUG_level2 },
|
||||
{ NULL }
|
||||
|
||||
@@ -183,6 +183,9 @@
|
||||
#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
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
@@ -512,7 +515,7 @@ uint8 isbc2012(t_bool io, uint8 data)
|
||||
} else { /* write data port */
|
||||
fdc201[fdcnum].iopb |= (data << 8);
|
||||
if (DEBUG)
|
||||
sim_printf("\n isbc202-%d: 0x7A IOPB=%04X PCX=%04X",
|
||||
sim_printf("\n isbc201-%d: 0x7A IOPB=%04X PCX=%04X",
|
||||
fdcnum, fdc201[fdcnum].iopb, PCX);
|
||||
isbc201_diskio(fdcnum);
|
||||
if (fdc201[fdcnum].intff)
|
||||
|
||||
736
Intel-Systems/common/isbc202.c.new.c
Normal file
736
Intel-Systems/common/isbc202.c.new.c
Normal file
@@ -0,0 +1,736 @@
|
||||
/* 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<SBC202_NUM; i++)
|
||||
if (port >= 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 */
|
||||
467
Intel-Systems/common/pcbus.c
Normal file
467
Intel-Systems/common/pcbus.c
Normal file
@@ -0,0 +1,467 @@
|
||||
/* pcbus.c: PC bus simulator
|
||||
|
||||
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:
|
||||
|
||||
This software was written by Bill Beech, Jul 2016, to allow emulation of PC XT
|
||||
Computer Systems.
|
||||
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
int32 mbirq = 0; /* set no interrupts */
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat xtbus_svc(UNIT *uptr);
|
||||
t_stat xtbus_reset(DEVICE *dptr);
|
||||
void set_irq(int32 int_num);
|
||||
void clr_irq(int32 int_num);
|
||||
uint8 nulldev(t_bool io, uint8 data);
|
||||
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port);
|
||||
void dump_dev_table(void);
|
||||
t_stat xtbus_reset (DEVICE *dptr);
|
||||
uint8 xtbus_get_mbyte(uint32 addr);
|
||||
void xtbus_put_mbyte(uint32 addr, uint8 val);
|
||||
|
||||
/* external function prototypes */
|
||||
extern uint8 RAM_get_mbyte(uint32 addr);
|
||||
extern void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
extern t_stat SBC_reset(DEVICE *dptr); /* reset the PC XT simulator */
|
||||
extern void set_cpuint(int32 int_num);
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern int32 int_req; /* i8088 INT signal */
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* Standard SIMH Device Data Structures */
|
||||
|
||||
UNIT xtbus_unit = {
|
||||
UDATA (&xtbus_svc, 0, 0), 20
|
||||
};
|
||||
|
||||
REG xtbus_reg[] = {
|
||||
{ HRDATA (MBIRQ, mbirq, 32) },
|
||||
};
|
||||
|
||||
DEBTAB xtbus_debug[] = {
|
||||
{ "ALL", DEBUG_all },
|
||||
{ "FLOW", DEBUG_flow },
|
||||
{ "READ", DEBUG_read },
|
||||
{ "WRITE", DEBUG_write },
|
||||
{ "LEV1", DEBUG_level1 },
|
||||
{ "LEV2", DEBUG_level2 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE xtbus_dev = {
|
||||
"PCBUS", //name
|
||||
&xtbus_unit, //units
|
||||
xtbus_reg, //registers
|
||||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
NULL, //examine
|
||||
NULL, //deposit
|
||||
&xtbus_reset, //reset
|
||||
NULL, //boot
|
||||
NULL, //attach
|
||||
NULL, //detach
|
||||
NULL, //ctxt
|
||||
DEV_DEBUG, //flags
|
||||
0, //dctrl
|
||||
xtbus_debug, //debflags
|
||||
NULL, //msize
|
||||
NULL //lname
|
||||
};
|
||||
|
||||
/* Service routines to handle simulator functions */
|
||||
|
||||
/* service routine - actually does the simulated interrupts */
|
||||
|
||||
t_stat xtbus_svc(UNIT *uptr)
|
||||
{
|
||||
switch (mbirq) {
|
||||
case INT_1:
|
||||
set_cpuint(INT_R);
|
||||
sim_printf("xtbus_svc: mbirq=%04X int_req=%04X\n", mbirq, int_req);
|
||||
break;
|
||||
default:
|
||||
//sim_printf("xtbus_svc: default mbirq=%04X\n", mbirq);
|
||||
break;
|
||||
}
|
||||
sim_activate (&xtbus_unit, xtbus_unit.wait); /* continue poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat xtbus_reset(DEVICE *dptr)
|
||||
{
|
||||
SBC_reset(NULL);
|
||||
sim_printf(" Xtbus: Reset\n");
|
||||
sim_activate (&xtbus_unit, xtbus_unit.wait); /* activate unit */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
void set_irq(int32 int_num)
|
||||
{
|
||||
mbirq |= int_num;
|
||||
sim_printf("set_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
|
||||
}
|
||||
|
||||
void clr_irq(int32 int_num)
|
||||
{
|
||||
mbirq &= ~int_num;
|
||||
sim_printf("clr_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
|
||||
}
|
||||
|
||||
/* This is the I/O configuration table. There are 1024 possible
|
||||
device addresses, if a device is plugged to a port it's routine
|
||||
address is here, 'nulldev' means no device has been registered.
|
||||
The actual 808X can address 65,536 I/O ports but the IBM only uses
|
||||
the first 1024. */
|
||||
|
||||
struct idev {
|
||||
uint8 (*routine)(t_bool io, uint8 data);
|
||||
};
|
||||
|
||||
struct idev dev_table[1024] = {
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 000H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 004H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 008H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 010H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 014H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 018H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 01CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 020H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 024H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 028H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 02CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 030H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 034H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 038H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 03CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 040H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 044H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 048H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 050H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 054H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 058H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 05CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 060H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 064H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 068H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 06CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 070H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 074H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 078H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 07CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 080H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 084H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 088H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 08CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 090H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 094H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 098H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 09CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0FCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 100H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 104H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 108H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 10CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 110H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 114H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 118H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 11CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 120H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 124H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 128H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 12CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 130H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 134H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 138H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 13CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 140H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 144H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 148H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 14CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 150H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 154H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 158H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 15CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 160H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 164H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 168H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 16CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 170H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 174H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 178H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 17CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 180H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 184H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 188H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 18CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 190H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 194H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 198H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 19CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1FCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 200H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 204H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 208H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 20CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 210H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 214H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 218H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 21CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 220H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 224H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 228H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 22CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 230H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 234H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 238H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 23CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 240H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 244H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 248H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 24CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 250H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 254H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 258H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 25CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 260H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 264H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 268H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 26CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 270H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 274H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 278H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 27CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 280H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 284H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 288H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 28CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 290H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 294H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 298H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 29CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2FCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 300H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 304H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 308H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 30CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 310H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 314H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 318H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 31CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 320H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 324H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 328H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 32CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 330H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 334H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 338H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 33CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 340H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 344H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 348H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 34CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 350H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 354H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 358H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 35CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 360H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 364H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 368H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 36CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 370H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 374H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 378H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 37CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 380H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 384H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 388H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 38CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 390H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 394H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 398H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 39CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 3FCH */
|
||||
};
|
||||
|
||||
uint8 nulldev(t_bool flag, uint8 data)
|
||||
{
|
||||
sim_printf("xtbus: I/O Port %03X is not assigned io=%d data=%02X\n",
|
||||
port, flag, data);
|
||||
if (flag == 0) /* if we got here, no valid I/O device */
|
||||
return 0xFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port)
|
||||
{
|
||||
if (dev_table[port].routine != &nulldev) { /* port already assigned */
|
||||
sim_printf("xtbus: I/O Port %03X is already assigned\n", port);
|
||||
} else {
|
||||
sim_printf("Port %03X is assigned\n", port);
|
||||
dev_table[port].routine = routine;
|
||||
}
|
||||
//dump_dev_table();
|
||||
return port;
|
||||
}
|
||||
|
||||
void dump_dev_table(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<1024; i++) {
|
||||
if (dev_table[i].routine != &nulldev) { /* assigned port */
|
||||
sim_printf("Port %03X is assigned\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get a byte from bus */
|
||||
|
||||
uint8 xtbus_get_mbyte(uint32 addr)
|
||||
{
|
||||
return RAM_get_mbyte(addr);
|
||||
}
|
||||
|
||||
/* put a byte to bus */
|
||||
|
||||
void xtbus_put_mbyte(uint32 addr, uint8 val)
|
||||
{
|
||||
RAM_put_mbyte(addr, val);
|
||||
}
|
||||
|
||||
/* end of pcbus.c */
|
||||
|
||||
177
Intel-Systems/common/pceprom.c
Normal file
177
Intel-Systems/common/pceprom.c
Normal file
@@ -0,0 +1,177 @@
|
||||
/* pceprom.c: Intel EPROM simulator for 8-bit SBCs
|
||||
|
||||
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:
|
||||
|
||||
These functions support a simulated ROM devices on aPC XT SBC.
|
||||
This allows the attachment of the device to a binary file containing the EPROM
|
||||
code image. Unit will support a single 2764, 27128, 27256, or 27512 type EPROM.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr);
|
||||
t_stat EPROM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
uint8 EPROM_get_mbyte(uint32 addr);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
/* 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 },
|
||||
{ "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=%05X unit_capac=%05X\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, uint32 base, uint32 size)
|
||||
{
|
||||
sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=%05X size=%05X\n", base, size);
|
||||
if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */
|
||||
EPROM_unit.capac = size; /* set EPROM size */
|
||||
EPROM_unit.u3 = base; /* set EPROM base addr */
|
||||
sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
|
||||
sim_printf(" EPROM: Available [%05X-%05XH]\n",
|
||||
base, size);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
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(uint32 addr)
|
||||
{
|
||||
uint8 val;
|
||||
uint32 romoff;
|
||||
|
||||
romoff = addr - EPROM_unit.u3;
|
||||
sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%05X romoff=%05X\n", addr, romoff);
|
||||
if (romoff < EPROM_unit.capac) {
|
||||
val = *((uint8 *)EPROM_unit.filebuf + romoff);
|
||||
sim_debug (DEBUG_read, &EPROM_dev, " val=%02X\n", val);
|
||||
return (val & 0xFF);
|
||||
}
|
||||
sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n");
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* end of pceprom.c */
|
||||
145
Intel-Systems/common/pcram8.c
Normal file
145
Intel-Systems/common/pcram8.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/* pcram8.c: Intel RAM simulator for 8-bit SBCs
|
||||
|
||||
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:
|
||||
|
||||
These functions support a simulated RAM devices on a PC XT SBC.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat RAM_svc (UNIT *uptr);
|
||||
t_stat RAM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
uint8 RAM_get_mbyte(uint32 addr);
|
||||
void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern UNIT i8255_unit[];
|
||||
|
||||
/* 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 },
|
||||
{ "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, uint32 base, uint32 size)
|
||||
{
|
||||
sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%05X size=%05X\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 [%05X-%05XH]\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(uint32 addr)
|
||||
{
|
||||
uint8 val;
|
||||
|
||||
sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr);
|
||||
if ((addr >= (uint32)RAM_unit.u3) && ( addr < (uint32)(RAM_unit.u3 + RAM_unit.capac))) {
|
||||
val = *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3));
|
||||
sim_debug (DEBUG_read, &RAM_dev, " val=%04X\n", val);
|
||||
return (val & 0xFF);
|
||||
}
|
||||
sim_debug (DEBUG_read, &RAM_dev, " Out of range\n");
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* put a byte to memory */
|
||||
|
||||
void RAM_put_mbyte(uint32 addr, uint8 val)
|
||||
{
|
||||
sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
|
||||
if ((addr >= (uint32)RAM_unit.u3) && (addr < (uint32)(RAM_unit.u3 + RAM_unit.capac))) {
|
||||
*((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF;
|
||||
sim_debug (DEBUG_write, &RAM_dev, "\n");
|
||||
return;
|
||||
}
|
||||
sim_debug (DEBUG_write, &RAM_dev, " Out of range\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of pcram8.c */
|
||||
Reference in New Issue
Block a user