135 lines
4.9 KiB
C
135 lines
4.9 KiB
C
/* 3b2_cpu.h: AT&T 3B2 Model 400 IO dispatch implemenation
|
|
|
|
Copyright (c) 2017, Seth J. Morabito
|
|
|
|
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 THE AUTHORS OR COPYRIGHT HOLDERS
|
|
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 the author shall
|
|
not be used in advertising or otherwise to promote the sale, use or
|
|
other dealings in this Software without prior written authorization
|
|
from the author.
|
|
*/
|
|
|
|
#include "3b2_io.h"
|
|
|
|
struct iolink iotable[] = {
|
|
{ MMUBASE, MMUBASE+MMUSIZE, &mmu_read, &mmu_write },
|
|
{ IFBASE, IFBASE+IFSIZE, &if_read, &if_write },
|
|
{ IDBASE, IDBASE+IDSIZE, &id_read, &id_write },
|
|
{ TIMERBASE, TIMERBASE+TIMERSIZE, &timer_read, &timer_write },
|
|
{ NVRAMBASE, NVRAMBASE+NVRAMSIZE, &nvram_read, &nvram_write },
|
|
{ CSRBASE, CSRBASE+CSRSIZE, &csr_read, &csr_write },
|
|
{ IUBASE, IUBASE+IUSIZE, &iu_read, &iu_write },
|
|
{ DMAIDBASE, DMAIDBASE+DMAIDSIZE, &dmac_read, &dmac_write },
|
|
{ DMAIUABASE, DMAIUABASE+DMAIUASIZE, &dmac_read, &dmac_write },
|
|
{ DMAIUBBASE, DMAIUBBASE+DMAIUBSIZE, &dmac_read, &dmac_write },
|
|
{ DMACBASE, DMACBASE+DMACSIZE, &dmac_read, &dmac_write },
|
|
{ DMAIFBASE, DMAIFBASE+DMAIFSIZE, &dmac_read, &dmac_write },
|
|
{ TODBASE, TODBASE+TODSIZE, &tod_read, &tod_write },
|
|
{ 0, 0, NULL, NULL}
|
|
};
|
|
|
|
uint32 io_read(uint32 pa, size_t size)
|
|
{
|
|
struct iolink *p;
|
|
|
|
/* Special devices */
|
|
if (pa == 0x4c003) {
|
|
/* MEMSIZE register */
|
|
|
|
/* It appears that the following values map to memory sizes:
|
|
0x00: 512KB ( 524,288 B)
|
|
0x01: 2MB (2,097,152 B)
|
|
0x02: 1MB (1,048,576 B)
|
|
0x03: 4MB (4,194,304 B)
|
|
*/
|
|
switch(MEM_SIZE) {
|
|
case 0x80000: /* 512KB */
|
|
return 0;
|
|
case 0x100000: /* 1MB */
|
|
return 2;
|
|
case 0x200000: /* 2MB */
|
|
return 1;
|
|
case 0x400000: /* 4MB */
|
|
return 3;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/* IO Board Area - Unimplemented */
|
|
if (pa >= 0x200000 && pa < 0x2000000) {
|
|
sim_debug(IO_D_MSG, &cpu_dev, "[%08x] [IO BOARD READ] ADDR=%08x\n", R[NUM_PC], pa);
|
|
/* When we implement boards, register them here
|
|
N.B.: High byte of board ID is read at 0xnnnnn0,
|
|
low byte at 0xnnnnn1 */
|
|
|
|
/* Since we have no cards in our system, there's nothing
|
|
to read. We indicate that our bus read timed out with
|
|
CSRTIMO, then abort.*/
|
|
csr_data |= CSRTIMO;
|
|
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
|
return 0;
|
|
}
|
|
|
|
for (p = &iotable[0]; p->low != 0; p++) {
|
|
if ((pa >= p->low) && (pa < p->high) && p->read) {
|
|
return p->read(pa, size);
|
|
}
|
|
}
|
|
|
|
/* Not found. */
|
|
sim_debug(IO_D_MSG, &cpu_dev,
|
|
"[%08x] [io_read] ADDR=%08x: No device found.\n",
|
|
R[NUM_PC], pa);
|
|
csr_data |= CSRTIMO;
|
|
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
|
return 0;
|
|
}
|
|
|
|
void io_write(uint32 pa, uint32 val, size_t size)
|
|
{
|
|
struct iolink *p;
|
|
|
|
/* IO Board Area - Unimplemented */
|
|
if (pa >= 0x200000 && pa < 0x2000000) {
|
|
sim_debug(IO_D_MSG, &cpu_dev,
|
|
"[%08x] ADDR=%08x, DATA=%08x\n",
|
|
R[NUM_PC], pa, val);
|
|
csr_data |= CSRTIMO;
|
|
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
|
return;
|
|
}
|
|
|
|
for (p = &iotable[0]; p->low != 0; p++) {
|
|
if ((pa >= p->low) && (pa < p->high) && p->write) {
|
|
p->write(pa, val, size);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* Not found. */
|
|
sim_debug(IO_D_MSG, &cpu_dev,
|
|
"[%08x] [io_write] ADDR=%08x: No device found.\n",
|
|
R[NUM_PC], pa);
|
|
csr_data |= CSRTIMO;
|
|
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
|
}
|